F: include/exec/helper*.h.inc
F: include/exec/helper-info.c.inc
F: include/exec/page-protection.h
-F: include/sysemu/cpus.h
-F: include/sysemu/tcg.h
+F: include/system/cpus.h
+F: include/system/tcg.h
F: include/hw/core/tcg-cpu-ops.h
F: host/include/*/host/cpuinfo.h
F: util/cpuinfo-*.c
F: accel/kvm/
F: accel/stubs/kvm-stub.c
F: include/hw/kvm/
-F: include/sysemu/kvm*.h
+F: include/system/kvm*.h
F: scripts/kvm/kvm_flightrecorder
ARM KVM CPUs
M: Huacai Chen <chenhuacai@kernel.org>
S: Odd Fixes
F: target/mips/kvm*
-F: target/mips/sysemu/
+F: target/mips/system/
PPC KVM CPUs
M: Nicholas Piggin <npiggin@gmail.com>
M: David Woodhouse <dwmw2@infradead.org>
M: Paul Durrant <paul@xen.org>
S: Supported
-F: include/sysemu/kvm_xen.h
+F: include/system/kvm_xen.h
F: target/i386/kvm/xen*
F: hw/i386/kvm/xen*
F: tests/avocado/kvm_xen_guest.py
R: Paolo Bonzini <pbonzini@redhat.com>
S: Maintained
F: include/qemu/accel.h
-F: include/sysemu/accel-*.h
+F: include/system/accel-*.h
F: include/hw/core/accel-cpu.h
F: accel/accel-*.c
F: accel/Makefile.objs
W: https://wiki.qemu.org/Features/HVF
S: Maintained
F: accel/hvf/
-F: include/sysemu/hvf.h
-F: include/sysemu/hvf_int.h
+F: include/system/hvf.h
+F: include/system/hvf_int.h
WHPX CPUs
M: Sunil Muthuswamy <sunilmut@microsoft.com>
S: Supported
F: target/i386/whpx/
-F: include/sysemu/whpx.h
+F: include/system/whpx.h
Guest CPU Cores (Xen)
---------------------
F: hw/pci-host/xen_igd_pt.c
F: include/hw/block/dataplane/xen*
F: include/hw/xen/
-F: include/sysemu/xen.h
-F: include/sysemu/xen-mapcache.h
+F: include/system/xen.h
+F: include/system/xen-mapcache.h
F: stubs/xen-hw-stub.c
F: docs/system/arm/xenpvh.rst
F: docs/system/i386/xenpvh.rst
NetBSD Virtual Machine Monitor (NVMM) CPU support
M: Reinoud Zandijk <reinoud@netbsd.org>
S: Maintained
-F: include/sysemu/nvmm.h
+F: include/system/nvmm.h
F: target/i386/nvmm/
Hosts
M: Paolo Bonzini <pbonzini@redhat.com>
S: Maintained
F: os-posix.c
-F: include/sysemu/os-posix.h
+F: include/system/os-posix.h
F: util/*posix*.c
F: include/qemu/*posix*.h
R: Zhao Liu <zhao1.liu@intel.com>
S: Supported
F: hw/core/cpu-common.c
-F: hw/core/cpu-sysemu.c
+F: hw/core/cpu-system.c
F: hw/core/machine-qmp-cmds.c
F: hw/core/machine.c
F: hw/core/machine-smp.c
F: include/hw/boards.h
F: include/hw/core/cpu.h
F: include/hw/cpu/cluster.h
-F: include/sysemu/numa.h
+F: include/system/numa.h
F: tests/functional/test_cpu_queries.py
F: tests/functional/test_empty_cpu_model.py
F: tests/unit/test-smp-parse.c
M: Zhenzhong Duan <zhenzhong.duan@intel.com>
S: Supported
F: backends/iommufd.c
-F: include/sysemu/iommufd.h
+F: include/system/iommufd.h
F: backends/host_iommu_device.c
-F: include/sysemu/host_iommu_device.h
+F: include/system/host_iommu_device.h
F: include/qemu/chardev_open.h
F: util/chardev_open.c
F: docs/devel/vfio-iommufd.rst
F: docs/interop/vhost-user.rst
F: contrib/vhost-user-*/
F: backends/vhost-user.c
-F: include/sysemu/vhost-user-backend.h
+F: include/system/vhost-user-backend.h
F: subprojects/libvhost-user/
vhost-shadow-virtqueue
F: hw/virtio/virtio-balloon*.c
F: include/hw/virtio/virtio-balloon.h
F: system/balloon.c
-F: include/sysemu/balloon.h
+F: include/system/balloon.h
F: tests/qtest/virtio-balloon-test.c
virtio-9p
S: Supported
F: hw/virtio/virtio-rng.c
F: include/hw/virtio/virtio-rng.h
-F: include/sysemu/rng*.h
+F: include/system/rng*.h
F: backends/rng*.c
F: tests/qtest/virtio-rng-test.c
F: qapi/block*.json
F: qapi/transaction.json
F: include/block/
-F: include/sysemu/block-*.h
+F: include/system/block-*.h
F: qemu-img*
F: docs/tools/qemu-img.rst
F: qemu-io*
R: David Gibson <david@gibson.dropbear.id.au>
S: Maintained
F: system/device_tree.c
-F: include/sysemu/device_tree.h
+F: include/system/device_tree.h
Dump
S: Supported
F: hw/misc/vmcoreinfo.c
F: include/hw/misc/vmcoreinfo.h
F: include/qemu/win_dump_defs
-F: include/sysemu/dump-arch.h
-F: include/sysemu/dump.h
+F: include/system/dump-arch.h
+F: include/system/dump.h
F: qapi/dump.json
F: scripts/dump-guest-memory.py
F: stubs/dump.c
F: include/exec/memory.h
F: include/exec/ram_addr.h
F: include/exec/ramblock.h
-F: include/sysemu/memory_mapping.h
+F: include/system/memory_mapping.h
F: system/dma-helpers.c
F: system/ioport.c
F: system/memory.c
M: Paolo Bonzini <pbonzini@redhat.com>
S: Maintained
F: include/qemu/main-loop.h
-F: include/sysemu/runstate.h
-F: include/sysemu/runstate-action.h
+F: include/system/runstate.h
+F: include/system/runstate-action.h
F: util/main-loop.c
F: util/qemu-timer*.c
F: system/vl.c
M: Igor Mammedov <imammedo@redhat.com>
S: Maintained
F: backends/hostmem*.c
-F: include/sysemu/hostmem.h
+F: include/system/hostmem.h
F: docs/system/vm-templating.rst
T: git https://gitlab.com/ehabkost/qemu.git machine-next
M: Gonglei <arei.gonglei@huawei.com>
M: zhenwei pi <pizhenwei@bytedance.com>
S: Maintained
-F: include/sysemu/cryptodev*.h
+F: include/system/cryptodev*.h
F: backends/cryptodev*.c
F: qapi/cryptodev.json
R: Paolo Bonzini <pbonzini@redhat.com>
S: Maintained
F: system/qtest.c
-F: include/sysemu/qtest.h
+F: include/system/qtest.h
F: accel/qtest/
F: tests/qtest/
F: docs/devel/qgraph.rst
Stats
S: Orphan
-F: include/sysemu/stats.h
+F: include/system/stats.h
F: stats/
F: qapi/stats.json
F: system/tpm*
F: hw/tpm/*
F: include/hw/acpi/tpm.h
-F: include/sysemu/tpm*
+F: include/system/tpm*
F: qapi/tpm.json
F: backends/tpm/
F: tests/qtest/*tpm*
M: Alistair Francis <alistair.francis@wdc.com>
S: Maintained
F: backends/spdm-socket.c
-F: include/sysemu/spdm-socket.h
+F: include/system/spdm-socket.h
Checkpatch
S: Odd Fixes
M: Hyman Huang <yong.huang@smartx.com>
S: Maintained
F: system/dirtylimit.c
-F: include/sysemu/dirtylimit.h
+F: include/system/dirtylimit.h
F: migration/dirtyrate.c
F: migration/dirtyrate.h
-F: include/sysemu/dirtyrate.h
+F: include/system/dirtyrate.h
F: docs/devel/migration/dirty-limit.rst
Detached LUKS header
M: Daniel P. Berrange <berrange@redhat.com>
S: Odd Fixes
F: system/qemu-seccomp.c
-F: include/sysemu/seccomp.h
+F: include/system/seccomp.h
F: tests/unit/test-seccomp.c
Cryptography
F: block/blkreplay.c
F: net/filter-replay.c
F: include/exec/replay-core.h
-F: include/sysemu/replay.h
+F: include/system/replay.h
F: docs/devel/replay.rst
F: docs/system/replay.rst
F: stubs/replay.c
S: Maintained
F: include/hw/resettable.h
F: include/hw/core/resetcontainer.h
-F: include/sysemu/reset.h
+F: include/system/reset.h
F: hw/core/reset.c
F: hw/core/resettable.c
F: hw/core/resetcontainer.c
#include "qemu/thread.h"
#include "qemu/main-loop.h"
#include "hw/core/cpu.h"
-#include "sysemu/accel-blocker.h"
+#include "system/accel-blocker.h"
static QemuLockCnt accel_in_ioctl_lock;
static QemuEvent accel_in_ioctl_event;
#include "qemu/osdep.h"
#include "qemu/accel.h"
#include "hw/boards.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
#include "qemu/error-report.h"
#include "accel-system.h"
#include "qemu/osdep.h"
#include "qemu/rcu.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
#include "qemu/guest-random.h"
#include "qemu/main-loop.h"
#include "hw/core/cpu.h"
#include "exec/exec-all.h"
#include "gdbstub/enums.h"
#include "hw/boards.h"
-#include "sysemu/cpus.h"
-#include "sysemu/hvf.h"
-#include "sysemu/hvf_int.h"
-#include "sysemu/runstate.h"
+#include "system/cpus.h"
+#include "system/hvf.h"
+#include "system/hvf_int.h"
+#include "system/runstate.h"
#include "qemu/guest-random.h"
HVFState *hvf_state;
#include "qemu/osdep.h"
#include "qemu/error-report.h"
-#include "sysemu/hvf.h"
-#include "sysemu/hvf_int.h"
+#include "system/hvf.h"
+#include "system/hvf_int.h"
const char *hvf_return_string(hv_return_t ret)
{
#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
-#include "sysemu/kvm.h"
-#include "sysemu/kvm_int.h"
-#include "sysemu/runstate.h"
-#include "sysemu/cpus.h"
+#include "system/kvm.h"
+#include "system/kvm_int.h"
+#include "system/runstate.h"
+#include "system/cpus.h"
#include "qemu/guest-random.h"
#include "qapi/error.h"
#include "hw/pci/msix.h"
#include "hw/s390x/adapter.h"
#include "gdbstub/enums.h"
-#include "sysemu/kvm_int.h"
-#include "sysemu/runstate.h"
-#include "sysemu/cpus.h"
-#include "sysemu/accel-blocker.h"
+#include "system/kvm_int.h"
+#include "system/runstate.h"
+#include "system/cpus.h"
+#include "system/accel-blocker.h"
#include "qemu/bswap.h"
#include "exec/memory.h"
#include "exec/ram_addr.h"
#include "qapi/visitor.h"
#include "qapi/qapi-types-common.h"
#include "qapi/qapi-visit-common.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "qemu/guest-random.h"
-#include "sysemu/hw_accel.h"
+#include "system/hw_accel.h"
#include "kvm-cpus.h"
-#include "sysemu/dirtylimit.h"
+#include "system/dirtylimit.h"
#include "qemu/range.h"
#include "hw/boards.h"
-#include "sysemu/stats.h"
+#include "system/stats.h"
/* This check must be after config-host.h is included */
#ifdef CONFIG_EVENTFD
#ifndef KVM_CPUS_H
#define KVM_CPUS_H
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
int kvm_init_vcpu(CPUState *cpu, Error **errp);
int kvm_cpu_exec(CPUState *cpu);
#include "qemu/option.h"
#include "qemu/config-file.h"
#include "qemu/accel.h"
-#include "sysemu/qtest.h"
-#include "sysemu/cpus.h"
+#include "system/qtest.h"
+#include "system/cpus.h"
#include "qemu/guest-random.h"
#include "qemu/main-loop.h"
#include "hw/core/cpu.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "hw/pci/msi.h"
KVMState *kvm_state;
*/
#include "qemu/osdep.h"
-#include "sysemu/xen.h"
+#include "system/xen.h"
#include "qapi/qapi-commands-migration.h"
bool xen_allowed;
*/
#include "qemu/osdep.h"
-#include "sysemu/cpus.h"
-#include "sysemu/tcg.h"
+#include "system/cpus.h"
+#include "system/tcg.h"
#include "qemu/plugin.h"
#include "internal-common.h"
#include "qemu/rcu.h"
#include "exec/log.h"
#include "qemu/main-loop.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
#include "exec/cpu-all.h"
-#include "sysemu/cpu-timers.h"
+#include "system/cpu-timers.h"
#include "exec/replay-core.h"
-#include "sysemu/tcg.h"
+#include "system/tcg.h"
#include "exec/helper-proto-common.h"
#include "tb-jmp-cache.h"
#include "tb-hash.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
-#include "sysemu/cpus.h"
-#include "sysemu/qtest.h"
+#include "system/cpus.h"
+#include "system/qtest.h"
#include "qemu/main-loop.h"
#include "qemu/option.h"
#include "qemu/seqlock.h"
-#include "sysemu/replay.h"
-#include "sysemu/runstate.h"
+#include "system/replay.h"
+#include "system/runstate.h"
#include "hw/core/cpu.h"
-#include "sysemu/cpu-timers.h"
-#include "sysemu/cpu-timers-internal.h"
+#include "system/cpu-timers.h"
+#include "system/cpu-timers-internal.h"
/*
* ICOUNT: Instruction Counter
#include "qapi/type-helpers.h"
#include "qapi/qapi-commands-machine.h"
#include "monitor/monitor.h"
-#include "sysemu/cpus.h"
-#include "sysemu/cpu-timers.h"
-#include "sysemu/tcg.h"
+#include "system/cpus.h"
+#include "system/cpu-timers.h"
+#include "system/tcg.h"
#include "tcg/tcg.h"
#include "internal-common.h"
#include "tb-context.h"
#include "exec/page-protection.h"
#include "exec/tb-flush.h"
#include "exec/translate-all.h"
-#include "sysemu/tcg.h"
+#include "system/tcg.h"
#include "tcg/tcg.h"
#include "tb-hash.h"
#include "tb-context.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/replay.h"
-#include "sysemu/cpu-timers.h"
+#include "system/replay.h"
+#include "system/cpu-timers.h"
#include "qemu/main-loop.h"
#include "qemu/guest-random.h"
#include "exec/exec-all.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/tcg.h"
-#include "sysemu/replay.h"
-#include "sysemu/cpu-timers.h"
+#include "system/tcg.h"
+#include "system/replay.h"
+#include "system/cpu-timers.h"
#include "qemu/main-loop.h"
#include "qemu/notify.h"
#include "qemu/guest-random.h"
#include "qemu/osdep.h"
#include "qemu/lockable.h"
-#include "sysemu/tcg.h"
-#include "sysemu/replay.h"
-#include "sysemu/cpu-timers.h"
+#include "system/tcg.h"
+#include "system/replay.h"
+#include "system/cpu-timers.h"
#include "qemu/main-loop.h"
#include "qemu/notify.h"
#include "qemu/guest-random.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/tcg.h"
-#include "sysemu/replay.h"
-#include "sysemu/cpu-timers.h"
+#include "system/tcg.h"
+#include "system/replay.h"
+#include "system/cpu-timers.h"
#include "qemu/main-loop.h"
#include "qemu/guest-random.h"
#include "qemu/timer.h"
#ifndef TCG_ACCEL_OPS_H
#define TCG_ACCEL_OPS_H
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
void tcg_cpu_destroy(CPUState *cpu);
int tcg_cpu_exec(CPUState *cpu);
*/
#include "qemu/osdep.h"
-#include "sysemu/tcg.h"
+#include "system/tcg.h"
#include "exec/replay-core.h"
-#include "sysemu/cpu-timers.h"
+#include "system/cpu-timers.h"
#include "tcg/startup.h"
#include "tcg/oversized-guest.h"
#include "qapi/error.h"
#include "qemu/cacheinfo.h"
#include "qemu/timer.h"
#include "exec/log.h"
-#include "sysemu/cpus.h"
-#include "sysemu/cpu-timers.h"
-#include "sysemu/tcg.h"
+#include "system/cpus.h"
+#include "system/cpu-timers.h"
+#include "system/tcg.h"
#include "qapi/error.h"
#include "hw/core/tcg-cpu-ops.h"
#include "tb-jmp-cache.h"
#include "qemu/error-report.h"
#include "exec/exec-all.h"
#include "exec/translate-all.h"
-#include "sysemu/tcg.h"
-#include "sysemu/replay.h"
+#include "system/tcg.h"
+#include "system/replay.h"
#include "hw/core/tcg-cpu-ops.h"
#include "hw/core/cpu.h"
#include "hw/xen/xen_igd.h"
#include "chardev/char.h"
#include "qemu/accel.h"
-#include "sysemu/cpus.h"
-#include "sysemu/xen.h"
-#include "sysemu/runstate.h"
+#include "system/cpus.h"
+#include "system/xen.h"
+#include "system/runstate.h"
#include "migration/misc.h"
#include "migration/global_state.h"
#include "hw/boards.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/help_option.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/replay.h"
-#include "sysemu/runstate.h"
+#include "system/system.h"
+#include "system/replay.h"
+#include "system/runstate.h"
#include "ui/qemu-spice.h"
#include "trace.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/cryptodev.h"
+#include "system/cryptodev.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "standard-headers/linux/virtio_crypto.h"
#include "qemu/error-report.h"
#include "qemu/queue.h"
#include "qom/object.h"
-#include "sysemu/cryptodev.h"
+#include "system/cryptodev.h"
#include "standard-headers/linux/virtio_crypto.h"
#include <keyutils.h>
#include "qemu/error-report.h"
#include "hw/virtio/vhost-user.h"
#include "standard-headers/linux/virtio_crypto.h"
-#include "sysemu/cryptodev-vhost.h"
+#include "system/cryptodev-vhost.h"
#include "chardev/char-fe.h"
-#include "sysemu/cryptodev-vhost-user.h"
+#include "system/cryptodev-vhost-user.h"
#include "qom/object.h"
#include "qemu/osdep.h"
#include "hw/virtio/virtio-bus.h"
-#include "sysemu/cryptodev-vhost.h"
+#include "system/cryptodev-vhost.h"
#ifdef CONFIG_VHOST_CRYPTO
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "hw/virtio/virtio-crypto.h"
-#include "sysemu/cryptodev-vhost-user.h"
+#include "system/cryptodev-vhost-user.h"
uint64_t
cryptodev_vhost_get_max_queues(
*/
#include "qemu/osdep.h"
-#include "sysemu/cryptodev.h"
-#include "sysemu/stats.h"
+#include "system/cryptodev.h"
+#include "system/stats.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-cryptodev.h"
#include "qapi/qapi-types-stats.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/host_iommu_device.h"
+#include "system/host_iommu_device.h"
OBJECT_DEFINE_ABSTRACT_TYPE(HostIOMMUDevice,
host_iommu_device,
#include <sys/ioctl.h>
#include "qom/object_interfaces.h"
#include "qapi/error.h"
-#include "sysemu/hostmem.h"
+#include "system/hostmem.h"
#include "hw/i386/hostmem-epc.h"
static bool
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qemu/madvise.h"
-#include "sysemu/hostmem.h"
+#include "system/hostmem.h"
#include "qom/object_interfaces.h"
#include "qom/object.h"
#include "qapi/visitor.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/hostmem.h"
+#include "system/hostmem.h"
#include "qom/object_interfaces.h"
#include "qemu/memfd.h"
#include "qemu/module.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/hostmem.h"
+#include "system/hostmem.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "qom/object_interfaces.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/hostmem.h"
+#include "system/hostmem.h"
#include "qapi/error.h"
#define TYPE_MEMORY_BACKEND_SHM "memory-backend-shm"
*/
#include "qemu/osdep.h"
-#include "sysemu/hostmem.h"
+#include "system/hostmem.h"
#include "hw/boards.h"
#include "qapi/error.h"
#include "qapi/qapi-builtin-visit.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/iommufd.h"
+#include "system/iommufd.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "qom/object_interfaces.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/rng.h"
+#include "system/rng.h"
#include "qemu/main-loop.h"
#include "qemu/guest-random.h"
#include "qom/object.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
OBJECT_DECLARE_SIMPLE_TYPE(RngBuiltin, RNG_BUILTIN)
*/
#include "qemu/osdep.h"
-#include "sysemu/rng.h"
+#include "system/rng.h"
#include "chardev/char-fe.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/rng-random.h"
-#include "sysemu/rng.h"
+#include "system/rng-random.h"
+#include "system/rng.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/main-loop.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/rng.h"
+#include "system/rng.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "qom/object_interfaces.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/spdm-socket.h"
+#include "system/spdm-socket.h"
#include "qapi/error.h"
static bool read_bytes(const int socket, uint8_t *buffer,
*/
#include "qemu/osdep.h"
-#include "sysemu/tpm_backend.h"
+#include "system/tpm_backend.h"
#include "qapi/error.h"
-#include "sysemu/tpm.h"
+#include "system/tpm.h"
#include "qemu/thread.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "qemu/sockets.h"
#include "qemu/lockable.h"
#include "io/channel-socket.h"
-#include "sysemu/runstate.h"
-#include "sysemu/tpm_backend.h"
-#include "sysemu/tpm_util.h"
+#include "system/runstate.h"
+#include "system/tpm_backend.h"
+#include "system/tpm_util.h"
#include "tpm_int.h"
#include "tpm_ioctl.h"
#include "migration/blocker.h"
#define BACKENDS_TPM_INT_H
#include "qemu/option.h"
-#include "sysemu/tpm.h"
+#include "system/tpm.h"
#define TPM_STANDARD_CMDLINE_OPTS \
{ \
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qemu/sockets.h"
-#include "sysemu/tpm_backend.h"
-#include "sysemu/tpm_util.h"
+#include "system/tpm_backend.h"
+#include "system/tpm_util.h"
#include "tpm_int.h"
#include "qapi/clone-visitor.h"
#include "qapi/qapi-visit-tpm.h"
#include "tpm_int.h"
#include "exec/memory.h"
#include "hw/qdev-properties.h"
-#include "sysemu/tpm_backend.h"
-#include "sysemu/tpm_util.h"
+#include "system/tpm_backend.h"
+#include "system/tpm_util.h"
#include "trace.h"
/* tpm backend property */
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qom/object_interfaces.h"
-#include "sysemu/vhost-user-backend.h"
-#include "sysemu/kvm.h"
+#include "system/vhost-user-backend.h"
+#include "system/kvm.h"
#include "io/channel-command.h"
#include "hw/virtio/virtio-bus.h"
#include "qapi/qmp/qstring.h"
#include "qapi/qobject-output-visitor.h"
#include "qapi/qapi-visit-block-core.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qemu/notify.h"
#include "qemu/option.h"
#include "qemu/coroutine.h"
#include "block/accounting.h"
#include "block/block_int.h"
#include "qemu/timer.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
static QEMUClockType clock_type = QEMU_CLOCK_REALTIME;
static const int qtest_latency_ns = NANOSECONDS_PER_SECOND / 1000;
#include "block/dirty-bitmap.h"
#include "qapi/error.h"
#include "qemu/cutils.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qemu/bitmap.h"
#include "qemu/error-report.h"
#include "qapi/qmp/qlist.h"
#include "qapi/qmp/qstring.h"
#include "qapi/qobject-input-visitor.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
/* All APIs are thread-safe */
#include "qemu/error-report.h"
#include "qapi/qmp/qdict.h"
#include "qemu/module.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "exec/memory.h" /* for ram_block_discard_disable() */
#include "block/block-io.h"
#include "qemu/module.h"
#include "block/block-io.h"
#include "block/block_int.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "qapi/error.h"
typedef struct Request {
*/
#include "qemu/osdep.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "block/block_int.h"
#include "block/blockjob.h"
#include "block/coroutines.h"
#include "block/throttle-groups.h"
#include "hw/qdev-core.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/runstate.h"
-#include "sysemu/replay.h"
+#include "system/blockdev.h"
+#include "system/runstate.h"
+#include "system/replay.h"
#include "qapi/error.h"
#include "qapi/qapi-events-block.h"
#include "qemu/id.h"
#include "block/block_int-io.h"
#include "block/dirty-bitmap.h"
#include "block/reqlist.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qemu/units.h"
#include "qemu/co-shared-resource.h"
#include "qemu/coroutine.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/block-ram-registrar.h"
+#include "system/block-backend.h"
+#include "system/block-ram-registrar.h"
#include "qapi/error.h"
static void ram_block_added(RAMBlockNotifier *n, void *host, size_t size,
#include "qapi/error.h"
#include "qemu/ratelimit.h"
#include "qemu/memalign.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
enum {
/*
#include "qemu/osdep.h"
#include "qapi/qmp/qjson.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
#include "block/block_int.h"
#include "block/block_int.h"
/* For blk_bs() in generated block/block-gen.c */
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
/*
* I/O API functions. These functions are thread-safe.
#include "block/block_int.h"
#include "block/qdict.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "crypto/block.h"
#include "qapi/opts-visitor.h"
#include "qapi/qapi-visit-crypto.h"
#include "qemu/osdep.h"
#include "block/block.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/iothread.h"
+#include "system/block-backend.h"
+#include "system/iothread.h"
#include "block/export.h"
#include "block/fuse.h"
#include "block/nbd.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-block.h"
#include "qemu/main-loop.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include <fuse.h>
#include <fuse_lowlevel.h>
#ifndef VIRTIO_BLK_HANDLER_H
#define VIRTIO_BLK_HANDLER_H
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#define VIRTIO_BLK_SECTOR_BITS 9
#define VIRTIO_BLK_SECTOR_SIZE (1ULL << VIRTIO_BLK_SECTOR_BITS)
#include "qemu/osdep.h"
#include "trace.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "block/aio-wait.h"
#include "block/blockjob.h"
#include "block/blockjob_int.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
/* Maximum bounce buffer for copy-on-read and write zeroes, in bytes */
#define MAX_BOUNCE_BUFFER (32768 << BDRV_SECTOR_BITS)
#include "qemu/coroutine.h"
#include "qemu/defer-call.h"
#include "qapi/error.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "trace.h"
/* Only used for assertions. */
#include <poll.h>
#include <math.h>
#include <arpa/inet.h>
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "qemu/bitops.h"
#include "qemu/module.h"
#include "qemu/option.h"
#include "qemu/uuid.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-machine.h"
#include "qapi/qmp/qdict.h"
#include "qemu/coroutine.h"
#include "qemu/defer-call.h"
#include "qapi/error.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
/* Only used for assertions. */
#include "qemu/coroutine_int.h"
'../include/block/dirty-bitmap.h',
'../include/block/block_int-io.h',
'../include/block/block-global-state.h',
- '../include/sysemu/block-backend-global-state.h',
- '../include/sysemu/block-backend-io.h',
+ '../include/system/block-backend-global-state.h',
+ '../include/system/block-backend-io.h',
'coroutines.h'
),
command: [wrapper_py, '@OUTPUT@', '@INPUT@'])
block_ss.add(files('stream.c'))
-system_ss.add(files('qapi-sysemu.c'))
+system_ss.add(files('qapi-system.c'))
subdir('export')
subdir('monitor')
#include "block/blockjob_int.h"
#include "block/block_int.h"
#include "block/dirty-bitmap.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qapi/error.h"
#include "qemu/ratelimit.h"
#include "qemu/bitmap.h"
#include "qemu/osdep.h"
#include "hw/boards.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
+#include "system/block-backend.h"
+#include "system/blockdev.h"
#include "qapi/qapi-commands-block.h"
#include "qapi/qapi-commands-block-export.h"
#include "qapi/qmp/qdict.h"
#include "qemu/sockets.h"
#include "qemu/cutils.h"
#include "qemu/error-report.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "monitor/monitor.h"
#include "monitor/hmp.h"
#include "block/nbd.h"
#include "qemu/module.h"
#include "qemu/option.h"
#include "qemu/cutils.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "qapi/qapi-visit-block-core.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qstring.h"
#include "qemu/option.h"
#include "block/block-io.h"
#include "block/block_int.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#define NULL_OPT_LATENCY "latency-ns"
#define NULL_OPT_ZEROES "read-zeroes"
#include "qemu/vfio-helpers.h"
#include "block/block-io.h"
#include "block/block_int.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/replay.h"
+#include "system/block-backend.h"
+#include "system/replay.h"
#include "trace.h"
#include "block/nvme.h"
#include "qapi/error.h"
#include "block/block_int.h"
#include "block/qdict.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qemu/module.h"
#include "qemu/option.h"
#include "qapi/qmp/qdict.h"
+++ /dev/null
-/*
- * QMP command handlers specific to the system emulators
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or
- * later. See the COPYING file in the top-level directory.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- *
- * 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 "block/block_int.h"
-#include "qapi/error.h"
-#include "qapi/qapi-commands-block.h"
-#include "qapi/qmp/qdict.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
-
-static BlockBackend *qmp_get_blk(const char *blk_name, const char *qdev_id,
- Error **errp)
-{
- BlockBackend *blk;
-
- if (!blk_name == !qdev_id) {
- error_setg(errp, "Need exactly one of 'device' and 'id'");
- return NULL;
- }
-
- if (qdev_id) {
- blk = blk_by_qdev_id(qdev_id, errp);
- } else {
- blk = blk_by_name(blk_name);
- if (blk == NULL) {
- error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
- "Device '%s' not found", blk_name);
- }
- }
-
- return blk;
-}
-
-/*
- * Attempt to open the tray of @device.
- * If @force, ignore its tray lock.
- * Else, if the tray is locked, don't open it, but ask the guest to open it.
- * On error, store an error through @errp and return -errno.
- * If @device does not exist, return -ENODEV.
- * If it has no removable media, return -ENOTSUP.
- * If it has no tray, return -ENOSYS.
- * If the guest was asked to open the tray, return -EINPROGRESS.
- * Else, return 0.
- */
-static int do_open_tray(const char *blk_name, const char *qdev_id,
- bool force, Error **errp)
-{
- BlockBackend *blk;
- const char *device = qdev_id ?: blk_name;
- bool locked;
-
- blk = qmp_get_blk(blk_name, qdev_id, errp);
- if (!blk) {
- return -ENODEV;
- }
-
- if (!blk_dev_has_removable_media(blk)) {
- error_setg(errp, "Device '%s' is not removable", device);
- return -ENOTSUP;
- }
-
- if (!blk_dev_has_tray(blk)) {
- error_setg(errp, "Device '%s' does not have a tray", device);
- return -ENOSYS;
- }
-
- if (blk_dev_is_tray_open(blk)) {
- return 0;
- }
-
- locked = blk_dev_is_medium_locked(blk);
- if (locked) {
- blk_dev_eject_request(blk, force);
- }
-
- if (!locked || force) {
- blk_dev_change_media_cb(blk, false, &error_abort);
- }
-
- if (locked && !force) {
- error_setg(errp, "Device '%s' is locked and force was not specified, "
- "wait for tray to open and try again", device);
- return -EINPROGRESS;
- }
-
- return 0;
-}
-
-void qmp_blockdev_open_tray(const char *device,
- const char *id,
- bool has_force, bool force,
- Error **errp)
-{
- Error *local_err = NULL;
- int rc;
-
- if (!has_force) {
- force = false;
- }
- rc = do_open_tray(device, id, force, &local_err);
- if (rc && rc != -ENOSYS && rc != -EINPROGRESS) {
- error_propagate(errp, local_err);
- return;
- }
- error_free(local_err);
-}
-
-void qmp_blockdev_close_tray(const char *device,
- const char *id,
- Error **errp)
-{
- BlockBackend *blk;
- Error *local_err = NULL;
-
- blk = qmp_get_blk(device, id, errp);
- if (!blk) {
- return;
- }
-
- if (!blk_dev_has_removable_media(blk)) {
- error_setg(errp, "Device '%s' is not removable", device ?: id);
- return;
- }
-
- if (!blk_dev_has_tray(blk)) {
- /* Ignore this command on tray-less devices */
- return;
- }
-
- if (!blk_dev_is_tray_open(blk)) {
- return;
- }
-
- blk_dev_change_media_cb(blk, true, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-}
-
-static void GRAPH_UNLOCKED
-blockdev_remove_medium(const char *device, const char *id, Error **errp)
-{
- BlockBackend *blk;
- BlockDriverState *bs;
- bool has_attached_device;
-
- GLOBAL_STATE_CODE();
-
- blk = qmp_get_blk(device, id, errp);
- if (!blk) {
- return;
- }
-
- /* For BBs without a device, we can exchange the BDS tree at will */
- has_attached_device = blk_get_attached_dev(blk);
-
- if (has_attached_device && !blk_dev_has_removable_media(blk)) {
- error_setg(errp, "Device '%s' is not removable", device ?: id);
- return;
- }
-
- if (has_attached_device && blk_dev_has_tray(blk) &&
- !blk_dev_is_tray_open(blk))
- {
- error_setg(errp, "Tray of device '%s' is not open", device ?: id);
- return;
- }
-
- bs = blk_bs(blk);
- if (!bs) {
- return;
- }
-
- bdrv_graph_rdlock_main_loop();
- if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
- bdrv_graph_rdunlock_main_loop();
- return;
- }
- bdrv_graph_rdunlock_main_loop();
-
- blk_remove_bs(blk);
-
- if (!blk_dev_has_tray(blk)) {
- /* For tray-less devices, blockdev-open-tray is a no-op (or may not be
- * called at all); therefore, the medium needs to be ejected here.
- * Do it after blk_remove_bs() so blk_is_inserted(blk) returns the @load
- * value passed here (i.e. false). */
- blk_dev_change_media_cb(blk, false, &error_abort);
- }
-}
-
-void qmp_blockdev_remove_medium(const char *id, Error **errp)
-{
- blockdev_remove_medium(NULL, id, errp);
-}
-
-static void qmp_blockdev_insert_anon_medium(BlockBackend *blk,
- BlockDriverState *bs, Error **errp)
-{
- Error *local_err = NULL;
- bool has_device;
- int ret;
-
- /* For BBs without a device, we can exchange the BDS tree at will */
- has_device = blk_get_attached_dev(blk);
-
- if (has_device && !blk_dev_has_removable_media(blk)) {
- error_setg(errp, "Device is not removable");
- return;
- }
-
- if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) {
- error_setg(errp, "Tray of the device is not open");
- return;
- }
-
- if (blk_bs(blk)) {
- error_setg(errp, "There already is a medium in the device");
- return;
- }
-
- ret = blk_insert_bs(blk, bs, errp);
- if (ret < 0) {
- return;
- }
-
- if (!blk_dev_has_tray(blk)) {
- /* For tray-less devices, blockdev-close-tray is a no-op (or may not be
- * called at all); therefore, the medium needs to be pushed into the
- * slot here.
- * Do it after blk_insert_bs() so blk_is_inserted(blk) returns the @load
- * value passed here (i.e. true). */
- blk_dev_change_media_cb(blk, true, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- blk_remove_bs(blk);
- return;
- }
- }
-}
-
-static void blockdev_insert_medium(const char *device, const char *id,
- const char *node_name, Error **errp)
-{
- BlockBackend *blk;
- BlockDriverState *bs;
-
- GRAPH_RDLOCK_GUARD_MAINLOOP();
-
- blk = qmp_get_blk(device, id, errp);
- if (!blk) {
- return;
- }
-
- bs = bdrv_find_node(node_name);
- if (!bs) {
- error_setg(errp, "Node '%s' not found", node_name);
- return;
- }
-
- if (bdrv_has_blk(bs)) {
- error_setg(errp, "Node '%s' is already in use", node_name);
- return;
- }
-
- qmp_blockdev_insert_anon_medium(blk, bs, errp);
-}
-
-void qmp_blockdev_insert_medium(const char *id, const char *node_name,
- Error **errp)
-{
- blockdev_insert_medium(NULL, id, node_name, errp);
-}
-
-void qmp_blockdev_change_medium(const char *device,
- const char *id,
- const char *filename,
- const char *format,
- bool has_force, bool force,
- bool has_read_only,
- BlockdevChangeReadOnlyMode read_only,
- Error **errp)
-{
- BlockBackend *blk;
- BlockDriverState *medium_bs = NULL;
- int bdrv_flags;
- bool detect_zeroes;
- int rc;
- QDict *options = NULL;
- Error *err = NULL;
-
- blk = qmp_get_blk(device, id, errp);
- if (!blk) {
- goto fail;
- }
-
- if (blk_bs(blk)) {
- blk_update_root_state(blk);
- }
-
- bdrv_flags = blk_get_open_flags_from_root_state(blk);
- bdrv_flags &= ~(BDRV_O_TEMPORARY | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING |
- BDRV_O_PROTOCOL | BDRV_O_AUTO_RDONLY);
-
- if (!has_read_only) {
- read_only = BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN;
- }
-
- switch (read_only) {
- case BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN:
- break;
-
- case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_ONLY:
- bdrv_flags &= ~BDRV_O_RDWR;
- break;
-
- case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_WRITE:
- bdrv_flags |= BDRV_O_RDWR;
- break;
-
- default:
- abort();
- }
-
- options = qdict_new();
- detect_zeroes = blk_get_detect_zeroes_from_root_state(blk);
- qdict_put_str(options, "detect-zeroes", detect_zeroes ? "on" : "off");
-
- if (format) {
- qdict_put_str(options, "driver", format);
- }
-
- medium_bs = bdrv_open(filename, NULL, options, bdrv_flags, errp);
-
- if (!medium_bs) {
- goto fail;
- }
-
- rc = do_open_tray(device, id, force, &err);
- if (rc && rc != -ENOSYS) {
- error_propagate(errp, err);
- goto fail;
- }
- error_free(err);
- err = NULL;
-
- blockdev_remove_medium(device, id, &err);
- if (err) {
- error_propagate(errp, err);
- goto fail;
- }
-
- qmp_blockdev_insert_anon_medium(blk, medium_bs, &err);
- if (err) {
- error_propagate(errp, err);
- goto fail;
- }
-
- qmp_blockdev_close_tray(device, id, errp);
-
-fail:
- /* If the medium has been inserted, the device has its own reference, so
- * ours must be relinquished; and if it has not been inserted successfully,
- * the reference must be relinquished anyway */
- bdrv_unref(medium_bs);
-}
-
-void qmp_eject(const char *device, const char *id,
- bool has_force, bool force, Error **errp)
-{
- Error *local_err = NULL;
- int rc;
-
- if (!has_force) {
- force = false;
- }
-
- rc = do_open_tray(device, id, force, &local_err);
- if (rc && rc != -ENOSYS) {
- error_propagate(errp, local_err);
- return;
- }
- error_free(local_err);
-
- blockdev_remove_medium(device, id, errp);
-}
-
-/* throttling disk I/O limits */
-void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp)
-{
- ThrottleConfig cfg;
- BlockDriverState *bs;
- BlockBackend *blk;
-
- blk = qmp_get_blk(arg->device, arg->id, errp);
- if (!blk) {
- return;
- }
-
- bs = blk_bs(blk);
- if (!bs) {
- error_setg(errp, "Device has no medium");
- return;
- }
-
- throttle_config_init(&cfg);
- cfg.buckets[THROTTLE_BPS_TOTAL].avg = arg->bps;
- cfg.buckets[THROTTLE_BPS_READ].avg = arg->bps_rd;
- cfg.buckets[THROTTLE_BPS_WRITE].avg = arg->bps_wr;
-
- cfg.buckets[THROTTLE_OPS_TOTAL].avg = arg->iops;
- cfg.buckets[THROTTLE_OPS_READ].avg = arg->iops_rd;
- cfg.buckets[THROTTLE_OPS_WRITE].avg = arg->iops_wr;
-
- if (arg->has_bps_max) {
- cfg.buckets[THROTTLE_BPS_TOTAL].max = arg->bps_max;
- }
- if (arg->has_bps_rd_max) {
- cfg.buckets[THROTTLE_BPS_READ].max = arg->bps_rd_max;
- }
- if (arg->has_bps_wr_max) {
- cfg.buckets[THROTTLE_BPS_WRITE].max = arg->bps_wr_max;
- }
- if (arg->has_iops_max) {
- cfg.buckets[THROTTLE_OPS_TOTAL].max = arg->iops_max;
- }
- if (arg->has_iops_rd_max) {
- cfg.buckets[THROTTLE_OPS_READ].max = arg->iops_rd_max;
- }
- if (arg->has_iops_wr_max) {
- cfg.buckets[THROTTLE_OPS_WRITE].max = arg->iops_wr_max;
- }
-
- if (arg->has_bps_max_length) {
- cfg.buckets[THROTTLE_BPS_TOTAL].burst_length = arg->bps_max_length;
- }
- if (arg->has_bps_rd_max_length) {
- cfg.buckets[THROTTLE_BPS_READ].burst_length = arg->bps_rd_max_length;
- }
- if (arg->has_bps_wr_max_length) {
- cfg.buckets[THROTTLE_BPS_WRITE].burst_length = arg->bps_wr_max_length;
- }
- if (arg->has_iops_max_length) {
- cfg.buckets[THROTTLE_OPS_TOTAL].burst_length = arg->iops_max_length;
- }
- if (arg->has_iops_rd_max_length) {
- cfg.buckets[THROTTLE_OPS_READ].burst_length = arg->iops_rd_max_length;
- }
- if (arg->has_iops_wr_max_length) {
- cfg.buckets[THROTTLE_OPS_WRITE].burst_length = arg->iops_wr_max_length;
- }
-
- if (arg->has_iops_size) {
- cfg.op_size = arg->iops_size;
- }
-
- if (!throttle_is_valid(&cfg, errp)) {
- return;
- }
-
- if (throttle_enabled(&cfg)) {
- /* Enable I/O limits if they're not enabled yet, otherwise
- * just update the throttling group. */
- if (!blk_get_public(blk)->throttle_group_member.throttle_state) {
- blk_io_limits_enable(blk, arg->group ?: arg->device ?: arg->id);
- } else if (arg->group) {
- blk_io_limits_update_group(blk, arg->group);
- }
- /* Set the new throttling configuration */
- blk_set_io_limits(blk, &cfg);
- } else if (blk_get_public(blk)->throttle_group_member.throttle_state) {
- /* If all throttling settings are set to 0, disable I/O limits */
- blk_io_limits_disable(blk);
- }
-}
-
-void qmp_block_latency_histogram_set(
- const char *id,
- bool has_boundaries, uint64List *boundaries,
- bool has_boundaries_read, uint64List *boundaries_read,
- bool has_boundaries_write, uint64List *boundaries_write,
- bool has_boundaries_append, uint64List *boundaries_append,
- bool has_boundaries_flush, uint64List *boundaries_flush,
- Error **errp)
-{
- BlockBackend *blk = qmp_get_blk(NULL, id, errp);
- BlockAcctStats *stats;
- int ret;
-
- if (!blk) {
- return;
- }
-
- stats = blk_get_stats(blk);
-
- if (!has_boundaries && !has_boundaries_read && !has_boundaries_write &&
- !has_boundaries_flush)
- {
- block_latency_histograms_clear(stats);
- return;
- }
-
- if (has_boundaries || has_boundaries_read) {
- ret = block_latency_histogram_set(
- stats, BLOCK_ACCT_READ,
- has_boundaries_read ? boundaries_read : boundaries);
- if (ret) {
- error_setg(errp, "Device '%s' set read boundaries fail", id);
- return;
- }
- }
-
- if (has_boundaries || has_boundaries_write) {
- ret = block_latency_histogram_set(
- stats, BLOCK_ACCT_WRITE,
- has_boundaries_write ? boundaries_write : boundaries);
- if (ret) {
- error_setg(errp, "Device '%s' set write boundaries fail", id);
- return;
- }
- }
-
- if (has_boundaries || has_boundaries_append) {
- ret = block_latency_histogram_set(
- stats, BLOCK_ACCT_ZONE_APPEND,
- has_boundaries_append ? boundaries_append : boundaries);
- if (ret) {
- error_setg(errp, "Device '%s' set append write boundaries fail", id);
- return;
- }
- }
-
- if (has_boundaries || has_boundaries_flush) {
- ret = block_latency_histogram_set(
- stats, BLOCK_ACCT_FLUSH,
- has_boundaries_flush ? boundaries_flush : boundaries);
- if (ret) {
- error_setg(errp, "Device '%s' set flush boundaries fail", id);
- return;
- }
- }
-}
--- /dev/null
+/*
+ * QMP command handlers specific to the system emulators
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later. See the COPYING file in the top-level directory.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * 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 "block/block_int.h"
+#include "qapi/error.h"
+#include "qapi/qapi-commands-block.h"
+#include "qapi/qmp/qdict.h"
+#include "system/block-backend.h"
+#include "system/blockdev.h"
+
+static BlockBackend *qmp_get_blk(const char *blk_name, const char *qdev_id,
+ Error **errp)
+{
+ BlockBackend *blk;
+
+ if (!blk_name == !qdev_id) {
+ error_setg(errp, "Need exactly one of 'device' and 'id'");
+ return NULL;
+ }
+
+ if (qdev_id) {
+ blk = blk_by_qdev_id(qdev_id, errp);
+ } else {
+ blk = blk_by_name(blk_name);
+ if (blk == NULL) {
+ error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+ "Device '%s' not found", blk_name);
+ }
+ }
+
+ return blk;
+}
+
+/*
+ * Attempt to open the tray of @device.
+ * If @force, ignore its tray lock.
+ * Else, if the tray is locked, don't open it, but ask the guest to open it.
+ * On error, store an error through @errp and return -errno.
+ * If @device does not exist, return -ENODEV.
+ * If it has no removable media, return -ENOTSUP.
+ * If it has no tray, return -ENOSYS.
+ * If the guest was asked to open the tray, return -EINPROGRESS.
+ * Else, return 0.
+ */
+static int do_open_tray(const char *blk_name, const char *qdev_id,
+ bool force, Error **errp)
+{
+ BlockBackend *blk;
+ const char *device = qdev_id ?: blk_name;
+ bool locked;
+
+ blk = qmp_get_blk(blk_name, qdev_id, errp);
+ if (!blk) {
+ return -ENODEV;
+ }
+
+ if (!blk_dev_has_removable_media(blk)) {
+ error_setg(errp, "Device '%s' is not removable", device);
+ return -ENOTSUP;
+ }
+
+ if (!blk_dev_has_tray(blk)) {
+ error_setg(errp, "Device '%s' does not have a tray", device);
+ return -ENOSYS;
+ }
+
+ if (blk_dev_is_tray_open(blk)) {
+ return 0;
+ }
+
+ locked = blk_dev_is_medium_locked(blk);
+ if (locked) {
+ blk_dev_eject_request(blk, force);
+ }
+
+ if (!locked || force) {
+ blk_dev_change_media_cb(blk, false, &error_abort);
+ }
+
+ if (locked && !force) {
+ error_setg(errp, "Device '%s' is locked and force was not specified, "
+ "wait for tray to open and try again", device);
+ return -EINPROGRESS;
+ }
+
+ return 0;
+}
+
+void qmp_blockdev_open_tray(const char *device,
+ const char *id,
+ bool has_force, bool force,
+ Error **errp)
+{
+ Error *local_err = NULL;
+ int rc;
+
+ if (!has_force) {
+ force = false;
+ }
+ rc = do_open_tray(device, id, force, &local_err);
+ if (rc && rc != -ENOSYS && rc != -EINPROGRESS) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ error_free(local_err);
+}
+
+void qmp_blockdev_close_tray(const char *device,
+ const char *id,
+ Error **errp)
+{
+ BlockBackend *blk;
+ Error *local_err = NULL;
+
+ blk = qmp_get_blk(device, id, errp);
+ if (!blk) {
+ return;
+ }
+
+ if (!blk_dev_has_removable_media(blk)) {
+ error_setg(errp, "Device '%s' is not removable", device ?: id);
+ return;
+ }
+
+ if (!blk_dev_has_tray(blk)) {
+ /* Ignore this command on tray-less devices */
+ return;
+ }
+
+ if (!blk_dev_is_tray_open(blk)) {
+ return;
+ }
+
+ blk_dev_change_media_cb(blk, true, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+}
+
+static void GRAPH_UNLOCKED
+blockdev_remove_medium(const char *device, const char *id, Error **errp)
+{
+ BlockBackend *blk;
+ BlockDriverState *bs;
+ bool has_attached_device;
+
+ GLOBAL_STATE_CODE();
+
+ blk = qmp_get_blk(device, id, errp);
+ if (!blk) {
+ return;
+ }
+
+ /* For BBs without a device, we can exchange the BDS tree at will */
+ has_attached_device = blk_get_attached_dev(blk);
+
+ if (has_attached_device && !blk_dev_has_removable_media(blk)) {
+ error_setg(errp, "Device '%s' is not removable", device ?: id);
+ return;
+ }
+
+ if (has_attached_device && blk_dev_has_tray(blk) &&
+ !blk_dev_is_tray_open(blk))
+ {
+ error_setg(errp, "Tray of device '%s' is not open", device ?: id);
+ return;
+ }
+
+ bs = blk_bs(blk);
+ if (!bs) {
+ return;
+ }
+
+ bdrv_graph_rdlock_main_loop();
+ if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
+ bdrv_graph_rdunlock_main_loop();
+ return;
+ }
+ bdrv_graph_rdunlock_main_loop();
+
+ blk_remove_bs(blk);
+
+ if (!blk_dev_has_tray(blk)) {
+ /* For tray-less devices, blockdev-open-tray is a no-op (or may not be
+ * called at all); therefore, the medium needs to be ejected here.
+ * Do it after blk_remove_bs() so blk_is_inserted(blk) returns the @load
+ * value passed here (i.e. false). */
+ blk_dev_change_media_cb(blk, false, &error_abort);
+ }
+}
+
+void qmp_blockdev_remove_medium(const char *id, Error **errp)
+{
+ blockdev_remove_medium(NULL, id, errp);
+}
+
+static void qmp_blockdev_insert_anon_medium(BlockBackend *blk,
+ BlockDriverState *bs, Error **errp)
+{
+ Error *local_err = NULL;
+ bool has_device;
+ int ret;
+
+ /* For BBs without a device, we can exchange the BDS tree at will */
+ has_device = blk_get_attached_dev(blk);
+
+ if (has_device && !blk_dev_has_removable_media(blk)) {
+ error_setg(errp, "Device is not removable");
+ return;
+ }
+
+ if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) {
+ error_setg(errp, "Tray of the device is not open");
+ return;
+ }
+
+ if (blk_bs(blk)) {
+ error_setg(errp, "There already is a medium in the device");
+ return;
+ }
+
+ ret = blk_insert_bs(blk, bs, errp);
+ if (ret < 0) {
+ return;
+ }
+
+ if (!blk_dev_has_tray(blk)) {
+ /* For tray-less devices, blockdev-close-tray is a no-op (or may not be
+ * called at all); therefore, the medium needs to be pushed into the
+ * slot here.
+ * Do it after blk_insert_bs() so blk_is_inserted(blk) returns the @load
+ * value passed here (i.e. true). */
+ blk_dev_change_media_cb(blk, true, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ blk_remove_bs(blk);
+ return;
+ }
+ }
+}
+
+static void blockdev_insert_medium(const char *device, const char *id,
+ const char *node_name, Error **errp)
+{
+ BlockBackend *blk;
+ BlockDriverState *bs;
+
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
+
+ blk = qmp_get_blk(device, id, errp);
+ if (!blk) {
+ return;
+ }
+
+ bs = bdrv_find_node(node_name);
+ if (!bs) {
+ error_setg(errp, "Node '%s' not found", node_name);
+ return;
+ }
+
+ if (bdrv_has_blk(bs)) {
+ error_setg(errp, "Node '%s' is already in use", node_name);
+ return;
+ }
+
+ qmp_blockdev_insert_anon_medium(blk, bs, errp);
+}
+
+void qmp_blockdev_insert_medium(const char *id, const char *node_name,
+ Error **errp)
+{
+ blockdev_insert_medium(NULL, id, node_name, errp);
+}
+
+void qmp_blockdev_change_medium(const char *device,
+ const char *id,
+ const char *filename,
+ const char *format,
+ bool has_force, bool force,
+ bool has_read_only,
+ BlockdevChangeReadOnlyMode read_only,
+ Error **errp)
+{
+ BlockBackend *blk;
+ BlockDriverState *medium_bs = NULL;
+ int bdrv_flags;
+ bool detect_zeroes;
+ int rc;
+ QDict *options = NULL;
+ Error *err = NULL;
+
+ blk = qmp_get_blk(device, id, errp);
+ if (!blk) {
+ goto fail;
+ }
+
+ if (blk_bs(blk)) {
+ blk_update_root_state(blk);
+ }
+
+ bdrv_flags = blk_get_open_flags_from_root_state(blk);
+ bdrv_flags &= ~(BDRV_O_TEMPORARY | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING |
+ BDRV_O_PROTOCOL | BDRV_O_AUTO_RDONLY);
+
+ if (!has_read_only) {
+ read_only = BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN;
+ }
+
+ switch (read_only) {
+ case BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN:
+ break;
+
+ case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_ONLY:
+ bdrv_flags &= ~BDRV_O_RDWR;
+ break;
+
+ case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_WRITE:
+ bdrv_flags |= BDRV_O_RDWR;
+ break;
+
+ default:
+ abort();
+ }
+
+ options = qdict_new();
+ detect_zeroes = blk_get_detect_zeroes_from_root_state(blk);
+ qdict_put_str(options, "detect-zeroes", detect_zeroes ? "on" : "off");
+
+ if (format) {
+ qdict_put_str(options, "driver", format);
+ }
+
+ medium_bs = bdrv_open(filename, NULL, options, bdrv_flags, errp);
+
+ if (!medium_bs) {
+ goto fail;
+ }
+
+ rc = do_open_tray(device, id, force, &err);
+ if (rc && rc != -ENOSYS) {
+ error_propagate(errp, err);
+ goto fail;
+ }
+ error_free(err);
+ err = NULL;
+
+ blockdev_remove_medium(device, id, &err);
+ if (err) {
+ error_propagate(errp, err);
+ goto fail;
+ }
+
+ qmp_blockdev_insert_anon_medium(blk, medium_bs, &err);
+ if (err) {
+ error_propagate(errp, err);
+ goto fail;
+ }
+
+ qmp_blockdev_close_tray(device, id, errp);
+
+fail:
+ /* If the medium has been inserted, the device has its own reference, so
+ * ours must be relinquished; and if it has not been inserted successfully,
+ * the reference must be relinquished anyway */
+ bdrv_unref(medium_bs);
+}
+
+void qmp_eject(const char *device, const char *id,
+ bool has_force, bool force, Error **errp)
+{
+ Error *local_err = NULL;
+ int rc;
+
+ if (!has_force) {
+ force = false;
+ }
+
+ rc = do_open_tray(device, id, force, &local_err);
+ if (rc && rc != -ENOSYS) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ error_free(local_err);
+
+ blockdev_remove_medium(device, id, errp);
+}
+
+/* throttling disk I/O limits */
+void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp)
+{
+ ThrottleConfig cfg;
+ BlockDriverState *bs;
+ BlockBackend *blk;
+
+ blk = qmp_get_blk(arg->device, arg->id, errp);
+ if (!blk) {
+ return;
+ }
+
+ bs = blk_bs(blk);
+ if (!bs) {
+ error_setg(errp, "Device has no medium");
+ return;
+ }
+
+ throttle_config_init(&cfg);
+ cfg.buckets[THROTTLE_BPS_TOTAL].avg = arg->bps;
+ cfg.buckets[THROTTLE_BPS_READ].avg = arg->bps_rd;
+ cfg.buckets[THROTTLE_BPS_WRITE].avg = arg->bps_wr;
+
+ cfg.buckets[THROTTLE_OPS_TOTAL].avg = arg->iops;
+ cfg.buckets[THROTTLE_OPS_READ].avg = arg->iops_rd;
+ cfg.buckets[THROTTLE_OPS_WRITE].avg = arg->iops_wr;
+
+ if (arg->has_bps_max) {
+ cfg.buckets[THROTTLE_BPS_TOTAL].max = arg->bps_max;
+ }
+ if (arg->has_bps_rd_max) {
+ cfg.buckets[THROTTLE_BPS_READ].max = arg->bps_rd_max;
+ }
+ if (arg->has_bps_wr_max) {
+ cfg.buckets[THROTTLE_BPS_WRITE].max = arg->bps_wr_max;
+ }
+ if (arg->has_iops_max) {
+ cfg.buckets[THROTTLE_OPS_TOTAL].max = arg->iops_max;
+ }
+ if (arg->has_iops_rd_max) {
+ cfg.buckets[THROTTLE_OPS_READ].max = arg->iops_rd_max;
+ }
+ if (arg->has_iops_wr_max) {
+ cfg.buckets[THROTTLE_OPS_WRITE].max = arg->iops_wr_max;
+ }
+
+ if (arg->has_bps_max_length) {
+ cfg.buckets[THROTTLE_BPS_TOTAL].burst_length = arg->bps_max_length;
+ }
+ if (arg->has_bps_rd_max_length) {
+ cfg.buckets[THROTTLE_BPS_READ].burst_length = arg->bps_rd_max_length;
+ }
+ if (arg->has_bps_wr_max_length) {
+ cfg.buckets[THROTTLE_BPS_WRITE].burst_length = arg->bps_wr_max_length;
+ }
+ if (arg->has_iops_max_length) {
+ cfg.buckets[THROTTLE_OPS_TOTAL].burst_length = arg->iops_max_length;
+ }
+ if (arg->has_iops_rd_max_length) {
+ cfg.buckets[THROTTLE_OPS_READ].burst_length = arg->iops_rd_max_length;
+ }
+ if (arg->has_iops_wr_max_length) {
+ cfg.buckets[THROTTLE_OPS_WRITE].burst_length = arg->iops_wr_max_length;
+ }
+
+ if (arg->has_iops_size) {
+ cfg.op_size = arg->iops_size;
+ }
+
+ if (!throttle_is_valid(&cfg, errp)) {
+ return;
+ }
+
+ if (throttle_enabled(&cfg)) {
+ /* Enable I/O limits if they're not enabled yet, otherwise
+ * just update the throttling group. */
+ if (!blk_get_public(blk)->throttle_group_member.throttle_state) {
+ blk_io_limits_enable(blk, arg->group ?: arg->device ?: arg->id);
+ } else if (arg->group) {
+ blk_io_limits_update_group(blk, arg->group);
+ }
+ /* Set the new throttling configuration */
+ blk_set_io_limits(blk, &cfg);
+ } else if (blk_get_public(blk)->throttle_group_member.throttle_state) {
+ /* If all throttling settings are set to 0, disable I/O limits */
+ blk_io_limits_disable(blk);
+ }
+}
+
+void qmp_block_latency_histogram_set(
+ const char *id,
+ bool has_boundaries, uint64List *boundaries,
+ bool has_boundaries_read, uint64List *boundaries_read,
+ bool has_boundaries_write, uint64List *boundaries_write,
+ bool has_boundaries_append, uint64List *boundaries_append,
+ bool has_boundaries_flush, uint64List *boundaries_flush,
+ Error **errp)
+{
+ BlockBackend *blk = qmp_get_blk(NULL, id, errp);
+ BlockAcctStats *stats;
+ int ret;
+
+ if (!blk) {
+ return;
+ }
+
+ stats = blk_get_stats(blk);
+
+ if (!has_boundaries && !has_boundaries_read && !has_boundaries_write &&
+ !has_boundaries_flush)
+ {
+ block_latency_histograms_clear(stats);
+ return;
+ }
+
+ if (has_boundaries || has_boundaries_read) {
+ ret = block_latency_histogram_set(
+ stats, BLOCK_ACCT_READ,
+ has_boundaries_read ? boundaries_read : boundaries);
+ if (ret) {
+ error_setg(errp, "Device '%s' set read boundaries fail", id);
+ return;
+ }
+ }
+
+ if (has_boundaries || has_boundaries_write) {
+ ret = block_latency_histogram_set(
+ stats, BLOCK_ACCT_WRITE,
+ has_boundaries_write ? boundaries_write : boundaries);
+ if (ret) {
+ error_setg(errp, "Device '%s' set write boundaries fail", id);
+ return;
+ }
+ }
+
+ if (has_boundaries || has_boundaries_append) {
+ ret = block_latency_histogram_set(
+ stats, BLOCK_ACCT_ZONE_APPEND,
+ has_boundaries_append ? boundaries_append : boundaries);
+ if (ret) {
+ error_setg(errp, "Device '%s' set append write boundaries fail", id);
+ return;
+ }
+ }
+
+ if (has_boundaries || has_boundaries_flush) {
+ ret = block_latency_histogram_set(
+ stats, BLOCK_ACCT_FLUSH,
+ has_boundaries_flush ? boundaries_flush : boundaries);
+ if (ret) {
+ error_setg(errp, "Device '%s' set flush boundaries fail", id);
+ return;
+ }
+ }
+}
#include "qapi/qmp/qnum.h"
#include "qapi/qmp/qstring.h"
#include "qemu/qemu-print.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
BlockDriverState *bs,
#include "qemu/error-report.h"
#include "block/block_int.h"
#include "block/qdict.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qemu/module.h"
#include "qemu/option.h"
#include "qemu/bswap.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qapi/error.h"
#include "qcow2.h"
#include "qemu/bswap.h"
#include "qemu/osdep.h"
#include "block/qdict.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "qcow2.h"
#include "qemu/memalign.h"
#include "trace.h"
#include "qed.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qobject-input-visitor.h"
#include "qapi/qapi-visit-block-core.h"
#include "block/qdict.h"
#include "crypto/secret.h"
#include "qemu/cutils.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "qapi/qmp/qstring.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qjson.h"
#include "block/blockjob.h"
#include "block/block_int.h"
#include "block/block_backup.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "block/replication.h"
#include "qemu/osdep.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qemu/cutils.h"
#include "block/block_int.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qstring.h"
#include "qemu/option.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
QemuOptsList internal_snapshot_opts = {
.name = "snapshot",
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "qemu/ratelimit.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "block/copy-on-read.h"
enum {
*/
#include "qemu/osdep.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "block/throttle-groups.h"
#include "qemu/throttle-options.h"
#include "qemu/main-loop.h"
#include "qemu/queue.h"
#include "qemu/thread.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
#include "qapi/error.h"
#include "qapi/qapi-visit-block-core.h"
#include "qom/object.h"
#include "qapi/qapi-visit-block-core.h"
#include "block/block_int.h"
#include "block/qdict.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qemu/module.h"
#include "qemu/option.h"
#include "qemu/bswap.h"
#include "qapi/error.h"
#include "block/block_int.h"
#include "block/qdict.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qemu/module.h"
#include "qemu/option.h"
#include "qemu/crc32c.h"
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "block/block_int.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qapi/qmp/qdict.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qapi/error.h"
#include "block/block_int.h"
#include "block/qdict.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qemu/module.h"
#include "qemu/option.h"
#include "migration/blocker.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/block-backend.h"
+#include "system/blockdev.h"
+#include "system/block-backend.h"
#include "hw/block/block.h"
#include "qapi/error.h"
#include "qapi/clone-visitor.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
+#include "system/block-backend.h"
+#include "system/blockdev.h"
#include "hw/block/block.h"
#include "block/blockjob.h"
#include "block/dirty-bitmap.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qlist.h"
#include "qapi/qobject-output-visitor.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/iothread.h"
+#include "system/system.h"
+#include "system/iothread.h"
#include "block/block_int.h"
#include "block/trace.h"
-#include "sysemu/runstate.h"
-#include "sysemu/replay.h"
+#include "system/runstate.h"
+#include "system/replay.h"
#include "qemu/cutils.h"
#include "qemu/help_option.h"
#include "qemu/main-loop.h"
#include "block/blockjob_int.h"
#include "block/block_int.h"
#include "block/trace.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qapi/error.h"
#include "qapi/qapi-events-block-core.h"
#include "qapi/qmp/qerror.h"
#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "chardev/char-fe.h"
#include "chardev/char-io.h"
#include "qemu/option.h"
#include "qemu/bitops.h"
#include "chardev/char.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qapi/qapi-commands-control.h"
#include "chardev-internal.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-char.h"
#include "qapi/qmp/qerror.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "qemu/help_option.h"
#include "qemu/module.h"
#include "qemu/option.h"
#include "qemu/main-loop.h"
#include "exec/cpu-common.h"
#include "hw/core/cpu.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
#include "qemu/lockable.h"
#include "trace/trace-root.h"
#include "exec/address-spaces.h"
#include "exec/memory.h"
#endif
-#include "sysemu/cpus.h"
-#include "sysemu/tcg.h"
+#include "system/cpus.h"
+#include "system/tcg.h"
#include "exec/tswap.h"
#include "exec/replay-core.h"
#include "exec/cpu-common.h"
#include "crypto/akcipher.h"
#include "crypto/random.h"
#include "qapi/error.h"
-#include "sysemu/cryptodev.h"
+#include "system/cryptodev.h"
#include "rsakey.h"
typedef struct QCryptoGcryptRSA {
#include "crypto/akcipher.h"
#include "crypto/random.h"
#include "qapi/error.h"
-#include "sysemu/cryptodev.h"
+#include "system/cryptodev.h"
#include "rsakey.h"
typedef struct QCryptoNettleRSA {
QEMU files related to TPM backends:
- ``backends/tpm.c``
- - ``include/sysemu/tpm.h``
- - ``include/sysemu/tpm_backend.h``
+ - ``include/system/tpm.h``
+ - ``include/system/tpm_backend.h``
The QEMU TPM passthrough device
-------------------------------
QEMU files related to the TPM passthrough device:
- ``backends/tpm/tpm_passthrough.c``
- ``backends/tpm/tpm_util.c``
- - ``include/sysemu/tpm_util.h``
+ - ``include/system/tpm_util.h``
Command line to start QEMU with the TPM passthrough device using the host's
QEMU files related to the TPM emulator device:
- ``backends/tpm/tpm_emulator.c``
- ``backends/tpm/tpm_util.c``
- - ``include/sysemu/tpm_util.h``
+ - ``include/system/tpm_util.h``
The following commands start the swtpm with a UnixIO control channel over
a socket interface. They do not need to be run as root.
#include "qemu/bswap.h"
#include "exec/target_page.h"
#include "monitor/monitor.h"
-#include "sysemu/dump.h"
-#include "sysemu/runstate.h"
-#include "sysemu/cpus.h"
+#include "system/dump.h"
+#include "system/runstate.h"
+#include "system/cpus.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-dump.h"
#include "qapi/qapi-events-dump.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/dump.h"
+#include "system/dump.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "exec/cpu-defs.h"
#ifndef WIN_DUMP_H
#define WIN_DUMP_H
-#include "sysemu/dump.h"
+#include "system/dump.h"
/* Check Windows dump availability for the current target */
bool win_dump_available(Error **errp);
#include "qom/object_interfaces.h"
#include "qapi/error.h"
#include "block/thread-pool.h"
-#include "sysemu/event-loop-base.h"
+#include "system/event-loop-base.h"
typedef struct {
const char *name;
#endif
#include "hw/core/cpu.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/runstate.h"
+#include "system/hw_accel.h"
+#include "system/runstate.h"
#include "exec/replay-core.h"
#include "exec/hwaddr.h"
#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "semihosting/semihost.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "gdbstub/user.h"
#include "gdbstub/syscalls.h"
#include "gdbstub/commands.h"
#include "gdbstub/commands.h"
#include "exec/hwaddr.h"
#include "exec/tb-flush.h"
-#include "sysemu/cpus.h"
-#include "sysemu/runstate.h"
-#include "sysemu/replay.h"
+#include "system/cpus.h"
+#include "system/runstate.h"
+#include "system/replay.h"
#include "hw/core/cpu.h"
#include "hw/cpu/cluster.h"
#include "hw/boards.h"
#include "qemu/rcu.h"
#include "qemu/rcu_queue.h"
#include "qemu/cutils.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
/* Root node for synth file system */
static V9fsSynthNode synth_root = {
#include "hw/virtio/virtio-access.h"
#include "qemu/iov.h"
#include "qemu/module.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
static void virtio_9p_push_and_notify(V9fsPDU *pdu)
{
#include "hw/acpi/aml-build.h"
#include "qemu/bswap.h"
#include "qemu/bitops.h"
-#include "sysemu/numa.h"
+#include "system/numa.h"
#include "hw/boards.h"
#include "hw/acpi/tpm.h"
#include "hw/pci/pci_host.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qemu/option.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "trace.h"
struct acpi_table_header {
#include "qapi/error.h"
#include "qapi/qapi-events-acpi.h"
#include "trace.h"
-#include "sysemu/numa.h"
+#include "system/numa.h"
#define ACPI_CPU_SELECTOR_OFFSET_WR 0
#define ACPI_CPU_FLAGS_OFFSET_RW 4
#include "hw/acpi/aml-build.h"
#include "hw/acpi/bios-linker-loader.h"
#include "exec/address-spaces.h"
-#include "sysemu/hostmem.h"
+#include "system/hostmem.h"
#include "hw/acpi/erst.h"
#include "trace.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "qemu/error-report.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
static const uint32_t ged_supported_events[] = {
ACPI_GED_MEM_HOTPLUG_EVT,
#include "qemu/osdep.h"
#include "qemu/units.h"
-#include "sysemu/numa.h"
+#include "system/numa.h"
#include "hw/acpi/aml-build.h"
#include "hw/acpi/hmat.h"
#define HMAT_H
#include "hw/acpi/bios-linker-loader.h"
-#include "sysemu/numa.h"
+#include "system/numa.h"
/*
* ACPI 6.3: 5.2.27.3 Memory Proximity Domain Attributes Structure,
#include "migration/vmstate.h"
#include "qemu/timer.h"
#include "hw/core/cpu.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
+#include "system/reset.h"
+#include "system/runstate.h"
#include "hw/acpi/acpi.h"
#include "hw/acpi/ich9_tco.h"
#include "hw/acpi/ich9_timer.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/watchdog.h"
+#include "system/watchdog.h"
#include "hw/southbridge/ich9.h"
#include "migration/vmstate.h"
#include "hw/acpi/acpi.h"
#include "hw/acpi/pcihp.h"
#include "hw/acpi/piix4.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/xen.h"
+#include "system/runstate.h"
+#include "system/system.h"
+#include "system/xen.h"
#include "qapi/error.h"
#include "qemu/range.h"
#include "hw/acpi/cpu_hotplug.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "migration/vmstate.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
void vmgenid_build_acpi(VmGenIdState *vms, GArray *table_data, GArray *guid,
BIOSLinker *linker, const char *oem_id)
#include "hw/sysbus.h"
#include "hw/arm/allwinner-a10.h"
#include "hw/misc/unimp.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/boards.h"
#include "hw/usb/hcd-ohci.h"
#include "hw/loader.h"
#include "hw/misc/unimp.h"
#include "hw/usb/hcd-ehci.h"
#include "hw/loader.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/arm/allwinner-h3.h"
#include "target/arm/cpu-qom.h"
#include "target/arm/gtimer.h"
#include "hw/misc/unimp.h"
#include "hw/usb/hcd-ehci.h"
#include "hw/loader.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/arm/allwinner-r40.h"
#include "hw/misc/allwinner-r40-dramc.h"
#include "target/arm/cpu-qom.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-clock.h"
#include "elf.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qemu/log.h"
#include "hw/sensor/tmp105.h"
#include "hw/misc/led.h"
#include "hw/qdev-properties.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/reset.h"
+#include "system/block-backend.h"
+#include "system/reset.h"
#include "hw/loader.h"
#include "qemu/error-report.h"
#include "qemu/units.h"
#include "hw/qdev-clock.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
static struct arm_boot_info aspeed_board_binfo = {
.board_id = -1, /* device-tree-only board */
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "exec/address-spaces.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/qdev-clock.h"
#include "hw/misc/unimp.h"
#include "hw/arm/aspeed_soc.h"
#include "qemu/error-report.h"
#include "hw/i2c/aspeed_i2c.h"
#include "net/net.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "target/arm/cpu-qom.h"
#define ASPEED_SOC_IOMEM_SIZE 0x00200000
#include "qemu/error-report.h"
#include "hw/i2c/aspeed_i2c.h"
#include "net/net.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "target/arm/cpu-qom.h"
#define ASPEED_SOC_IOMEM_SIZE 0x00200000
#include "qemu/error-report.h"
#include "hw/i2c/aspeed_i2c.h"
#include "net/net.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/intc/arm_gicv3.h"
#include "qapi/qmp/qlist.h"
#include "qemu/log.h"
#include "hw/arm/bcm2835_peripherals.h"
#include "hw/misc/bcm2835_mbox_defs.h"
#include "hw/arm/raspi_platform.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
/* Peripheral base address on the VC (GPU) system bus */
#define BCM2835_VC_PERI_BASE 0x7e000000
#include <libfdt.h>
#include "hw/arm/boot.h"
#include "hw/arm/linux-boot-if.h"
-#include "sysemu/kvm.h"
-#include "sysemu/tcg.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/numa.h"
+#include "system/kvm.h"
+#include "system/tcg.h"
+#include "system/system.h"
+#include "system/numa.h"
#include "hw/boards.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "hw/loader.h"
#include "elf.h"
-#include "sysemu/device_tree.h"
+#include "system/device_tree.h"
#include "qemu/config-file.h"
#include "qemu/option.h"
#include "qemu/units.h"
#include "qemu/module.h"
#include "hw/arm/digic.h"
#include "hw/qdev-properties.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#define DIGIC4_TIMER_BASE(n) (0xc0210000 + (n) * 0x100)
#include "hw/arm/digic.h"
#include "hw/block/flash.h"
#include "hw/loader.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
#include "qemu/units.h"
#include "qemu/cutils.h"
#include "cpu.h"
#include "hw/cpu/a9mpcore.h"
#include "hw/irq.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/sysemu.h"
+#include "system/blockdev.h"
+#include "system/system.h"
#include "hw/sysbus.h"
#include "hw/arm/boot.h"
#include "hw/loader.h"
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qapi/error.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/block-backend.h"
+#include "system/system.h"
+#include "system/block-backend.h"
#include "hw/boards.h"
#include "hw/qdev-clock.h"
#include "hw/arm/aspeed_soc.h"
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/arm/fsl-imx25.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/qdev-properties.h"
#include "chardev/char.h"
#include "target/arm/cpu-qom.h"
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/arm/fsl-imx31.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "exec/address-spaces.h"
#include "hw/qdev-properties.h"
#include "chardev/char.h"
#include "hw/usb/imx-usb-phy.h"
#include "hw/boards.h"
#include "hw/qdev-properties.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "chardev/char.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "hw/misc/unimp.h"
#include "hw/usb/imx-usb-phy.h"
#include "hw/boards.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "target/arm/cpu-qom.h"
#include "hw/arm/fsl-imx7.h"
#include "hw/misc/unimp.h"
#include "hw/boards.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "target/arm/cpu-qom.h"
#include "hw/arm/boot.h"
#include "hw/loader.h"
#include "net/net.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
+#include "system/runstate.h"
+#include "system/system.h"
#include "hw/boards.h"
#include "qemu/error-report.h"
#include "hw/char/pl011.h"
#include "hw/arm/boot.h"
#include "hw/boards.h"
#include "qemu/error-report.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
#include "hw/i2c/i2c.h"
#include "qemu/cutils.h"
#include "hw/net/smc91c111.h"
#include "net/net.h"
#include "exec/address-spaces.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
+#include "system/runstate.h"
+#include "system/system.h"
#include "qemu/log.h"
#include "qemu/error-report.h"
#include "hw/char/pl011.h"
#include "net/net.h"
#include "hw/net/lan9118.h"
#include "hw/char/serial-mm.h"
-#include "sysemu/qtest.h"
-#include "sysemu/sysemu.h"
+#include "system/qtest.h"
+#include "system/system.h"
#include "qemu/cutils.h"
/* Memory map for Kzm Emulation Baseboard:
#include "hw/boards.h"
#include "hw/qdev-properties.h"
#include "qemu/error-report.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
static void mcimx6ul_evk_init(MachineState *machine)
{
#include "hw/boards.h"
#include "hw/qdev-properties.h"
#include "qemu/error-report.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
static void mcimx7d_sabre_init(MachineState *machine)
{
#include "qapi/error.h"
#include "hw/boards.h"
#include "hw/arm/boot.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "exec/address-spaces.h"
#include "hw/arm/nrf51_soc.h"
#include "hw/or-irq.h"
#include "hw/boards.h"
#include "exec/address-spaces.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/reset.h"
+#include "system/system.h"
+#include "system/reset.h"
#include "hw/misc/unimp.h"
#include "hw/char/cmsdk-apb-uart.h"
#include "hw/timer/cmsdk-apb-timer.h"
#include "hw/or-irq.h"
#include "hw/boards.h"
#include "exec/address-spaces.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/qdev-properties.h"
#include "hw/misc/unimp.h"
#include "hw/char/cmsdk-apb-uart.h"
#include "qapi/qmp/qlist.h"
#include "exec/address-spaces.h"
#include "cpu.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/boards.h"
#include "hw/or-irq.h"
#include "hw/qdev-clock.h"
#include "hw/arm/msf2-soc.h"
#include "hw/misc/unimp.h"
#include "hw/qdev-clock.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#define MSF2_TIMER_BASE 0x40004000
#define MSF2_SYSREG_BASE 0x40038000
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "exec/address-spaces.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/arm/boot.h"
#include "hw/arm/armsse.h"
#include "hw/boards.h"
#include "migration/vmstate.h"
#include "hw/arm/boot.h"
#include "net/net.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/boards.h"
#include "hw/char/serial-mm.h"
#include "qemu/timer.h"
#include "hw/irq.h"
#include "hw/or-irq.h"
#include "hw/audio/wm8750.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/runstate.h"
-#include "sysemu/dma.h"
+#include "system/block-backend.h"
+#include "system/runstate.h"
+#include "system/dma.h"
#include "ui/pixel_ops.h"
#include "qemu/cutils.h"
#include "qom/object.h"
#include "qapi/error.h"
#include "qemu/bswap.h"
#include "qemu/units.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "target/arm/cpu-qom.h"
/*
#include "qapi/error.h"
#include "qemu/datadir.h"
#include "qemu/units.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/block-backend.h"
+#include "system/blockdev.h"
+#include "system/system.h"
+#include "system/block-backend.h"
#include "qemu/error-report.h"
#include "hw/qdev-properties.h"
#include "hw/arm/boot.h"
#include "hw/arm/omap.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/sysemu.h"
+#include "system/blockdev.h"
+#include "system/system.h"
#include "hw/arm/soc_dma.h"
-#include "sysemu/qtest.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
-#include "sysemu/rtc.h"
+#include "system/qtest.h"
+#include "system/reset.h"
+#include "system/runstate.h"
+#include "system/rtc.h"
#include "qemu/range.h"
#include "hw/sysbus.h"
#include "qemu/cutils.h"
#include "hw/boards.h"
#include "hw/arm/boot.h"
#include "hw/block/flash.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
#include "exec/address-spaces.h"
#include "qemu/cutils.h"
#include "qemu/error-report.h"
#include "hw/display/bcm2835_fb.h"
#include "hw/registerfields.h"
#include "qemu/error-report.h"
-#include "sysemu/device_tree.h"
+#include "system/device_tree.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "hw/arm/boot.h"
#include "hw/pci/pci.h"
#include "hw/qdev-core.h"
#include "net/net.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/boards.h"
#include "hw/i2c/i2c.h"
#include "qemu/error-report.h"
#include "hw/boards.h"
#include "hw/qdev-properties.h"
#include "qemu/error-report.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
static struct arm_boot_info sabrelite_binfo = {
/* DDR memory start */
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/units.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/kvm.h"
-#include "sysemu/numa.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
+#include "system/device_tree.h"
+#include "system/kvm.h"
+#include "system/numa.h"
+#include "system/runstate.h"
+#include "system/system.h"
#include "exec/hwaddr.h"
#include "kvm_arm.h"
#include "hw/arm/boot.h"
#include "hw/boards.h"
#include "qemu/log.h"
#include "exec/address-spaces.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/arm/armv7m.h"
#include "hw/char/pl011.h"
#include "hw/input/stellaris_gamepad.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-clock.h"
#include "hw/misc/unimp.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
/* stm32f100_soc implementation is derived from stm32f205_soc */
#include "hw/arm/stm32f205_soc.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-clock.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
/* At the moment only Timer 2 to 5 are modelled */
static const uint32_t timer_addr[STM_NUM_TIMERS] = { 0x40000000, 0x40000400,
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "exec/address-spaces.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/arm/stm32f405_soc.h"
#include "hw/qdev-clock.h"
#include "hw/misc/unimp.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "exec/address-spaces.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/or-irq.h"
#include "hw/arm/stm32l4x5_soc.h"
#include "hw/char/stm32l4x5_usart.h"
#include "hw/arm/boot.h"
#include "chardev/char-fe.h"
#include "chardev/char-serial.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/rtc.h"
+#include "system/system.h"
+#include "system/rtc.h"
#include "hw/ssi/ssi.h"
#include "qapi/error.h"
#include "qemu/cutils.h"
#include "hw/arm/boot.h"
#include "hw/net/smc91c111.h"
#include "net/net.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/pci/pci.h"
#include "hw/i2c/i2c.h"
#include "hw/i2c/arm_sbcon_i2c.h"
#include "hw/net/lan9118.h"
#include "hw/i2c/i2c.h"
#include "net/net.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "hw/block/flash.h"
-#include "sysemu/device_tree.h"
+#include "system/device_tree.h"
#include "qemu/error-report.h"
#include <libfdt.h>
#include "hw/char/pl011.h"
#include "hw/intc/arm_gicv3_its_common.h"
#include "hw/mem/nvdimm.h"
#include "hw/platform-bus.h"
-#include "sysemu/numa.h"
-#include "sysemu/reset.h"
-#include "sysemu/tpm.h"
+#include "system/numa.h"
+#include "system/reset.h"
+#include "system/tpm.h"
#include "migration/vmstate.h"
#include "hw/acpi/ghes.h"
#include "hw/acpi/viot.h"
#include "hw/vfio/vfio-amd-xgbe.h"
#include "hw/display/ramfb.h"
#include "net/net.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/numa.h"
-#include "sysemu/runstate.h"
-#include "sysemu/tpm.h"
-#include "sysemu/tcg.h"
-#include "sysemu/kvm.h"
-#include "sysemu/hvf.h"
-#include "sysemu/qtest.h"
+#include "system/device_tree.h"
+#include "system/numa.h"
+#include "system/runstate.h"
+#include "system/tpm.h"
+#include "system/tcg.h"
+#include "system/kvm.h"
+#include "system/hvf.h"
+#include "system/qtest.h"
#include "hw/loader.h"
#include "qapi/error.h"
#include "qemu/bitops.h"
#include "qemu/error-report.h"
#include "qapi/qapi-commands-migration.h"
#include "hw/boards.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/xen/xen-pvh-common.h"
#include "hw/xen/arch_hvm.h"
#include "qemu/error-report.h"
#include "qapi/qapi-commands-migration.h"
#include "hw/boards.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/xen/xen-hvm-common.h"
#include "hw/xen/arch_hvm.h"
#include "hw/sysbus.h"
#include "hw/arm/boot.h"
#include "net/net.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/boards.h"
#include "hw/block/flash.h"
#include "hw/loader.h"
#include "hw/cpu/a9mpcore.h"
#include "hw/qdev-clock.h"
#include "hw/misc/unimp.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "qom/object.h"
#include "exec/tswap.h"
#include "target/arm/cpu-qom.h"
#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
-#include "sysemu/device_tree.h"
+#include "system/device_tree.h"
#include "hw/block/flash.h"
#include "hw/boards.h"
#include "hw/sysbus.h"
#include "qemu/module.h"
#include "hw/sysbus.h"
#include "net/net.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/kvm.h"
+#include "system/system.h"
+#include "system/kvm.h"
#include "hw/arm/boot.h"
#include "kvm_arm.h"
#include "hw/misc/unimp.h"
#include "hw/boards.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
-#include "sysemu/device_tree.h"
+#include "system/device_tree.h"
#include "qom/object.h"
#include "net/can_emu.h"
#include "audio/audio.h"
#include "hw/intc/arm_gic_common.h"
#include "hw/misc/unimp.h"
#include "hw/boards.h"
-#include "sysemu/kvm.h"
-#include "sysemu/sysemu.h"
+#include "system/kvm.h"
+#include "system/system.h"
#include "kvm_arm.h"
#include "target/arm/cpu-qom.h"
#include "target/arm/gtimer.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "qom/object.h"
#include "ac97.h"
#include "migration/vmstate.h"
#include "qemu/cutils.h"
#include "qemu/module.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "qom/object.h"
#include "trace.h"
#include "intel-hda.h"
#include "migration/vmstate.h"
#include "intel-hda-defs.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "qapi/error.h"
#include "qom/object.h"
#include "qemu/log.h"
#include "qemu/error-report.h"
#include "qemu/lockable.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "trace.h"
#include "qapi/error.h"
#include "hw/audio/virtio-snd.h"
#include "qapi/error.h"
#include "exec/memory.h"
#include "exec/address-spaces.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "qom/object.h"
#include "qemu/osdep.h"
#include "block/block_int-common.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/block-backend.h"
+#include "system/blockdev.h"
+#include "system/block-backend.h"
#include "hw/block/block.h"
#include "qapi/error.h"
#include "qapi/qapi-types-block.h"
#include "hw/xen/xen.h"
#include "hw/block/xen_blkif.h"
#include "hw/xen/interface/io/ring.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/iothread.h"
+#include "system/block-backend.h"
+#include "system/iothread.h"
#include "xen-block.h"
typedef struct XenBlockRequest {
#include "hw/block/block.h"
#include "hw/xen/xen-bus.h"
-#include "sysemu/iothread.h"
+#include "system/iothread.h"
typedef struct XenBlockDataPlane XenBlockDataPlane;
#include "hw/qdev-properties-system.h"
#include "migration/vmstate.h"
#include "hw/block/block.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/sysemu.h"
+#include "system/block-backend.h"
+#include "system/blockdev.h"
+#include "system/system.h"
#include "exec/ioport.h"
#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "hw/qdev-properties-system.h"
#include "migration/vmstate.h"
#include "hw/block/block.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/sysemu.h"
+#include "system/block-backend.h"
+#include "system/blockdev.h"
+#include "system/system.h"
#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qapi/qapi-types-block.h"
#include "qemu/bswap.h"
#include "hw/block/block.h"
#include "qemu/osdep.h"
#include "qemu/units.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "hw/block/block.h"
#include "hw/block/flash.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "hw/block/flash.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "hw/block/flash.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/bitops.h"
#include "qemu/option.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/runstate.h"
+#include "system/blockdev.h"
+#include "system/runstate.h"
#include "trace.h"
#define PFLASH_BE 0
#include "qemu/error-report.h"
#include "qemu/bitmap.h"
#include "qemu/timer.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qemu/host-utils.h"
#include "qemu/module.h"
#include "hw/sysbus.h"
#include "qemu/osdep.h"
#include "qemu/main-loop.h"
#include "qapi/error.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "hw/block/block.h"
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-bus.h"
#include "hw/virtio/virtio-access.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/runstate.h"
+#include "system/system.h"
+#include "system/runstate.h"
static const int user_feature_bits[] = {
VIRTIO_BLK_F_SIZE_MAX,
#include "trace.h"
#include "hw/block/block.h"
#include "hw/qdev-properties.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/block-ram-registrar.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/runstate.h"
+#include "system/blockdev.h"
+#include "system/block-ram-registrar.h"
+#include "system/system.h"
+#include "system/runstate.h"
#include "hw/virtio/virtio-blk.h"
#include "scsi/constants.h"
#ifdef __linux__
#include "hw/qdev-properties.h"
#include "hw/xen/xen-block.h"
#include "hw/xen/xen-backend.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/iothread.h"
+#include "system/blockdev.h"
+#include "system/block-backend.h"
+#include "system/iothread.h"
#include "dataplane/xen-block.h"
#include "hw/xen/interface/io/xs_wire.h"
#include "trace.h"
#include "qemu/log.h"
#include "trace.h"
#include "exec/address-spaces.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "hw/char/goldfish_tty.h"
#define GOLDFISH_TTY_VERSION 1
*/
#include "qemu/osdep.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/isa/isa.h"
#include "hw/qdev-properties.h"
#include "hw/char/parallel-isa.h"
#include "migration/vmstate.h"
#include "hw/char/parallel-isa.h"
#include "hw/char/parallel.h"
-#include "sysemu/reset.h"
-#include "sysemu/sysemu.h"
+#include "system/reset.h"
+#include "system/system.h"
#include "trace.h"
#include "qom/object.h"
#include "qemu/error-report.h"
#include "exec/address-spaces.h"
#include "exec/tswap.h"
-#include "sysemu/dma.h"
-#include "sysemu/runstate.h"
+#include "system/dma.h"
+#include "system/runstate.h"
#define RISCV_DEBUG_HTIF 0
#define HTIF_DEBUG(fmt, ...) \
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/module.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/acpi/acpi_aml_interface.h"
#include "hw/char/serial.h"
#include "hw/char/serial-isa.h"
#include "chardev/char-serial.h"
#include "qapi/error.h"
#include "qemu/timer.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
+#include "system/reset.h"
+#include "system/runstate.h"
#include "qemu/error-report.h"
#include "trace.h"
#include "hw/qdev-properties.h"
#include <termios.h>
#include "qapi/error.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "chardev/char-fe.h"
#include "hw/xen/xen-backend.h"
#include "hw/xen/xen-bus-helper.h"
#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "qapi/visitor.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
#include "hw/clock.h"
#include "trace.h"
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/core/cpu.h"
-#include "sysemu/hw_accel.h"
+#include "system/hw_accel.h"
#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "qemu/lockcnt.h"
#include "exec/log.h"
#include "exec/gdbstub.h"
-#include "sysemu/tcg.h"
+#include "system/tcg.h"
#include "hw/boards.h"
#include "hw/qdev-properties.h"
#include "trace.h"
+++ /dev/null
-/*
- * QEMU CPU model (system emulation specific)
- *
- * Copyright (c) 2012-2014 SUSE LINUX Products GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see
- * <http://www.gnu.org/licenses/gpl-2.0.html>
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "exec/tswap.h"
-#include "hw/core/sysemu-cpu-ops.h"
-
-bool cpu_paging_enabled(const CPUState *cpu)
-{
- CPUClass *cc = CPU_GET_CLASS(cpu);
-
- if (cc->sysemu_ops->get_paging_enabled) {
- return cc->sysemu_ops->get_paging_enabled(cpu);
- }
-
- return false;
-}
-
-bool cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
- Error **errp)
-{
- CPUClass *cc = CPU_GET_CLASS(cpu);
-
- if (cc->sysemu_ops->get_memory_mapping) {
- return cc->sysemu_ops->get_memory_mapping(cpu, list, errp);
- }
-
- error_setg(errp, "Obtaining memory mappings is unsupported on this CPU.");
- return false;
-}
-
-hwaddr cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
- MemTxAttrs *attrs)
-{
- CPUClass *cc = CPU_GET_CLASS(cpu);
-
- if (cc->sysemu_ops->get_phys_page_attrs_debug) {
- return cc->sysemu_ops->get_phys_page_attrs_debug(cpu, addr, attrs);
- }
- /* Fallback for CPUs which don't implement the _attrs_ hook */
- *attrs = MEMTXATTRS_UNSPECIFIED;
- return cc->sysemu_ops->get_phys_page_debug(cpu, addr);
-}
-
-hwaddr cpu_get_phys_page_debug(CPUState *cpu, vaddr addr)
-{
- MemTxAttrs attrs = {};
-
- return cpu_get_phys_page_attrs_debug(cpu, addr, &attrs);
-}
-
-int cpu_asidx_from_attrs(CPUState *cpu, MemTxAttrs attrs)
-{
- int ret = 0;
-
- if (cpu->cc->sysemu_ops->asidx_from_attrs) {
- ret = cpu->cc->sysemu_ops->asidx_from_attrs(cpu, attrs);
- assert(ret < cpu->num_ases && ret >= 0);
- }
- return ret;
-}
-
-int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
- void *opaque)
-{
- CPUClass *cc = CPU_GET_CLASS(cpu);
-
- if (!cc->sysemu_ops->write_elf32_qemunote) {
- return 0;
- }
- return (*cc->sysemu_ops->write_elf32_qemunote)(f, cpu, opaque);
-}
-
-int cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cpu,
- int cpuid, void *opaque)
-{
- CPUClass *cc = CPU_GET_CLASS(cpu);
-
- if (!cc->sysemu_ops->write_elf32_note) {
- return -1;
- }
- return (*cc->sysemu_ops->write_elf32_note)(f, cpu, cpuid, opaque);
-}
-
-int cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
- void *opaque)
-{
- CPUClass *cc = CPU_GET_CLASS(cpu);
-
- if (!cc->sysemu_ops->write_elf64_qemunote) {
- return 0;
- }
- return (*cc->sysemu_ops->write_elf64_qemunote)(f, cpu, opaque);
-}
-
-int cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu,
- int cpuid, void *opaque)
-{
- CPUClass *cc = CPU_GET_CLASS(cpu);
-
- if (!cc->sysemu_ops->write_elf64_note) {
- return -1;
- }
- return (*cc->sysemu_ops->write_elf64_note)(f, cpu, cpuid, opaque);
-}
-
-bool cpu_virtio_is_big_endian(CPUState *cpu)
-{
- CPUClass *cc = CPU_GET_CLASS(cpu);
-
- if (cc->sysemu_ops->virtio_is_big_endian) {
- return cc->sysemu_ops->virtio_is_big_endian(cpu);
- }
- return target_words_bigendian();
-}
-
-GuestPanicInformation *cpu_get_crash_info(CPUState *cpu)
-{
- CPUClass *cc = CPU_GET_CLASS(cpu);
- GuestPanicInformation *res = NULL;
-
- if (cc->sysemu_ops->get_crash_info) {
- res = cc->sysemu_ops->get_crash_info(cpu);
- }
- return res;
-}
--- /dev/null
+/*
+ * QEMU CPU model (system specific)
+ *
+ * Copyright (c) 2012-2014 SUSE LINUX Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "exec/tswap.h"
+#include "hw/core/sysemu-cpu-ops.h"
+
+bool cpu_paging_enabled(const CPUState *cpu)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ if (cc->sysemu_ops->get_paging_enabled) {
+ return cc->sysemu_ops->get_paging_enabled(cpu);
+ }
+
+ return false;
+}
+
+bool cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
+ Error **errp)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ if (cc->sysemu_ops->get_memory_mapping) {
+ return cc->sysemu_ops->get_memory_mapping(cpu, list, errp);
+ }
+
+ error_setg(errp, "Obtaining memory mappings is unsupported on this CPU.");
+ return false;
+}
+
+hwaddr cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
+ MemTxAttrs *attrs)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ if (cc->sysemu_ops->get_phys_page_attrs_debug) {
+ return cc->sysemu_ops->get_phys_page_attrs_debug(cpu, addr, attrs);
+ }
+ /* Fallback for CPUs which don't implement the _attrs_ hook */
+ *attrs = MEMTXATTRS_UNSPECIFIED;
+ return cc->sysemu_ops->get_phys_page_debug(cpu, addr);
+}
+
+hwaddr cpu_get_phys_page_debug(CPUState *cpu, vaddr addr)
+{
+ MemTxAttrs attrs = {};
+
+ return cpu_get_phys_page_attrs_debug(cpu, addr, &attrs);
+}
+
+int cpu_asidx_from_attrs(CPUState *cpu, MemTxAttrs attrs)
+{
+ int ret = 0;
+
+ if (cpu->cc->sysemu_ops->asidx_from_attrs) {
+ ret = cpu->cc->sysemu_ops->asidx_from_attrs(cpu, attrs);
+ assert(ret < cpu->num_ases && ret >= 0);
+ }
+ return ret;
+}
+
+int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
+ void *opaque)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ if (!cc->sysemu_ops->write_elf32_qemunote) {
+ return 0;
+ }
+ return (*cc->sysemu_ops->write_elf32_qemunote)(f, cpu, opaque);
+}
+
+int cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cpu,
+ int cpuid, void *opaque)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ if (!cc->sysemu_ops->write_elf32_note) {
+ return -1;
+ }
+ return (*cc->sysemu_ops->write_elf32_note)(f, cpu, cpuid, opaque);
+}
+
+int cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
+ void *opaque)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ if (!cc->sysemu_ops->write_elf64_qemunote) {
+ return 0;
+ }
+ return (*cc->sysemu_ops->write_elf64_qemunote)(f, cpu, opaque);
+}
+
+int cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu,
+ int cpuid, void *opaque)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ if (!cc->sysemu_ops->write_elf64_note) {
+ return -1;
+ }
+ return (*cc->sysemu_ops->write_elf64_note)(f, cpu, cpuid, opaque);
+}
+
+bool cpu_virtio_is_big_endian(CPUState *cpu)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ if (cc->sysemu_ops->virtio_is_big_endian) {
+ return cc->sysemu_ops->virtio_is_big_endian(cpu);
+ }
+ return target_words_bigendian();
+}
+
+GuestPanicInformation *cpu_get_crash_info(CPUState *cpu)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+ GuestPanicInformation *res = NULL;
+
+ if (cc->sysemu_ops->get_crash_info) {
+ res = cc->sysemu_ops->get_crash_info(cpu);
+ }
+ return res;
+}
#include "qemu/osdep.h"
#include "exec/tswap.h"
-#include "sysemu/dma.h"
-#include "sysemu/reset.h"
+#include "system/dma.h"
+#include "system/reset.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "hw/qdev-properties.h"
#include "qemu/osdep.h"
#include "hw/core/cpu.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "hw/loader.h"
#include "hw/qdev-properties.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "guest-loader.h"
-#include "sysemu/device_tree.h"
+#include "system/device_tree.h"
#include "hw/boards.h"
/*
#include "hw/loader-fit.h"
#include "qemu/cutils.h"
#include "qemu/error-report.h"
-#include "sysemu/device_tree.h"
+#include "system/device_tree.h"
#include <libfdt.h>
#include <zlib.h>
#include "disas/disas.h"
#include "migration/vmstate.h"
#include "monitor/monitor.h"
-#include "sysemu/reset.h"
-#include "sysemu/sysemu.h"
+#include "system/reset.h"
+#include "system/system.h"
#include "uboot_image.h"
#include "hw/loader.h"
#include "hw/nvram/fw_cfg.h"
#include "exec/memory.h"
#include "hw/boards.h"
#include "qemu/cutils.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "tcg/debuginfo.h"
#include <zlib.h>
#include "qapi/qmp/qdict.h"
#include "qapi/string-output-visitor.h"
#include "qemu/error-report.h"
-#include "sysemu/numa.h"
+#include "system/numa.h"
#include "hw/boards.h"
void hmp_info_cpus(Monitor *mon, const QDict *qdict)
#include "qapi/type-helpers.h"
#include "qemu/uuid.h"
#include "qom/qom-qobject.h"
-#include "sysemu/hostmem.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/numa.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
+#include "system/hostmem.h"
+#include "system/hw_accel.h"
+#include "system/numa.h"
+#include "system/runstate.h"
+#include "system/system.h"
/*
* fast means: we NEVER interrupt vCPU threads to retrieve
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qemu/accel.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "qemu/error-report.h"
#include "qapi/qapi-visit-machine.h"
#include "qemu/madvise.h"
#include "qom/object_interfaces.h"
-#include "sysemu/cpus.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
-#include "sysemu/xen.h"
-#include "sysemu/qtest.h"
+#include "system/cpus.h"
+#include "system/system.h"
+#include "system/reset.h"
+#include "system/runstate.h"
+#include "system/xen.h"
+#include "system/qtest.h"
#include "hw/pci/pci_bridge.h"
#include "hw/mem/nvdimm.h"
#include "migration/global_state.h"
system_ss.add(when: 'CONFIG_EIF', if_true: [files('eif.c'), zlib, libcbor, gnutls])
system_ss.add(files(
- 'cpu-sysemu.c',
+ 'cpu-system.c',
'fw-path-provider.c',
'gpio.c',
'hotplug.c',
#include "qemu/osdep.h"
#include "qemu/units.h"
-#include "sysemu/hostmem.h"
-#include "sysemu/numa.h"
+#include "system/hostmem.h"
+#include "system/numa.h"
#include "exec/cpu-common.h"
#include "exec/ramlist.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qapi/opts-visitor.h"
#include "qapi/qapi-visit-machine.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
#include "hw/core/cpu.h"
#include "hw/mem/pc-dimm.h"
#include "hw/boards.h"
#include "migration/vmstate.h"
#include "qemu/host-utils.h"
#include "exec/replay-core.h"
-#include "sysemu/cpu-timers.h"
-#include "sysemu/qtest.h"
+#include "system/cpu-timers.h"
+#include "system/qtest.h"
#include "block/aio.h"
#include "hw/clock.h"
#include "audio/audio.h"
#include "chardev/char-fe.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
+#include "system/block-backend.h"
+#include "system/blockdev.h"
#include "net/net.h"
#include "hw/pci/pci.h"
#include "hw/pci/pcie.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "hw/resettable.h"
#include "hw/core/resetcontainer.h"
#endif
#include "hw/core/sysbus-fdt.h"
#include "qemu/error-report.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/tpm.h"
+#include "system/device_tree.h"
+#include "system/tpm.h"
#include "hw/platform-bus.h"
#include "hw/vfio/vfio-platform.h"
#include "hw/vfio/vfio-calxeda-xgmac.h"
#include "qemu/osdep.h"
#include "hw/qdev-core.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
static int qdev_get_dev_tree_depth(DeviceState *dev)
{
#include "hw/cpu/a15mpcore.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "kvm_arm.h"
#include "target/arm/gtimer.h"
#include "qemu/bitmap.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
#include "hw/boards.h"
#include "qapi/qapi-visit-machine.h"
#include "qemu/log.h"
#include "qemu/units.h"
#include "qemu/uuid.h"
-#include "sysemu/hostmem.h"
+#include "system/hostmem.h"
#include "qemu/range.h"
#define CXL_CAPACITY_MULTIPLIER (256 * MiB)
#include "qemu/module.h"
#include "qemu/units.h"
#include "qemu/log.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "qapi/error.h"
#include "trace.h"
#include "hw/pci/pci_device.h"
#include "qemu/osdep.h"
#include "qxl.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "trace.h"
static void qxl_blit(PCIQXLDevice *qxl, QXLRect *rect)
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "hw/qdev-properties.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "migration/vmstate.h"
#include "trace.h"
#include "hw/display/ramfb.h"
#include "hw/display/bochs-vbe.h" /* for limits */
#include "ui/console.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
struct QEMU_PACKED RAMFBCfg {
uint64_t addr;
#include "qemu/osdep.h"
#include "qemu/units.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "qapi/error.h"
#include "exec/tswap.h"
#include "hw/display/vga.h"
#include "qemu/module.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-gpu.h"
#include "hw/virtio/virtio-gpu-bswap.h"
#include "hw/virtio/virtio-gpu-pixman.h"
#include "trace.h"
#include "exec/ramblock.h"
-#include "sysemu/hostmem.h"
+#include "system/hostmem.h"
#include <sys/ioctl.h>
#include <linux/memfd.h>
#include "qemu/memfd.h"
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qemu/iov.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
#include "ui/console.h"
#include "ui/rect.h"
#include "trace.h"
-#include "sysemu/dma.h"
-#include "sysemu/sysemu.h"
+#include "system/dma.h"
+#include "system/system.h"
#include "hw/virtio/virtio.h"
#include "migration/qemu-file-types.h"
#include "hw/virtio/virtio-gpu.h"
#include "ui/input.h"
#include "ui/console.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/xen/xen-legacy-backend.h"
#include "hw/xen/interface/io/fbif.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
#include "qemu/timer.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "trace.h"
#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "hw/dma/sifive_pdma.h"
#define DMA_CONTROL 0x000
#include "hw/sparc/sun4m_iommu.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "trace.h"
#include "qemu/log.h"
#include "qemu/module.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "hw/stream.h"
#include "qom/object.h"
#include "trace.h"
#include "hw/irq.h"
#include "migration/vmstate.h"
#include "qemu/bitops.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "hw/ptimer.h"
#include "hw/stream.h"
#include "hw/register.h"
#include "qemu/osdep.h"
#include "hw/sysbus.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#define TYPE_GPIOPWR "gpio-pwr"
OBJECT_DECLARE_SIMPLE_TYPE(GPIO_PWR_State, GPIOPWR)
#include "elf.h"
#include "hw/loader.h"
#include "qemu/error-report.h"
-#include "sysemu/reset.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/qtest.h"
-#include "sysemu/runstate.h"
+#include "system/reset.h"
+#include "system/system.h"
+#include "system/qtest.h"
+#include "system/runstate.h"
#include "hw/rtc/mc146818rtc.h"
#include "hw/timer/i8254.h"
#include "hw/char/serial-mm.h"
#include "qemu/module.h"
#include "qemu/units.h"
#include "qemu/timer.h"
-#include "sysemu/balloon.h"
-#include "sysemu/hostmem.h"
-#include "sysemu/reset.h"
+#include "system/balloon.h"
+#include "system/hostmem.h"
+#include "system/reset.h"
#include "hv-balloon-our_range_memslots.h"
#include "hv-balloon-page_range_tree.h"
#include "trace.h"
#include "qapi/error.h"
#include "exec/address-spaces.h"
#include "exec/memory.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "qemu/bitops.h"
#include "qemu/error-report.h"
#include "qemu/lockable.h"
#include "hw/acpi/acpi_aml_interface.h"
#include "hw/input/i8042.h"
#include "hw/acpi/memory_hotplug.h"
-#include "sysemu/tpm.h"
+#include "system/tpm.h"
#include "hw/acpi/tpm.h"
#include "hw/acpi/vmgenid.h"
#include "hw/acpi/erst.h"
#include "hw/acpi/piix4.h"
-#include "sysemu/tpm_backend.h"
+#include "system/tpm_backend.h"
#include "hw/rtc/mc146818rtc_regs.h"
#include "migration/vmstate.h"
#include "hw/mem/memory-device.h"
#include "hw/mem/nvdimm.h"
-#include "sysemu/numa.h"
-#include "sysemu/reset.h"
+#include "system/numa.h"
+#include "system/reset.h"
#include "hw/hyperv/vmbus-bridge.h"
/* Supported chipsets: */
*/
#include "qemu/osdep.h"
-#include "sysemu/numa.h"
+#include "system/numa.h"
#include "hw/acpi/acpi.h"
#include "hw/acpi/aml-build.h"
#include "hw/firmware/smbios.h"
#include "hw/i386/apic-msidef.h"
#include "hw/i386/x86-iommu.h"
#include "hw/pci-host/q35.h"
-#include "sysemu/kvm.h"
-#include "sysemu/dma.h"
-#include "sysemu/sysemu.h"
+#include "system/kvm.h"
+#include "system/dma.h"
+#include "system/system.h"
#include "hw/i386/apic_internal.h"
#include "kvm/kvm_i386.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
#include "hw/i386/apic_internal.h"
#include "hw/pci/msi.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/kvm.h"
+#include "system/hw_accel.h"
+#include "system/kvm.h"
#include "kvm/kvm_i386.h"
static inline void kvm_apic_set_reg(struct kvm_lapic_state *kapic,
#include "qemu/osdep.h"
#include "qemu/host-utils.h"
#include "qemu/module.h"
-#include "sysemu/kvm.h"
-#include "sysemu/runstate.h"
-#include "sysemu/hw_accel.h"
+#include "system/kvm.h"
+#include "system/runstate.h"
+#include "system/hw_accel.h"
#include "kvm/kvm_i386.h"
#include "migration/vmstate.h"
#include "hw/sysbus.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "qemu/timer.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "hw/timer/i8254.h"
#include "hw/timer/i8254_internal.h"
#include "hw/qdev-properties-system.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "target/i386/kvm/kvm_i386.h"
#include "qom/object.h"
#include "qemu/module.h"
#include "hw/intc/kvm_irqcount.h"
#include "hw/irq.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "qom/object.h"
#define TYPE_KVM_I8259 "kvm-i8259"
#include "hw/qdev-properties.h"
#include "hw/intc/ioapic_internal.h"
#include "hw/intc/kvm_irqcount.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "kvm/kvm_i386.h"
/* PC Utility function */
#include "xen_overlay.h"
#include "xen_xenstore.h"
-#include "sysemu/kvm.h"
-#include "sysemu/kvm_xen.h"
+#include "system/kvm.h"
+#include "system/kvm_xen.h"
#include <linux/kvm.h>
#include <sys/eventfd.h>
#include "xen_gnttab.h"
#include "xen_primary_console.h"
-#include "sysemu/kvm.h"
-#include "sysemu/kvm_xen.h"
+#include "system/kvm.h"
+#include "system/kvm_xen.h"
#include "hw/xen/interface/memory.h"
#include "hw/xen/interface/grant_table.h"
#include "hw/xen/xen.h"
#include "xen_overlay.h"
-#include "sysemu/kvm.h"
-#include "sysemu/kvm_xen.h"
+#include "system/kvm.h"
+#include "system/kvm_xen.h"
#include <linux/kvm.h>
#include "hw/xen/interface/memory.h"
#include "xen_overlay.h"
#include "xen_primary_console.h"
-#include "sysemu/kvm.h"
-#include "sysemu/kvm_xen.h"
+#include "system/kvm.h"
+#include "system/kvm_xen.h"
#include "trace.h"
#include "xen_primary_console.h"
#include "xen_xenstore.h"
-#include "sysemu/kvm.h"
-#include "sysemu/kvm_xen.h"
+#include "system/kvm.h"
+#include "system/kvm_xen.h"
#include "trace.h"
#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
-#include "sysemu/device_tree.h"
+#include "system/device_tree.h"
#include "hw/char/serial-isa.h"
#include "hw/i386/fw_cfg.h"
#include "hw/rtc/mc146818rtc.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "qapi/qapi-visit-common.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/cpus.h"
-#include "sysemu/numa.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
+#include "system/system.h"
+#include "system/cpus.h"
+#include "system/numa.h"
+#include "system/reset.h"
+#include "system/runstate.h"
#include "acpi-microvm.h"
#include "microvm-dt.h"
#include "multiboot.h"
#include "hw/loader.h"
#include "elf.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qemu/error-report.h"
/* Show multiboot debug output */
#include "hw/virtio/virtio-mmio.h"
#include "hw/virtio/virtio-nsm.h"
#include "hw/virtio/vhost-user-vsock.h"
-#include "sysemu/hostmem.h"
+#include "system/hostmem.h"
static BusState *find_free_virtio_mmio_bus(void)
{
#include "hw/hyperv/hv-balloon.h"
#include "hw/i386/fw_cfg.h"
#include "hw/i386/vmport.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
#include "hw/ide/ide-bus.h"
#include "hw/timer/hpet.h"
#include "hw/loader.h"
#include "hw/timer/i8254.h"
#include "hw/input/i8042.h"
#include "hw/audio/pcspk.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/xen.h"
-#include "sysemu/reset.h"
+#include "system/system.h"
+#include "system/xen.h"
+#include "system/reset.h"
#include "kvm/kvm_i386.h"
#include "hw/xen/xen.h"
#include "qapi/qmp/qlist.h"
#include "hw/ide/isa.h"
#include "hw/ide/pci.h"
#include "hw/irq.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "hw/i386/kvm/clock.h"
#include "hw/sysbus.h"
#include "hw/i2c/smbus_eeprom.h"
#include "hw/acpi/acpi.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
-#include "sysemu/xen.h"
+#include "system/xen.h"
#ifdef CONFIG_XEN
#include <xen/hvm/hvm_info_table.h>
#include "hw/xen/xen_pt.h"
#include "hw/xen/xen.h"
#include "migration/global_state.h"
#include "migration/misc.h"
-#include "sysemu/runstate.h"
-#include "sysemu/numa.h"
+#include "system/runstate.h"
+#include "system/numa.h"
#include "hw/hyperv/vmbus-bridge.h"
#include "hw/mem/nvdimm.h"
#include "hw/i386/acpi-build.h"
#include "hw/loader.h"
#include "hw/i2c/smbus_eeprom.h"
#include "hw/rtc/mc146818rtc.h"
-#include "sysemu/tcg.h"
-#include "sysemu/kvm.h"
+#include "system/tcg.h"
+#include "system/kvm.h"
#include "hw/i386/kvm/clock.h"
#include "hw/pci-host/q35.h"
#include "hw/pci/pcie_port.h"
#include "hw/usb/hcd-uhci.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
-#include "sysemu/numa.h"
+#include "system/numa.h"
#include "hw/hyperv/vmbus-bridge.h"
#include "hw/mem/nvdimm.h"
#include "hw/i386/acpi-build.h"
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qemu/error-report.h"
#include "qemu/option.h"
#include "qemu/units.h"
#include "hw/loader.h"
#include "hw/qdev-properties.h"
#include "hw/block/flash.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "target/i386/sev.h"
#define FLASH_SECTOR_SIZE 4096
*/
#include "qemu/osdep.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "migration/vmstate.h"
#include "hw/irq.h"
#include "hw/isa/isa.h"
#include "qemu/error-report.h"
#include "qapi/qapi-commands-misc-target.h"
#include "exec/address-spaces.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/reset.h"
+#include "system/hw_accel.h"
+#include "system/reset.h"
#include <sys/ioctl.h>
#include "hw/acpi/aml-build.h"
#include "qemu/osdep.h"
#include "qemu/module.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/cpus.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/kvm.h"
-#include "sysemu/runstate.h"
+#include "system/system.h"
+#include "system/cpus.h"
+#include "system/hw_accel.h"
+#include "system/kvm.h"
+#include "system/runstate.h"
#include "exec/address-spaces.h"
#include "hw/i386/apic_internal.h"
#include "hw/sysbus.h"
#include "hw/i386/vmport.h"
#include "hw/qdev-properties.h"
#include "hw/boards.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/qtest.h"
+#include "system/system.h"
+#include "system/hw_accel.h"
+#include "system/qtest.h"
#include "qemu/log.h"
#include "trace.h"
#include "qom/object.h"
#include "qemu/units.h"
#include "qemu/datadir.h"
#include "qapi/error.h"
-#include "sysemu/numa.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/xen.h"
+#include "system/numa.h"
+#include "system/system.h"
+#include "system/xen.h"
#include "trace.h"
#include "hw/i386/x86.h"
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
-#include "sysemu/whpx.h"
-#include "sysemu/cpu-timers.h"
+#include "system/whpx.h"
+#include "system/cpu-timers.h"
#include "trace.h"
#include "hw/i386/x86.h"
#include "target/i386/cpu.h"
#include "hw/intc/i8259.h"
#include "hw/irq.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
/* TSC handling */
uint64_t cpu_get_tsc(CPUX86State *env)
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "trace.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
void x86_iommu_iec_register_notifier(X86IOMMUState *iommu,
iec_notify_fn fn, void *data)
#include "qapi/qapi-visit-common.h"
#include "qapi/qapi-visit-machine.h"
#include "qapi/visitor.h"
-#include "sysemu/qtest.h"
-#include "sysemu/numa.h"
+#include "system/qtest.h"
+#include "system/numa.h"
#include "trace.h"
#include "hw/acpi/aml-build.h"
#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "hw/boards.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/xen/arch_hvm.h"
#include <xen/hvm/hvm_info_table.h>
#include "hw/xen/xen-pvh-common.h"
#include "migration/vmstate.h"
#include "net/net.h"
#include "trace.h"
-#include "sysemu/xen.h"
-#include "sysemu/block-backend.h"
+#include "system/xen.h"
+#include "system/block-backend.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qom/object.h"
#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "migration/vmstate.h"
#include "hw/ide/ahci-sysbus.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "qemu/main-loop.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/dma.h"
+#include "system/block-backend.h"
+#include "system/dma.h"
#include "ahci-internal.h"
#include "ide-internal.h"
#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "hw/scsi/scsi.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "scsi/constants.h"
#include "ide-internal.h"
#include "trace.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
#include "hw/isa/isa.h"
-#include "sysemu/dma.h"
-#include "sysemu/reset.h"
+#include "system/dma.h"
+#include "system/reset.h"
#include "hw/ide/pci.h"
#include "ide-internal.h"
#include "qemu/timer.h"
#include "qemu/hw-version.h"
#include "qemu/memalign.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/dma.h"
+#include "system/system.h"
+#include "system/blockdev.h"
+#include "system/dma.h"
#include "hw/block/block.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qapi/error.h"
#include "qemu/cutils.h"
-#include "sysemu/replay.h"
-#include "sysemu/runstate.h"
+#include "system/replay.h"
+#include "system/runstate.h"
#include "ide-internal.h"
#include "trace.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
#include "hw/isa/isa.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "hw/ide/pci.h"
#include "hw/ide/ahci-pci.h"
#include "ahci-internal.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/runstate.h"
+#include "system/block-backend.h"
+#include "system/blockdev.h"
+#include "system/runstate.h"
#include "ide-internal.h"
static char *idebus_get_fw_dev_path(DeviceState *dev);
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "hw/ide/ide-dev.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/sysemu.h"
+#include "system/block-backend.h"
+#include "system/blockdev.h"
+#include "system/system.h"
#include "qapi/visitor.h"
#include "ide-internal.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
#include "qemu/module.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "hw/ide/isa.h"
#include "qom/object.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
#include "hw/misc/macio/macio.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/dma.h"
+#include "system/block-backend.h"
+#include "system/dma.h"
#include "ide-internal.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "hw/ide/mmio.h"
#include "hw/qdev-properties.h"
#include "hw/irq.h"
#include "hw/pci/pci.h"
#include "migration/vmstate.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "hw/ide/pci.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
#include "qemu/range.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "hw/isa/vt82c686.h"
#include "hw/ide/pci.h"
#include "hw/irq.h"
#include "hw/irq.h"
#include "hw/input/i8042.h"
#include "hw/qdev-properties.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
+#include "system/reset.h"
+#include "system/runstate.h"
#include "trace.h"
#include "migration/vmstate.h"
#include "ui/console.h"
#include "ui/input.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
+#include "system/reset.h"
+#include "system/runstate.h"
#include "qapi/error.h"
#include "trace.h"
#include "hw/intc/kvm_irqcount.h"
#include "hw/pci/msi.h"
#include "qemu/host-utils.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "trace.h"
#include "hw/i386/apic-msidef.h"
#include "qapi/error.h"
#include "hw/intc/kvm_irqcount.h"
#include "trace.h"
#include "hw/boards.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "trace.h"
-#include "sysemu/kvm.h"
-#include "sysemu/qtest.h"
+#include "system/kvm.h"
+#include "system/qtest.h"
/* #define DEBUG_GIC */
#include "hw/arm/linux-boot-if.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
static int gic_pre_save(void *opaque)
{
#include "qapi/error.h"
#include "qemu/module.h"
#include "migration/blocker.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "kvm_arm.h"
#include "gic_internal.h"
#include "vgic_common.h"
#include "hw/irq.h"
#include "hw/pci/msi.h"
#include "hw/qdev-properties.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qom/object.h"
#include "migration/vmstate.h"
#include "gicv3_internal.h"
#include "hw/arm/linux-boot-if.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
static void gicv3_gicd_no_migration_shift_bug_post_load(GICv3State *cs)
#include "cpu.h"
#include "target/arm/cpregs.h"
#include "target/arm/cpu-features.h"
-#include "sysemu/tcg.h"
-#include "sysemu/qtest.h"
+#include "system/tcg.h"
+#include "system/qtest.h"
/*
* Special case return value from hppvi_index(); must be larger than
#include "hw/intc/arm_gicv3_its_common.h"
#include "qemu/log.h"
#include "qemu/module.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
static int gicv3_its_pre_save(void *opaque)
{
#include "qemu/error-report.h"
#include "hw/intc/arm_gicv3_its_common.h"
#include "hw/qdev-properties.h"
-#include "sysemu/runstate.h"
-#include "sysemu/kvm.h"
+#include "system/runstate.h"
+#include "system/kvm.h"
#include "kvm_arm.h"
#include "migration/blocker.h"
#include "qom/object.h"
#include "hw/intc/arm_gicv3_common.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
-#include "sysemu/kvm.h"
-#include "sysemu/runstate.h"
+#include "system/kvm.h"
+#include "system/runstate.h"
#include "kvm_arm.h"
#include "gicv3_internal.h"
#include "vgic_common.h"
#include "hw/intc/armv7m_nvic.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
-#include "sysemu/tcg.h"
-#include "sysemu/runstate.h"
+#include "system/tcg.h"
+#include "system/runstate.h"
#include "target/arm/cpu.h"
#include "target/arm/cpu-features.h"
#include "exec/exec-all.h"
#include "hw/intc/ioapic_internal.h"
#include "hw/pci/msi.h"
#include "hw/qdev-properties.h"
-#include "sysemu/kvm.h"
-#include "sysemu/sysemu.h"
+#include "system/kvm.h"
+#include "system/system.h"
#include "hw/i386/apic-msidef.h"
#include "hw/i386/x86-iommu.h"
#include "trace.h"
#include "qapi/error.h"
#include "hw/sysbus.h"
#include "exec/memory.h"
-#include "sysemu/kvm.h"
-#include "sysemu/reset.h"
+#include "system/kvm.h"
+#include "system/reset.h"
#include "kvm_mips.h"
#include "hw/intc/mips_gic.h"
#include "hw/irq.h"
#include "hw/pci/msi.h"
#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qom/object.h"
#include "qemu/module.h"
#include "qapi/error.h"
#include "target/ppc/cpu.h"
-#include "sysemu/cpus.h"
-#include "sysemu/dma.h"
-#include "sysemu/reset.h"
+#include "system/cpus.h"
+#include "system/dma.h"
+#include "system/reset.h"
#include "hw/ppc/fdt.h"
#include "hw/ppc/pnv.h"
#include "hw/ppc/pnv_chip.h"
#include "qemu/log.h"
#include "qapi/error.h"
#include "target/ppc/cpu.h"
-#include "sysemu/cpus.h"
-#include "sysemu/dma.h"
+#include "system/cpus.h"
+#include "system/dma.h"
#include "hw/ppc/fdt.h"
#include "hw/ppc/pnv.h"
#include "hw/ppc/pnv_chip.h"
#include "hw/ppc/xive2_regs.h"
#include "hw/ppc/ppc.h"
#include "hw/qdev-properties.h"
-#include "sysemu/reset.h"
-#include "sysemu/qtest.h"
+#include "system/reset.h"
+#include "system/qtest.h"
#include <libfdt.h>
#include "hw/intc/riscv_aplic.h"
#include "hw/irq.h"
#include "target/riscv/cpu.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/kvm.h"
+#include "system/system.h"
+#include "system/kvm.h"
#include "kvm/kvm_riscv.h"
#include "migration/vmstate.h"
#include "hw/irq.h"
#include "target/riscv/cpu.h"
#include "target/riscv/cpu_bits.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/kvm.h"
+#include "system/system.h"
+#include "system/kvm.h"
#include "migration/vmstate.h"
#define IMSIC_MMIO_PAGE_LE 0x00
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qapi/error.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "hw/s390x/s390_flic.h"
#include "hw/s390x/adapter.h"
#include "hw/s390x/css.h"
#include "target/riscv/cpu.h"
#include "migration/vmstate.h"
#include "hw/irq.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
static bool addr_between(uint32_t addr, uint32_t base, uint32_t num)
{
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "target/ppc/cpu.h"
-#include "sysemu/cpus.h"
-#include "sysemu/reset.h"
+#include "system/cpus.h"
+#include "system/reset.h"
#include "migration/vmstate.h"
#include "hw/ppc/fdt.h"
#include "hw/ppc/spapr.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "target/ppc/cpu.h"
-#include "sysemu/cpus.h"
-#include "sysemu/kvm.h"
-#include "sysemu/runstate.h"
+#include "system/cpus.h"
+#include "system/kvm.h"
+#include "system/runstate.h"
#include "hw/ppc/spapr.h"
#include "hw/ppc/spapr_cpu_core.h"
#include "hw/ppc/spapr_xive.h"
#include "migration/vmstate.h"
#include "hw/intc/intc.h"
#include "hw/irq.h"
-#include "sysemu/kvm.h"
-#include "sysemu/reset.h"
+#include "system/kvm.h"
+#include "system/reset.h"
#include "target/ppc/cpu.h"
void icp_pic_print_info(ICPState *icp, GString *buf)
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "trace.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "hw/ppc/spapr.h"
#include "hw/ppc/spapr_cpu_core.h"
#include "hw/ppc/xics.h"
#include "qemu/module.h"
#include "qapi/error.h"
#include "target/ppc/cpu.h"
-#include "sysemu/cpus.h"
-#include "sysemu/dma.h"
-#include "sysemu/reset.h"
+#include "system/cpus.h"
+#include "system/dma.h"
+#include "system/reset.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "hw/irq.h"
#include "qemu/module.h"
#include "qapi/error.h"
#include "target/ppc/cpu.h"
-#include "sysemu/cpus.h"
-#include "sysemu/dma.h"
+#include "system/cpus.h"
+#include "system/dma.h"
#include "hw/qdev-properties.h"
#include "hw/ppc/xive.h"
#include "hw/ppc/xive2.h"
#include "hw/ipmi/ipmi.h"
#include "hw/qdev-properties.h"
#include "qom/object_interfaces.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "hw/nmi.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qemu/timer.h"
#include "hw/ipmi/ipmi.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qapi/error.h"
#include "hw/sysbus.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/isa/isa.h"
static ISABus *isabus;
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qapi/error.h"
-#include "sysemu/blockdev.h"
+#include "system/blockdev.h"
#include "chardev/char.h"
#include "hw/char/parallel.h"
#include "hw/block/fdc.h"
#include "hw/acpi/ich9_timer.h"
#include "hw/pci/pci_bus.h"
#include "hw/qdev-properties.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
+#include "system/runstate.h"
+#include "system/system.h"
#include "hw/core/cpu.h"
#include "hw/nvram/fw_cfg.h"
#include "qemu/cutils.h"
#include "hw/ide/piix.h"
#include "hw/intc/i8259.h"
#include "hw/isa/isa.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "migration/vmstate.h"
#include "hw/acpi/acpi_aml_interface.h"
#include "hw/acpi/bios-linker-loader.h"
#include "migration/vmstate.h"
#include "hw/mem/memory-device.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
/* Supported chipsets: */
#include "hw/pci-host/ls7a.h"
#include "hw/acpi/generic_event_device.h"
#include "hw/pci-host/gpex.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/tpm.h"
+#include "system/system.h"
+#include "system/tpm.h"
#include "hw/platform-bus.h"
#include "hw/acpi/aml-build.h"
#include "hw/acpi/hmat.h"
#include "hw/loader.h"
#include "elf.h"
#include "qemu/error-report.h"
-#include "sysemu/reset.h"
-#include "sysemu/qtest.h"
+#include "system/reset.h"
+#include "system/qtest.h"
struct memmap_entry *memmap_table;
unsigned memmap_entries;
#include "hw/loongarch/fw_cfg.h"
#include "hw/loongarch/virt.h"
#include "hw/nvram/fw_cfg.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
static void fw_cfg_boot_set(void *opaque, const char *boot_device,
Error **errp)
#include "qapi/error.h"
#include "hw/boards.h"
#include "hw/char/serial-mm.h"
-#include "sysemu/kvm.h"
-#include "sysemu/tcg.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/qtest.h"
-#include "sysemu/runstate.h"
-#include "sysemu/reset.h"
-#include "sysemu/rtc.h"
+#include "system/kvm.h"
+#include "system/tcg.h"
+#include "system/system.h"
+#include "system/qtest.h"
+#include "system/runstate.h"
+#include "system/reset.h"
+#include "system/rtc.h"
#include "hw/loongarch/virt.h"
#include "exec/address-spaces.h"
#include "hw/irq.h"
#include "qapi/qapi-visit-common.h"
#include "hw/acpi/generic_event_device.h"
#include "hw/mem/nvdimm.h"
-#include "sysemu/device_tree.h"
+#include "system/device_tree.h"
#include <libfdt.h>
#include "hw/core/sysbus-fdt.h"
#include "hw/platform-bus.h"
#include "hw/display/ramfb.h"
#include "hw/mem/pc-dimm.h"
-#include "sysemu/tpm.h"
-#include "sysemu/block-backend.h"
+#include "system/tpm.h"
+#include "system/block-backend.h"
#include "hw/block/flash.h"
#include "hw/virtio/virtio-iommu.h"
#include "qemu/error-report.h"
#include "hw/loader.h"
#include "elf.h"
#include "qemu/error-report.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
#define KERNEL_LOAD_ADDR 0x10000
#define AN5206_MBAR_ADDR 0x10000000
#include "hw/m68k/mcf.h"
#include "qemu/timer.h"
#include "hw/ptimer.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/sysbus.h"
/* General purpose timer module. */
#include "hw/m68k/mcf_fec.h"
#include "qemu/timer.h"
#include "hw/ptimer.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/qtest.h"
+#include "system/system.h"
+#include "system/qtest.h"
#include "net/net.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "qemu/osdep.h"
#include "exec/hwaddr.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/qtest.h"
+#include "system/system.h"
+#include "system/qtest.h"
#include "hw/irq.h"
#include "hw/m68k/next-cube.h"
#include "hw/boards.h"
#include "qemu/units.h"
#include "qemu/datadir.h"
#include "qemu/guest-random.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "cpu.h"
#include "hw/boards.h"
#include "hw/or-irq.h"
#include "net/util.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
-#include "sysemu/qtest.h"
-#include "sysemu/runstate.h"
-#include "sysemu/reset.h"
+#include "system/qtest.h"
+#include "system/runstate.h"
+#include "system/reset.h"
#include "migration/vmstate.h"
#define MACROM_ADDR 0x40800000
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qemu/guest-random.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "cpu.h"
#include "hw/boards.h"
#include "hw/qdev-properties.h"
#include "net/net.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
-#include "sysemu/qtest.h"
-#include "sysemu/runstate.h"
-#include "sysemu/reset.h"
+#include "system/qtest.h"
+#include "system/runstate.h"
+#include "system/reset.h"
#include "hw/intc/m68k_irqc.h"
#include "hw/misc/virt_ctrl.h"
#include "qemu/range.h"
#include "qemu/rcu.h"
#include "qemu/guest-random.h"
-#include "sysemu/hostmem.h"
-#include "sysemu/numa.h"
+#include "system/hostmem.h"
+#include "system/numa.h"
#include "hw/cxl/cxl.h"
#include "hw/pci/msix.h"
#include "hw/boards.h"
#include "qemu/range.h"
#include "hw/virtio/vhost.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "exec/address-spaces.h"
#include "trace.h"
#include "hw/mem/nvdimm.h"
#include "hw/qdev-properties.h"
#include "hw/mem/memory-device.h"
-#include "sysemu/hostmem.h"
+#include "system/hostmem.h"
static void nvdimm_get_label_size(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "qemu/module.h"
-#include "sysemu/hostmem.h"
-#include "sysemu/numa.h"
+#include "system/hostmem.h"
+#include "system/numa.h"
#include "trace.h"
static int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp);
#include "hw/sysbus.h"
#include "qapi/error.h"
#include "qemu/units.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
#include "hw/mem/sparse-mem.h"
#define SPARSE_MEM(obj) OBJECT_CHECK(SparseMemState, (obj), TYPE_SPARSE_MEM)
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "qemu/guest-random.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/reset.h"
+#include "system/device_tree.h"
+#include "system/reset.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "elf.h"
#include "hw/sysbus.h"
#include "net/net.h"
#include "hw/block/flash.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/boards.h"
#include "hw/char/serial-mm.h"
#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "net/net.h"
#include "hw/block/flash.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/boards.h"
#include "hw/misc/unimp.h"
#include "exec/address-spaces.h"
#include "qemu/guest-random.h"
#include "qemu/log.h"
#include "chardev/char.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/qtest.h"
-#include "sysemu/runstate.h"
-#include "sysemu/reset.h"
+#include "system/device_tree.h"
+#include "system/system.h"
+#include "system/qtest.h"
+#include "system/runstate.h"
+#include "system/reset.h"
#include <libfdt.h>
#include "qom/object.h"
#include "hw/mips/mips.h"
#include "hw/qdev-clock.h"
#include "hw/qdev-properties.h"
-#include "sysemu/kvm.h"
-#include "sysemu/reset.h"
+#include "system/kvm.h"
+#include "system/reset.h"
qemu_irq get_cps_irq(MIPSCPSState *s, int pin_number)
{
#include "hw/qdev-properties.h"
#include "elf.h"
#include "hw/isa/vt82c686.h"
-#include "sysemu/qtest.h"
-#include "sysemu/reset.h"
-#include "sysemu/sysemu.h"
+#include "system/qtest.h"
+#include "system/reset.h"
+#include "system/system.h"
#include "qemu/error-report.h"
#include "exec/tswap.h"
#include "hw/char/parallel.h"
#include "hw/isa/isa.h"
#include "hw/block/fdc.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/boards.h"
#include "net/net.h"
#include "hw/scsi/esp.h"
#include "hw/audio/pcspk.h"
#include "hw/input/i8042.h"
#include "hw/sysbus.h"
-#include "sysemu/qtest.h"
-#include "sysemu/reset.h"
+#include "system/qtest.h"
+#include "system/reset.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/help_option.h"
#include "hw/pci-host/gpex.h"
#include "hw/usb.h"
#include "net/net.h"
-#include "sysemu/kvm.h"
-#include "sysemu/qtest.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
+#include "system/kvm.h"
+#include "system/qtest.h"
+#include "system/reset.h"
+#include "system/runstate.h"
#include "qemu/error-report.h"
#define PM_CNTL_MODE 0x10
#include "qom/object.h"
#include "hw/sysbus.h" /* SysBusDevice */
#include "qemu/host-utils.h"
-#include "sysemu/qtest.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
+#include "system/qtest.h"
+#include "system/reset.h"
+#include "system/runstate.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "semihosting/semihost.h"
#include "hw/mips/cps.h"
#include "hw/qdev-clock.h"
#include "qemu/osdep.h"
#include "qemu/main-loop.h"
#include "hw/irq.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "kvm_mips.h"
static void cpu_mips_irq_request(void *opaque, int irq, int level)
#include "hw/mips/mips.h"
#include "hw/char/serial-mm.h"
#include "net/net.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "elf.h"
#include "hw/sysbus.h"
#include "hw/qdev-properties.h"
#include "qemu/error-report.h"
-#include "sysemu/qtest.h"
-#include "sysemu/reset.h"
+#include "system/qtest.h"
+#include "system/reset.h"
#include "cpu.h"
#define BIOS_SIZE (4 * MiB)
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "qemu/timer.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "qemu/bitops.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
#include "hw/misc/bcm2835_powermgt.h"
#include "migration/vmstate.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#define PASSWORD 0x5a000000
#define PASSWORD_MASK 0xff000000
#include "hw/irq.h"
#include "hw/misc/bcm2835_mbox_defs.h"
#include "hw/arm/raspberrypi-fw-defs.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "trace.h"
#include "hw/qdev-properties.h"
#include "qemu/module.h"
#include "qom/object.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#define TYPE_ISA_DEBUG_EXIT_DEVICE "isa-debug-exit"
OBJECT_DECLARE_SIMPLE_TYPE(ISADebugExitState, ISA_DEBUG_EXIT_DEVICE)
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "qom/object.h"
#ifndef DEBUG_PMU
#include "hw/misc/imx7_snvs.h"
#include "qemu/cutils.h"
#include "qemu/module.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/rtc.h"
-#include "sysemu/runstate.h"
+#include "system/system.h"
+#include "system/rtc.h"
+#include "system/runstate.h"
#include "trace.h"
#define RTC_FREQ 32768ULL
#include "qemu/bitops.h"
#include "qemu/log.h"
#include "qemu/module.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "trace.h"
#include "qapi/error.h"
#include "hw/sysbus.h"
#include "hw/qdev-properties-system.h"
#include "hw/pci/msi.h"
#include "hw/pci/msix.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "migration/blocker.h"
#include "migration/vmstate.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qom/object_interfaces.h"
#include "chardev/char-fe.h"
-#include "sysemu/hostmem.h"
+#include "system/hostmem.h"
#include "qapi/visitor.h"
#include "hw/misc/ivshmem.h"
#include "qapi/error.h"
#include "trace.h"
#include "hw/irq.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/runstate.h"
+#include "system/system.h"
+#include "system/runstate.h"
#include "migration/vmstate.h"
#include "qom/object.h"
#include "hw/misc/lasi.h"
#include "hw/misc/mac_via.h"
#include "hw/misc/mos6522.h"
#include "hw/input/adb.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "qapi/error.h"
#include "qemu/cutils.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/rtc.h"
+#include "system/block-backend.h"
+#include "system/rtc.h"
#include "trace.h"
#include "qemu/log.h"
#include "migration/vmstate.h"
#include "hw/misc/macio/cuda.h"
#include "qemu/timer.h"
-#include "sysemu/runstate.h"
-#include "sysemu/rtc.h"
+#include "system/runstate.h"
+#include "system/rtc.h"
#include "qapi/error.h"
#include "qemu/cutils.h"
#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "qemu/log.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
/* debug DBDMA */
#define DEBUG_DBDMA 0
#include "hw/irq.h"
#include "hw/misc/macio/pmu.h"
#include "qemu/timer.h"
-#include "sysemu/runstate.h"
-#include "sysemu/rtc.h"
+#include "system/runstate.h"
+#include "system/rtc.h"
#include "qapi/error.h"
#include "qemu/cutils.h"
#include "qemu/log.h"
#include "qemu/timer.h"
#include "qemu/units.h"
#include "trace.h"
-#include "sysemu/watchdog.h"
+#include "system/watchdog.h"
/*
* The reference clock hz, and the SECCNT and CNTR25M registers in this module,
#include "hw/qdev-properties.h"
#include "qemu/event_notifier.h"
#include "qemu/module.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "qom/object.h"
typedef struct PCITestDevHdr {
#include "qemu/osdep.h"
#include "qemu/module.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "hw/nvram/fw_cfg.h"
#include "hw/qdev-properties.h"
#include "qemu/osdep.h"
#include "qemu/module.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "hw/nvram/fw_cfg.h"
#include "hw/qdev-properties.h"
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/module.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "hw/nvram/fw_cfg.h"
#include "hw/qdev-properties.h"
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "hw/sysbus.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
typedef struct SECUREECState {
SysBusDevice parent_obj;
#include "hw/misc/sifive_e_aon.h"
#include "qapi/visitor.h"
#include "qapi/error.h"
-#include "sysemu/watchdog.h"
+#include "system/watchdog.h"
#include "hw/qdev-properties.h"
REG32(AON_WDT_WDOGCFG, 0x0)
#include "qapi/error.h"
#include "qemu/log.h"
#include "qemu/module.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "hw/misc/sifive_test.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
static uint64_t sifive_test_read(void *opaque, hwaddr addr, unsigned int size)
{
#include "qemu/log.h"
#include "qemu/module.h"
#include "hw/misc/sifive_u_otp.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/block-backend.h"
+#include "system/blockdev.h"
+#include "system/block-backend.h"
#define WRITTEN_BIT_ON 0x1
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "trace.h"
#include "qom/object.h"
#include "migration/vmstate.h"
#include "qemu/log.h"
#include "trace.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "hw/misc/virt_ctrl.h"
enum {
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/module.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "hw/nvram/fw_cfg.h"
#include "migration/vmstate.h"
#include "hw/misc/vmcoreinfo.h"
#include "qemu/osdep.h"
#include "qemu/timer.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "qemu/log.h"
#include "net/checksum.h"
#include "qemu/module.h"
#include "exec/cpu-common.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "hw/net/allwinner-sun8i-emac.h"
/* EMAC register offsets */
#include "qapi/error.h"
#include "qemu/log.h"
#include "qemu/module.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "net/checksum.h"
#include "net/eth.h"
#include "net/eth.h"
#include "net/net.h"
#include "net/checksum.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/dma.h"
+#include "system/system.h"
+#include "system/dma.h"
#include "qemu/iov.h"
#include "qemu/module.h"
#include "qemu/range.h"
#include "net/tap.h"
#include "qemu/module.h"
#include "qemu/range.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/hw.h"
#include "hw/net/mii.h"
#include "hw/pci/msi.h"
#include "hw/net/mii.h"
#include "hw/pci/msi.h"
#include "hw/pci/msix.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "net_tx_pkt.h"
#include "net_rx_pkt.h"
#include "net/net.h"
#include "net/eth.h"
#include "hw/nvram/eeprom93xx.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/dma.h"
-#include "sysemu/reset.h"
+#include "system/system.h"
+#include "system/dma.h"
+#include "system/reset.h"
#include "qemu/bitops.h"
#include "qemu/module.h"
#include "qapi/error.h"
#include "qemu/osdep.h"
#include "hw/irq.h"
#include "hw/net/ftgmac100.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "qapi/error.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "net/tap.h"
#include "qemu/module.h"
#include "qemu/range.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/hw.h"
#include "hw/net/mii.h"
#include "hw/pci/pci.h"
#include "hw/net/mii.h"
#include "hw/pci/msi.h"
#include "hw/pci/msix.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "net_tx_pkt.h"
#include "net_rx_pkt.h"
#include "hw/net/imx_fec.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "net/checksum.h"
#include "hw/net/lance.h"
#include "hw/qdev-properties.h"
#include "trace.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
static void parent_lance_reset(void *opaque, int irq, int level)
#include "qapi/error.h"
#include "qemu/timer.h"
#include "hw/sysbus.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "net/eth.h"
#include "hw/net/lasi_82596.h"
#include "hw/net/i82596.h"
#include "hw/irq.h"
#include "hw/net/mv88w8618_eth.h"
#include "migration/vmstate.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "net/net.h"
#define MP_ETH_SIZE 0x00001000
#include "hw/net/ne2000-isa.h"
#include "migration/vmstate.h"
#include "ne2000.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "qemu/module.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "ne2000.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
typedef struct PCINE2000State {
PCIDevice dev;
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/units.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "trace.h"
#define CRC_LENGTH 4
#include "qemu/cutils.h"
#include "qemu/log.h"
#include "qemu/units.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "trace.h"
REG32(NPCM_DMA_BUS_MODE, 0x1000)
#include "net/net.h"
#include "qemu/module.h"
#include "qemu/timer.h"
-#include "sysemu/dma.h"
-#include "sysemu/sysemu.h"
+#include "system/dma.h"
+#include "system/system.h"
#include "trace.h"
#include "pcnet.h"
#include "hw/pci/pci_device.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "qemu/module.h"
#include "qemu/timer.h"
#include "net/net.h"
#include "net/eth.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qom/object.h"
/* debug RTL8139 card */
#include "hw/ppc/spapr.h"
#include "hw/ppc/spapr_vio.h"
#include "hw/qdev-properties.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "trace.h"
#include <libfdt.h>
#include "net/eth.h"
#include "net/checksum.h"
#include "hw/net/mii.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "trace.h"
#include "qom/object.h"
#include "qemu/module.h"
#include "net/checksum.h"
#include "net/eth.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "trace.h"
#include "qom/object.h"
#include "hw/qdev-properties.h"
#include "hw/nvram/eeprom93xx.h"
#include "migration/vmstate.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "tulip.h"
#include "trace.h"
#include "net/eth.h"
#include "hw/virtio/virtio-access.h"
#include "migration/misc.h"
#include "standard-headers/linux/ethtool.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/replay.h"
+#include "system/system.h"
+#include "system/replay.h"
#include "trace.h"
#include "monitor/qdev.h"
#include "monitor/monitor.h"
#include "hw/pci/pci_device.h"
#include "net_rx_pkt.h"
#include "hw/virtio/vhost.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
#define VIRTIO_NET_VM_VERSION 11
#include "hw/qdev-properties.h"
#include "net/tap.h"
#include "net/checksum.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qemu/bswap.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/range.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/hostmem.h"
+#include "system/system.h"
+#include "system/block-backend.h"
+#include "system/hostmem.h"
#include "hw/pci/msix.h"
#include "hw/pci/pcie_sriov.h"
-#include "sysemu/spdm-socket.h"
+#include "system/spdm-socket.h"
#include "migration/vmstate.h"
#include "nvme.h"
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "nvme.h"
#include "dif.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qemu/bitops.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/block-backend.h"
+#include "system/system.h"
+#include "system/block-backend.h"
#include "nvme.h"
#include "trace.h"
#include "qemu/cutils.h"
#include "qemu/error-report.h"
#include "hw/nvram/chrp_nvram.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
static int chrp_nvram_set_var(uint8_t *nvram, int addr, const char *str,
int max_len)
#include "hw/nvram/eeprom_at24c.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qom/object.h"
/* #define DEBUG_AT24C */
#include "qemu/osdep.h"
#include "qemu/datadir.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/dma.h"
-#include "sysemu/reset.h"
+#include "system/system.h"
+#include "system/dma.h"
+#include "system/reset.h"
#include "exec/address-spaces.h"
#include "hw/boards.h"
#include "hw/nvram/fw_cfg.h"
#include "hw/nvram/mac_nvram.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "migration/vmstate.h"
#include "qemu/cutils.h"
#include "qemu/module.h"
#include "qapi/error.h"
#include <libfdt.h>
-#include "sysemu/block-backend.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/runstate.h"
+#include "system/block-backend.h"
+#include "system/device_tree.h"
+#include "system/system.h"
+#include "system/runstate.h"
#include "migration/vmstate.h"
#include "hw/nvram/chrp_nvram.h"
#include "hw/ppc/spapr.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "qapi/error.h"
-#include "sysemu/blockdev.h"
+#include "system/blockdev.h"
#include "migration/vmstate.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "qapi/error.h"
-#include "sysemu/blockdev.h"
+#include "system/blockdev.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "elf.h"
#include "hw/loader.h"
#include "hw/openrisc/boot.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/qtest.h"
-#include "sysemu/reset.h"
+#include "system/device_tree.h"
+#include "system/qtest.h"
+#include "system/reset.h"
#include "qemu/error-report.h"
#include <libfdt.h>
#include "cpu.h"
#include "migration/vmstate.h"
#include "qemu/timer.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#define TIMER_PERIOD 50 /* 50 ns period for 20 MHz timer */
#include "hw/openrisc/boot.h"
#include "hw/qdev-properties.h"
#include "exec/address-spaces.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/sysemu.h"
+#include "system/device_tree.h"
+#include "system/system.h"
#include "hw/sysbus.h"
-#include "sysemu/qtest.h"
-#include "sysemu/reset.h"
+#include "system/qtest.h"
+#include "system/reset.h"
#include "hw/core/split-irq.h"
#include <libfdt.h>
#include "hw/rtc/goldfish_rtc.h"
#include "hw/sysbus.h"
#include "hw/virtio/virtio-mmio.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/qtest.h"
-#include "sysemu/reset.h"
+#include "system/device_tree.h"
+#include "system/system.h"
+#include "system/qtest.h"
+#include "system/reset.h"
#include <libfdt.h>
#include "qemu/range.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
-#include "sysemu/numa.h"
+#include "system/numa.h"
#include "hw/boards.h"
#include "qom/object.h"
#include "hw/pci-host/bonito.h"
#include "hw/pci/pci_host.h"
#include "migration/vmstate.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "hw/misc/unimp.h"
#include "hw/registerfields.h"
#include "qom/object.h"
#include "hw/ppc/pnv.h"
#include "hw/qdev-properties.h"
#include "qom/object.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
/*
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "qom/object.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#define phb3_error(phb, fmt, ...) \
qemu_log_mask(LOG_GUEST_ERROR, "phb3[%d:%d]: " fmt "\n", \
#include "hw/pci/msi.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
static uint64_t phb3_msi_ive_addr(PnvPHB3 *phb, int srcno)
{
#include "hw/ppc/pnv.h"
#include "hw/ppc/pnv_chip.h"
#include "hw/qdev-properties.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include <libfdt.h>
#include "hw/pci-host/ppc4xx.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "hw/pci/pci_device.h"
#include "hw/pci/pci_host.h"
#include "trace.h"
#include "qapi/error.h"
#include "qemu/log.h"
#include "qemu/module.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "trace.h"
/*
#include "hw/xen/xen.h"
#include "qemu/range.h"
#include "qapi/error.h"
-#include "sysemu/xen.h"
+#include "system/xen.h"
#include "hw/i386/kvm/xen_evtchn.h"
#include "hw/pci/msix.h"
#include "hw/pci/pci.h"
#include "hw/xen/xen.h"
-#include "sysemu/xen.h"
+#include "system/xen.h"
#include "migration/qemu-file-types.h"
#include "migration/vmstate.h"
#include "qemu/range.h"
#include "migration/qemu-file-types.h"
#include "migration/vmstate.h"
#include "net/net.h"
-#include "sysemu/numa.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
+#include "system/numa.h"
+#include "system/runstate.h"
+#include "system/system.h"
#include "hw/loader.h"
#include "qemu/error-report.h"
#include "qemu/range.h"
#include "hw/ide/pci.h"
#include "hw/i2c/smbus_eeprom.h"
#include "hw/ppc/ppc.h"
-#include "sysemu/qtest.h"
-#include "sysemu/reset.h"
+#include "system/qtest.h"
+#include "system/reset.h"
#include "kvm_ppc.h"
#define BUS_FREQ_HZ 100000000
#include "hw/block/flash.h"
#include "hw/char/serial-mm.h"
#include "hw/pci/pci.h"
-#include "sysemu/block-backend-io.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/kvm.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
+#include "system/block-backend-io.h"
+#include "system/system.h"
+#include "system/kvm.h"
+#include "system/reset.h"
+#include "system/runstate.h"
#include "kvm_ppc.h"
-#include "sysemu/device_tree.h"
+#include "system/device_tree.h"
#include "hw/ppc/openpic.h"
#include "hw/ppc/openpic_kvm.h"
#include "hw/ppc/ppc.h"
#include "qemu/units.h"
#include "e500.h"
#include "hw/net/fsl_etsec/etsec.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/kvm.h"
+#include "system/device_tree.h"
+#include "system/kvm.h"
#include "hw/sysbus.h"
#include "hw/pci/pci.h"
#include "hw/ppc/openpic.h"
#include "hw/ppc/mac_dbdma.h"
#include "hw/pci/pci.h"
#include "net/net.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/nvram/fw_cfg.h"
#include "hw/char/escc.h"
#include "hw/misc/macio/macio.h"
#include "hw/fw-path-provider.h"
#include "elf.h"
#include "qemu/error-report.h"
-#include "sysemu/kvm.h"
-#include "sysemu/reset.h"
+#include "system/kvm.h"
+#include "system/reset.h"
#include "kvm_ppc.h"
#include "hw/usb.h"
#include "hw/sysbus.h"
#include "hw/qdev-properties.h"
#include "hw/boards.h"
#include "hw/input/adb.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "net/net.h"
#include "hw/isa/isa.h"
#include "hw/pci/pci.h"
#include "hw/fw-path-provider.h"
#include "elf.h"
#include "qemu/error-report.h"
-#include "sysemu/kvm.h"
-#include "sysemu/reset.h"
+#include "system/kvm.h"
+#include "system/reset.h"
#include "kvm_ppc.h"
#define MAX_IDE_BUS 2
#include "qemu/osdep.h"
#include "qemu/log.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "cpu.h"
#include "hw/sysbus.h"
#include "qom/object.h"
#include "qemu/osdep.h"
#include "e500.h"
-#include "sysemu/device_tree.h"
+#include "system/device_tree.h"
#include "hw/ppc/openpic.h"
#include "qemu/error-report.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "qom/object_interfaces.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "migration/blocker.h"
#include "exec/confidential-guest-support.h"
#include "hw/ide/pci.h"
#include "hw/i2c/smbus_eeprom.h"
#include "hw/qdev-properties.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
-#include "sysemu/qtest.h"
+#include "system/reset.h"
+#include "system/runstate.h"
+#include "system/qtest.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "hw/fw-path-provider.h"
#include "elf.h"
#include "qemu/log.h"
#include "qemu/error-report.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "kvm_ppc.h"
#include "exec/address-spaces.h"
#include "qom/qom-qobject.h"
#include "qapi/qmp/qdict.h"
#include "trace.h"
#include "qemu/datadir.h"
-#include "sysemu/device_tree.h"
+#include "system/device_tree.h"
#include "hw/ppc/vof.h"
#include <libfdt.h>
#include "qemu/units.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
-#include "sysemu/qtest.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/numa.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
-#include "sysemu/cpus.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/hw_accel.h"
+#include "system/qtest.h"
+#include "system/system.h"
+#include "system/numa.h"
+#include "system/reset.h"
+#include "system/runstate.h"
+#include "system/cpus.h"
+#include "system/device_tree.h"
+#include "system/hw_accel.h"
#include "target/ppc/cpu.h"
#include "hw/ppc/fdt.h"
#include "hw/ppc/ppc.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "target/ppc/cpu.h"
#include "qapi/error.h"
#include "qemu/log.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "qapi/error.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qapi/error.h"
#include "exec/hwaddr.h"
#include "exec/memory.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
#include "hw/qdev-core.h"
#include "hw/qdev-properties.h"
#include "hw/ppc/pnv.h"
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "qemu/log.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/units.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
+#include "system/block-backend.h"
+#include "system/blockdev.h"
#include "hw/loader.h"
#include "hw/ppc/pnv_pnor.h"
#include "hw/qdev-properties.h"
#include "target/ppc/cpu.h"
#include "qemu/log.h"
#include "qemu/module.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "qapi/error.h"
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/module.h"
-#include "sysemu/hw_accel.h"
+#include "system/hw_accel.h"
#include "target/ppc/cpu.h"
#include "hw/sysbus.h"
#include "hw/ppc/ppc.h"
#include "hw/ppc/ppc_e500.h"
#include "qemu/timer.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "qemu/error-report.h"
-#include "sysemu/kvm.h"
-#include "sysemu/replay.h"
-#include "sysemu/runstate.h"
+#include "system/kvm.h"
+#include "system/replay.h"
+#include "system/runstate.h"
#include "kvm_ppc.h"
#include "migration/vmstate.h"
#include "trace.h"
#include "ppc405.h"
#include "hw/rtc/m48t59.h"
#include "hw/block/flash.h"
-#include "sysemu/qtest.h"
-#include "sysemu/reset.h"
-#include "sysemu/block-backend.h"
+#include "system/qtest.h"
+#include "system/reset.h"
+#include "system/block-backend.h"
#include "hw/boards.h"
#include "qemu/error-report.h"
#include "hw/loader.h"
#include "ppc405.h"
#include "hw/char/serial-mm.h"
#include "qemu/timer.h"
-#include "sysemu/reset.h"
-#include "sysemu/sysemu.h"
+#include "system/reset.h"
+#include "system/system.h"
#include "exec/address-spaces.h"
#include "hw/intc/ppc-uic.h"
#include "trace.h"
#include "net/net.h"
#include "hw/pci/pci.h"
#include "hw/boards.h"
-#include "sysemu/kvm.h"
-#include "sysemu/device_tree.h"
+#include "system/kvm.h"
+#include "system/device_tree.h"
#include "hw/loader.h"
#include "elf.h"
#include "hw/char/serial-mm.h"
#include "hw/ppc/ppc.h"
#include "hw/pci-host/ppc4xx.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/reset.h"
+#include "system/system.h"
+#include "system/reset.h"
#include "hw/sysbus.h"
#include "hw/intc/ppc-uic.h"
#include "hw/qdev-properties.h"
#include "hw/pci-host/ppc4xx.h"
#include "hw/qdev-properties.h"
#include "hw/pci/pci.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "cpu.h"
#include "ppc440.h"
#include "cpu.h"
#include "hw/ppc/ppc.h"
#include "qemu/timer.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
+#include "system/reset.h"
+#include "system/runstate.h"
#include "hw/loader.h"
#include "kvm_ppc.h"
#include "qemu/units.h"
#include "hw/hw.h"
#include "hw/sysbus.h"
-#include "sysemu/hw_accel.h"
+#include "system/hw_accel.h"
#include "hw/ppc/ppc.h"
#include "e500.h"
#include "qom/object.h"
#include "hw/rtc/mc146818rtc.h"
#include "hw/isa/pc87312.h"
#include "hw/qdev-properties.h"
-#include "sysemu/kvm.h"
-#include "sysemu/reset.h"
+#include "system/kvm.h"
+#include "system/reset.h"
#include "trace.h"
#include "elf.h"
#include "qemu/units.h"
#include "qom/object.h"
#include "qemu/error-report.h" /* for error_report() */
#include "qemu/module.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "cpu.h"
#include "trace.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "hw/boards.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "kvm_ppc.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/block-backend.h"
+#include "system/device_tree.h"
+#include "system/block-backend.h"
#include "exec/page-protection.h"
#include "hw/loader.h"
#include "elf.h"
#include "ppc440.h"
#include "hw/pci-host/ppc4xx.h"
#include "hw/block/flash.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/reset.h"
+#include "system/system.h"
+#include "system/reset.h"
#include "hw/sysbus.h"
#include "hw/char/serial-mm.h"
#include "hw/i2c/ppc4xx_i2c.h"
#include "qapi/qapi-events-machine.h"
#include "qapi/qapi-events-qdev.h"
#include "qapi/visitor.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/hostmem.h"
-#include "sysemu/numa.h"
-#include "sysemu/tcg.h"
-#include "sysemu/qtest.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
+#include "system/system.h"
+#include "system/hostmem.h"
+#include "system/numa.h"
+#include "system/tcg.h"
+#include "system/qtest.h"
+#include "system/reset.h"
+#include "system/runstate.h"
#include "qemu/log.h"
#include "hw/fw-path-provider.h"
#include "elf.h"
#include "net/net.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/cpus.h"
-#include "sysemu/hw_accel.h"
+#include "system/device_tree.h"
+#include "system/cpus.h"
+#include "system/hw_accel.h"
#include "kvm_ppc.h"
#include "migration/misc.h"
#include "migration/qemu-file-types.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
-#include "sysemu/hw_accel.h"
+#include "system/hw_accel.h"
#include "exec/ram_addr.h"
#include "target/ppc/cpu.h"
#include "target/ppc/mmu-hash64.h"
#include "cpu-models.h"
#include "kvm_ppc.h"
#include "migration/vmstate.h"
-#include "sysemu/tcg.h"
+#include "system/tcg.h"
#include "hw/ppc/spapr.h"
#include "target/ppc/cpu.h"
#include "hw/ppc/spapr.h"
#include "qapi/error.h"
-#include "sysemu/cpus.h"
-#include "sysemu/kvm.h"
+#include "system/cpus.h"
+#include "system/kvm.h"
#include "target/ppc/kvm_ppc.h"
#include "hw/ppc/ppc.h"
#include "target/ppc/mmu-hash64.h"
#include "target/ppc/power8-pmu.h"
-#include "sysemu/numa.h"
-#include "sysemu/reset.h"
-#include "sysemu/hw_accel.h"
+#include "system/numa.h"
+#include "system/reset.h"
+#include "system/hw_accel.h"
#include "qemu/error-report.h"
static void spapr_reset_vcpu(PowerPCCPU *cpu)
#include "hw/ppc/spapr.h" /* for RTAS return codes */
#include "hw/pci-host/spapr.h" /* spapr_phb_remove_pci_device_cb callback */
#include "hw/ppc/spapr_nvdimm.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/reset.h"
+#include "system/device_tree.h"
+#include "system/reset.h"
#include "trace.h"
#define DRC_CONTAINER_PATH "dr-connector"
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/runstate.h"
+#include "system/device_tree.h"
+#include "system/runstate.h"
#include "hw/ppc/fdt.h"
#include "hw/ppc/spapr.h"
#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/runstate.h"
-#include "sysemu/tcg.h"
+#include "system/hw_accel.h"
+#include "system/runstate.h"
+#include "system/tcg.h"
#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "qemu/module.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "kvm_ppc.h"
#include "migration/vmstate.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "trace.h"
#include "hw/ppc/spapr.h"
#include "hw/ppc/xics_spapr.h"
#include "hw/qdev-properties.h"
#include "cpu-models.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "trace.h"
#include "hw/pci/pci_ids.h"
#include "hw/ppc/spapr_drc.h"
#include "hw/qdev-properties.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/kvm.h"
-#include "sysemu/hostmem.h"
-#include "sysemu/numa.h"
+#include "system/device_tree.h"
+#include "system/kvm.h"
+#include "system/hostmem.h"
+#include "system/numa.h"
#include "hw/ppc/spapr_numa.h"
#include "qemu/log.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/rng.h"
+#include "system/device_tree.h"
+#include "system/rng.h"
#include "hw/ppc/spapr.h"
#include "hw/qdev-properties.h"
#include "kvm_ppc.h"
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/error-report.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/cpus.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/runstate.h"
-#include "sysemu/qtest.h"
+#include "system/system.h"
+#include "system/device_tree.h"
+#include "system/cpus.h"
+#include "system/hw_accel.h"
+#include "system/runstate.h"
+#include "system/qtest.h"
#include "kvm_ppc.h"
#include "hw/ppc/spapr.h"
#include "qemu/osdep.h"
#include "qemu/timer.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/rtc.h"
+#include "system/system.h"
+#include "system/rtc.h"
#include "hw/ppc/spapr.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "hw/ppc/spapr.h"
#include "hw/qdev-properties.h"
#include "trace.h"
#include "hw/loader.h"
#include "elf.h"
#include "hw/sysbus.h"
-#include "sysemu/kvm.h"
-#include "sysemu/device_tree.h"
+#include "system/kvm.h"
+#include "system/device_tree.h"
#include "kvm_ppc.h"
#include "migration/vmstate.h"
#include "hw/ppc/spapr_cpu_core.h"
#include "hw/ppc/fdt.h"
#include "hw/ppc/vof.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qom/qom-qobject.h"
#include "trace.h"
#include "hw/sysbus.h"
#include "hw/char/serial-mm.h"
#include "hw/block/flash.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/reset.h"
+#include "system/system.h"
+#include "system/reset.h"
#include "hw/boards.h"
-#include "sysemu/device_tree.h"
+#include "system/device_tree.h"
#include "hw/loader.h"
#include "elf.h"
#include "qapi/error.h"
#include "exec/address-spaces.h"
#include "hw/ppc/vof.h"
#include "hw/ppc/fdt.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "qom/qom-qobject.h"
#include "trace.h"
#include "io/channel.h"
#include "hw/remote/mpqemu-link.h"
#include "qapi/error.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "hw/pci/pci.h"
#include "exec/memattrs.h"
#include "hw/remote/memory.h"
#include "hw/remote/iohub.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
static void process_config_write(QIOChannel *ioc, PCIDevice *dev,
MPQemuMsg *msg, Error **errp);
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "io/channel.h"
-#include "sysemu/iothread.h"
+#include "system/iothread.h"
#include "trace.h"
/*
#include "hw/remote/proxy-memory-listener.h"
#include "qom/object.h"
#include "qemu/event_notifier.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
static void probe_pci_info(PCIDevice *dev, Error **errp);
static void proxy_device_reset(DeviceState *dev);
#include "hw/remote/machine.h"
#include "io/channel-util.h"
#include "qapi/error.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/pci/pci.h"
#include "qemu/sockets.h"
#include "monitor/monitor.h"
#include "qom/object_interfaces.h"
#include "qemu/error-report.h"
#include "trace.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "hw/boards.h"
#include "hw/remote/machine.h"
#include "qapi/error.h"
#include "qemu/notify.h"
#include "qemu/thread.h"
#include "qemu/main-loop.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "libvfio-user.h"
#include "hw/qdev-core.h"
#include "hw/pci/pci.h"
#include "hw/riscv/boot.h"
#include "hw/riscv/boot_opensbi.h"
#include "elf.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/qtest.h"
-#include "sysemu/kvm.h"
-#include "sysemu/reset.h"
+#include "system/device_tree.h"
+#include "system/qtest.h"
+#include "system/kvm.h"
+#include "system/reset.h"
#include <libfdt.h>
#include "hw/riscv/microchip_pfsoc.h"
#include "hw/intc/riscv_aclint.h"
#include "hw/intc/sifive_plic.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/sysemu.h"
+#include "system/device_tree.h"
+#include "system/system.h"
/*
* The BIOS image used by this machine is called Hart Software Services (HSS).
#include "hw/boards.h"
#include "hw/qdev-properties.h"
#include "hw/riscv/numa.h"
-#include "sysemu/device_tree.h"
+#include "system/device_tree.h"
static bool numa_enabled(const MachineState *ms)
{
#include "hw/misc/unimp.h"
#include "hw/riscv/boot.h"
#include "qemu/units.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
/*
* This version of the OpenTitan machine currently supports
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/module.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "hw/sysbus.h"
#include "target/riscv/cpu.h"
#include "hw/qdev-properties.h"
#include "qemu/error-report.h"
#include "hw/intc/sifive_plic.h"
#include "hw/intc/riscv_aclint.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/qdev-properties.h"
#include "exec/address-spaces.h"
#include "hw/riscv/boot.h"
#include "hw/misc/sifive_e_prci.h"
#include "hw/misc/sifive_e_aon.h"
#include "chardev/char.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
static const MemMapEntry sifive_e_memmap[] = {
[SIFIVE_E_DEV_DEBUG] = { 0x0, 0x1000 },
#include "hw/intc/sifive_plic.h"
#include "chardev/char.h"
#include "net/eth.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
+#include "system/device_tree.h"
+#include "system/runstate.h"
+#include "system/system.h"
#include <libfdt.h>
#include "hw/char/riscv_htif.h"
#include "hw/intc/riscv_aclint.h"
#include "chardev/char.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/sysemu.h"
+#include "system/device_tree.h"
+#include "system/system.h"
#include <libfdt.h>
#include "migration/vmstate.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#define ACPI_BUILD_TABLE_SIZE 0x20000
#define ACPI_BUILD_INTC_ID(socket, index) ((socket << 24) | (index))
#include "hw/misc/sifive_test.h"
#include "hw/platform-bus.h"
#include "chardev/char.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/tcg.h"
-#include "sysemu/kvm.h"
-#include "sysemu/tpm.h"
-#include "sysemu/qtest.h"
+#include "system/device_tree.h"
+#include "system/system.h"
+#include "system/tcg.h"
+#include "system/kvm.h"
+#include "system/tpm.h"
+#include "system/qtest.h"
#include "hw/pci/pci.h"
#include "hw/pci-host/gpex.h"
#include "hw/display/ramfb.h"
#include "qemu/module.h"
#include "hw/qdev-properties.h"
#include "hw/rtc/allwinner-rtc.h"
-#include "sysemu/rtc.h"
+#include "system/rtc.h"
#include "trace.h"
/* RTC registers */
#include "migration/vmstate.h"
#include "qemu/log.h"
#include "qemu/timer.h"
-#include "sysemu/rtc.h"
+#include "system/rtc.h"
#include "trace.h"
#include "migration/vmstate.h"
#include "qemu/bcd.h"
#include "qom/object.h"
-#include "sysemu/rtc.h"
+#include "system/rtc.h"
#include "trace.h"
/* Size of NVRAM including both the user-accessible area and the
#include "hw/arm/exynos4210.h"
#include "qom/object.h"
-#include "sysemu/rtc.h"
+#include "system/rtc.h"
#define DEBUG_RTC 0
#include "hw/sysbus.h"
#include "qemu/bitops.h"
#include "qemu/timer.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/rtc.h"
+#include "system/system.h"
+#include "system/rtc.h"
#include "qemu/cutils.h"
#include "qemu/log.h"
#include "hw/irq.h"
#include "hw/register.h"
#include "qemu/timer.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qemu/cutils.h"
#include "qemu/log.h"
#include "migration/vmstate.h"
#include "hw/misc/unimp.h"
-#include "sysemu/rtc.h"
+#include "system/rtc.h"
#include "hw/registerfields.h"
#define SYS_TOYTRIM 0x20
#include "qemu/bcd.h"
#include "hw/i2c/i2c.h"
#include "qom/object.h"
-#include "sysemu/rtc.h"
+#include "system/rtc.h"
#define TYPE_M41T80 "m41t80"
OBJECT_DECLARE_SIMPLE_TYPE(M41t80State, M41T80)
#include "hw/qdev-properties.h"
#include "hw/rtc/m48t59.h"
#include "qemu/timer.h"
-#include "sysemu/runstate.h"
-#include "sysemu/rtc.h"
-#include "sysemu/sysemu.h"
+#include "system/runstate.h"
+#include "system/rtc.h"
+#include "system/system.h"
#include "hw/sysbus.h"
#include "qapi/error.h"
#include "qemu/bcd.h"
#include "qemu/module.h"
#include "trace.h"
-#include "sysemu/watchdog.h"
+#include "system/watchdog.h"
#include "m48t59-internal.h"
#include "migration/vmstate.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "qemu/timer.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/replay.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
-#include "sysemu/rtc.h"
+#include "system/system.h"
+#include "system/replay.h"
+#include "system/reset.h"
+#include "system/runstate.h"
+#include "system/rtc.h"
#include "hw/rtc/mc146818rtc.h"
#include "hw/rtc/mc146818rtc_regs.h"
#include "migration/vmstate.h"
#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "qemu/timer.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/rtc.h"
+#include "system/system.h"
+#include "system/rtc.h"
#include "qemu/cutils.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/module.h"
#include "hw/irq.h"
#include "qemu/cutils.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/rtc.h"
+#include "system/system.h"
+#include "system/rtc.h"
#include "trace.h"
#include "hw/rtc/xlnx-zynqmp-rtc.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
#include "hw/loader.h"
#include "hw/rx/rx62n.h"
-#include "sysemu/qtest.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/reset.h"
+#include "system/qtest.h"
+#include "system/device_tree.h"
+#include "system/reset.h"
#include "hw/boards.h"
#include "qom/object.h"
#include "hw/loader.h"
#include "hw/sysbus.h"
#include "hw/qdev-properties.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qapi/qmp/qlist.h"
#include "qom/object.h"
#include "qemu/osdep.h"
#include "qemu/datadir.h"
#include "qapi/error.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
-#include "sysemu/tcg.h"
+#include "system/reset.h"
+#include "system/runstate.h"
+#include "system/tcg.h"
#include "elf.h"
#include "hw/loader.h"
#include "hw/qdev-properties.h"
#include "hw/s390x/css.h"
#include "hw/s390x/css-bridge.h"
#include "hw/s390x/s390-ccw.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
IOInstEnding s390_ccw_cmd_request(SubchDev *sch)
{
#include "hw/pci/msi.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
+#include "system/reset.h"
+#include "system/runstate.h"
#include "trace.h"
#include "exec/memop.h"
#include "exec/memory.h"
#include "qemu/error-report.h"
-#include "sysemu/hw_accel.h"
+#include "system/hw_accel.h"
#include "hw/pci/pci_device.h"
#include "hw/s390x/s390-pci-inst.h"
#include "hw/s390x/s390-pci-bus.h"
#include "qemu/osdep.h"
#include "hw/s390x/storage-keys.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qapi/qapi-commands-misc-target.h"
#include "qapi/qmp/qdict.h"
#include "qemu/error-report.h"
-#include "sysemu/memory_mapping.h"
+#include "system/memory_mapping.h"
#include "exec/address-spaces.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "migration/qemu-file-types.h"
#include "migration/register.h"
#include "trace.h"
#include "migration/qemu-file.h"
#include "hw/s390x/storage-attributes.h"
#include "qemu/error-report.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "exec/ram_addr.h"
#include "kvm/kvm_s390x.h"
#include "qapi/error.h"
#include "qemu/qemu-print.h"
#include "qemu/units.h"
#include "hw/s390x/s390-pci-bus.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "hw/s390x/storage-keys.h"
#include "hw/s390x/storage-attributes.h"
#include "hw/s390x/event-facility.h"
#include "hw/nmi.h"
#include "hw/qdev-properties.h"
#include "hw/s390x/tod.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/cpus.h"
+#include "system/system.h"
+#include "system/cpus.h"
#include "target/s390x/kvm/pv.h"
#include "migration/blocker.h"
#include "qapi/visitor.h"
#include "hw/s390x/sclp.h"
#include "qemu/module.h"
#include "hw/s390x/event-facility.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
typedef struct ConfigMgtData {
EventBufferHeader ebh;
#include "hw/s390x/sclp.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "hw/s390x/event-facility.h"
typedef struct SignalQuiesce {
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/module.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "hw/s390x/tod.h"
#include "target/s390x/kvm/pv.h"
#include "kvm/kvm_s390x.h"
#include "qemu/module.h"
#include "cpu.h"
#include "tcg/tcg_s390x.h"
-#include "sysemu/rtc.h"
+#include "system/rtc.h"
static void qemu_s390_tod_get(const S390TODState *td, S390TOD *tod,
Error **errp)
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
-#include "sysemu/kvm.h"
-#include "sysemu/tcg.h"
-#include "sysemu/qtest.h"
+#include "system/kvm.h"
+#include "system/tcg.h"
+#include "system/qtest.h"
#include "migration/qemu-file-types.h"
#include "migration/register.h"
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "exec/address-spaces.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "net/net.h"
#include "hw/virtio/virtio.h"
#include "migration/qemu-file-types.h"
#include "trace.h"
#include "hw/s390x/css-bridge.h"
#include "hw/s390x/s390-virtio-ccw.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#define NR_CLASSIC_INDICATOR_BITS 64
#include "hw/pci/pci_device.h"
#include "hw/scsi/scsi.h"
#include "migration/vmstate.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "trace.h"
#include "qemu/osdep.h"
#include "hw/pci/pci.h"
#include "hw/qdev-properties.h"
-#include "sysemu/dma.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/rtc.h"
+#include "system/dma.h"
+#include "system/block-backend.h"
+#include "system/rtc.h"
#include "hw/pci/msi.h"
#include "hw/pci/msix.h"
#include "qemu/iov.h"
#include "qemu/osdep.h"
#include "hw/pci/pci.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "hw/pci/msi.h"
#include "qemu/iov.h"
#include "hw/scsi/scsi.h"
#include "qemu/osdep.h"
#include "hw/pci/pci.h"
#include "hw/qdev-properties.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "hw/pci/msi.h"
#include "qemu/iov.h"
#include "qemu/main-loop.h"
#include "migration/qemu-file-types.h"
#include "migration/vmstate.h"
#include "scsi/constants.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/runstate.h"
+#include "system/block-backend.h"
+#include "system/blockdev.h"
+#include "system/system.h"
+#include "system/runstate.h"
#include "trace.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "qemu/cutils.h"
static char *scsibus_get_dev_path(DeviceState *dev);
#include "migration/vmstate.h"
#include "hw/scsi/emulation.h"
#include "scsi/constants.h"
-#include "sysemu/arch_init.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
+#include "system/arch_init.h"
+#include "system/block-backend.h"
+#include "system/blockdev.h"
#include "hw/block/block.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
-#include "sysemu/dma.h"
-#include "sysemu/sysemu.h"
+#include "system/dma.h"
+#include "system/system.h"
#include "qemu/cutils.h"
#include "trace.h"
#include "qom/object.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "hw/scsi/emulation.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "trace.h"
#ifdef __linux__
#include "hw/fw-path-provider.h"
#include "hw/qdev-properties.h"
#include "qemu/cutils.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
/* Features supported by host kernel. */
static const int kernel_feature_bits[] = {
#include "hw/virtio/vhost-user-scsi.h"
#include "hw/virtio/virtio.h"
#include "chardev/char-fe.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
/* Features supported by the host application */
static const int user_feature_bits[] = {
#include "qapi/error.h"
#include "hw/virtio/virtio-scsi.h"
#include "qemu/error-report.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "hw/scsi/scsi.h"
#include "scsi/constants.h"
#include "hw/virtio/virtio-bus.h"
#include "qemu/error-report.h"
#include "qemu/iov.h"
#include "qemu/module.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/dma.h"
+#include "system/block-backend.h"
+#include "system/dma.h"
#include "hw/qdev-properties.h"
#include "hw/scsi/scsi.h"
#include "scsi/constants.h"
#include "qemu/module.h"
#include "qemu/units.h"
#include "qapi/error.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/dma.h"
+#include "system/blockdev.h"
+#include "system/dma.h"
#include "hw/qdev-properties.h"
#include "hw/irq.h"
#include "hw/sd/allwinner-sdhost.h"
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/module.h"
-#include "sysemu/blockdev.h"
+#include "system/blockdev.h"
#include "hw/irq.h"
#include "hw/sd/bcm2835_sdhost.h"
#include "migration/vmstate.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/blockdev.h"
+#include "system/blockdev.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "hw/irq.h"
#include "qemu/cutils.h"
#include "hw/irq.h"
#include "hw/registerfields.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "hw/sd/sd.h"
#include "hw/sd/sdcard_legacy.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "qemu/timer.h"
#include "qemu/bitops.h"
#include "hw/sd/sdhci.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/blockdev.h"
+#include "system/blockdev.h"
#include "hw/ssi/ssi.h"
#include "migration/vmstate.h"
#include "hw/qdev-properties.h"
#include "cpu.h"
#include "hw/sysbus.h"
#include "hw/sh4/sh.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
+#include "system/reset.h"
+#include "system/runstate.h"
+#include "system/system.h"
#include "hw/boards.h"
#include "hw/pci/pci.h"
#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "hw/irq.h"
#include "hw/sh4/sh.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "sh7750_regs.h"
#include "qemu/config-file.h"
#include "qemu/module.h"
#include "qemu/option.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qemu/uuid.h"
#include "hw/firmware/smbios.h"
#include "hw/loader.h"
#include "qemu/osdep.h"
#include "qemu/bswap.h"
#include "hw/firmware/smbios.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qapi/error.h"
struct smbios_header {
#include "qemu/timer.h"
#include "hw/ptimer.h"
#include "hw/qdev-properties.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/qtest.h"
-#include "sysemu/reset.h"
+#include "system/system.h"
+#include "system/qtest.h"
+#include "system/reset.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "elf.h"
#include "migration/vmstate.h"
#include "hw/sparc/sparc32_dma.h"
#include "hw/block/fdc.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
+#include "system/reset.h"
+#include "system/runstate.h"
+#include "system/system.h"
#include "net/net.h"
#include "hw/boards.h"
#include "hw/scsi/esp.h"
#include "hw/loader.h"
#include "hw/sparc/sparc64.h"
#include "hw/rtc/sun4v-rtc.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qemu/error-report.h"
-#include "sysemu/qtest.h"
-#include "sysemu/sysemu.h"
+#include "system/qtest.h"
+#include "system/system.h"
#include "qapi/error.h"
typedef struct NiagaraBoardState {
#include "hw/boards.h"
#include "hw/sparc/sparc64.h"
#include "qemu/timer.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "trace.h"
#include "hw/block/fdc.h"
#include "net/net.h"
#include "qemu/timer.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
+#include "system/runstate.h"
+#include "system/system.h"
#include "hw/boards.h"
#include "hw/nvram/sun_nvram.h"
#include "hw/nvram/chrp_nvram.h"
#include "hw/ssi/xilinx_spips.h"
#include "qapi/error.h"
#include "hw/register.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "migration/blocker.h"
#include "migration/vmstate.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "hw/core/cpu.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
#ifndef A9_GTIMER_ERR_DEBUG
#define A9_GTIMER_ERR_DEBUG 0
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "qemu/timer.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qom/object.h"
-#include "sysemu/watchdog.h"
+#include "system/watchdog.h"
#define OSMR0 0x00
#define OSMR1 0x04
#include "hw/pci/pci_ids.h"
#include "hw/acpi/tpm.h"
#include "migration/vmstate.h"
-#include "sysemu/tpm_backend.h"
-#include "sysemu/tpm_util.h"
-#include "sysemu/reset.h"
-#include "sysemu/xen.h"
+#include "system/tpm_backend.h"
+#include "system/tpm_util.h"
+#include "system/reset.h"
+#include "system/xen.h"
#include "tpm_prop.h"
#include "tpm_ppi.h"
#include "trace.h"
#include "qemu/osdep.h"
#include "qemu/memalign.h"
#include "qapi/error.h"
-#include "sysemu/memory_mapping.h"
+#include "system/memory_mapping.h"
#include "migration/vmstate.h"
#include "hw/qdev-core.h"
#include "hw/acpi/tpm.h"
#ifndef HW_TPM_PROP_H
#define HW_TPM_PROP_H
-#include "sysemu/tpm_backend.h"
+#include "system/tpm_backend.h"
#include "hw/qdev-properties.h"
extern const PropertyInfo qdev_prop_tpm;
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
-#include "sysemu/tpm_backend.h"
-#include "sysemu/tpm_util.h"
+#include "system/tpm_backend.h"
+#include "system/tpm_util.h"
#include "tpm_prop.h"
#include "hw/ppc/spapr.h"
#ifndef TPM_TPM_TIS_H
#define TPM_TPM_TIS_H
-#include "sysemu/tpm_backend.h"
+#include "system/tpm_backend.h"
#include "tpm_ppi.h"
#define TPM_TIS_NUM_LOCALITIES 5 /* per spec */
#include "hw/pci/pci_ids.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
-#include "sysemu/tpm_backend.h"
-#include "sysemu/tpm_util.h"
+#include "system/tpm_backend.h"
+#include "system/tpm_util.h"
#include "tpm_ppi.h"
#include "trace.h"
#include "qemu/memalign.h"
#include "hw/scsi/scsi.h"
#include "scsi/constants.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qemu/cutils.h"
#include "trace.h"
#include "ufs.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-machine.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "monitor/monitor.h"
#include "hw/usb.h"
#include "qapi/type-helpers.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "migration/vmstate.h"
#include "monitor/monitor.h"
#include "trace.h"
#include "qemu/error-report.h"
#include "qemu/queue.h"
#include "qemu/config-file.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qemu/iov.h"
#include "qemu/module.h"
#include "qemu/cutils.h"
#include "hw/usb.h"
#include "hw/usb/desc.h"
#include "hw/usb/msd.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/block-backend.h"
+#include "system/system.h"
+#include "system/block-backend.h"
static const struct SCSIBusInfo usb_msd_scsi_info_storage = {
.tcq = false,
#include "hw/irq.h"
#include "hw/sysbus.h"
#include "hw/usb.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "qom/object.h"
#define DWC2_MMIO_SIZE 0x11000
#include "trace.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#define FRAME_TIMER_FREQ 1000
#define FRAME_TIMER_NS (NANOSECONDS_PER_SECOND / FRAME_TIMER_FREQ)
#include "qemu/timer.h"
#include "hw/usb.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "hw/pci/pci_device.h"
#include "hw/sysbus.h"
#define HCD_OHCI_H
#include "hw/sysbus.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "hw/usb.h"
#include "qom/object.h"
#include "qapi/error.h"
#include "qemu/timer.h"
#include "qemu/iov.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "trace.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "hw/usb.h"
#include "hw/usb/xhci.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
OBJECT_DECLARE_SIMPLE_TYPE(XHCIState, XHCI)
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
+#include "system/runstate.h"
+#include "system/system.h"
#include "trace.h"
#include "hw/qdev-properties.h"
*/
#include "qemu/osdep.h"
#include "hw/usb.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
int usb_packet_map(USBPacket *p, QEMUSGList *sgl)
{
#include "qemu/units.h"
#include "qapi/error.h"
#include "qemu/timer.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
+#include "system/runstate.h"
+#include "system/system.h"
#include "qapi/qmp/qerror.h"
#include "qemu/error-report.h"
#include "qemu/iov.h"
#include <sys/ioctl.h>
#include "qapi/error.h"
#include "hw/vfio/vfio-common.h"
-#include "sysemu/iommufd.h"
+#include "system/iommufd.h"
#include "hw/s390x/ap-device.h"
#include "qemu/error-report.h"
#include "qemu/event_notifier.h"
#include "qapi/error.h"
#include "hw/vfio/vfio-common.h"
-#include "sysemu/iommufd.h"
+#include "system/iommufd.h"
#include "hw/s390x/s390-ccw.h"
#include "hw/s390x/vfio-ccw.h"
#include "hw/qdev-properties.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qemu/range.h"
-#include "sysemu/kvm.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
+#include "system/kvm.h"
+#include "system/reset.h"
+#include "system/runstate.h"
#include "trace.h"
#include "qapi/error.h"
#include "migration/misc.h"
#include "migration/blocker.h"
#include "migration/qemu-file.h"
-#include "sysemu/tpm.h"
+#include "system/tpm.h"
VFIODeviceList vfio_device_list =
QLIST_HEAD_INITIALIZER(vfio_device_list);
#include "exec/ram_addr.h"
#include "qemu/error-report.h"
#include "qemu/range.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "trace.h"
#include "qapi/error.h"
#include "pci.h"
#include "hw/vfio/vfio-common.h"
#include "migration/misc.h"
#include "qapi/error.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
static int vfio_cpr_reboot_notifier(NotifierWithReturn *notifier,
MigrationEvent *e, Error **errp)
#include "qemu/error-report.h"
#include "trace.h"
#include "qapi/error.h"
-#include "sysemu/iommufd.h"
+#include "system/iommufd.h"
#include "hw/qdev-core.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "qemu/cutils.h"
#include "qemu/chardev_open.h"
#include "pci.h"
#include <linux/vfio.h>
#include <sys/ioctl.h>
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "hw/vfio/vfio-common.h"
#include "migration/misc.h"
#include "migration/savevm.h"
#include "qemu/module.h"
#include "qemu/range.h"
#include "qemu/units.h"
-#include "sysemu/kvm.h"
-#include "sysemu/runstate.h"
+#include "system/kvm.h"
+#include "system/runstate.h"
#include "pci.h"
#include "trace.h"
#include "qapi/error.h"
#include "migration/blocker.h"
#include "migration/qemu-file.h"
-#include "sysemu/iommufd.h"
+#include "system/iommufd.h"
#define TYPE_VFIO_PCI_NOHOTPLUG "vfio-pci-nohotplug"
#include "qemu/queue.h"
#include "qemu/timer.h"
#include "qom/object.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#define PCI_ANY_ID (~0)
#include <linux/vfio.h>
#include "hw/vfio/vfio-platform.h"
-#include "sysemu/iommufd.h"
+#include "system/iommufd.h"
#include "migration/vmstate.h"
#include "qemu/error-report.h"
#include "qemu/lockable.h"
#include "hw/irq.h"
#include "hw/platform-bus.h"
#include "hw/qdev-properties.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
/*
* Functions used whatever the injection method
#ifdef CONFIG_KVM
#include <linux/kvm.h>
#endif
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "exec/address-spaces.h"
#include "hw/vfio/vfio-common.h"
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-bus.h"
#include "hw/virtio/vdpa-dev.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/runstate.h"
+#include "system/system.h"
+#include "system/runstate.h"
static void
vhost_vdpa_device_dummy_handle_output(VirtIODevice *vdev, VirtQueue *vq)
#include "hw/virtio/vhost.h"
#include "hw/virtio/vhost-user-fs.h"
#include "monitor/monitor.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
static const int user_feature_bits[] = {
VIRTIO_F_VERSION_1,
#include "hw/pci/msi.h"
#include "hw/pci/msix.h"
#include "hw/loader.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "hw/virtio/virtio-pci.h"
#include "qom/object.h"
#include "hw/virtio/virtio-net.h"
#include "chardev/char-fe.h"
#include "io/channel-socket.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qemu/uuid.h"
#include "qemu/sockets.h"
-#include "sysemu/runstate.h"
-#include "sysemu/cryptodev.h"
+#include "system/runstate.h"
+#include "system/cryptodev.h"
#include "migration/postcopy-ram.h"
#include "trace.h"
#include "exec/ramblock.h"
#include "hw/mem/memory-device.h"
#include "migration/blocker.h"
#include "migration/qemu-file-types.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "trace.h"
/* enabled until disconnected backend stabilizes */
#include "hw/mem/pc-dimm.h"
#include "hw/qdev-properties.h"
#include "hw/boards.h"
-#include "sysemu/balloon.h"
+#include "system/balloon.h"
#include "hw/virtio/virtio-balloon.h"
#include "exec/address-spaces.h"
#include "qapi/error.h"
#include "hw/virtio/virtio-crypto.h"
#include "hw/qdev-properties.h"
#include "standard-headers/linux/virtio_ids.h"
-#include "sysemu/cryptodev-vhost.h"
+#include "system/cryptodev-vhost.h"
#define VIRTIO_CRYPTO_VM_VERSION 1
#include "exec/target_page.h"
#include "hw/qdev-properties.h"
#include "hw/virtio/virtio.h"
-#include "sysemu/kvm.h"
-#include "sysemu/reset.h"
-#include "sysemu/sysemu.h"
+#include "system/kvm.h"
+#include "system/reset.h"
+#include "system/system.h"
#include "qemu/reserved-region.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "qemu/cutils.h"
#include "qemu/error-report.h"
#include "qemu/units.h"
-#include "sysemu/numa.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
+#include "system/numa.h"
+#include "system/system.h"
+#include "system/reset.h"
+#include "system/runstate.h"
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-bus.h"
#include "hw/virtio/virtio-mem.h"
#include "migration/qemu-file-types.h"
#include "qemu/host-utils.h"
#include "qemu/module.h"
-#include "sysemu/kvm.h"
-#include "sysemu/replay.h"
+#include "system/kvm.h"
+#include "system/replay.h"
#include "hw/virtio/virtio-mmio.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "hw/pci/msi.h"
#include "hw/pci/msix.h"
#include "hw/loader.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "hw/virtio/virtio-pci.h"
#include "qemu/range.h"
#include "hw/virtio/virtio-bus.h"
#include "qapi/visitor.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "trace.h"
#define VIRTIO_PCI_REGION_SIZE(dev) VIRTIO_PCI_CONFIG_OFF(msix_present(dev))
#include "hw/virtio/virtio-access.h"
#include "standard-headers/linux/virtio_ids.h"
#include "standard-headers/linux/virtio_pmem.h"
-#include "sysemu/hostmem.h"
+#include "system/hostmem.h"
#include "block/aio.h"
#include "block/thread-pool.h"
#include "trace.h"
#include "hw/virtio/virtio.h"
#include "hw/qdev-properties.h"
#include "hw/virtio/virtio-rng.h"
-#include "sysemu/rng.h"
-#include "sysemu/runstate.h"
+#include "system/rng.h"
+#include "system/runstate.h"
#include "qom/object_interfaces.h"
#include "trace.h"
#include "hw/virtio/virtio-bus.h"
#include "hw/qdev-properties.h"
#include "hw/virtio/virtio-access.h"
-#include "sysemu/dma.h"
-#include "sysemu/runstate.h"
+#include "system/dma.h"
+#include "system/runstate.h"
#include "virtio-qmp.h"
#include "standard-headers/linux/virtio_ids.h"
#include "hw/sysbus.h"
#include "hw/registerfields.h"
#include "hw/watchdog/allwinner-wdt.h"
-#include "sysemu/watchdog.h"
+#include "system/watchdog.h"
#include "migration/vmstate.h"
/* WDT registers */
#include "trace.h"
#include "qapi/error.h"
#include "qemu/module.h"
-#include "sysemu/watchdog.h"
+#include "system/watchdog.h"
#include "hw/sysbus.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/reset.h"
-#include "sysemu/watchdog.h"
+#include "system/reset.h"
+#include "system/watchdog.h"
#include "hw/qdev-properties.h"
#include "hw/watchdog/sbsa_gwdt.h"
#include "qemu/timer.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-run-state.h"
#include "qapi/qapi-events-run-state.h"
-#include "sysemu/runstate.h"
-#include "sysemu/watchdog.h"
+#include "system/runstate.h"
+#include "system/watchdog.h"
#include "hw/nmi.h"
#include "qemu/help_option.h"
#include "trace.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/timer.h"
-#include "sysemu/watchdog.h"
+#include "system/watchdog.h"
#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "hw/watchdog/wdt_aspeed.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/reset.h"
-#include "sysemu/watchdog.h"
+#include "system/reset.h"
+#include "system/watchdog.h"
#include "qemu/timer.h"
#include "hw/watchdog/wdt_diag288.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
#include "qemu/timer.h"
-#include "sysemu/watchdog.h"
+#include "system/watchdog.h"
#include "hw/pci/pci_device.h"
#include "migration/vmstate.h"
#include "qom/object.h"
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "qemu/timer.h"
-#include "sysemu/watchdog.h"
+#include "system/watchdog.h"
#include "hw/isa/isa.h"
#include "migration/vmstate.h"
#include "qom/object.h"
#include "qemu/osdep.h"
#include "qemu/bitops.h"
#include "qemu/module.h"
-#include "sysemu/watchdog.h"
+#include "system/watchdog.h"
#include "migration/vmstate.h"
#include "hw/qdev-properties.h"
#include "monitor/monitor.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "net/net.h"
#include "trace.h"
#include "hw/xen/xen_native.h"
#include "qemu/bitmap.h"
-#include "sysemu/runstate.h"
-#include "sysemu/xen-mapcache.h"
+#include "system/runstate.h"
+#include "system/xen-mapcache.h"
#include "trace.h"
#include <xenevtchn.h>
#include "hw/boards.h"
#include "hw/irq.h"
#include "hw/sysbus.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/tpm.h"
-#include "sysemu/tpm_backend.h"
+#include "system/system.h"
+#include "system/tpm.h"
+#include "system/tpm_backend.h"
#include "hw/xen/xen-pvh-common.h"
#include "trace.h"
#include "qemu/osdep.h"
#include "hw/xen/xen-legacy-backend.h"
#include "qemu/option.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/sysemu.h"
+#include "system/blockdev.h"
+#include "system/system.h"
/* ------------------------------------------------------------- */
#include "hw/boards.h"
#include "hw/xen/xen-legacy-backend.h"
#include "hw/xen/xen-bus.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/sysemu.h"
+#include "system/block-backend.h"
+#include "system/system.h"
static void xen_init_pv(MachineState *machine)
{
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "sysemu/reset.h"
-#include "sysemu/sysemu.h"
+#include "system/reset.h"
+#include "system/system.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "elf.h"
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "hw/pci-host/gpex.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "cpu.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "hw/block/flash.h"
#include "chardev/char.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
+#include "system/device_tree.h"
+#include "system/reset.h"
+#include "system/runstate.h"
#include "qemu/error-report.h"
#include "qemu/option.h"
#include "bootparam.h"
#ifndef CONFIG_USER_ONLY
#include "cpu.h"
-#include "sysemu/xen.h"
-#include "sysemu/tcg.h"
+#include "system/xen.h"
+#include "system/tcg.h"
#include "exec/ramlist.h"
#include "exec/ramblock.h"
#include "exec/exec-all.h"
#include "qemu/units.h"
#include "hw/registerfields.h"
#include "hw/acpi/aml-build.h"
-#include "sysemu/tpm.h"
+#include "system/tpm.h"
#ifdef CONFIG_TPM
#include "hw/i2c/allwinner-i2c.h"
#include "hw/ssi/allwinner-a10-spi.h"
#include "hw/watchdog/allwinner-wdt.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "target/arm/cpu.h"
#include "qom/object.h"
#include "hw/i2c/allwinner-i2c.h"
#include "hw/watchdog/allwinner-wdt.h"
#include "target/arm/cpu.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
/**
* Allwinner H3 device list
#include "hw/usb/hcd-ehci.h"
#include "hw/watchdog/allwinner-wdt.h"
#include "target/arm/cpu.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
enum {
AW_R40_DEV_SRAM_A1,
#include "hw/arm/boot.h"
#include "hw/arm/bsa.h"
#include "hw/block/flash.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "hw/intc/arm_gicv3_common.h"
#include "qom/object.h"
#define HW_BOARDS_H
#include "exec/memory.h"
-#include "sysemu/hostmem.h"
-#include "sysemu/blockdev.h"
+#include "system/hostmem.h"
+#include "system/blockdev.h"
#include "qapi/qapi-types-machine.h"
#include "qemu/module.h"
#include "qom/object.h"
* See the COPYING file in the top-level directory.
*/
-#ifndef SYSEMU_CPU_OPS_H
-#define SYSEMU_CPU_OPS_H
+#ifndef SYSTEM_CPU_OPS_H
+#define SYSTEM_CPU_OPS_H
#include "hw/core/cpu.h"
} SysemuCPUOps;
-#endif /* SYSEMU_CPU_OPS_H */
+#endif /* SYSTEM_CPU_OPS_H */
#include "hw/sysbus.h"
#include "hw/register.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "qom/object.h"
#define ZDMA_R_MAX (0x204 / 4)
#include "hw/sysbus.h"
#include "ui/console.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "qom/object.h"
#define XLNX_DPDMA_REG_ARRAY_SIZE (0x1000 >> 2)
#ifndef HW_HYPERV_VMBUS_H
#define HW_HYPERV_VMBUS_H
-#include "sysemu/sysemu.h"
-#include "sysemu/dma.h"
+#include "system/system.h"
+#include "system/dma.h"
#include "hw/qdev-core.h"
#include "migration/vmstate.h"
#include "hw/hyperv/vmbus-proto.h"
#ifndef QEMU_HOSTMEM_EPC_H
#define QEMU_HOSTMEM_EPC_H
-#include "sysemu/hostmem.h"
+#include "system/hostmem.h"
#define TYPE_MEMORY_BACKEND_EPC "memory-backend-epc"
#ifndef IDE_DEV_H
#define IDE_DEV_H
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "hw/qdev-properties.h"
#include "hw/block/block.h"
#ifndef HW_ISA_SUPERIO_H
#define HW_ISA_SUPERIO_H
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/isa/isa.h"
#include "qom/object.h"
#include "exec/hwaddr.h"
#include "standard-headers/linux/qemu_fw_cfg.h"
#include "hw/sysbus.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "qom/object.h"
#define TYPE_FW_CFG "fw_cfg"
#ifndef XLNX_BBRAM_H
#define XLNX_BBRAM_H
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "hw/qdev-core.h"
#include "hw/irq.h"
#include "hw/sysbus.h"
#ifndef XLNX_EFUSE_H
#define XLNX_EFUSE_H
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "hw/qdev-core.h"
#define TYPE_XLNX_EFUSE "xlnx-efuse"
#define QEMU_PCI_H
#include "exec/memory.h"
-#include "sysemu/dma.h"
-#include "sysemu/host_iommu_device.h"
+#include "system/dma.h"
+#include "system/host_iommu_device.h"
/* PCI includes legacy ISA access. */
#include "hw/isa/isa.h"
#include "exec/memory.h"
#include "qemu/iov.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "hw/sysbus.h"
#include "qom/object.h"
#define HW_SPAPR_H
#include "qemu/units.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "hw/boards.h"
#include "hw/ppc/spapr_drc.h"
#include "hw/mem/pc-dimm.h"
#include <libfdt.h>
#include "qom/object.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "hw/qdev-core.h"
#include "qapi/error.h"
*/
#include "hw/ppc/spapr.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
#include "hw/irq.h"
#include "qom/object.h"
#ifndef PPC_XIVE_H
#define PPC_XIVE_H
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "hw/sysbus.h"
#include "hw/ppc/xive_regs.h"
#include "qom/object.h"
#include "hw/boards.h"
#include "hw/sysbus.h"
-#include "sysemu/numa.h"
+#include "system/numa.h"
/**
* riscv_socket_count:
#include "hw/s390x/adapter.h"
#include "hw/s390x/s390_flic.h"
#include "hw/s390x/ioinst.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "target/s390x/cpu-qom.h"
/* Channel subsystem constants. */
#define HW_S390_PCI_INST_H
#include "s390-pci-bus.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
/* Load/Store status codes */
#define ZPCI_PCI_ST_FUNC_NOT_ENABLED 4
#include "qapi/error.h"
#include "hw/boards.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "exec/address-spaces.h"
#include "qom/object.h"
#ifdef CONFIG_LINUX
#include <linux/vfio.h>
#endif
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/vfio/vfio-container-base.h"
-#include "sysemu/host_iommu_device.h"
-#include "sysemu/iommufd.h"
+#include "system/host_iommu_device.h"
+#include "system/iommufd.h"
#define VFIO_MSG_PREFIX "vfio %s: "
#include "standard-headers/linux/virtio_balloon.h"
#include "hw/virtio/virtio.h"
-#include "sysemu/iothread.h"
+#include "system/iothread.h"
#include "qom/object.h"
#define TYPE_VIRTIO_BALLOON "virtio-balloon-device"
#include "standard-headers/linux/virtio_blk.h"
#include "hw/virtio/virtio.h"
#include "hw/block/block.h"
-#include "sysemu/iothread.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/block-ram-registrar.h"
+#include "system/iothread.h"
+#include "system/block-backend.h"
+#include "system/block-ram-registrar.h"
#include "qom/object.h"
#include "qapi/qapi-types-virtio.h"
#include "standard-headers/linux/virtio_crypto.h"
#include "hw/virtio/virtio.h"
-#include "sysemu/iothread.h"
-#include "sysemu/cryptodev.h"
+#include "system/iothread.h"
+#include "system/cryptodev.h"
#include "qom/object.h"
#include "ui/console.h"
#include "hw/virtio/virtio.h"
#include "qemu/log.h"
-#include "sysemu/vhost-user-backend.h"
+#include "system/vhost-user-backend.h"
#include "standard-headers/linux/virtio_gpu.h"
#include "standard-headers/linux/virtio_ids.h"
#include "hw/virtio/vhost-user.h"
#include "hw/virtio/vhost-user-base.h"
#include "ui/input.h"
-#include "sysemu/vhost-user-backend.h"
+#include "system/vhost-user-backend.h"
/* ----------------------------------------------------------------- */
/* virtio input protocol */
#include "hw/pci/pci.h"
#include "qom/object.h"
#include "qapi/qapi-types-virtio.h"
-#include "sysemu/host_iommu_device.h"
+#include "system/host_iommu_device.h"
#define TYPE_VIRTIO_IOMMU "virtio-iommu-device"
#define TYPE_VIRTIO_IOMMU_PCI "virtio-iommu-pci"
#include "hw/resettable.h"
#include "hw/virtio/virtio.h"
#include "qapi/qapi-types-misc.h"
-#include "sysemu/hostmem.h"
+#include "system/hostmem.h"
#include "qom/object.h"
#define TYPE_VIRTIO_MEM "virtio-mem"
#define QEMU_VIRTIO_RNG_H
#include "hw/virtio/virtio.h"
-#include "sysemu/rng.h"
+#include "system/rng.h"
#include "standard-headers/linux/virtio_rng.h"
#include "qom/object.h"
#include "hw/virtio/virtio.h"
#include "hw/scsi/scsi.h"
#include "chardev/char-fe.h"
-#include "sysemu/iothread.h"
+#include "system/iothread.h"
#define TYPE_VIRTIO_SCSI_COMMON "virtio-scsi-common"
OBJECT_DECLARE_SIMPLE_TYPE(VirtIOSCSICommon, VIRTIO_SCSI_COMMON)
#include "hw/xen/xen-bus.h"
#include "hw/block/block.h"
#include "hw/block/dataplane/xen-block.h"
-#include "sysemu/iothread.h"
+#include "system/iothread.h"
#include "qom/object.h"
typedef enum XenBlockVdevType {
#include "hw/hw.h"
#include "hw/xen/xen_native.h"
#include "hw/xen/xen-legacy-backend.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/xen.h"
-#include "sysemu/xen-mapcache.h"
+#include "system/runstate.h"
+#include "system/system.h"
+#include "system/xen.h"
+#include "system/xen-mapcache.h"
#include "qemu/error-report.h"
#include <xen/hvm/ioreq.h>
#include "block/aio.h"
#include "qom/object.h"
-#include "sysemu/event-loop-base.h"
+#include "system/event-loop-base.h"
#define SIG_IPI SIGUSR1
* To avoid getting into possible circular include dependencies, this
* file should not include any other QEMU headers, with the exceptions
* of config-host.h, config-target.h, qemu/compiler.h,
- * sysemu/os-posix.h, sysemu/os-win32.h, glib-compat.h and
+ * system/os-posix.h, system/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.
*
#include <sys/stat.h>
#include <sys/time.h>
#include <assert.h>
-/* setjmp must be declared before sysemu/os-win32.h
+/* setjmp must be declared before system/os-win32.h
* because it is redefined there. */
#include <setjmp.h>
#include <signal.h>
#include "glib-compat.h"
#ifdef _WIN32
-#include "sysemu/os-win32.h"
+#include "system/os-win32.h"
#endif
#ifdef CONFIG_POSIX
-#include "sysemu/os-posix.h"
+#include "system/os-posix.h"
#endif
#ifdef __cplusplus
+++ /dev/null
-/*
- * Accelerator blocking API, to prevent new ioctls from starting and wait the
- * running ones finish.
- * This mechanism differs from pause/resume_all_vcpus() in that it does not
- * release the BQL.
- *
- * Copyright (c) 2022 Red Hat Inc.
- *
- * Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-#ifndef ACCEL_BLOCKER_H
-#define ACCEL_BLOCKER_H
-
-#include "sysemu/cpus.h"
-
-void accel_blocker_init(void);
-
-/*
- * accel_{cpu_}ioctl_begin/end:
- * Mark when ioctl is about to run or just finished.
- *
- * accel_{cpu_}ioctl_begin will block after accel_ioctl_inhibit_begin() is
- * called, preventing new ioctls to run. They will continue only after
- * accel_ioctl_inibith_end().
- */
-void accel_ioctl_begin(void);
-void accel_ioctl_end(void);
-void accel_cpu_ioctl_begin(CPUState *cpu);
-void accel_cpu_ioctl_end(CPUState *cpu);
-
-/*
- * accel_ioctl_inhibit_begin: start critical section
- *
- * This function makes sure that:
- * 1) incoming accel_{cpu_}ioctl_begin() calls block
- * 2) wait that all ioctls that were already running reach
- * accel_{cpu_}ioctl_end(), kicking vcpus if necessary.
- *
- * This allows the caller to access shared data or perform operations without
- * worrying of concurrent vcpus accesses.
- */
-void accel_ioctl_inhibit_begin(void);
-
-/*
- * accel_ioctl_inhibit_end: end critical section started by
- * accel_ioctl_inhibit_begin()
- *
- * This function allows blocked accel_{cpu_}ioctl_begin() to continue.
- */
-void accel_ioctl_inhibit_end(void);
-
-#endif /* ACCEL_BLOCKER_H */
+++ /dev/null
-/*
- * Accelerator OPS, used for cpus.c module
- *
- * Copyright 2021 SUSE LLC
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef ACCEL_OPS_H
-#define ACCEL_OPS_H
-
-#include "exec/cpu-common.h"
-#include "qom/object.h"
-
-#define ACCEL_OPS_SUFFIX "-ops"
-#define TYPE_ACCEL_OPS "accel" ACCEL_OPS_SUFFIX
-#define ACCEL_OPS_NAME(name) (name "-" TYPE_ACCEL_OPS)
-
-typedef struct AccelOpsClass AccelOpsClass;
-DECLARE_CLASS_CHECKERS(AccelOpsClass, ACCEL_OPS, TYPE_ACCEL_OPS)
-
-/**
- * struct AccelOpsClass - accelerator interfaces
- *
- * This structure is used to abstract accelerator differences from the
- * core CPU code. Not all have to be implemented.
- */
-struct AccelOpsClass {
- /*< private >*/
- ObjectClass parent_class;
- /*< public >*/
-
- /* initialization function called when accel is chosen */
- void (*ops_init)(AccelOpsClass *ops);
-
- bool (*cpus_are_resettable)(void);
- void (*cpu_reset_hold)(CPUState *cpu);
-
- void (*create_vcpu_thread)(CPUState *cpu); /* MANDATORY NON-NULL */
- void (*kick_vcpu_thread)(CPUState *cpu);
- bool (*cpu_thread_is_idle)(CPUState *cpu);
-
- void (*synchronize_post_reset)(CPUState *cpu);
- void (*synchronize_post_init)(CPUState *cpu);
- void (*synchronize_state)(CPUState *cpu);
- void (*synchronize_pre_loadvm)(CPUState *cpu);
- void (*synchronize_pre_resume)(bool step_pending);
-
- void (*handle_interrupt)(CPUState *cpu, int mask);
-
- /**
- * @get_virtual_clock: fetch virtual clock
- * @set_virtual_clock: set virtual clock
- *
- * These allow the timer subsystem to defer to the accelerator to
- * fetch time. The set function is needed if the accelerator wants
- * to track the changes to time as the timer is warped through
- * various timer events.
- */
- int64_t (*get_virtual_clock)(void);
- void (*set_virtual_clock)(int64_t time);
-
- int64_t (*get_elapsed_ticks)(void);
-
- /* gdbstub hooks */
- bool (*supports_guest_debug)(void);
- int (*update_guest_debug)(CPUState *cpu);
- int (*insert_breakpoint)(CPUState *cpu, int type, vaddr addr, vaddr len);
- int (*remove_breakpoint)(CPUState *cpu, int type, vaddr addr, vaddr len);
- void (*remove_all_breakpoints)(CPUState *cpu);
-};
-
-#endif /* ACCEL_OPS_H */
+++ /dev/null
-#ifndef QEMU_ARCH_INIT_H
-#define QEMU_ARCH_INIT_H
-
-
-enum {
- QEMU_ARCH_ALL = -1,
- QEMU_ARCH_ALPHA = (1 << 0),
- QEMU_ARCH_ARM = (1 << 1),
- QEMU_ARCH_I386 = (1 << 3),
- QEMU_ARCH_M68K = (1 << 4),
- QEMU_ARCH_MICROBLAZE = (1 << 6),
- QEMU_ARCH_MIPS = (1 << 7),
- QEMU_ARCH_PPC = (1 << 8),
- QEMU_ARCH_S390X = (1 << 9),
- QEMU_ARCH_SH4 = (1 << 10),
- QEMU_ARCH_SPARC = (1 << 11),
- QEMU_ARCH_XTENSA = (1 << 12),
- QEMU_ARCH_OPENRISC = (1 << 13),
- QEMU_ARCH_TRICORE = (1 << 16),
- QEMU_ARCH_HPPA = (1 << 18),
- QEMU_ARCH_RISCV = (1 << 19),
- QEMU_ARCH_RX = (1 << 20),
- QEMU_ARCH_AVR = (1 << 21),
- QEMU_ARCH_HEXAGON = (1 << 22),
- QEMU_ARCH_LOONGARCH = (1 << 23),
-};
-
-extern const uint32_t arch_type;
-
-void qemu_init_arch_modules(void);
-
-#endif
+++ /dev/null
-/*
- * Balloon
- *
- * Copyright IBM, Corp. 2008
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef QEMU_BALLOON_H
-#define QEMU_BALLOON_H
-
-#include "exec/cpu-common.h"
-#include "qapi/qapi-types-machine.h"
-
-typedef void (QEMUBalloonEvent)(void *opaque, ram_addr_t target);
-typedef void (QEMUBalloonStatus)(void *opaque, BalloonInfo *info);
-
-int qemu_add_balloon_handler(QEMUBalloonEvent *event_func,
- QEMUBalloonStatus *stat_func, void *opaque);
-void qemu_remove_balloon_handler(void *opaque);
-
-#endif
+++ /dev/null
-/*
- * QEMU Block backends
- *
- * Copyright (C) 2014-2016 Red Hat, Inc.
- *
- * Authors:
- * Markus Armbruster <armbru@redhat.com>,
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1
- * or later. See the COPYING.LIB file in the top-level directory.
- */
-
-#ifndef BLOCK_BACKEND_COMMON_H
-#define BLOCK_BACKEND_COMMON_H
-
-#include "qemu/iov.h"
-#include "block/throttle-groups.h"
-
-/*
- * TODO Have to include block/block.h for a bunch of block layer
- * types. Unfortunately, this pulls in the whole BlockDriverState
- * API, which we don't want used by many BlockBackend users. Some of
- * the types belong here, and the rest should be split into a common
- * header and one for the BlockDriverState API.
- */
-#include "block/block.h"
-
-/* Callbacks for block device models */
-typedef struct BlockDevOps {
-
- /*
- * Global state (GS) API. These functions run under the BQL.
- *
- * See include/block/block-global-state.h for more information about
- * the GS API.
- */
-
- /*
- * Runs when virtual media changed (monitor commands eject, change)
- * Argument load is true on load and false on eject.
- * Beware: doesn't run when a host device's physical media
- * changes. Sure would be useful if it did.
- * Device models with removable media must implement this callback.
- */
- void (*change_media_cb)(void *opaque, bool load, Error **errp);
- /*
- * Runs when an eject request is issued from the monitor, the tray
- * is closed, and the medium is locked.
- * Device models that do not implement is_medium_locked will not need
- * this callback. Device models that can lock the medium or tray might
- * want to implement the callback and unlock the tray when "force" is
- * true, even if they do not support eject requests.
- */
- void (*eject_request_cb)(void *opaque, bool force);
-
- /*
- * Is the virtual medium locked into the device?
- * Device models implement this only when device has such a lock.
- */
- bool (*is_medium_locked)(void *opaque);
-
- /*
- * Runs when the backend receives a drain request.
- */
- void (*drained_begin)(void *opaque);
- /*
- * Runs when the backend's last drain request ends.
- */
- void (*drained_end)(void *opaque);
- /*
- * Is the device still busy?
- */
- bool (*drained_poll)(void *opaque);
-
- /*
- * I/O API functions. These functions are thread-safe.
- *
- * See include/block/block-io.h for more information about
- * the I/O API.
- */
-
- /*
- * Is the virtual tray open?
- * Device models implement this only when the device has a tray.
- */
- bool (*is_tray_open)(void *opaque);
-
- /*
- * Runs when the size changed (e.g. monitor command block_resize)
- */
- void (*resize_cb)(void *opaque);
-} BlockDevOps;
-
-/*
- * This struct is embedded in (the private) BlockBackend struct and contains
- * fields that must be public. This is in particular for QLIST_ENTRY() and
- * friends so that BlockBackends can be kept in lists outside block-backend.c
- */
-typedef struct BlockBackendPublic {
- ThrottleGroupMember throttle_group_member;
-} BlockBackendPublic;
-
-#endif /* BLOCK_BACKEND_COMMON_H */
+++ /dev/null
-/*
- * QEMU Block backends
- *
- * Copyright (C) 2014-2016 Red Hat, Inc.
- *
- * Authors:
- * Markus Armbruster <armbru@redhat.com>,
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1
- * or later. See the COPYING.LIB file in the top-level directory.
- */
-
-#ifndef BLOCK_BACKEND_GLOBAL_STATE_H
-#define BLOCK_BACKEND_GLOBAL_STATE_H
-
-#include "block-backend-common.h"
-
-/*
- * Global state (GS) API. These functions run under the BQL.
- *
- * See include/block/block-global-state.h for more information about
- * the GS API.
- */
-
-BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm);
-
-BlockBackend * no_coroutine_fn
-blk_new_with_bs(BlockDriverState *bs, uint64_t perm, uint64_t shared_perm,
- Error **errp);
-
-BlockBackend * coroutine_fn no_co_wrapper
-blk_co_new_with_bs(BlockDriverState *bs, uint64_t perm, uint64_t shared_perm,
- Error **errp);
-
-BlockBackend * no_coroutine_fn
-blk_new_open(const char *filename, const char *reference, QDict *options,
- int flags, Error **errp);
-
-BlockBackend * coroutine_fn no_co_wrapper
-blk_co_new_open(const char *filename, const char *reference, QDict *options,
- int flags, Error **errp);
-
-int blk_get_refcnt(BlockBackend *blk);
-void blk_ref(BlockBackend *blk);
-
-void no_coroutine_fn blk_unref(BlockBackend *blk);
-void coroutine_fn no_co_wrapper blk_co_unref(BlockBackend *blk);
-
-void blk_remove_all_bs(void);
-BlockBackend *blk_by_name(const char *name);
-BlockBackend *blk_next(BlockBackend *blk);
-BlockBackend *blk_all_next(BlockBackend *blk);
-bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp);
-void monitor_remove_blk(BlockBackend *blk);
-
-BlockBackendPublic *blk_get_public(BlockBackend *blk);
-
-void blk_remove_bs(BlockBackend *blk);
-int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp);
-int blk_replace_bs(BlockBackend *blk, BlockDriverState *new_bs, Error **errp);
-bool GRAPH_RDLOCK bdrv_has_blk(BlockDriverState *bs);
-bool GRAPH_RDLOCK bdrv_is_root_node(BlockDriverState *bs);
-int GRAPH_UNLOCKED blk_set_perm(BlockBackend *blk, uint64_t perm,
- uint64_t shared_perm, Error **errp);
-void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm);
-
-void blk_iostatus_enable(BlockBackend *blk);
-BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk);
-void blk_iostatus_reset(BlockBackend *blk);
-int blk_attach_dev(BlockBackend *blk, DeviceState *dev);
-void blk_detach_dev(BlockBackend *blk, DeviceState *dev);
-DeviceState *blk_get_attached_dev(BlockBackend *blk);
-BlockBackend *blk_by_dev(void *dev);
-BlockBackend *blk_by_qdev_id(const char *id, Error **errp);
-void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque);
-
-int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags);
-void blk_aio_cancel(BlockAIOCB *acb);
-int blk_commit_all(void);
-bool blk_in_drain(BlockBackend *blk);
-void blk_drain(BlockBackend *blk);
-void blk_drain_all(void);
-void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error,
- BlockdevOnError on_write_error);
-bool blk_supports_write_perm(BlockBackend *blk);
-bool blk_is_sg(BlockBackend *blk);
-void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
-int blk_get_flags(BlockBackend *blk);
-bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp);
-int blk_set_aio_context(BlockBackend *blk, AioContext *new_context,
- Error **errp);
-void blk_add_aio_context_notifier(BlockBackend *blk,
- void (*attached_aio_context)(AioContext *new_context, void *opaque),
- void (*detach_aio_context)(void *opaque), void *opaque);
-void blk_remove_aio_context_notifier(BlockBackend *blk,
- void (*attached_aio_context)(AioContext *,
- void *),
- void (*detach_aio_context)(void *),
- void *opaque);
-void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify);
-BlockBackendRootState *blk_get_root_state(BlockBackend *blk);
-void blk_update_root_state(BlockBackend *blk);
-bool blk_get_detect_zeroes_from_root_state(BlockBackend *blk);
-int blk_get_open_flags_from_root_state(BlockBackend *blk);
-
-int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
- int64_t pos, int size);
-int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size);
-int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz);
-int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo);
-
-void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg);
-void blk_io_limits_disable(BlockBackend *blk);
-void blk_io_limits_enable(BlockBackend *blk, const char *group);
-void blk_io_limits_update_group(BlockBackend *blk, const char *group);
-void blk_set_force_allow_inactivate(BlockBackend *blk);
-
-bool blk_register_buf(BlockBackend *blk, void *host, size_t size, Error **errp);
-void blk_unregister_buf(BlockBackend *blk, void *host, size_t size);
-
-const BdrvChild *blk_root(BlockBackend *blk);
-
-int blk_make_empty(BlockBackend *blk, Error **errp);
-
-#endif /* BLOCK_BACKEND_GLOBAL_STATE_H */
+++ /dev/null
-/*
- * QEMU Block backends
- *
- * Copyright (C) 2014-2016 Red Hat, Inc.
- *
- * Authors:
- * Markus Armbruster <armbru@redhat.com>,
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1
- * or later. See the COPYING.LIB file in the top-level directory.
- */
-
-#ifndef BLOCK_BACKEND_IO_H
-#define BLOCK_BACKEND_IO_H
-
-#include "block-backend-common.h"
-#include "block/accounting.h"
-
-/*
- * I/O API functions. These functions are thread-safe.
- *
- * See include/block/block-io.h for more information about
- * the I/O API.
- */
-
-const char *blk_name(const BlockBackend *blk);
-
-BlockDriverState *blk_bs(BlockBackend *blk);
-
-void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow);
-void blk_set_allow_aio_context_change(BlockBackend *blk, bool allow);
-void blk_set_disable_request_queuing(BlockBackend *blk, bool disable);
-bool blk_iostatus_is_enabled(const BlockBackend *blk);
-
-char *blk_get_attached_dev_id(BlockBackend *blk);
-
-BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
- int64_t bytes, BdrvRequestFlags flags,
- BlockCompletionFunc *cb, void *opaque);
-
-BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset,
- QEMUIOVector *qiov, BdrvRequestFlags flags,
- BlockCompletionFunc *cb, void *opaque);
-BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset,
- QEMUIOVector *qiov, BdrvRequestFlags flags,
- BlockCompletionFunc *cb, void *opaque);
-BlockAIOCB *blk_aio_flush(BlockBackend *blk,
- BlockCompletionFunc *cb, void *opaque);
-BlockAIOCB *blk_aio_zone_report(BlockBackend *blk, int64_t offset,
- unsigned int *nr_zones,
- BlockZoneDescriptor *zones,
- BlockCompletionFunc *cb, void *opaque);
-BlockAIOCB *blk_aio_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
- int64_t offset, int64_t len,
- BlockCompletionFunc *cb, void *opaque);
-BlockAIOCB *blk_aio_zone_append(BlockBackend *blk, int64_t *offset,
- QEMUIOVector *qiov, BdrvRequestFlags flags,
- BlockCompletionFunc *cb, void *opaque);
-BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes,
- BlockCompletionFunc *cb, void *opaque);
-void blk_aio_cancel_async(BlockAIOCB *acb);
-BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
- BlockCompletionFunc *cb, void *opaque);
-
-void blk_inc_in_flight(BlockBackend *blk);
-void blk_dec_in_flight(BlockBackend *blk);
-
-bool coroutine_fn GRAPH_RDLOCK blk_co_is_inserted(BlockBackend *blk);
-bool co_wrapper_mixed_bdrv_rdlock blk_is_inserted(BlockBackend *blk);
-
-bool coroutine_fn GRAPH_RDLOCK blk_co_is_available(BlockBackend *blk);
-bool co_wrapper_mixed_bdrv_rdlock blk_is_available(BlockBackend *blk);
-
-void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked);
-void co_wrapper blk_lock_medium(BlockBackend *blk, bool locked);
-
-void coroutine_fn blk_co_eject(BlockBackend *blk, bool eject_flag);
-void co_wrapper blk_eject(BlockBackend *blk, bool eject_flag);
-
-int64_t coroutine_fn blk_co_getlength(BlockBackend *blk);
-int64_t co_wrapper_mixed blk_getlength(BlockBackend *blk);
-
-void coroutine_fn blk_co_get_geometry(BlockBackend *blk,
- uint64_t *nb_sectors_ptr);
-void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr);
-
-int64_t coroutine_fn blk_co_nb_sectors(BlockBackend *blk);
-int64_t blk_nb_sectors(BlockBackend *blk);
-
-void *blk_try_blockalign(BlockBackend *blk, size_t size);
-void *blk_blockalign(BlockBackend *blk, size_t size);
-bool blk_is_writable(BlockBackend *blk);
-bool blk_enable_write_cache(BlockBackend *blk);
-BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read);
-BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
- int error);
-void blk_error_action(BlockBackend *blk, BlockErrorAction action,
- bool is_read, int error);
-void blk_iostatus_set_err(BlockBackend *blk, int error);
-int blk_get_max_iov(BlockBackend *blk);
-int blk_get_max_hw_iov(BlockBackend *blk);
-
-AioContext *blk_get_aio_context(BlockBackend *blk);
-BlockAcctStats *blk_get_stats(BlockBackend *blk);
-void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
- BlockCompletionFunc *cb, void *opaque);
-BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
- BlockCompletionFunc *cb,
- void *opaque, int ret);
-
-uint32_t blk_get_request_alignment(BlockBackend *blk);
-uint32_t blk_get_max_transfer(BlockBackend *blk);
-uint64_t blk_get_max_hw_transfer(BlockBackend *blk);
-
-int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
- BlockBackend *blk_out, int64_t off_out,
- int64_t bytes, BdrvRequestFlags read_flags,
- BdrvRequestFlags write_flags);
-
-int coroutine_fn blk_co_block_status_above(BlockBackend *blk,
- BlockDriverState *base,
- int64_t offset, int64_t bytes,
- int64_t *pnum, int64_t *map,
- BlockDriverState **file);
-int coroutine_fn blk_co_is_allocated_above(BlockBackend *blk,
- BlockDriverState *base,
- bool include_base, int64_t offset,
- int64_t bytes, int64_t *pnum);
-
-/*
- * "I/O or GS" API functions. These functions can run without
- * the BQL, but only in one specific iothread/main loop.
- *
- * See include/block/block-io.h for more information about
- * the "I/O or GS" API.
- */
-
-int co_wrapper_mixed blk_pread(BlockBackend *blk, int64_t offset,
- int64_t bytes, void *buf,
- BdrvRequestFlags flags);
-int coroutine_fn blk_co_pread(BlockBackend *blk, int64_t offset, int64_t bytes,
- void *buf, BdrvRequestFlags flags);
-
-int co_wrapper_mixed blk_preadv(BlockBackend *blk, int64_t offset,
- int64_t bytes, QEMUIOVector *qiov,
- BdrvRequestFlags flags);
-int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
- int64_t bytes, QEMUIOVector *qiov,
- BdrvRequestFlags flags);
-
-int co_wrapper_mixed blk_preadv_part(BlockBackend *blk, int64_t offset,
- int64_t bytes, QEMUIOVector *qiov,
- size_t qiov_offset,
- BdrvRequestFlags flags);
-int coroutine_fn blk_co_preadv_part(BlockBackend *blk, int64_t offset,
- int64_t bytes, QEMUIOVector *qiov,
- size_t qiov_offset, BdrvRequestFlags flags);
-
-int co_wrapper_mixed blk_pwrite(BlockBackend *blk, int64_t offset,
- int64_t bytes, const void *buf,
- BdrvRequestFlags flags);
-int coroutine_fn blk_co_pwrite(BlockBackend *blk, int64_t offset, int64_t bytes,
- const void *buf, BdrvRequestFlags flags);
-
-int co_wrapper_mixed blk_pwritev(BlockBackend *blk, int64_t offset,
- int64_t bytes, QEMUIOVector *qiov,
- BdrvRequestFlags flags);
-int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
- int64_t bytes, QEMUIOVector *qiov,
- BdrvRequestFlags flags);
-
-int co_wrapper_mixed blk_pwritev_part(BlockBackend *blk, int64_t offset,
- int64_t bytes, QEMUIOVector *qiov,
- size_t qiov_offset,
- BdrvRequestFlags flags);
-int coroutine_fn blk_co_pwritev_part(BlockBackend *blk, int64_t offset,
- int64_t bytes,
- QEMUIOVector *qiov, size_t qiov_offset,
- BdrvRequestFlags flags);
-
-int co_wrapper_mixed blk_pwrite_compressed(BlockBackend *blk,
- int64_t offset, int64_t bytes,
- const void *buf);
-int coroutine_fn blk_co_pwrite_compressed(BlockBackend *blk, int64_t offset,
- int64_t bytes, const void *buf);
-
-int co_wrapper_mixed blk_pwrite_zeroes(BlockBackend *blk, int64_t offset,
- int64_t bytes,
- BdrvRequestFlags flags);
-int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
- int64_t bytes, BdrvRequestFlags flags);
-
-int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset,
- unsigned int *nr_zones,
- BlockZoneDescriptor *zones);
-int co_wrapper_mixed blk_zone_report(BlockBackend *blk, int64_t offset,
- unsigned int *nr_zones,
- BlockZoneDescriptor *zones);
-int coroutine_fn blk_co_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
- int64_t offset, int64_t len);
-int co_wrapper_mixed blk_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
- int64_t offset, int64_t len);
-int coroutine_fn blk_co_zone_append(BlockBackend *blk, int64_t *offset,
- QEMUIOVector *qiov,
- BdrvRequestFlags flags);
-int co_wrapper_mixed blk_zone_append(BlockBackend *blk, int64_t *offset,
- QEMUIOVector *qiov,
- BdrvRequestFlags flags);
-
-int co_wrapper_mixed blk_pdiscard(BlockBackend *blk, int64_t offset,
- int64_t bytes);
-int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset,
- int64_t bytes);
-
-int co_wrapper_mixed blk_flush(BlockBackend *blk);
-int coroutine_fn blk_co_flush(BlockBackend *blk);
-
-int co_wrapper_mixed blk_ioctl(BlockBackend *blk, unsigned long int req,
- void *buf);
-int coroutine_fn blk_co_ioctl(BlockBackend *blk, unsigned long int req,
- void *buf);
-
-int co_wrapper_mixed blk_truncate(BlockBackend *blk, int64_t offset,
- bool exact, PreallocMode prealloc,
- BdrvRequestFlags flags, Error **errp);
-int coroutine_fn blk_co_truncate(BlockBackend *blk, int64_t offset, bool exact,
- PreallocMode prealloc, BdrvRequestFlags flags,
- Error **errp);
-
-#endif /* BLOCK_BACKEND_IO_H */
+++ /dev/null
-/*
- * QEMU Block backends
- *
- * Copyright (C) 2014-2016 Red Hat, Inc.
- *
- * Authors:
- * Markus Armbruster <armbru@redhat.com>,
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1
- * or later. See the COPYING.LIB file in the top-level directory.
- */
-
-#ifndef BLOCK_BACKEND_H
-#define BLOCK_BACKEND_H
-
-#include "block-backend-global-state.h"
-#include "block-backend-io.h"
-
-/* DO NOT ADD ANYTHING IN HERE. USE ONE OF THE HEADERS INCLUDED ABOVE */
-
-#endif
+++ /dev/null
-/*
- * BlockBackend RAM Registrar
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-#ifndef BLOCK_RAM_REGISTRAR_H
-#define BLOCK_RAM_REGISTRAR_H
-
-#include "exec/ramlist.h"
-
-/**
- * struct BlockRAMRegistrar:
- *
- * Keeps RAMBlock memory registered with a BlockBackend using
- * blk_register_buf() including hotplugged memory.
- *
- * Emulated devices or other BlockBackend users initialize a BlockRAMRegistrar
- * with blk_ram_registrar_init() before submitting I/O requests with the
- * BDRV_REQ_REGISTERED_BUF flag set.
- */
-typedef struct {
- BlockBackend *blk;
- RAMBlockNotifier notifier;
- bool ok;
-} BlockRAMRegistrar;
-
-void blk_ram_registrar_init(BlockRAMRegistrar *r, BlockBackend *blk);
-void blk_ram_registrar_destroy(BlockRAMRegistrar *r);
-
-/* Have all RAMBlocks been registered successfully? */
-static inline bool blk_ram_registrar_ok(BlockRAMRegistrar *r)
-{
- return r->ok;
-}
-
-#endif /* BLOCK_RAM_REGISTRAR_H */
+++ /dev/null
-/*
- * QEMU host block devices
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or
- * later. See the COPYING file in the top-level directory.
- */
-
-#ifndef BLOCKDEV_H
-#define BLOCKDEV_H
-
-#include "block/block.h"
-#include "qemu/queue.h"
-
-typedef enum {
- IF_DEFAULT = -1, /* for use with drive_add() only */
- /*
- * IF_NONE must be zero, because we want MachineClass member
- * block_default_type to default-initialize to IF_NONE
- */
- IF_NONE = 0,
- IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD, IF_VIRTIO, IF_XEN,
- IF_COUNT
-} BlockInterfaceType;
-
-struct DriveInfo {
- BlockInterfaceType type;
- int bus;
- int unit;
- int auto_del; /* see blockdev_mark_auto_del() */
- bool is_default; /* Added by default_drive() ? */
- int media_cd;
- QemuOpts *opts;
- QTAILQ_ENTRY(DriveInfo) next;
-};
-
-/*
- * Global state (GS) API. These functions run under the BQL.
- *
- * See include/block/block-global-state.h for more information about
- * the GS API.
- */
-
-void blockdev_mark_auto_del(BlockBackend *blk);
-void blockdev_auto_del(BlockBackend *blk);
-
-DriveInfo *blk_legacy_dinfo(BlockBackend *blk);
-DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo);
-BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo);
-
-void override_max_devs(BlockInterfaceType type, int max_devs);
-
-DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
-void drive_check_orphaned(void);
-DriveInfo *drive_get_by_index(BlockInterfaceType type, int index);
-int drive_get_max_bus(BlockInterfaceType type);
-
-QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
- const char *optstr);
-DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type,
- Error **errp);
-
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2012 SUSE LINUX Products GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see
- * <http://www.gnu.org/licenses/gpl-2.0.html>
- */
-
-#ifndef SYSEMU_CPU_THROTTLE_H
-#define SYSEMU_CPU_THROTTLE_H
-
-#include "qemu/timer.h"
-
-/**
- * cpu_throttle_init:
- *
- * Initialize the CPU throttling API.
- */
-void cpu_throttle_init(void);
-
-/**
- * cpu_throttle_set:
- * @new_throttle_pct: Percent of sleep time. Valid range is 1 to 99.
- *
- * Throttles all vcpus by forcing them to sleep for the given percentage of
- * time. A throttle_percentage of 25 corresponds to a 75% duty cycle roughly.
- * (example: 10ms sleep for every 30ms awake).
- *
- * cpu_throttle_set can be called as needed to adjust new_throttle_pct.
- * Once the throttling starts, it will remain in effect until cpu_throttle_stop
- * is called.
- */
-void cpu_throttle_set(int new_throttle_pct);
-
-/**
- * cpu_throttle_stop:
- *
- * Stops the vcpu throttling started by cpu_throttle_set.
- */
-void cpu_throttle_stop(void);
-
-/**
- * cpu_throttle_active:
- *
- * Returns: %true if the vcpus are currently being throttled, %false otherwise.
- */
-bool cpu_throttle_active(void);
-
-/**
- * cpu_throttle_get_percentage:
- *
- * Returns the vcpu throttle percentage. See cpu_throttle_set for details.
- *
- * Returns: The throttle percentage in range 1 to 99.
- */
-int cpu_throttle_get_percentage(void);
-
-/**
- * cpu_throttle_dirty_sync_timer_tick:
- *
- * Dirty sync timer hook.
- */
-void cpu_throttle_dirty_sync_timer_tick(void *opaque);
-
-/**
- * cpu_throttle_dirty_sync_timer:
- *
- * Start or stop the dirty sync timer.
- */
-void cpu_throttle_dirty_sync_timer(bool enable);
-
-#endif /* SYSEMU_CPU_THROTTLE_H */
+++ /dev/null
-/*
- * QEMU System Emulator
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- *
- * 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.
- */
-
-#ifndef TIMERS_STATE_H
-#define TIMERS_STATE_H
-
-/* timers state, for sharing between icount and cpu-timers */
-
-typedef struct TimersState {
- /* Protected by BQL. */
- int64_t cpu_ticks_prev;
- int64_t cpu_ticks_offset;
-
- /*
- * Protect fields that can be respectively read outside the
- * BQL, and written from multiple threads.
- */
- QemuSeqLock vm_clock_seqlock;
- QemuSpin vm_clock_lock;
-
- int16_t cpu_ticks_enabled;
-
- /* Conversion factor from emulated instructions to virtual clock ticks. */
- int16_t icount_time_shift;
- /* Icount delta used for shift auto adjust. */
- int64_t last_delta;
-
- /* Compensate for varying guest execution speed. */
- aligned_int64_t qemu_icount_bias;
-
- int64_t vm_clock_warp_start;
- int64_t cpu_clock_offset;
-
- /* Only written by TCG thread */
- int64_t qemu_icount;
-
- /* for adjusting icount */
- QEMUTimer *icount_rt_timer;
- QEMUTimer *icount_vm_timer;
- QEMUTimer *icount_warp_timer;
-} TimersState;
-
-extern TimersState timers_state;
-
-/*
- * icount needs this internal from cpu-timers when adjusting the icount shift.
- */
-int64_t cpu_get_clock_locked(void);
-
-#endif /* TIMERS_STATE_H */
+++ /dev/null
-/*
- * CPU timers state API
- *
- * Copyright 2020 SUSE LLC
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-#ifndef SYSEMU_CPU_TIMERS_H
-#define SYSEMU_CPU_TIMERS_H
-
-#include "qemu/timer.h"
-
-/* init the whole cpu timers API, including icount, ticks, and cpu_throttle */
-void cpu_timers_init(void);
-
-/* icount - Instruction Counter API */
-
-/**
- * ICountMode: icount enablement state:
- *
- * @ICOUNT_DISABLED: Disabled - Do not count executed instructions.
- * @ICOUNT_PRECISE: Enabled - Fixed conversion of insn to ns via "shift" option
- * @ICOUNT_ADAPTATIVE: Enabled - Runtime adaptive algorithm to compute shift
- */
-typedef enum {
- ICOUNT_DISABLED = 0,
- ICOUNT_PRECISE,
- ICOUNT_ADAPTATIVE,
-} ICountMode;
-
-#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
-extern ICountMode use_icount;
-#define icount_enabled() (use_icount)
-#else
-#define icount_enabled() ICOUNT_DISABLED
-#endif
-
-/*
- * Update the icount with the executed instructions. Called by
- * cpus-tcg vCPU thread so the main-loop can see time has moved forward.
- */
-void icount_update(CPUState *cpu);
-
-/* get raw icount value */
-int64_t icount_get_raw(void);
-
-/* return the virtual CPU time in ns, based on the instruction counter. */
-int64_t icount_get(void);
-/*
- * convert an instruction counter value to ns, based on the icount shift.
- * This shift is set as a fixed value with the icount "shift" option
- * (precise mode), or it is constantly approximated and corrected at
- * runtime in adaptive mode.
- */
-int64_t icount_to_ns(int64_t icount);
-
-/**
- * icount_configure: configure the icount options, including "shift"
- * @opts: Options to parse
- * @errp: pointer to a NULL-initialized error object
- *
- * Return: true on success, else false setting @errp with error
- */
-bool icount_configure(QemuOpts *opts, Error **errp);
-
-/* used by tcg vcpu thread to calc icount budget */
-int64_t icount_round(int64_t count);
-
-/* if the CPUs are idle, start accounting real time to virtual clock. */
-void icount_start_warp_timer(void);
-void icount_account_warp_timer(void);
-void icount_notify_exit(void);
-
-/*
- * CPU Ticks and Clock
- */
-
-/* Caller must hold BQL */
-void cpu_enable_ticks(void);
-/* Caller must hold BQL */
-void cpu_disable_ticks(void);
-
-/*
- * return the time elapsed in VM between vm_start and vm_stop.
- * cpu_get_ticks() uses units of the host CPU cycle counter.
- */
-int64_t cpu_get_ticks(void);
-
-/*
- * Returns the monotonic time elapsed in VM, i.e.,
- * the time between vm_start and vm_stop
- */
-int64_t cpu_get_clock(void);
-
-void qemu_timer_notify_cb(void *opaque, QEMUClockType type);
-
-/* get/set VIRTUAL clock and VM elapsed ticks via the cpus accel interface */
-int64_t cpus_get_virtual_clock(void);
-void cpus_set_virtual_clock(int64_t new_time);
-int64_t cpus_get_elapsed_ticks(void);
-
-#endif /* SYSEMU_CPU_TIMERS_H */
+++ /dev/null
-#ifndef QEMU_CPUS_H
-#define QEMU_CPUS_H
-
-#include "sysemu/accel-ops.h"
-
-/* register accel-specific operations */
-void cpus_register_accel(const AccelOpsClass *i);
-
-/* return registers ops */
-const AccelOpsClass *cpus_get_accel(void);
-
-/* accel/dummy-cpus.c */
-
-/* Create a dummy vcpu for AccelOpsClass->create_vcpu_thread */
-void dummy_start_vcpu_thread(CPUState *);
-
-/* interface available for cpus accelerator threads */
-
-/* For temporary buffers for forming a name */
-#define VCPU_THREAD_NAME_SIZE 16
-
-void cpus_kick_thread(CPUState *cpu);
-bool cpu_work_list_empty(CPUState *cpu);
-bool cpu_thread_is_idle(CPUState *cpu);
-bool all_cpu_threads_idle(void);
-bool cpu_can_run(CPUState *cpu);
-void qemu_wait_io_event_common(CPUState *cpu);
-void qemu_wait_io_event(CPUState *cpu);
-void cpu_thread_signal_created(CPUState *cpu);
-void cpu_thread_signal_destroyed(CPUState *cpu);
-void cpu_handle_guest_debug(CPUState *cpu);
-
-/* end interface for cpus accelerator threads */
-
-bool qemu_in_vcpu_thread(void);
-void qemu_init_cpu_loop(void);
-void resume_all_vcpus(void);
-void pause_all_vcpus(void);
-void cpu_stop_current(void);
-
-extern int icount_align_option;
-
-/* Unblock cpu */
-void qemu_cpu_kick_self(void);
-
-bool cpus_are_resettable(void);
-
-void cpu_synchronize_all_states(void);
-void cpu_synchronize_all_post_reset(void);
-void cpu_synchronize_all_post_init(void);
-void cpu_synchronize_all_pre_loadvm(void);
-
-#endif
+++ /dev/null
-/*
- * QEMU Crypto Device Common Vhost User Implement
- *
- * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
- *
- * Authors:
- * Gonglei <arei.gonglei@huawei.com>
- *
- * 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.1 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/>.
- *
- */
-
-#ifndef CRYPTODEV_VHOST_USER_H
-#define CRYPTODEV_VHOST_USER_H
-
-#include "sysemu/cryptodev-vhost.h"
-
-#define VHOST_USER_MAX_AUTH_KEY_LEN 512
-#define VHOST_USER_MAX_CIPHER_KEY_LEN 64
-
-
-/**
- * cryptodev_vhost_user_get_vhost:
- * @cc: the client object for each queue
- * @b: the cryptodev backend common vhost object
- * @queue: the queue index
- *
- * Gets a new cryptodev backend common vhost object based on
- * @b and @queue
- *
- * Returns: the cryptodev backend common vhost object
- */
-CryptoDevBackendVhost *
-cryptodev_vhost_user_get_vhost(
- CryptoDevBackendClient *cc,
- CryptoDevBackend *b,
- uint16_t queue);
-
-#endif /* CRYPTODEV_VHOST_USER_H */
+++ /dev/null
-/*
- * QEMU Crypto Device Common Vhost Implement
- *
- * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
- *
- * Authors:
- * Gonglei <arei.gonglei@huawei.com>
- * Jay Zhou <jianjay.zhou@huawei.com>
- *
- * 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.1 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/>.
- *
- */
-#ifndef CRYPTODEV_VHOST_H
-#define CRYPTODEV_VHOST_H
-
-#include "hw/virtio/vhost.h"
-#include "hw/virtio/vhost-backend.h"
-#include "chardev/char.h"
-
-#include "sysemu/cryptodev.h"
-
-
-typedef struct CryptoDevBackendVhostOptions {
- VhostBackendType backend_type;
- void *opaque;
- int total_queues;
- CryptoDevBackendClient *cc;
-} CryptoDevBackendVhostOptions;
-
-typedef struct CryptoDevBackendVhost {
- struct vhost_dev dev;
- struct vhost_virtqueue vqs[1];
- int backend;
- CryptoDevBackendClient *cc;
-} CryptoDevBackendVhost;
-
-/**
- * cryptodev_vhost_get_max_queues:
- * @crypto: the cryptodev backend common vhost object
- *
- * Get the maximum queue number of @crypto.
- *
- *
- * Returns: the maximum queue number
- */
-uint64_t
-cryptodev_vhost_get_max_queues(
- CryptoDevBackendVhost *crypto);
-
-
-/**
- * cryptodev_vhost_init:
- * @options: the common vhost object's option
- *
- * Creates a new cryptodev backend common vhost object
- *
- ** The returned object must be released with
- * cryptodev_vhost_cleanup() when no
- * longer required
- *
- * Returns: the cryptodev backend common vhost object
- */
-struct CryptoDevBackendVhost *
-cryptodev_vhost_init(
- CryptoDevBackendVhostOptions *options);
-
-/**
- * cryptodev_vhost_cleanup:
- * @crypto: the cryptodev backend common vhost object
- *
- * Clean the resource associated with @crypto that realizaed
- * by cryptodev_vhost_init()
- *
- */
-void cryptodev_vhost_cleanup(
- CryptoDevBackendVhost *crypto);
-
-/**
- * cryptodev_get_vhost:
- * @cc: the client object for each queue
- * @b: the cryptodev backend common vhost object
- * @queue: the cryptodev backend queue index
- *
- * Gets a new cryptodev backend common vhost object based on
- * @b and @queue
- *
- * Returns: the cryptodev backend common vhost object
- */
-CryptoDevBackendVhost *
-cryptodev_get_vhost(CryptoDevBackendClient *cc,
- CryptoDevBackend *b,
- uint16_t queue);
-/**
- * cryptodev_vhost_start:
- * @dev: the virtio crypto object
- * @total_queues: the total count of queue
- *
- * Starts the vhost crypto logic
- *
- * Returns: 0 for success, negative for errors
- */
-int cryptodev_vhost_start(VirtIODevice *dev, int total_queues);
-
-/**
- * cryptodev_vhost_stop:
- * @dev: the virtio crypto object
- * @total_queues: the total count of queue
- *
- * Stops the vhost crypto logic
- *
- */
-void cryptodev_vhost_stop(VirtIODevice *dev, int total_queues);
-
-/**
- * cryptodev_vhost_virtqueue_mask:
- * @dev: the virtio crypto object
- * @queue: the cryptodev backend queue index
- * @idx: the virtqueue index
- * @mask: mask or not (true or false)
- *
- * Mask/unmask events for @idx virtqueue on @dev device
- *
- */
-void cryptodev_vhost_virtqueue_mask(VirtIODevice *dev,
- int queue,
- int idx, bool mask);
-
-/**
- * cryptodev_vhost_virtqueue_pending:
- * @dev: the virtio crypto object
- * @queue: the cryptodev backend queue index
- * @idx: the virtqueue index
- *
- * Test and clear event pending status for @idx virtqueue on @dev device.
- * Should be called after unmask to avoid losing events.
- *
- * Returns: true for success, false for errors
- */
-bool cryptodev_vhost_virtqueue_pending(VirtIODevice *dev,
- int queue, int idx);
-
-#endif /* CRYPTODEV_VHOST_H */
+++ /dev/null
-/*
- * QEMU Crypto Device Implementation
- *
- * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
- *
- * Authors:
- * Gonglei <arei.gonglei@huawei.com>
- *
- * 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.1 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/>.
- *
- */
-#ifndef CRYPTODEV_H
-#define CRYPTODEV_H
-
-#include "qemu/queue.h"
-#include "qemu/throttle.h"
-#include "qom/object.h"
-#include "qapi/qapi-types-cryptodev.h"
-
-/**
- * CryptoDevBackend:
- *
- * The CryptoDevBackend object is an interface
- * for different cryptodev backends, which provides crypto
- * operation wrapper.
- *
- */
-
-#define TYPE_CRYPTODEV_BACKEND "cryptodev-backend"
-
-OBJECT_DECLARE_TYPE(CryptoDevBackend, CryptoDevBackendClass,
- CRYPTODEV_BACKEND)
-
-
-#define MAX_CRYPTO_QUEUE_NUM 64
-
-typedef struct CryptoDevBackendConf CryptoDevBackendConf;
-typedef struct CryptoDevBackendPeers CryptoDevBackendPeers;
-typedef struct CryptoDevBackendClient
- CryptoDevBackendClient;
-
-/**
- * CryptoDevBackendSymSessionInfo:
- *
- * @cipher_alg: algorithm type of CIPHER
- * @key_len: byte length of cipher key
- * @hash_alg: algorithm type of HASH/MAC
- * @hash_result_len: byte length of HASH operation result
- * @auth_key_len: byte length of authenticated key
- * @add_len: byte length of additional authenticated data
- * @op_type: operation type (refer to virtio_crypto.h)
- * @direction: encryption or direction for CIPHER
- * @hash_mode: HASH mode for HASH operation (refer to virtio_crypto.h)
- * @alg_chain_order: order of algorithm chaining (CIPHER then HASH,
- * or HASH then CIPHER)
- * @cipher_key: point to a key of CIPHER
- * @auth_key: point to an authenticated key of MAC
- *
- */
-typedef struct CryptoDevBackendSymSessionInfo {
- /* corresponding with virtio crypto spec */
- uint32_t cipher_alg;
- uint32_t key_len;
- uint32_t hash_alg;
- uint32_t hash_result_len;
- uint32_t auth_key_len;
- uint32_t add_len;
- uint8_t op_type;
- uint8_t direction;
- uint8_t hash_mode;
- uint8_t alg_chain_order;
- uint8_t *cipher_key;
- uint8_t *auth_key;
-} CryptoDevBackendSymSessionInfo;
-
-/**
- * CryptoDevBackendAsymSessionInfo:
- */
-typedef struct CryptoDevBackendRsaPara {
- uint32_t padding_algo;
- uint32_t hash_algo;
-} CryptoDevBackendRsaPara;
-
-typedef struct CryptoDevBackendAsymSessionInfo {
- /* corresponding with virtio crypto spec */
- uint32_t algo;
- uint32_t keytype;
- uint32_t keylen;
- uint8_t *key;
- union {
- CryptoDevBackendRsaPara rsa;
- } u;
-} CryptoDevBackendAsymSessionInfo;
-
-typedef struct CryptoDevBackendSessionInfo {
- uint32_t op_code;
- union {
- CryptoDevBackendSymSessionInfo sym_sess_info;
- CryptoDevBackendAsymSessionInfo asym_sess_info;
- } u;
- uint64_t session_id;
-} CryptoDevBackendSessionInfo;
-
-/**
- * CryptoDevBackendSymOpInfo:
- *
- * @aad_len: byte length of additional authenticated data
- * @iv_len: byte length of initialization vector or counter
- * @src_len: byte length of source data
- * @dst_len: byte length of destination data
- * @digest_result_len: byte length of hash digest result
- * @hash_start_src_offset: Starting point for hash processing, specified
- * as number of bytes from start of packet in source data, only used for
- * algorithm chain
- * @cipher_start_src_offset: Starting point for cipher processing, specified
- * as number of bytes from start of packet in source data, only used for
- * algorithm chain
- * @len_to_hash: byte length of source data on which the hash
- * operation will be computed, only used for algorithm chain
- * @len_to_cipher: byte length of source data on which the cipher
- * operation will be computed, only used for algorithm chain
- * @op_type: operation type (refer to virtio_crypto.h)
- * @iv: point to the initialization vector or counter
- * @src: point to the source data
- * @dst: point to the destination data
- * @aad_data: point to the additional authenticated data
- * @digest_result: point to the digest result data
- * @data[0]: point to the extensional memory by one memory allocation
- *
- */
-typedef struct CryptoDevBackendSymOpInfo {
- uint32_t aad_len;
- uint32_t iv_len;
- uint32_t src_len;
- uint32_t dst_len;
- uint32_t digest_result_len;
- uint32_t hash_start_src_offset;
- uint32_t cipher_start_src_offset;
- uint32_t len_to_hash;
- uint32_t len_to_cipher;
- uint8_t op_type;
- uint8_t *iv;
- uint8_t *src;
- uint8_t *dst;
- uint8_t *aad_data;
- uint8_t *digest_result;
- uint8_t data[];
-} CryptoDevBackendSymOpInfo;
-
-
-/**
- * CryptoDevBackendAsymOpInfo:
- *
- * @src_len: byte length of source data
- * @dst_len: byte length of destination data
- * @src: point to the source data
- * @dst: point to the destination data
- *
- */
-typedef struct CryptoDevBackendAsymOpInfo {
- uint32_t src_len;
- uint32_t dst_len;
- uint8_t *src;
- uint8_t *dst;
-} CryptoDevBackendAsymOpInfo;
-
-typedef void (*CryptoDevCompletionFunc) (void *opaque, int ret);
-
-typedef struct CryptoDevBackendOpInfo {
- QCryptodevBackendAlgoType algtype;
- uint32_t op_code;
- uint32_t queue_index;
- CryptoDevCompletionFunc cb;
- void *opaque; /* argument for cb */
- uint64_t session_id;
- union {
- CryptoDevBackendSymOpInfo *sym_op_info;
- CryptoDevBackendAsymOpInfo *asym_op_info;
- } u;
- QTAILQ_ENTRY(CryptoDevBackendOpInfo) next;
-} CryptoDevBackendOpInfo;
-
-struct CryptoDevBackendClass {
- ObjectClass parent_class;
-
- void (*init)(CryptoDevBackend *backend, Error **errp);
- void (*cleanup)(CryptoDevBackend *backend, Error **errp);
-
- int (*create_session)(CryptoDevBackend *backend,
- CryptoDevBackendSessionInfo *sess_info,
- uint32_t queue_index,
- CryptoDevCompletionFunc cb,
- void *opaque);
-
- int (*close_session)(CryptoDevBackend *backend,
- uint64_t session_id,
- uint32_t queue_index,
- CryptoDevCompletionFunc cb,
- void *opaque);
-
- int (*do_op)(CryptoDevBackend *backend,
- CryptoDevBackendOpInfo *op_info);
-};
-
-struct CryptoDevBackendClient {
- QCryptodevBackendType type;
- char *info_str;
- unsigned int queue_index;
- int vring_enable;
- QTAILQ_ENTRY(CryptoDevBackendClient) next;
-};
-
-struct CryptoDevBackendPeers {
- CryptoDevBackendClient *ccs[MAX_CRYPTO_QUEUE_NUM];
- uint32_t queues;
-};
-
-struct CryptoDevBackendConf {
- CryptoDevBackendPeers peers;
-
- /* Supported service mask */
- uint32_t crypto_services;
-
- /* Detailed algorithms mask */
- uint32_t cipher_algo_l;
- uint32_t cipher_algo_h;
- uint32_t hash_algo;
- uint32_t mac_algo_l;
- uint32_t mac_algo_h;
- uint32_t aead_algo;
- uint32_t akcipher_algo;
- /* Maximum length of cipher key */
- uint32_t max_cipher_key_len;
- /* Maximum length of authenticated key */
- uint32_t max_auth_key_len;
- /* Maximum size of each crypto request's content */
- uint64_t max_size;
-};
-
-typedef struct CryptodevBackendSymStat {
- int64_t encrypt_ops;
- int64_t decrypt_ops;
- int64_t encrypt_bytes;
- int64_t decrypt_bytes;
-} CryptodevBackendSymStat;
-
-typedef struct CryptodevBackendAsymStat {
- int64_t encrypt_ops;
- int64_t decrypt_ops;
- int64_t sign_ops;
- int64_t verify_ops;
- int64_t encrypt_bytes;
- int64_t decrypt_bytes;
- int64_t sign_bytes;
- int64_t verify_bytes;
-} CryptodevBackendAsymStat;
-
-struct CryptoDevBackend {
- Object parent_obj;
-
- bool ready;
- /* Tag the cryptodev backend is used by virtio-crypto or not */
- bool is_used;
- CryptoDevBackendConf conf;
- CryptodevBackendSymStat *sym_stat;
- CryptodevBackendAsymStat *asym_stat;
-
- ThrottleState ts;
- ThrottleTimers tt;
- ThrottleConfig tc;
- QTAILQ_HEAD(, CryptoDevBackendOpInfo) opinfos;
-};
-
-#define CryptodevSymStatInc(be, op, bytes) do { \
- be->sym_stat->op##_bytes += (bytes); \
- be->sym_stat->op##_ops += 1; \
-} while (/*CONSTCOND*/0)
-
-#define CryptodevSymStatIncEncrypt(be, bytes) \
- CryptodevSymStatInc(be, encrypt, bytes)
-
-#define CryptodevSymStatIncDecrypt(be, bytes) \
- CryptodevSymStatInc(be, decrypt, bytes)
-
-#define CryptodevAsymStatInc(be, op, bytes) do { \
- be->asym_stat->op##_bytes += (bytes); \
- be->asym_stat->op##_ops += 1; \
-} while (/*CONSTCOND*/0)
-
-#define CryptodevAsymStatIncEncrypt(be, bytes) \
- CryptodevAsymStatInc(be, encrypt, bytes)
-
-#define CryptodevAsymStatIncDecrypt(be, bytes) \
- CryptodevAsymStatInc(be, decrypt, bytes)
-
-#define CryptodevAsymStatIncSign(be, bytes) \
- CryptodevAsymStatInc(be, sign, bytes)
-
-#define CryptodevAsymStatIncVerify(be, bytes) \
- CryptodevAsymStatInc(be, verify, bytes)
-
-
-/**
- * cryptodev_backend_new_client:
- *
- * Creates a new cryptodev backend client object.
- *
- * The returned object must be released with
- * cryptodev_backend_free_client() when no
- * longer required
- *
- * Returns: a new cryptodev backend client object
- */
-CryptoDevBackendClient *cryptodev_backend_new_client(void);
-
-/**
- * cryptodev_backend_free_client:
- * @cc: the cryptodev backend client object
- *
- * Release the memory associated with @cc that
- * was previously allocated by cryptodev_backend_new_client()
- */
-void cryptodev_backend_free_client(
- CryptoDevBackendClient *cc);
-
-/**
- * cryptodev_backend_cleanup:
- * @backend: the cryptodev backend object
- * @errp: pointer to a NULL-initialized error object
- *
- * Clean the resource associated with @backend that realizaed
- * by the specific backend's init() callback
- */
-void cryptodev_backend_cleanup(
- CryptoDevBackend *backend,
- Error **errp);
-
-/**
- * cryptodev_backend_create_session:
- * @backend: the cryptodev backend object
- * @sess_info: parameters needed by session creating
- * @queue_index: queue index of cryptodev backend client
- * @errp: pointer to a NULL-initialized error object
- * @cb: callback when session create is compeleted
- * @opaque: parameter passed to callback
- *
- * Create a session for symmetric/asymmetric algorithms
- *
- * Returns: 0 for success and cb will be called when creation is completed,
- * negative value for error, and cb will not be called.
- */
-int cryptodev_backend_create_session(
- CryptoDevBackend *backend,
- CryptoDevBackendSessionInfo *sess_info,
- uint32_t queue_index,
- CryptoDevCompletionFunc cb,
- void *opaque);
-
-/**
- * cryptodev_backend_close_session:
- * @backend: the cryptodev backend object
- * @session_id: the session id
- * @queue_index: queue index of cryptodev backend client
- * @errp: pointer to a NULL-initialized error object
- * @cb: callback when session create is compeleted
- * @opaque: parameter passed to callback
- *
- * Close a session for which was previously
- * created by cryptodev_backend_create_session()
- *
- * Returns: 0 for success and cb will be called when creation is completed,
- * negative value for error, and cb will not be called.
- */
-int cryptodev_backend_close_session(
- CryptoDevBackend *backend,
- uint64_t session_id,
- uint32_t queue_index,
- CryptoDevCompletionFunc cb,
- void *opaque);
-
-/**
- * cryptodev_backend_crypto_operation:
- * @backend: the cryptodev backend object
- * @op_info: pointer to a CryptoDevBackendOpInfo object
- *
- * Do crypto operation, such as encryption, decryption, signature and
- * verification
- *
- * Returns: 0 for success and cb will be called when creation is completed,
- * negative value for error, and cb will not be called.
- */
-int cryptodev_backend_crypto_operation(
- CryptoDevBackend *backend,
- CryptoDevBackendOpInfo *op_info);
-
-/**
- * cryptodev_backend_set_used:
- * @backend: the cryptodev backend object
- * @used: true or false
- *
- * Set the cryptodev backend is used by virtio-crypto or not
- */
-void cryptodev_backend_set_used(CryptoDevBackend *backend, bool used);
-
-/**
- * cryptodev_backend_is_used:
- * @backend: the cryptodev backend object
- *
- * Return the status that the cryptodev backend is used
- * by virtio-crypto or not
- *
- * Returns: true on used, or false on not used
- */
-bool cryptodev_backend_is_used(CryptoDevBackend *backend);
-
-/**
- * cryptodev_backend_set_ready:
- * @backend: the cryptodev backend object
- * @ready: true or false
- *
- * Set the cryptodev backend is ready or not, which is called
- * by the children of the cryptodev banckend interface.
- */
-void cryptodev_backend_set_ready(CryptoDevBackend *backend, bool ready);
-
-/**
- * cryptodev_backend_is_ready:
- * @backend: the cryptodev backend object
- *
- * Return the status that the cryptodev backend is ready or not
- *
- * Returns: true on ready, or false on not ready
- */
-bool cryptodev_backend_is_ready(CryptoDevBackend *backend);
-
-#endif /* CRYPTODEV_H */
+++ /dev/null
-/*
- * Header with function prototypes to help device tree manipulation using
- * libfdt. It also provides functions to read entries from device tree proc
- * interface.
- *
- * Copyright 2008 IBM Corporation.
- * Authors: Jerone Young <jyoung5@us.ibm.com>
- * Hollis Blanchard <hollisb@us.ibm.com>
- *
- * This work is licensed under the GNU GPL license version 2 or later.
- *
- */
-
-#ifndef DEVICE_TREE_H
-#define DEVICE_TREE_H
-
-void *create_device_tree(int *sizep);
-void *load_device_tree(const char *filename_path, int *sizep);
-#ifdef CONFIG_LINUX
-/**
- * load_device_tree_from_sysfs: reads the device tree information in the
- * /proc/device-tree directory and return the corresponding binary blob
- * buffer pointer. Asserts in case of error.
- */
-void *load_device_tree_from_sysfs(void);
-#endif
-
-/**
- * qemu_fdt_node_path: return the paths of nodes matching a given
- * name and compat string
- * @fdt: pointer to the dt blob
- * @name: node name
- * @compat: compatibility string
- * @errp: handle to an error object
- *
- * returns a newly allocated NULL-terminated array of node paths.
- * Use g_strfreev() to free it. If one or more nodes were found, the
- * array contains the path of each node and the last element equals to
- * NULL. If there is no error but no matching node was found, the
- * returned array contains a single element equal to NULL. If an error
- * was encountered when parsing the blob, the function returns NULL
- *
- * @name may be NULL to wildcard names and only match compatibility
- * strings.
- */
-char **qemu_fdt_node_path(void *fdt, const char *name, const char *compat,
- Error **errp);
-
-/**
- * qemu_fdt_node_unit_path: return the paths of nodes matching a given
- * node-name, ie. node-name and node-name@unit-address
- * @fdt: pointer to the dt blob
- * @name: node name
- * @errp: handle to an error object
- *
- * returns a newly allocated NULL-terminated array of node paths.
- * Use g_strfreev() to free it. If one or more nodes were found, the
- * array contains the path of each node and the last element equals to
- * NULL. If there is no error but no matching node was found, the
- * returned array contains a single element equal to NULL. If an error
- * was encountered when parsing the blob, the function returns NULL
- */
-char **qemu_fdt_node_unit_path(void *fdt, const char *name, Error **errp);
-
-int qemu_fdt_setprop(void *fdt, const char *node_path,
- const char *property, const void *val, int size);
-int qemu_fdt_setprop_cell(void *fdt, const char *node_path,
- const char *property, uint32_t val);
-int qemu_fdt_setprop_u64(void *fdt, const char *node_path,
- const char *property, uint64_t val);
-int qemu_fdt_setprop_string(void *fdt, const char *node_path,
- const char *property, const char *string);
-
-/**
- * qemu_fdt_setprop_string_array: set a string array property
- *
- * @fdt: pointer to the dt blob
- * @name: node name
- * @prop: property array
- * @array: pointer to an array of string pointers
- * @len: length of array
- *
- * assigns a string array to a property. This function converts and
- * array of strings to a sequential string with \0 separators before
- * setting the property.
- */
-int qemu_fdt_setprop_string_array(void *fdt, const char *node_path,
- const char *prop, char **array, int len);
-
-int qemu_fdt_setprop_phandle(void *fdt, const char *node_path,
- const char *property,
- const char *target_node_path);
-/**
- * qemu_fdt_getprop: retrieve the value of a given property
- * @fdt: pointer to the device tree blob
- * @node_path: node path
- * @property: name of the property to find
- * @lenp: fdt error if any or length of the property on success
- * @errp: handle to an error object
- *
- * returns a pointer to the property on success and NULL on failure
- */
-const void *qemu_fdt_getprop(void *fdt, const char *node_path,
- const char *property, int *lenp,
- Error **errp);
-/**
- * qemu_fdt_getprop_cell: retrieve the value of a given 4 byte property
- * @fdt: pointer to the device tree blob
- * @node_path: node path
- * @property: name of the property to find
- * @lenp: fdt error if any or -EINVAL if the property size is different from
- * 4 bytes, or 4 (expected length of the property) upon success.
- * @errp: handle to an error object
- *
- * returns the property value on success
- */
-uint32_t qemu_fdt_getprop_cell(void *fdt, const char *node_path,
- const char *property, int *lenp,
- Error **errp);
-uint32_t qemu_fdt_get_phandle(void *fdt, const char *path);
-uint32_t qemu_fdt_alloc_phandle(void *fdt);
-int qemu_fdt_nop_node(void *fdt, const char *node_path);
-int qemu_fdt_add_subnode(void *fdt, const char *name);
-int qemu_fdt_add_path(void *fdt, const char *path);
-
-#define qemu_fdt_setprop_cells(fdt, node_path, property, ...) \
- do { \
- uint32_t qdt_tmp[] = { __VA_ARGS__ }; \
- for (unsigned i_ = 0; i_ < ARRAY_SIZE(qdt_tmp); i_++) { \
- qdt_tmp[i_] = cpu_to_be32(qdt_tmp[i_]); \
- } \
- qemu_fdt_setprop(fdt, node_path, property, qdt_tmp, \
- sizeof(qdt_tmp)); \
- } while (0)
-
-void qemu_fdt_dumpdtb(void *fdt, int size);
-
-/**
- * qemu_fdt_setprop_sized_cells_from_array:
- * @fdt: device tree blob
- * @node_path: node to set property on
- * @property: property to set
- * @numvalues: number of values
- * @values: array of number-of-cells, value pairs
- *
- * Set the specified property on the specified node in the device tree
- * to be an array of cells. The values of the cells are specified via
- * the values list, which alternates between "number of cells used by
- * this value" and "value".
- * number-of-cells must be either 1 or 2 (other values will result in
- * an error being returned). If a value is too large to fit in the
- * number of cells specified for it, an error is returned.
- *
- * This function is useful because device tree nodes often have cell arrays
- * which are either lists of addresses or lists of address,size tuples, but
- * the number of cells used for each element vary depending on the
- * #address-cells and #size-cells properties of their parent node.
- * If you know all your cell elements are one cell wide you can use the
- * simpler qemu_fdt_setprop_cells(). If you're not setting up the
- * array programmatically, qemu_fdt_setprop_sized_cells may be more
- * convenient.
- *
- * Return value: 0 on success, <0 on error.
- */
-int qemu_fdt_setprop_sized_cells_from_array(void *fdt,
- const char *node_path,
- const char *property,
- int numvalues,
- uint64_t *values);
-
-/**
- * qemu_fdt_setprop_sized_cells:
- * @fdt: device tree blob
- * @node_path: node to set property on
- * @property: property to set
- * @...: list of number-of-cells, value pairs
- *
- * Set the specified property on the specified node in the device tree
- * to be an array of cells. The values of the cells are specified via
- * the variable arguments, which alternates between "number of cells
- * used by this value" and "value".
- *
- * This is a convenience wrapper for the function
- * qemu_fdt_setprop_sized_cells_from_array().
- *
- * Return value: 0 on success, <0 on error.
- */
-#define qemu_fdt_setprop_sized_cells(fdt, node_path, property, ...) \
- ({ \
- uint64_t qdt_tmp[] = { __VA_ARGS__ }; \
- qemu_fdt_setprop_sized_cells_from_array(fdt, node_path, \
- property, \
- ARRAY_SIZE(qdt_tmp) / 2, \
- qdt_tmp); \
- })
-
-
-/**
- * qemu_fdt_randomize_seeds:
- * @fdt: device tree blob
- *
- * Re-randomize all "rng-seed" properties with new seeds.
- */
-void qemu_fdt_randomize_seeds(void *fdt);
-
-#define FDT_PCI_RANGE_RELOCATABLE 0x80000000
-#define FDT_PCI_RANGE_PREFETCHABLE 0x40000000
-#define FDT_PCI_RANGE_ALIASED 0x20000000
-#define FDT_PCI_RANGE_TYPE_MASK 0x03000000
-#define FDT_PCI_RANGE_MMIO_64BIT 0x03000000
-#define FDT_PCI_RANGE_MMIO 0x02000000
-#define FDT_PCI_RANGE_IOPORT 0x01000000
-#define FDT_PCI_RANGE_CONFIG 0x00000000
-
-#endif /* DEVICE_TREE_H */
+++ /dev/null
-/*
- * Dirty page rate limit common functions
- *
- * Copyright (c) 2022 CHINA TELECOM CO.,LTD.
- *
- * Authors:
- * Hyman Huang(黄勇) <huangy81@chinatelecom.cn>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-#ifndef QEMU_DIRTYRLIMIT_H
-#define QEMU_DIRTYRLIMIT_H
-
-#define DIRTYLIMIT_CALC_TIME_MS 1000 /* 1000ms */
-
-int64_t vcpu_dirty_rate_get(int cpu_index);
-void vcpu_dirty_rate_stat_start(void);
-void vcpu_dirty_rate_stat_stop(void);
-void vcpu_dirty_rate_stat_initialize(void);
-void vcpu_dirty_rate_stat_finalize(void);
-
-void dirtylimit_state_lock(void);
-void dirtylimit_state_unlock(void);
-void dirtylimit_state_initialize(void);
-void dirtylimit_state_finalize(void);
-bool dirtylimit_in_service(void);
-bool dirtylimit_vcpu_index_valid(int cpu_index);
-void dirtylimit_process(void);
-void dirtylimit_change(bool start);
-void dirtylimit_set_vcpu(int cpu_index,
- uint64_t quota,
- bool enable);
-void dirtylimit_set_all(uint64_t quota,
- bool enable);
-void dirtylimit_vcpu_execute(CPUState *cpu);
-uint64_t dirtylimit_throttle_time_per_round(void);
-uint64_t dirtylimit_ring_full_time(void);
-#endif
+++ /dev/null
-/*
- * dirty page rate helper functions
- *
- * Copyright (c) 2022 CHINA TELECOM CO.,LTD.
- *
- * Authors:
- * Hyman Huang(黄勇) <huangy81@chinatelecom.cn>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef QEMU_DIRTYRATE_H
-#define QEMU_DIRTYRATE_H
-
-#include "qapi/qapi-types-migration.h"
-
-typedef struct VcpuStat {
- int nvcpu; /* number of vcpu */
- DirtyRateVcpu *rates; /* array of dirty rate for each vcpu */
-} VcpuStat;
-
-int64_t vcpu_calculate_dirtyrate(int64_t calc_time_ms,
- VcpuStat *stat,
- unsigned int flag,
- bool one_shot);
-
-void global_dirty_log_change(unsigned int flag,
- bool start);
-#endif
+++ /dev/null
-/*
- * DMA helper functions
- *
- * Copyright (c) 2009, 2020 Red Hat
- *
- * This work is licensed under the terms of the GNU General Public License
- * (GNU GPL), version 2 or later.
- */
-
-#ifndef DMA_H
-#define DMA_H
-
-#include "exec/memory.h"
-#include "exec/address-spaces.h"
-#include "block/block.h"
-#include "block/accounting.h"
-
-typedef enum {
- DMA_DIRECTION_TO_DEVICE = 0,
- DMA_DIRECTION_FROM_DEVICE = 1,
-} DMADirection;
-
-/*
- * When an IOMMU is present, bus addresses become distinct from
- * CPU/memory physical addresses and may be a different size. Because
- * the IOVA size depends more on the bus than on the platform, we more
- * or less have to treat these as 64-bit always to cover all (or at
- * least most) cases.
- */
-typedef uint64_t dma_addr_t;
-
-#define DMA_ADDR_BITS 64
-#define DMA_ADDR_FMT "%" PRIx64
-
-typedef struct ScatterGatherEntry ScatterGatherEntry;
-
-struct QEMUSGList {
- ScatterGatherEntry *sg;
- int nsg;
- int nalloc;
- dma_addr_t size;
- DeviceState *dev;
- AddressSpace *as;
-};
-
-static inline void dma_barrier(AddressSpace *as, DMADirection dir)
-{
- /*
- * This is called before DMA read and write operations
- * unless the _relaxed form is used and is responsible
- * for providing some sane ordering of accesses vs
- * concurrently running VCPUs.
- *
- * Users of map(), unmap() or lower level st/ld_*
- * operations are responsible for providing their own
- * ordering via barriers.
- *
- * This primitive implementation does a simple smp_mb()
- * before each operation which provides pretty much full
- * ordering.
- *
- * A smarter implementation can be devised if needed to
- * use lighter barriers based on the direction of the
- * transfer, the DMA context, etc...
- */
- smp_mb();
-}
-
-/* Checks that the given range of addresses is valid for DMA. This is
- * useful for certain cases, but usually you should just use
- * dma_memory_{read,write}() and check for errors */
-static inline bool dma_memory_valid(AddressSpace *as,
- dma_addr_t addr, dma_addr_t len,
- DMADirection dir, MemTxAttrs attrs)
-{
- return address_space_access_valid(as, addr, len,
- dir == DMA_DIRECTION_FROM_DEVICE,
- attrs);
-}
-
-static inline MemTxResult dma_memory_rw_relaxed(AddressSpace *as,
- dma_addr_t addr,
- void *buf, dma_addr_t len,
- DMADirection dir,
- MemTxAttrs attrs)
-{
- return address_space_rw(as, addr, attrs,
- buf, len, dir == DMA_DIRECTION_FROM_DEVICE);
-}
-
-static inline MemTxResult dma_memory_read_relaxed(AddressSpace *as,
- dma_addr_t addr,
- void *buf, dma_addr_t len)
-{
- return dma_memory_rw_relaxed(as, addr, buf, len,
- DMA_DIRECTION_TO_DEVICE,
- MEMTXATTRS_UNSPECIFIED);
-}
-
-static inline MemTxResult dma_memory_write_relaxed(AddressSpace *as,
- dma_addr_t addr,
- const void *buf,
- dma_addr_t len)
-{
- return dma_memory_rw_relaxed(as, addr, (void *)buf, len,
- DMA_DIRECTION_FROM_DEVICE,
- MEMTXATTRS_UNSPECIFIED);
-}
-
-/**
- * dma_memory_rw: Read from or write to an address space from DMA controller.
- *
- * Return a MemTxResult indicating whether the operation succeeded
- * or failed (eg unassigned memory, device rejected the transaction,
- * IOMMU fault).
- *
- * @as: #AddressSpace to be accessed
- * @addr: address within that address space
- * @buf: buffer with the data transferred
- * @len: the number of bytes to read or write
- * @dir: indicates the transfer direction
- * @attrs: memory transaction attributes
- */
-static inline MemTxResult dma_memory_rw(AddressSpace *as, dma_addr_t addr,
- void *buf, dma_addr_t len,
- DMADirection dir, MemTxAttrs attrs)
-{
- dma_barrier(as, dir);
-
- return dma_memory_rw_relaxed(as, addr, buf, len, dir, attrs);
-}
-
-/**
- * dma_memory_read: Read from an address space from DMA controller.
- *
- * Return a MemTxResult indicating whether the operation succeeded
- * or failed (eg unassigned memory, device rejected the transaction,
- * IOMMU fault). Called within RCU critical section.
- *
- * @as: #AddressSpace to be accessed
- * @addr: address within that address space
- * @buf: buffer with the data transferred
- * @len: length of the data transferred
- * @attrs: memory transaction attributes
- */
-static inline MemTxResult dma_memory_read(AddressSpace *as, dma_addr_t addr,
- void *buf, dma_addr_t len,
- MemTxAttrs attrs)
-{
- return dma_memory_rw(as, addr, buf, len,
- DMA_DIRECTION_TO_DEVICE, attrs);
-}
-
-/**
- * dma_memory_write: Write to address space from DMA controller.
- *
- * Return a MemTxResult indicating whether the operation succeeded
- * or failed (eg unassigned memory, device rejected the transaction,
- * IOMMU fault).
- *
- * @as: #AddressSpace to be accessed
- * @addr: address within that address space
- * @buf: buffer with the data transferred
- * @len: the number of bytes to write
- * @attrs: memory transaction attributes
- */
-static inline MemTxResult dma_memory_write(AddressSpace *as, dma_addr_t addr,
- const void *buf, dma_addr_t len,
- MemTxAttrs attrs)
-{
- return dma_memory_rw(as, addr, (void *)buf, len,
- DMA_DIRECTION_FROM_DEVICE, attrs);
-}
-
-/**
- * dma_memory_set: Fill memory with a constant byte from DMA controller.
- *
- * Return a MemTxResult indicating whether the operation succeeded
- * or failed (eg unassigned memory, device rejected the transaction,
- * IOMMU fault).
- *
- * @as: #AddressSpace to be accessed
- * @addr: address within that address space
- * @c: constant byte to fill the memory
- * @len: the number of bytes to fill with the constant byte
- * @attrs: memory transaction attributes
- */
-MemTxResult dma_memory_set(AddressSpace *as, dma_addr_t addr,
- uint8_t c, dma_addr_t len, MemTxAttrs attrs);
-
-/**
- * dma_memory_map: Map a physical memory region into a host virtual address.
- *
- * May map a subset of the requested range, given by and returned in @plen.
- * May return %NULL and set *@plen to zero(0), if resources needed to perform
- * the mapping are exhausted.
- * Use only for reads OR writes - not for read-modify-write operations.
- *
- * @as: #AddressSpace to be accessed
- * @addr: address within that address space
- * @len: pointer to length of buffer; updated on return
- * @dir: indicates the transfer direction
- * @attrs: memory attributes
- */
-static inline void *dma_memory_map(AddressSpace *as,
- dma_addr_t addr, dma_addr_t *len,
- DMADirection dir, MemTxAttrs attrs)
-{
- hwaddr xlen = *len;
- void *p;
-
- p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE,
- attrs);
- *len = xlen;
- return p;
-}
-
-/**
- * dma_memory_unmap: Unmaps a memory region previously mapped by dma_memory_map()
- *
- * Will also mark the memory as dirty if @dir == %DMA_DIRECTION_FROM_DEVICE.
- * @access_len gives the amount of memory that was actually read or written
- * by the caller.
- *
- * @as: #AddressSpace used
- * @buffer: host pointer as returned by dma_memory_map()
- * @len: buffer length as returned by dma_memory_map()
- * @dir: indicates the transfer direction
- * @access_len: amount of data actually transferred
- */
-static inline void dma_memory_unmap(AddressSpace *as,
- void *buffer, dma_addr_t len,
- DMADirection dir, dma_addr_t access_len)
-{
- address_space_unmap(as, buffer, (hwaddr)len,
- dir == DMA_DIRECTION_FROM_DEVICE, access_len);
-}
-
-#define DEFINE_LDST_DMA(_lname, _sname, _bits, _end) \
- static inline MemTxResult ld##_lname##_##_end##_dma(AddressSpace *as, \
- dma_addr_t addr, \
- uint##_bits##_t *pval, \
- MemTxAttrs attrs) \
- { \
- MemTxResult res = dma_memory_read(as, addr, pval, (_bits) / 8, attrs); \
- _end##_bits##_to_cpus(pval); \
- return res; \
- } \
- static inline MemTxResult st##_sname##_##_end##_dma(AddressSpace *as, \
- dma_addr_t addr, \
- uint##_bits##_t val, \
- MemTxAttrs attrs) \
- { \
- val = cpu_to_##_end##_bits(val); \
- return dma_memory_write(as, addr, &val, (_bits) / 8, attrs); \
- }
-
-static inline MemTxResult ldub_dma(AddressSpace *as, dma_addr_t addr,
- uint8_t *val, MemTxAttrs attrs)
-{
- return dma_memory_read(as, addr, val, 1, attrs);
-}
-
-static inline MemTxResult stb_dma(AddressSpace *as, dma_addr_t addr,
- uint8_t val, MemTxAttrs attrs)
-{
- return dma_memory_write(as, addr, &val, 1, attrs);
-}
-
-DEFINE_LDST_DMA(uw, w, 16, le);
-DEFINE_LDST_DMA(l, l, 32, le);
-DEFINE_LDST_DMA(q, q, 64, le);
-DEFINE_LDST_DMA(uw, w, 16, be);
-DEFINE_LDST_DMA(l, l, 32, be);
-DEFINE_LDST_DMA(q, q, 64, be);
-
-#undef DEFINE_LDST_DMA
-
-struct ScatterGatherEntry {
- dma_addr_t base;
- dma_addr_t len;
-};
-
-void qemu_sglist_init(QEMUSGList *qsg, DeviceState *dev, int alloc_hint,
- AddressSpace *as);
-void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len);
-void qemu_sglist_destroy(QEMUSGList *qsg);
-
-typedef BlockAIOCB *DMAIOFunc(int64_t offset, QEMUIOVector *iov,
- BlockCompletionFunc *cb, void *cb_opaque,
- void *opaque);
-
-BlockAIOCB *dma_blk_io(AioContext *ctx,
- QEMUSGList *sg, uint64_t offset, uint32_t align,
- DMAIOFunc *io_func, void *io_func_opaque,
- BlockCompletionFunc *cb, void *opaque, DMADirection dir);
-BlockAIOCB *dma_blk_read(BlockBackend *blk,
- QEMUSGList *sg, uint64_t offset, uint32_t align,
- BlockCompletionFunc *cb, void *opaque);
-BlockAIOCB *dma_blk_write(BlockBackend *blk,
- QEMUSGList *sg, uint64_t offset, uint32_t align,
- BlockCompletionFunc *cb, void *opaque);
-MemTxResult dma_buf_read(void *ptr, dma_addr_t len, dma_addr_t *residual,
- QEMUSGList *sg, MemTxAttrs attrs);
-MemTxResult dma_buf_write(void *ptr, dma_addr_t len, dma_addr_t *residual,
- QEMUSGList *sg, MemTxAttrs attrs);
-
-void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,
- QEMUSGList *sg, enum BlockAcctType type);
-
-/**
- * dma_aligned_pow2_mask: Return the address bit mask of the largest
- * power of 2 size less or equal than @end - @start + 1, aligned with @start,
- * and bounded by 1 << @max_addr_bits bits.
- *
- * @start: range start address
- * @end: range end address (greater than @start)
- * @max_addr_bits: max address bits (<= 64)
- */
-uint64_t dma_aligned_pow2_mask(uint64_t start, uint64_t end,
- int max_addr_bits);
-
-#endif
+++ /dev/null
-/*
- * QEMU dump
- *
- * Copyright Fujitsu, Corp. 2011, 2012
- *
- * Authors:
- * Wen Congyang <wency@cn.fujitsu.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#ifndef DUMP_ARCH_H
-#define DUMP_ARCH_H
-
-typedef struct ArchDumpInfo {
- int d_machine; /* Architecture */
- int d_endian; /* ELFDATA2LSB or ELFDATA2MSB */
- int d_class; /* ELFCLASS32 or ELFCLASS64 */
- uint32_t page_size; /* The target's page size. If it's variable and
- * unknown, then this should be the maximum. */
- uint64_t phys_base; /* The target's physmem base. */
- void (*arch_sections_add_fn)(DumpState *s);
- uint64_t (*arch_sections_write_hdr_fn)(DumpState *s, uint8_t *buff);
- int (*arch_sections_write_fn)(DumpState *s, uint8_t *buff);
- void (*arch_cleanup_fn)(DumpState *s);
-} ArchDumpInfo;
-
-struct GuestPhysBlockList; /* memory_mapping.h */
-int cpu_get_dump_info(ArchDumpInfo *info,
- const struct GuestPhysBlockList *guest_phys_blocks);
-ssize_t cpu_get_note_size(int class, int machine, int nr_cpus);
-
-#endif
+++ /dev/null
-/*
- * QEMU dump
- *
- * Copyright Fujitsu, Corp. 2011, 2012
- *
- * Authors:
- * Wen Congyang <wency@cn.fujitsu.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#ifndef DUMP_H
-#define DUMP_H
-
-#include "qapi/qapi-types-dump.h"
-#include "qemu/thread.h"
-
-#define MAKEDUMPFILE_SIGNATURE "makedumpfile"
-#define MAX_SIZE_MDF_HEADER (4096) /* max size of makedumpfile_header */
-#define TYPE_FLAT_HEADER (1) /* type of flattened format */
-#define VERSION_FLAT_HEADER (1) /* version of flattened format */
-#define END_FLAG_FLAT_HEADER (-1)
-
-#ifndef ARCH_PFN_OFFSET
-#define ARCH_PFN_OFFSET (0)
-#endif
-
-/*
- * flag for compressed format
- */
-#define DUMP_DH_COMPRESSED_ZLIB (0x1)
-#define DUMP_DH_COMPRESSED_LZO (0x2)
-#define DUMP_DH_COMPRESSED_SNAPPY (0x4)
-
-#define KDUMP_SIGNATURE "KDUMP "
-#define SIG_LEN (sizeof(KDUMP_SIGNATURE) - 1)
-#define DUMP_LEVEL (1)
-#define DISKDUMP_HEADER_BLOCKS (1)
-
-#include "sysemu/dump-arch.h"
-#include "sysemu/memory_mapping.h"
-
-typedef struct QEMU_PACKED MakedumpfileHeader {
- char signature[16]; /* = "makedumpfile" */
- int64_t type;
- int64_t version;
-} MakedumpfileHeader;
-
-typedef struct QEMU_PACKED MakedumpfileDataHeader {
- int64_t offset;
- int64_t buf_size;
-} MakedumpfileDataHeader;
-
-typedef struct QEMU_PACKED NewUtsname {
- char sysname[65];
- char nodename[65];
- char release[65];
- char version[65];
- char machine[65];
- char domainname[65];
-} NewUtsname;
-
-typedef struct QEMU_PACKED DiskDumpHeader32 {
- char signature[SIG_LEN]; /* = "KDUMP " */
- uint32_t header_version; /* Dump header version */
- NewUtsname utsname; /* copy of system_utsname */
- char timestamp[10]; /* Time stamp */
- uint32_t status; /* Above flags */
- uint32_t block_size; /* Size of a block in byte */
- uint32_t sub_hdr_size; /* Size of arch dependent header in block */
- uint32_t bitmap_blocks; /* Size of Memory bitmap in block */
- uint32_t max_mapnr; /* = max_mapnr ,
- obsoleted in header_version 6 */
- uint32_t total_ram_blocks; /* Number of blocks should be written */
- uint32_t device_blocks; /* Number of total blocks in dump device */
- uint32_t written_blocks; /* Number of written blocks */
- uint32_t current_cpu; /* CPU# which handles dump */
- uint32_t nr_cpus; /* Number of CPUs */
-} DiskDumpHeader32;
-
-typedef struct QEMU_PACKED DiskDumpHeader64 {
- char signature[SIG_LEN]; /* = "KDUMP " */
- uint32_t header_version; /* Dump header version */
- NewUtsname utsname; /* copy of system_utsname */
- char timestamp[22]; /* Time stamp */
- uint32_t status; /* Above flags */
- uint32_t block_size; /* Size of a block in byte */
- uint32_t sub_hdr_size; /* Size of arch dependent header in block */
- uint32_t bitmap_blocks; /* Size of Memory bitmap in block */
- uint32_t max_mapnr; /* = max_mapnr,
- obsoleted in header_version 6 */
- uint32_t total_ram_blocks; /* Number of blocks should be written */
- uint32_t device_blocks; /* Number of total blocks in dump device */
- uint32_t written_blocks; /* Number of written blocks */
- uint32_t current_cpu; /* CPU# which handles dump */
- uint32_t nr_cpus; /* Number of CPUs */
-} DiskDumpHeader64;
-
-typedef struct QEMU_PACKED KdumpSubHeader32 {
- uint32_t phys_base;
- uint32_t dump_level; /* header_version 1 and later */
- uint32_t split; /* header_version 2 and later */
- uint32_t start_pfn; /* header_version 2 and later,
- obsoleted in header_version 6 */
- uint32_t end_pfn; /* header_version 2 and later,
- obsoleted in header_version 6 */
- uint64_t offset_vmcoreinfo; /* header_version 3 and later */
- uint32_t size_vmcoreinfo; /* header_version 3 and later */
- uint64_t offset_note; /* header_version 4 and later */
- uint32_t note_size; /* header_version 4 and later */
- uint64_t offset_eraseinfo; /* header_version 5 and later */
- uint32_t size_eraseinfo; /* header_version 5 and later */
- uint64_t start_pfn_64; /* header_version 6 and later */
- uint64_t end_pfn_64; /* header_version 6 and later */
- uint64_t max_mapnr_64; /* header_version 6 and later */
-} KdumpSubHeader32;
-
-typedef struct QEMU_PACKED KdumpSubHeader64 {
- uint64_t phys_base;
- uint32_t dump_level; /* header_version 1 and later */
- uint32_t split; /* header_version 2 and later */
- uint64_t start_pfn; /* header_version 2 and later,
- obsoleted in header_version 6 */
- uint64_t end_pfn; /* header_version 2 and later,
- obsoleted in header_version 6 */
- uint64_t offset_vmcoreinfo; /* header_version 3 and later */
- uint64_t size_vmcoreinfo; /* header_version 3 and later */
- uint64_t offset_note; /* header_version 4 and later */
- uint64_t note_size; /* header_version 4 and later */
- uint64_t offset_eraseinfo; /* header_version 5 and later */
- uint64_t size_eraseinfo; /* header_version 5 and later */
- uint64_t start_pfn_64; /* header_version 6 and later */
- uint64_t end_pfn_64; /* header_version 6 and later */
- uint64_t max_mapnr_64; /* header_version 6 and later */
-} KdumpSubHeader64;
-
-typedef struct DataCache {
- DumpState *state; /* dump state related to this data */
- uint8_t *buf; /* buffer for cached data */
- size_t buf_size; /* size of the buf */
- size_t data_size; /* size of cached data in buf */
- off_t offset; /* offset of the file */
-} DataCache;
-
-typedef struct QEMU_PACKED PageDescriptor {
- uint64_t offset; /* the offset of the page data*/
- uint32_t size; /* the size of this dump page */
- uint32_t flags; /* flags */
- uint64_t page_flags; /* page flags */
-} PageDescriptor;
-
-typedef struct DumpState {
- GuestPhysBlockList guest_phys_blocks;
- ArchDumpInfo dump_info;
- MemoryMappingList list;
- bool resume;
- bool detached;
- bool kdump_raw;
- hwaddr memory_offset;
- int fd;
-
- /*
- * Dump filter area variables
- *
- * A filtered dump only contains the guest memory designated by
- * the start address and length variables defined below.
- *
- * If length is 0, no filtering is applied.
- */
- int64_t filter_area_begin; /* Start address of partial guest memory area */
- int64_t filter_area_length; /* Length of partial guest memory area */
-
- /* Elf dump related data */
- uint32_t phdr_num;
- uint32_t shdr_num;
- ssize_t note_size;
- hwaddr shdr_offset;
- hwaddr phdr_offset;
- hwaddr section_offset;
- hwaddr note_offset;
-
- void *elf_section_hdrs; /* Pointer to section header buffer */
- void *elf_section_data; /* Pointer to section data buffer */
- uint64_t elf_section_data_size; /* Size of section data */
- GArray *string_table_buf; /* String table data buffer */
-
- uint8_t *note_buf; /* buffer for notes */
- size_t note_buf_offset; /* the writing place in note_buf */
- uint32_t nr_cpus; /* number of guest's cpu */
- uint64_t max_mapnr; /* the biggest guest's phys-mem's number */
- size_t len_dump_bitmap; /* the size of the place used to store
- dump_bitmap in vmcore */
- off_t offset_dump_bitmap; /* offset of dump_bitmap part in vmcore */
- off_t offset_page; /* offset of page part in vmcore */
- size_t num_dumpable; /* number of page that can be dumped */
- uint32_t flag_compress; /* indicate the compression format */
- DumpStatus status; /* current dump status */
-
- bool has_format; /* whether format is provided */
- DumpGuestMemoryFormat format; /* valid only if has_format == true */
- QemuThread dump_thread; /* thread for detached dump */
-
- int64_t total_size; /* total memory size (in bytes) to
- * be dumped. When filter is
- * enabled, this will only count
- * those to be written. */
- int64_t written_size; /* written memory size (in bytes),
- * this could be used to calculate
- * how much work we have
- * finished. */
- uint8_t *guest_note; /* ELF note content */
- size_t guest_note_size;
-} DumpState;
-
-uint16_t cpu_to_dump16(DumpState *s, uint16_t val);
-uint32_t cpu_to_dump32(DumpState *s, uint32_t val);
-uint64_t cpu_to_dump64(DumpState *s, uint64_t val);
-
-int64_t dump_filtered_memblock_size(GuestPhysBlock *block, int64_t filter_area_start,
- int64_t filter_area_length);
-int64_t dump_filtered_memblock_start(GuestPhysBlock *block, int64_t filter_area_start,
- int64_t filter_area_length);
-#endif
+++ /dev/null
-/*
- * QEMU event-loop backend
- *
- * Copyright (C) 2022 Red Hat Inc
- *
- * Authors:
- * Nicolas Saenz Julienne <nsaenzju@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-#ifndef QEMU_EVENT_LOOP_BASE_H
-#define QEMU_EVENT_LOOP_BASE_H
-
-#include "qom/object.h"
-#include "block/aio.h"
-
-#define TYPE_EVENT_LOOP_BASE "event-loop-base"
-OBJECT_DECLARE_TYPE(EventLoopBase, EventLoopBaseClass,
- EVENT_LOOP_BASE)
-
-struct EventLoopBaseClass {
- ObjectClass parent_class;
-
- void (*init)(EventLoopBase *base, Error **errp);
- void (*update_params)(EventLoopBase *base, Error **errp);
- bool (*can_be_deleted)(EventLoopBase *base);
-};
-
-struct EventLoopBase {
- Object parent;
-
- /* AioContext AIO engine parameters */
- int64_t aio_max_batch;
-
- /* AioContext thread pool parameters */
- int64_t thread_pool_min;
- int64_t thread_pool_max;
-};
-#endif
+++ /dev/null
-/*
- * Host IOMMU device abstract declaration
- *
- * Copyright (C) 2024 Intel Corporation.
- *
- * Authors: Zhenzhong Duan <zhenzhong.duan@intel.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- */
-
-#ifndef HOST_IOMMU_DEVICE_H
-#define HOST_IOMMU_DEVICE_H
-
-#include "qom/object.h"
-#include "qapi/error.h"
-
-/**
- * struct HostIOMMUDeviceCaps - Define host IOMMU device capabilities.
- *
- * @type: host platform IOMMU type.
- *
- * @hw_caps: host platform IOMMU capabilities (e.g. on IOMMUFD this represents
- * the @out_capabilities value returned from IOMMU_GET_HW_INFO ioctl)
- */
-typedef struct HostIOMMUDeviceCaps {
- uint32_t type;
- uint64_t hw_caps;
-} HostIOMMUDeviceCaps;
-
-#define TYPE_HOST_IOMMU_DEVICE "host-iommu-device"
-OBJECT_DECLARE_TYPE(HostIOMMUDevice, HostIOMMUDeviceClass, HOST_IOMMU_DEVICE)
-
-struct HostIOMMUDevice {
- Object parent_obj;
-
- char *name;
- void *agent; /* pointer to agent device, ie. VFIO or VDPA device */
- PCIBus *aliased_bus;
- int aliased_devfn;
- HostIOMMUDeviceCaps caps;
-};
-
-/**
- * struct HostIOMMUDeviceClass - The base class for all host IOMMU devices.
- *
- * Different types of host devices (e.g., VFIO or VDPA device) or devices
- * with different backend (e.g., VFIO legacy container or IOMMUFD backend)
- * will have different implementations of the HostIOMMUDeviceClass.
- */
-struct HostIOMMUDeviceClass {
- ObjectClass parent_class;
-
- /**
- * @realize: initialize host IOMMU device instance further.
- *
- * Mandatory callback.
- *
- * @hiod: pointer to a host IOMMU device instance.
- *
- * @opaque: pointer to agent device of this host IOMMU device,
- * e.g., VFIO base device or VDPA device.
- *
- * @errp: pass an Error out when realize fails.
- *
- * Returns: true on success, false on failure.
- */
- bool (*realize)(HostIOMMUDevice *hiod, void *opaque, Error **errp);
- /**
- * @get_cap: check if a host IOMMU device capability is supported.
- *
- * Optional callback, if not implemented, hint not supporting query
- * of @cap.
- *
- * @hiod: pointer to a host IOMMU device instance.
- *
- * @cap: capability to check.
- *
- * @errp: pass an Error out when fails to query capability.
- *
- * Returns: <0 on failure, 0 if a @cap is unsupported, or else
- * 1 or some positive value for some special @cap,
- * i.e., HOST_IOMMU_DEVICE_CAP_AW_BITS.
- */
- int (*get_cap)(HostIOMMUDevice *hiod, int cap, Error **errp);
- /**
- * @get_iova_ranges: Return the list of usable iova_ranges along with
- * @hiod Host IOMMU device
- *
- * @hiod: handle to the host IOMMU device
- */
- GList* (*get_iova_ranges)(HostIOMMUDevice *hiod);
- /**
- *
- * @get_page_size_mask: Return the page size mask supported along this
- * @hiod Host IOMMU device
- *
- * @hiod: handle to the host IOMMU device
- */
- uint64_t (*get_page_size_mask)(HostIOMMUDevice *hiod);
-};
-
-/*
- * Host IOMMU device capability list.
- */
-#define HOST_IOMMU_DEVICE_CAP_IOMMU_TYPE 0
-#define HOST_IOMMU_DEVICE_CAP_AW_BITS 1
-
-#define HOST_IOMMU_DEVICE_CAP_AW_BITS_MAX 64
-#endif
+++ /dev/null
-/*
- * QEMU Host Memory Backend
- *
- * Copyright (C) 2013-2014 Red Hat Inc
- *
- * Authors:
- * Igor Mammedov <imammedo@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef SYSEMU_HOSTMEM_H
-#define SYSEMU_HOSTMEM_H
-
-#include "sysemu/numa.h"
-#include "qapi/qapi-types-machine.h"
-#include "qom/object.h"
-#include "exec/memory.h"
-#include "qemu/bitmap.h"
-#include "qemu/thread-context.h"
-
-#define TYPE_MEMORY_BACKEND "memory-backend"
-OBJECT_DECLARE_TYPE(HostMemoryBackend, HostMemoryBackendClass,
- MEMORY_BACKEND)
-
-/* hostmem-ram.c */
-/**
- * @TYPE_MEMORY_BACKEND_RAM:
- * name of backend that uses mmap on the anonymous RAM
- */
-
-#define TYPE_MEMORY_BACKEND_RAM "memory-backend-ram"
-
-/* hostmem-file.c */
-/**
- * @TYPE_MEMORY_BACKEND_FILE:
- * name of backend that uses mmap on a file descriptor
- */
-#define TYPE_MEMORY_BACKEND_FILE "memory-backend-file"
-
-#define TYPE_MEMORY_BACKEND_MEMFD "memory-backend-memfd"
-
-
-/**
- * HostMemoryBackendClass:
- * @parent_class: opaque parent class container
- */
-struct HostMemoryBackendClass {
- ObjectClass parent_class;
-
- /**
- * alloc: Allocate memory from backend.
- *
- * @backend: the #HostMemoryBackend.
- * @errp: pointer to Error*, to store an error if it happens.
- *
- * Return: true on success, else false setting @errp with error.
- */
- bool (*alloc)(HostMemoryBackend *backend, Error **errp);
-};
-
-/**
- * @HostMemoryBackend
- *
- * @parent: opaque parent object container
- * @size: amount of memory backend provides
- * @mr: MemoryRegion representing host memory belonging to backend
- * @prealloc_threads: number of threads to be used for preallocatining RAM
- */
-struct HostMemoryBackend {
- /* private */
- Object parent;
-
- /* protected */
- uint64_t size;
- bool merge, dump, use_canonical_path;
- bool prealloc, is_mapped, share, reserve;
- bool guest_memfd, aligned;
- uint32_t prealloc_threads;
- ThreadContext *prealloc_context;
- DECLARE_BITMAP(host_nodes, MAX_NODES + 1);
- HostMemPolicy policy;
-
- MemoryRegion mr;
-};
-
-bool host_memory_backend_mr_inited(HostMemoryBackend *backend);
-MemoryRegion *host_memory_backend_get_memory(HostMemoryBackend *backend);
-
-void host_memory_backend_set_mapped(HostMemoryBackend *backend, bool mapped);
-bool host_memory_backend_is_mapped(HostMemoryBackend *backend);
-size_t host_memory_backend_pagesize(HostMemoryBackend *memdev);
-char *host_memory_backend_get_name(HostMemoryBackend *backend);
-
-#endif
+++ /dev/null
-/*
- * QEMU Hypervisor.framework (HVF) support
- *
- * Copyright Google Inc., 2017
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-/* header to be included in non-HVF-specific code */
-
-#ifndef HVF_H
-#define HVF_H
-
-#include "qemu/accel.h"
-#include "qom/object.h"
-
-#ifdef COMPILING_PER_TARGET
-#include "cpu.h"
-
-#ifdef CONFIG_HVF
-extern bool hvf_allowed;
-#define hvf_enabled() (hvf_allowed)
-#else /* !CONFIG_HVF */
-#define hvf_enabled() 0
-#endif /* !CONFIG_HVF */
-
-#endif /* COMPILING_PER_TARGET */
-
-#define TYPE_HVF_ACCEL ACCEL_CLASS_NAME("hvf")
-
-typedef struct HVFState HVFState;
-DECLARE_INSTANCE_CHECKER(HVFState, HVF_STATE,
- TYPE_HVF_ACCEL)
-
-#ifdef COMPILING_PER_TARGET
-struct hvf_sw_breakpoint {
- vaddr pc;
- vaddr saved_insn;
- int use_count;
- QTAILQ_ENTRY(hvf_sw_breakpoint) entry;
-};
-
-struct hvf_sw_breakpoint *hvf_find_sw_breakpoint(CPUState *cpu,
- vaddr pc);
-int hvf_sw_breakpoints_active(CPUState *cpu);
-
-int hvf_arch_insert_sw_breakpoint(CPUState *cpu, struct hvf_sw_breakpoint *bp);
-int hvf_arch_remove_sw_breakpoint(CPUState *cpu, struct hvf_sw_breakpoint *bp);
-int hvf_arch_insert_hw_breakpoint(vaddr addr, vaddr len, int type);
-int hvf_arch_remove_hw_breakpoint(vaddr addr, vaddr len, int type);
-void hvf_arch_remove_all_hw_breakpoints(void);
-
-/*
- * hvf_update_guest_debug:
- * @cs: CPUState for the CPU to update
- *
- * Update guest to enable or disable debugging. Per-arch specifics will be
- * handled by calling down to hvf_arch_update_guest_debug.
- */
-int hvf_update_guest_debug(CPUState *cpu);
-void hvf_arch_update_guest_debug(CPUState *cpu);
-
-/*
- * Return whether the guest supports debugging.
- */
-bool hvf_arch_supports_guest_debug(void);
-#endif /* COMPILING_PER_TARGET */
-
-#endif
+++ /dev/null
-/*
- * QEMU Hypervisor.framework (HVF) support
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-/* header to be included in HVF-specific code */
-
-#ifndef HVF_INT_H
-#define HVF_INT_H
-
-#ifdef __aarch64__
-#include <Hypervisor/Hypervisor.h>
-typedef hv_vcpu_t hvf_vcpuid;
-#else
-#include <Hypervisor/hv.h>
-typedef hv_vcpuid_t hvf_vcpuid;
-#endif
-
-/* hvf_slot flags */
-#define HVF_SLOT_LOG (1 << 0)
-
-typedef struct hvf_slot {
- uint64_t start;
- uint64_t size;
- uint8_t *mem;
- int slot_id;
- uint32_t flags;
- MemoryRegion *region;
-} hvf_slot;
-
-typedef struct hvf_vcpu_caps {
- uint64_t vmx_cap_pinbased;
- uint64_t vmx_cap_procbased;
- uint64_t vmx_cap_procbased2;
- uint64_t vmx_cap_entry;
- uint64_t vmx_cap_exit;
- uint64_t vmx_cap_preemption_timer;
-} hvf_vcpu_caps;
-
-struct HVFState {
- AccelState parent;
- hvf_slot slots[32];
- int num_slots;
-
- hvf_vcpu_caps *hvf_caps;
- uint64_t vtimer_offset;
- QTAILQ_HEAD(, hvf_sw_breakpoint) hvf_sw_breakpoints;
-};
-extern HVFState *hvf_state;
-
-struct AccelCPUState {
- hvf_vcpuid fd;
- void *exit;
- bool vtimer_masked;
- sigset_t unblock_ipi_mask;
- bool guest_debug_enabled;
- bool dirty;
-};
-
-void assert_hvf_ok_impl(hv_return_t ret, const char *file, unsigned int line,
- const char *exp);
-#define assert_hvf_ok(EX) assert_hvf_ok_impl((EX), __FILE__, __LINE__, #EX)
-const char *hvf_return_string(hv_return_t ret);
-int hvf_arch_init(void);
-hv_return_t hvf_arch_vm_create(MachineState *ms, uint32_t pa_range);
-int hvf_arch_init_vcpu(CPUState *cpu);
-void hvf_arch_vcpu_destroy(CPUState *cpu);
-int hvf_vcpu_exec(CPUState *);
-hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
-int hvf_put_registers(CPUState *);
-int hvf_get_registers(CPUState *);
-void hvf_kick_vcpu_thread(CPUState *cpu);
-
-#endif
+++ /dev/null
-/*
- * QEMU Hardware accelerators support
- *
- * Copyright 2016 Google, Inc.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#ifndef QEMU_HW_ACCEL_H
-#define QEMU_HW_ACCEL_H
-
-#include "hw/core/cpu.h"
-#include "sysemu/kvm.h"
-#include "sysemu/hvf.h"
-#include "sysemu/whpx.h"
-#include "sysemu/nvmm.h"
-
-void cpu_synchronize_state(CPUState *cpu);
-void cpu_synchronize_post_reset(CPUState *cpu);
-void cpu_synchronize_post_init(CPUState *cpu);
-void cpu_synchronize_pre_loadvm(CPUState *cpu);
-
-#endif /* QEMU_HW_ACCEL_H */
+++ /dev/null
-/*
- * iommufd container backend declaration
- *
- * Copyright (C) 2024 Intel Corporation.
- * Copyright Red Hat, Inc. 2024
- *
- * Authors: Yi Liu <yi.l.liu@intel.com>
- * Eric Auger <eric.auger@redhat.com>
- * Zhenzhong Duan <zhenzhong.duan@intel.com>
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-#ifndef SYSEMU_IOMMUFD_H
-#define SYSEMU_IOMMUFD_H
-
-#include "qom/object.h"
-#include "exec/hwaddr.h"
-#include "exec/cpu-common.h"
-#include "sysemu/host_iommu_device.h"
-
-#define TYPE_IOMMUFD_BACKEND "iommufd"
-OBJECT_DECLARE_TYPE(IOMMUFDBackend, IOMMUFDBackendClass, IOMMUFD_BACKEND)
-
-struct IOMMUFDBackendClass {
- ObjectClass parent_class;
-};
-
-struct IOMMUFDBackend {
- Object parent;
-
- /*< protected >*/
- int fd; /* /dev/iommu file descriptor */
- bool owned; /* is the /dev/iommu opened internally */
- uint32_t users;
-
- /*< public >*/
-};
-
-bool iommufd_backend_connect(IOMMUFDBackend *be, Error **errp);
-void iommufd_backend_disconnect(IOMMUFDBackend *be);
-
-bool iommufd_backend_alloc_ioas(IOMMUFDBackend *be, uint32_t *ioas_id,
- Error **errp);
-void iommufd_backend_free_id(IOMMUFDBackend *be, uint32_t id);
-int iommufd_backend_map_dma(IOMMUFDBackend *be, uint32_t ioas_id, hwaddr iova,
- ram_addr_t size, void *vaddr, bool readonly);
-int iommufd_backend_unmap_dma(IOMMUFDBackend *be, uint32_t ioas_id,
- hwaddr iova, ram_addr_t size);
-bool iommufd_backend_get_device_info(IOMMUFDBackend *be, uint32_t devid,
- uint32_t *type, void *data, uint32_t len,
- uint64_t *caps, Error **errp);
-bool iommufd_backend_alloc_hwpt(IOMMUFDBackend *be, uint32_t dev_id,
- uint32_t pt_id, uint32_t flags,
- uint32_t data_type, uint32_t data_len,
- void *data_ptr, uint32_t *out_hwpt,
- Error **errp);
-bool iommufd_backend_set_dirty_tracking(IOMMUFDBackend *be, uint32_t hwpt_id,
- bool start, Error **errp);
-bool iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be, uint32_t hwpt_id,
- uint64_t iova, ram_addr_t size,
- uint64_t page_size, uint64_t *data,
- Error **errp);
-
-#define TYPE_HOST_IOMMU_DEVICE_IOMMUFD TYPE_HOST_IOMMU_DEVICE "-iommufd"
-#endif
+++ /dev/null
-/*
- * Event loop thread
- *
- * Copyright Red Hat Inc., 2013
- *
- * Authors:
- * Stefan Hajnoczi <stefanha@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#ifndef IOTHREAD_H
-#define IOTHREAD_H
-
-#include "block/aio.h"
-#include "qemu/thread.h"
-#include "qom/object.h"
-#include "sysemu/event-loop-base.h"
-
-#define TYPE_IOTHREAD "iothread"
-
-struct IOThread {
- EventLoopBase parent_obj;
-
- QemuThread thread;
- AioContext *ctx;
- bool run_gcontext; /* whether we should run gcontext */
- GMainContext *worker_context;
- GMainLoop *main_loop;
- QemuSemaphore init_done_sem; /* is thread init done? */
- bool stopping; /* has iothread_stop() been called? */
- bool running; /* should iothread_run() continue? */
- int thread_id;
-
- /* AioContext poll parameters */
- int64_t poll_max_ns;
- int64_t poll_grow;
- int64_t poll_shrink;
-};
-typedef struct IOThread IOThread;
-
-DECLARE_INSTANCE_CHECKER(IOThread, IOTHREAD,
- TYPE_IOTHREAD)
-
-char *iothread_get_id(IOThread *iothread);
-IOThread *iothread_by_id(const char *id);
-AioContext *iothread_get_aio_context(IOThread *iothread);
-GMainContext *iothread_get_g_main_context(IOThread *iothread);
-
-/*
- * Helpers used to allocate iothreads for internal use. These
- * iothreads will not be seen by monitor clients when query using
- * "query-iothreads".
- */
-IOThread *iothread_create(const char *id, Error **errp);
-void iothread_stop(IOThread *iothread);
-void iothread_destroy(IOThread *iothread);
-
-/*
- * Returns true if executing within IOThread context,
- * false otherwise.
- */
-bool qemu_in_iothread(void);
-
-#endif /* IOTHREAD_H */
+++ /dev/null
-/*
- * QEMU KVM support
- *
- * Copyright IBM, Corp. 2008
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-/* header to be included in non-KVM-specific code */
-
-#ifndef QEMU_KVM_H
-#define QEMU_KVM_H
-
-#include "exec/memattrs.h"
-#include "qemu/accel.h"
-#include "qom/object.h"
-
-#ifdef COMPILING_PER_TARGET
-# ifdef CONFIG_KVM
-# include <linux/kvm.h>
-# define CONFIG_KVM_IS_POSSIBLE
-# endif
-#else
-# define CONFIG_KVM_IS_POSSIBLE
-#endif
-
-#ifdef CONFIG_KVM_IS_POSSIBLE
-
-extern bool kvm_allowed;
-extern bool kvm_kernel_irqchip;
-extern bool kvm_split_irqchip;
-extern bool kvm_async_interrupts_allowed;
-extern bool kvm_halt_in_kernel_allowed;
-extern bool kvm_resamplefds_allowed;
-extern bool kvm_msi_via_irqfd_allowed;
-extern bool kvm_gsi_routing_allowed;
-extern bool kvm_gsi_direct_mapping;
-extern bool kvm_readonly_mem_allowed;
-extern bool kvm_msi_use_devid;
-
-#define kvm_enabled() (kvm_allowed)
-/**
- * kvm_irqchip_in_kernel:
- *
- * Returns: true if an in-kernel irqchip was created.
- * What this actually means is architecture and machine model
- * specific: on PC, for instance, it means that the LAPIC
- * is in kernel. This function should never be used from generic
- * target-independent code: use one of the following functions or
- * some other specific check instead.
- */
-#define kvm_irqchip_in_kernel() (kvm_kernel_irqchip)
-
-/**
- * kvm_irqchip_is_split:
- *
- * Returns: true if the irqchip implementation is split between
- * user and kernel space. The details are architecture and
- * machine specific. On PC, it means that the PIC, IOAPIC, and
- * PIT are in user space while the LAPIC is in the kernel.
- */
-#define kvm_irqchip_is_split() (kvm_split_irqchip)
-
-/**
- * kvm_async_interrupts_enabled:
- *
- * Returns: true if we can deliver interrupts to KVM
- * asynchronously (ie by ioctl from any thread at any time)
- * rather than having to do interrupt delivery synchronously
- * (where the vcpu must be stopped at a suitable point first).
- */
-#define kvm_async_interrupts_enabled() (kvm_async_interrupts_allowed)
-
-/**
- * kvm_halt_in_kernel
- *
- * Returns: true if halted cpus should still get a KVM_RUN ioctl to run
- * inside of kernel space. This only works if MP state is implemented.
- */
-#define kvm_halt_in_kernel() (kvm_halt_in_kernel_allowed)
-
-/**
- * kvm_irqfds_enabled:
- *
- * Returns: true if we can use irqfds to inject interrupts into
- * a KVM CPU (ie the kernel supports irqfds and we are running
- * with a configuration where it is meaningful to use them).
- *
- * Always available if running with in-kernel irqchip.
- */
-#define kvm_irqfds_enabled() kvm_irqchip_in_kernel()
-
-/**
- * kvm_resamplefds_enabled:
- *
- * Returns: true if we can use resamplefds to inject interrupts into
- * a KVM CPU (ie the kernel supports resamplefds and we are running
- * with a configuration where it is meaningful to use them).
- */
-#define kvm_resamplefds_enabled() (kvm_resamplefds_allowed)
-
-/**
- * kvm_msi_via_irqfd_enabled:
- *
- * Returns: true if we can route a PCI MSI (Message Signaled Interrupt)
- * to a KVM CPU via an irqfd. This requires that the kernel supports
- * this and that we're running in a configuration that permits it.
- */
-#define kvm_msi_via_irqfd_enabled() (kvm_msi_via_irqfd_allowed)
-
-/**
- * kvm_gsi_routing_enabled:
- *
- * Returns: true if GSI routing is enabled (ie the kernel supports
- * it and we're running in a configuration that permits it).
- */
-#define kvm_gsi_routing_enabled() (kvm_gsi_routing_allowed)
-
-/**
- * kvm_gsi_direct_mapping:
- *
- * Returns: true if GSI direct mapping is enabled.
- */
-#define kvm_gsi_direct_mapping() (kvm_gsi_direct_mapping)
-
-/**
- * kvm_readonly_mem_enabled:
- *
- * Returns: true if KVM readonly memory is enabled (ie the kernel
- * supports it and we're running in a configuration that permits it).
- */
-#define kvm_readonly_mem_enabled() (kvm_readonly_mem_allowed)
-
-/**
- * kvm_msi_devid_required:
- * Returns: true if KVM requires a device id to be provided while
- * defining an MSI routing entry.
- */
-#define kvm_msi_devid_required() (kvm_msi_use_devid)
-
-#else
-
-#define kvm_enabled() (0)
-#define kvm_irqchip_in_kernel() (false)
-#define kvm_irqchip_is_split() (false)
-#define kvm_async_interrupts_enabled() (false)
-#define kvm_halt_in_kernel() (false)
-#define kvm_irqfds_enabled() (false)
-#define kvm_resamplefds_enabled() (false)
-#define kvm_msi_via_irqfd_enabled() (false)
-#define kvm_gsi_routing_allowed() (false)
-#define kvm_gsi_direct_mapping() (false)
-#define kvm_readonly_mem_enabled() (false)
-#define kvm_msi_devid_required() (false)
-
-#endif /* CONFIG_KVM_IS_POSSIBLE */
-
-struct kvm_run;
-struct kvm_irq_routing_entry;
-
-typedef struct KVMCapabilityInfo {
- const char *name;
- int value;
-} KVMCapabilityInfo;
-
-#define KVM_CAP_INFO(CAP) { "KVM_CAP_" stringify(CAP), KVM_CAP_##CAP }
-#define KVM_CAP_LAST_INFO { NULL, 0 }
-
-struct KVMState;
-
-#define TYPE_KVM_ACCEL ACCEL_CLASS_NAME("kvm")
-typedef struct KVMState KVMState;
-DECLARE_INSTANCE_CHECKER(KVMState, KVM_STATE,
- TYPE_KVM_ACCEL)
-
-extern KVMState *kvm_state;
-typedef struct Notifier Notifier;
-
-typedef struct KVMRouteChange {
- KVMState *s;
- int changes;
-} KVMRouteChange;
-
-/* external API */
-
-unsigned int kvm_get_max_memslots(void);
-unsigned int kvm_get_free_memslots(void);
-bool kvm_has_sync_mmu(void);
-int kvm_has_vcpu_events(void);
-int kvm_max_nested_state_length(void);
-int kvm_has_gsi_routing(void);
-
-/**
- * kvm_arm_supports_user_irq
- *
- * Not all KVM implementations support notifications for kernel generated
- * interrupt events to user space. This function indicates whether the current
- * KVM implementation does support them.
- *
- * Returns: true if KVM supports using kernel generated IRQs from user space
- */
-bool kvm_arm_supports_user_irq(void);
-
-
-int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr);
-int kvm_on_sigbus(int code, void *addr);
-
-#ifdef COMPILING_PER_TARGET
-#include "cpu.h"
-
-void kvm_flush_coalesced_mmio_buffer(void);
-
-/**
- * kvm_update_guest_debug(): ensure KVM debug structures updated
- * @cs: the CPUState for this cpu
- * @reinject_trap: KVM trap injection control
- *
- * There are usually per-arch specifics which will be handled by
- * calling down to kvm_arch_update_guest_debug after the generic
- * fields have been set.
- */
-#ifdef TARGET_KVM_HAVE_GUEST_DEBUG
-int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap);
-#else
-static inline int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap)
-{
- return -EINVAL;
-}
-#endif
-
-/* internal API */
-
-int kvm_ioctl(KVMState *s, unsigned long type, ...);
-
-int kvm_vm_ioctl(KVMState *s, unsigned long type, ...);
-
-int kvm_vcpu_ioctl(CPUState *cpu, unsigned long type, ...);
-
-/**
- * kvm_device_ioctl - call an ioctl on a kvm device
- * @fd: The KVM device file descriptor as returned from KVM_CREATE_DEVICE
- * @type: The device-ctrl ioctl number
- *
- * Returns: -errno on error, nonnegative on success
- */
-int kvm_device_ioctl(int fd, unsigned long type, ...);
-
-/**
- * kvm_vm_check_attr - check for existence of a specific vm attribute
- * @s: The KVMState pointer
- * @group: the group
- * @attr: the attribute of that group to query for
- *
- * Returns: 1 if the attribute exists
- * 0 if the attribute either does not exist or if the vm device
- * interface is unavailable
- */
-int kvm_vm_check_attr(KVMState *s, uint32_t group, uint64_t attr);
-
-/**
- * kvm_device_check_attr - check for existence of a specific device attribute
- * @fd: The device file descriptor
- * @group: the group
- * @attr: the attribute of that group to query for
- *
- * Returns: 1 if the attribute exists
- * 0 if the attribute either does not exist or if the vm device
- * interface is unavailable
- */
-int kvm_device_check_attr(int fd, uint32_t group, uint64_t attr);
-
-/**
- * kvm_device_access - set or get value of a specific device attribute
- * @fd: The device file descriptor
- * @group: the group
- * @attr: the attribute of that group to set or get
- * @val: pointer to a storage area for the value
- * @write: true for set and false for get operation
- * @errp: error object handle
- *
- * Returns: 0 on success
- * < 0 on error
- * Use kvm_device_check_attr() in order to check for the availability
- * of optional attributes.
- */
-int kvm_device_access(int fd, int group, uint64_t attr,
- void *val, bool write, Error **errp);
-
-/**
- * kvm_create_device - create a KVM device for the device control API
- * @KVMState: The KVMState pointer
- * @type: The KVM device type (see Documentation/virtual/kvm/devices in the
- * kernel source)
- * @test: If true, only test if device can be created, but don't actually
- * create the device.
- *
- * Returns: -errno on error, nonnegative on success: @test ? 0 : device fd;
- */
-int kvm_create_device(KVMState *s, uint64_t type, bool test);
-
-/**
- * kvm_device_supported - probe whether KVM supports specific device
- *
- * @vmfd: The fd handler for VM
- * @type: type of device
- *
- * @return: true if supported, otherwise false.
- */
-bool kvm_device_supported(int vmfd, uint64_t type);
-
-/**
- * kvm_create_vcpu - Gets a parked KVM vCPU or creates a KVM vCPU
- * @cpu: QOM CPUState object for which KVM vCPU has to be fetched/created.
- *
- * @returns: 0 when success, errno (<0) when failed.
- */
-int kvm_create_vcpu(CPUState *cpu);
-
-/**
- * kvm_park_vcpu - Park QEMU KVM vCPU context
- * @cpu: QOM CPUState object for which QEMU KVM vCPU context has to be parked.
- *
- * @returns: none
- */
-void kvm_park_vcpu(CPUState *cpu);
-
-/**
- * kvm_unpark_vcpu - unpark QEMU KVM vCPU context
- * @s: KVM State
- * @vcpu_id: Architecture vCPU ID of the parked vCPU
- *
- * @returns: KVM fd
- */
-int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id);
-
-/**
- * kvm_create_and_park_vcpu - Create and park a KVM vCPU
- * @cpu: QOM CPUState object for which KVM vCPU has to be created and parked.
- *
- * @returns: 0 when success, errno (<0) when failed.
- */
-int kvm_create_and_park_vcpu(CPUState *cpu);
-
-/* Arch specific hooks */
-
-extern const KVMCapabilityInfo kvm_arch_required_capabilities[];
-
-void kvm_arch_accel_class_init(ObjectClass *oc);
-
-void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run);
-MemTxAttrs kvm_arch_post_run(CPUState *cpu, struct kvm_run *run);
-
-int kvm_arch_handle_exit(CPUState *cpu, struct kvm_run *run);
-
-int kvm_arch_process_async_events(CPUState *cpu);
-
-int kvm_arch_get_registers(CPUState *cpu, Error **errp);
-
-/* state subset only touched by the VCPU itself during runtime */
-#define KVM_PUT_RUNTIME_STATE 1
-/* state subset modified during VCPU reset */
-#define KVM_PUT_RESET_STATE 2
-/* full state set, modified during initialization or on vmload */
-#define KVM_PUT_FULL_STATE 3
-
-int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp);
-
-int kvm_arch_get_default_type(MachineState *ms);
-
-int kvm_arch_init(MachineState *ms, KVMState *s);
-
-int kvm_arch_init_vcpu(CPUState *cpu);
-int kvm_arch_destroy_vcpu(CPUState *cpu);
-
-bool kvm_vcpu_id_is_valid(int vcpu_id);
-
-/* Returns VCPU ID to be used on KVM_CREATE_VCPU ioctl() */
-unsigned long kvm_arch_vcpu_id(CPUState *cpu);
-
-#ifdef KVM_HAVE_MCE_INJECTION
-void kvm_arch_on_sigbus_vcpu(CPUState *cpu, int code, void *addr);
-#endif
-
-void kvm_arch_init_irq_routing(KVMState *s);
-
-int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
- uint64_t address, uint32_t data, PCIDevice *dev);
-
-/* Notify arch about newly added MSI routes */
-int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
- int vector, PCIDevice *dev);
-/* Notify arch about released MSI routes */
-int kvm_arch_release_virq_post(int virq);
-
-int kvm_arch_msi_data_to_gsi(uint32_t data);
-
-int kvm_set_irq(KVMState *s, int irq, int level);
-int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
-
-void kvm_irqchip_add_irq_route(KVMState *s, int gsi, int irqchip, int pin);
-
-void kvm_irqchip_add_change_notifier(Notifier *n);
-void kvm_irqchip_remove_change_notifier(Notifier *n);
-void kvm_irqchip_change_notify(void);
-
-struct kvm_guest_debug;
-struct kvm_debug_exit_arch;
-
-struct kvm_sw_breakpoint {
- vaddr pc;
- vaddr saved_insn;
- int use_count;
- QTAILQ_ENTRY(kvm_sw_breakpoint) entry;
-};
-
-struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *cpu,
- vaddr pc);
-
-int kvm_sw_breakpoints_active(CPUState *cpu);
-
-int kvm_arch_insert_sw_breakpoint(CPUState *cpu,
- struct kvm_sw_breakpoint *bp);
-int kvm_arch_remove_sw_breakpoint(CPUState *cpu,
- struct kvm_sw_breakpoint *bp);
-int kvm_arch_insert_hw_breakpoint(vaddr addr, vaddr len, int type);
-int kvm_arch_remove_hw_breakpoint(vaddr addr, vaddr len, int type);
-void kvm_arch_remove_all_hw_breakpoints(void);
-
-void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg);
-
-bool kvm_arch_stop_on_emulation_error(CPUState *cpu);
-
-int kvm_check_extension(KVMState *s, unsigned int extension);
-
-int kvm_vm_check_extension(KVMState *s, unsigned int extension);
-
-#define kvm_vm_enable_cap(s, capability, cap_flags, ...) \
- ({ \
- struct kvm_enable_cap cap = { \
- .cap = capability, \
- .flags = cap_flags, \
- }; \
- uint64_t args_tmp[] = { __VA_ARGS__ }; \
- size_t n = MIN(ARRAY_SIZE(args_tmp), ARRAY_SIZE(cap.args)); \
- memcpy(cap.args, args_tmp, n * sizeof(cap.args[0])); \
- kvm_vm_ioctl(s, KVM_ENABLE_CAP, &cap); \
- })
-
-#define kvm_vcpu_enable_cap(cpu, capability, cap_flags, ...) \
- ({ \
- struct kvm_enable_cap cap = { \
- .cap = capability, \
- .flags = cap_flags, \
- }; \
- uint64_t args_tmp[] = { __VA_ARGS__ }; \
- size_t n = MIN(ARRAY_SIZE(args_tmp), ARRAY_SIZE(cap.args)); \
- memcpy(cap.args, args_tmp, n * sizeof(cap.args[0])); \
- kvm_vcpu_ioctl(cpu, KVM_ENABLE_CAP, &cap); \
- })
-
-void kvm_set_sigmask_len(KVMState *s, unsigned int sigmask_len);
-
-int kvm_physical_memory_addr_from_host(KVMState *s, void *ram_addr,
- hwaddr *phys_addr);
-
-#endif /* COMPILING_PER_TARGET */
-
-void kvm_cpu_synchronize_state(CPUState *cpu);
-
-void kvm_init_cpu_signals(CPUState *cpu);
-
-/**
- * kvm_irqchip_add_msi_route - Add MSI route for specific vector
- * @c: KVMRouteChange instance.
- * @vector: which vector to add. This can be either MSI/MSIX
- * vector. The function will automatically detect whether
- * MSI/MSIX is enabled, and fetch corresponding MSI
- * message.
- * @dev: Owner PCI device to add the route. If @dev is specified
- * as @NULL, an empty MSI message will be inited.
- * @return: virq (>=0) when success, errno (<0) when failed.
- */
-int kvm_irqchip_add_msi_route(KVMRouteChange *c, int vector, PCIDevice *dev);
-int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg,
- PCIDevice *dev);
-void kvm_irqchip_commit_routes(KVMState *s);
-
-static inline KVMRouteChange kvm_irqchip_begin_route_changes(KVMState *s)
-{
- return (KVMRouteChange) { .s = s, .changes = 0 };
-}
-
-static inline void kvm_irqchip_commit_route_changes(KVMRouteChange *c)
-{
- if (c->changes) {
- kvm_irqchip_commit_routes(c->s);
- c->changes = 0;
- }
-}
-
-int kvm_irqchip_get_virq(KVMState *s);
-void kvm_irqchip_release_virq(KVMState *s, int virq);
-
-void kvm_add_routing_entry(KVMState *s,
- struct kvm_irq_routing_entry *entry);
-
-int kvm_irqchip_add_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
- EventNotifier *rn, int virq);
-int kvm_irqchip_remove_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
- int virq);
-int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
- EventNotifier *rn, qemu_irq irq);
-int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n,
- qemu_irq irq);
-void kvm_irqchip_set_qemuirq_gsi(KVMState *s, qemu_irq irq, int gsi);
-void kvm_init_irq_routing(KVMState *s);
-
-bool kvm_kernel_irqchip_allowed(void);
-bool kvm_kernel_irqchip_required(void);
-bool kvm_kernel_irqchip_split(void);
-
-/**
- * kvm_arch_irqchip_create:
- * @KVMState: The KVMState pointer
- *
- * Allow architectures to create an in-kernel irq chip themselves.
- *
- * Returns: < 0: error
- * 0: irq chip was not created
- * > 0: irq chip was created
- */
-int kvm_arch_irqchip_create(KVMState *s);
-
-/**
- * kvm_set_one_reg - set a register value in KVM via KVM_SET_ONE_REG ioctl
- * @id: The register ID
- * @source: The pointer to the value to be set. It must point to a variable
- * of the correct type/size for the register being accessed.
- *
- * Returns: 0 on success, or a negative errno on failure.
- */
-int kvm_set_one_reg(CPUState *cs, uint64_t id, void *source);
-
-/**
- * kvm_get_one_reg - get a register value from KVM via KVM_GET_ONE_REG ioctl
- * @id: The register ID
- * @target: The pointer where the value is to be stored. It must point to a
- * variable of the correct type/size for the register being accessed.
- *
- * Returns: 0 on success, or a negative errno on failure.
- */
-int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target);
-
-/* Notify resamplefd for EOI of specific interrupts. */
-void kvm_resample_fd_notify(int gsi);
-
-bool kvm_dirty_ring_enabled(void);
-
-uint32_t kvm_dirty_ring_size(void);
-
-void kvm_mark_guest_state_protected(void);
-
-/**
- * kvm_hwpoisoned_mem - indicate if there is any hwpoisoned page
- * reported for the VM.
- */
-bool kvm_hwpoisoned_mem(void);
-
-int kvm_create_guest_memfd(uint64_t size, uint64_t flags, Error **errp);
-
-int kvm_set_memory_attributes_private(hwaddr start, uint64_t size);
-int kvm_set_memory_attributes_shared(hwaddr start, uint64_t size);
-
-int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private);
-
-#endif
+++ /dev/null
-/*
- * Internal definitions for a target's KVM support
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#ifndef QEMU_KVM_INT_H
-#define QEMU_KVM_INT_H
-
-#include "exec/memory.h"
-#include "qapi/qapi-types-common.h"
-#include "qemu/accel.h"
-#include "qemu/queue.h"
-#include "sysemu/kvm.h"
-#include "hw/boards.h"
-#include "hw/i386/topology.h"
-#include "io/channel-socket.h"
-
-typedef struct KVMSlot
-{
- hwaddr start_addr;
- ram_addr_t memory_size;
- void *ram;
- int slot;
- int flags;
- int old_flags;
- /* Dirty bitmap cache for the slot */
- unsigned long *dirty_bmap;
- unsigned long dirty_bmap_size;
- /* Cache of the address space ID */
- int as_id;
- /* Cache of the offset in ram address space */
- ram_addr_t ram_start_offset;
- int guest_memfd;
- hwaddr guest_memfd_offset;
-} KVMSlot;
-
-typedef struct KVMMemoryUpdate {
- QSIMPLEQ_ENTRY(KVMMemoryUpdate) next;
- MemoryRegionSection section;
-} KVMMemoryUpdate;
-
-typedef struct KVMMemoryListener {
- MemoryListener listener;
- KVMSlot *slots;
- unsigned int nr_slots_used;
- unsigned int nr_slots_allocated;
- int as_id;
- QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_add;
- QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_del;
-} KVMMemoryListener;
-
-#define KVM_MSI_HASHTAB_SIZE 256
-
-typedef struct KVMHostTopoInfo {
- /* Number of package on the Host */
- unsigned int maxpkgs;
- /* Number of cpus on the Host */
- unsigned int maxcpus;
- /* Number of cpus on each different package */
- unsigned int *pkg_cpu_count;
- /* Each package can have different maxticks */
- unsigned int *maxticks;
-} KVMHostTopoInfo;
-
-struct KVMMsrEnergy {
- pid_t pid;
- bool enable;
- char *socket_path;
- QIOChannelSocket *sioc;
- QemuThread msr_thr;
- unsigned int guest_vcpus;
- unsigned int guest_vsockets;
- X86CPUTopoInfo guest_topo_info;
- KVMHostTopoInfo host_topo;
- const CPUArchIdList *guest_cpu_list;
- uint64_t *msr_value;
- uint64_t msr_unit;
- uint64_t msr_limit;
- uint64_t msr_info;
-};
-
-enum KVMDirtyRingReaperState {
- KVM_DIRTY_RING_REAPER_NONE = 0,
- /* The reaper is sleeping */
- KVM_DIRTY_RING_REAPER_WAIT,
- /* The reaper is reaping for dirty pages */
- KVM_DIRTY_RING_REAPER_REAPING,
-};
-
-/*
- * KVM reaper instance, responsible for collecting the KVM dirty bits
- * via the dirty ring.
- */
-struct KVMDirtyRingReaper {
- /* The reaper thread */
- QemuThread reaper_thr;
- volatile uint64_t reaper_iteration; /* iteration number of reaper thr */
- volatile enum KVMDirtyRingReaperState reaper_state; /* reap thr state */
-};
-struct KVMState
-{
- AccelState parent_obj;
- /* Max number of KVM slots supported */
- int nr_slots_max;
- int fd;
- int vmfd;
- int coalesced_mmio;
- int coalesced_pio;
- struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
- bool coalesced_flush_in_progress;
- int vcpu_events;
-#ifdef TARGET_KVM_HAVE_GUEST_DEBUG
- QTAILQ_HEAD(, kvm_sw_breakpoint) kvm_sw_breakpoints;
-#endif
- int max_nested_state_len;
- int kvm_shadow_mem;
- bool kernel_irqchip_allowed;
- bool kernel_irqchip_required;
- OnOffAuto kernel_irqchip_split;
- bool sync_mmu;
- bool guest_state_protected;
- uint64_t manual_dirty_log_protect;
- /*
- * Older POSIX says that ioctl numbers are signed int, but in
- * practice they are not. (Newer POSIX doesn't specify ioctl
- * at all.) Linux, glibc and *BSD all treat ioctl numbers as
- * unsigned, and real-world ioctl values like KVM_GET_XSAVE have
- * bit 31 set, which means that passing them via an 'int' will
- * result in sign-extension when they get converted back to the
- * 'unsigned long' which the ioctl() prototype uses. Luckily Linux
- * always treats the argument as an unsigned 32-bit int, so any
- * possible sign-extension is deliberately ignored, but for
- * consistency we keep to the same type that glibc is using.
- */
- unsigned long irq_set_ioctl;
- unsigned int sigmask_len;
- GHashTable *gsimap;
-#ifdef KVM_CAP_IRQ_ROUTING
- struct kvm_irq_routing *irq_routes;
- int nr_allocated_irq_routes;
- unsigned long *used_gsi_bitmap;
- unsigned int gsi_count;
-#endif
- KVMMemoryListener memory_listener;
- QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus;
-
- /* For "info mtree -f" to tell if an MR is registered in KVM */
- int nr_as;
- struct KVMAs {
- KVMMemoryListener *ml;
- AddressSpace *as;
- } *as;
- uint64_t kvm_dirty_ring_bytes; /* Size of the per-vcpu dirty ring */
- uint32_t kvm_dirty_ring_size; /* Number of dirty GFNs per ring */
- bool kvm_dirty_ring_with_bitmap;
- uint64_t kvm_eager_split_size; /* Eager Page Splitting chunk size */
- struct KVMDirtyRingReaper reaper;
- struct KVMMsrEnergy msr_energy;
- NotifyVmexitOption notify_vmexit;
- uint32_t notify_window;
- uint32_t xen_version;
- uint32_t xen_caps;
- uint16_t xen_gnttab_max_frames;
- uint16_t xen_evtchn_max_pirq;
- char *device;
-};
-
-void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml,
- AddressSpace *as, int as_id, const char *name);
-
-void kvm_set_max_memslot_size(hwaddr max_slot_size);
-
-/**
- * kvm_hwpoison_page_add:
- *
- * Parameters:
- * @ram_addr: the address in the RAM for the poisoned page
- *
- * Add a poisoned page to the list
- *
- * Return: None.
- */
-void kvm_hwpoison_page_add(ram_addr_t ram_addr);
-#endif
+++ /dev/null
-/*
- * Xen HVM emulation support in KVM
- *
- * Copyright © 2019 Oracle and/or its affiliates. All rights reserved.
- * Copyright © 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#ifndef QEMU_SYSEMU_KVM_XEN_H
-#define QEMU_SYSEMU_KVM_XEN_H
-
-/* The KVM API uses these to indicate "no GPA" or "no GFN" */
-#define INVALID_GPA UINT64_MAX
-#define INVALID_GFN UINT64_MAX
-
-/* QEMU plays the rôle of dom0 for "interdomain" communication. */
-#define DOMID_QEMU 0
-
-int kvm_xen_soft_reset(void);
-uint32_t kvm_xen_get_caps(void);
-void *kvm_xen_get_vcpu_info_hva(uint32_t vcpu_id);
-bool kvm_xen_has_vcpu_callback_vector(void);
-void kvm_xen_inject_vcpu_callback_vector(uint32_t vcpu_id, int type);
-void kvm_xen_set_callback_asserted(void);
-int kvm_xen_set_vcpu_virq(uint32_t vcpu_id, uint16_t virq, uint16_t port);
-uint16_t kvm_xen_get_gnttab_max_frames(void);
-uint16_t kvm_xen_get_evtchn_max_pirq(void);
-
-#define kvm_xen_has_cap(cap) (!!(kvm_xen_get_caps() & \
- KVM_XEN_HVM_CONFIG_ ## cap))
-
-#define XEN_SPECIAL_AREA_ADDR 0xfeff8000UL
-#define XEN_SPECIAL_AREA_SIZE 0x4000UL
-
-#define XEN_SPECIALPAGE_CONSOLE 0
-#define XEN_SPECIALPAGE_XENSTORE 1
-
-#define XEN_SPECIAL_PFN(x) ((XEN_SPECIAL_AREA_ADDR >> TARGET_PAGE_BITS) + \
- XEN_SPECIALPAGE_##x)
-
-#endif /* QEMU_SYSEMU_KVM_XEN_H */
+++ /dev/null
-/*
- * QEMU memory mapping
- *
- * Copyright Fujitsu, Corp. 2011, 2012
- *
- * Authors:
- * Wen Congyang <wency@cn.fujitsu.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#ifndef MEMORY_MAPPING_H
-#define MEMORY_MAPPING_H
-
-#include "qemu/queue.h"
-#include "exec/cpu-common.h"
-
-typedef struct GuestPhysBlock {
- /* visible to guest, reflects PCI hole, etc */
- hwaddr target_start;
-
- /* implies size */
- hwaddr target_end;
-
- /* points into host memory */
- uint8_t *host_addr;
-
- /* points to the MemoryRegion that this block belongs to */
- MemoryRegion *mr;
-
- QTAILQ_ENTRY(GuestPhysBlock) next;
-} GuestPhysBlock;
-
-/* point-in-time snapshot of guest-visible physical mappings */
-typedef struct GuestPhysBlockList {
- unsigned num;
- QTAILQ_HEAD(, GuestPhysBlock) head;
-} GuestPhysBlockList;
-
-/* The physical and virtual address in the memory mapping are contiguous. */
-typedef struct MemoryMapping {
- hwaddr phys_addr;
- vaddr virt_addr;
- ram_addr_t length;
- QTAILQ_ENTRY(MemoryMapping) next;
-} MemoryMapping;
-
-struct MemoryMappingList {
- unsigned int num;
- MemoryMapping *last_mapping;
- QTAILQ_HEAD(, MemoryMapping) head;
-};
-
-/*
- * add or merge the memory region [phys_addr, phys_addr + length) into the
- * memory mapping's list. The region's virtual address starts with virt_addr,
- * and is contiguous. The list is sorted by phys_addr.
- */
-void memory_mapping_list_add_merge_sorted(MemoryMappingList *list,
- hwaddr phys_addr,
- hwaddr virt_addr,
- ram_addr_t length);
-
-void memory_mapping_list_free(MemoryMappingList *list);
-
-void memory_mapping_list_init(MemoryMappingList *list);
-
-void guest_phys_blocks_free(GuestPhysBlockList *list);
-void guest_phys_blocks_init(GuestPhysBlockList *list);
-void guest_phys_blocks_append(GuestPhysBlockList *list);
-
-bool qemu_get_guest_memory_mapping(MemoryMappingList *list,
- const GuestPhysBlockList *guest_phys_blocks,
- Error **errp);
-
-/* get guest's memory mapping without do paging(virtual address is 0). */
-void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list,
- const GuestPhysBlockList *guest_phys_blocks);
-
-void memory_mapping_filter(MemoryMappingList *list, int64_t begin,
- int64_t length);
-
-#endif
+++ /dev/null
-#ifndef SYSEMU_NUMA_H
-#define SYSEMU_NUMA_H
-
-#include "qemu/bitmap.h"
-#include "qapi/qapi-types-machine.h"
-#include "exec/cpu-common.h"
-
-struct CPUArchId;
-
-#define MAX_NODES 128
-#define NUMA_NODE_UNASSIGNED MAX_NODES
-#define NUMA_DISTANCE_MIN 10
-#define NUMA_DISTANCE_DEFAULT 20
-#define NUMA_DISTANCE_MAX 254
-#define NUMA_DISTANCE_UNREACHABLE 255
-
-/* the value of AcpiHmatLBInfo flags */
-enum {
- HMAT_LB_MEM_MEMORY = 0,
- HMAT_LB_MEM_CACHE_1ST_LEVEL = 1,
- HMAT_LB_MEM_CACHE_2ND_LEVEL = 2,
- HMAT_LB_MEM_CACHE_3RD_LEVEL = 3,
- HMAT_LB_LEVELS /* must be the last entry */
-};
-
-/* the value of AcpiHmatLBInfo data type */
-enum {
- HMAT_LB_DATA_ACCESS_LATENCY = 0,
- HMAT_LB_DATA_READ_LATENCY = 1,
- HMAT_LB_DATA_WRITE_LATENCY = 2,
- HMAT_LB_DATA_ACCESS_BANDWIDTH = 3,
- HMAT_LB_DATA_READ_BANDWIDTH = 4,
- HMAT_LB_DATA_WRITE_BANDWIDTH = 5,
- HMAT_LB_TYPES /* must be the last entry */
-};
-
-#define UINT16_BITS 16
-
-typedef struct NodeInfo {
- uint64_t node_mem;
- struct HostMemoryBackend *node_memdev;
- bool present;
- bool has_cpu;
- bool has_gi;
- uint8_t lb_info_provided;
- uint16_t initiator;
- uint8_t distance[MAX_NODES];
-} NodeInfo;
-
-typedef struct NumaNodeMem {
- uint64_t node_mem;
- uint64_t node_plugged_mem;
-} NumaNodeMem;
-
-struct HMAT_LB_Data {
- uint8_t initiator;
- uint8_t target;
- uint64_t data;
-};
-typedef struct HMAT_LB_Data HMAT_LB_Data;
-
-struct HMAT_LB_Info {
- /* Indicates it's memory or the specified level memory side cache. */
- uint8_t hierarchy;
-
- /* Present the type of data, access/read/write latency or bandwidth. */
- uint8_t data_type;
-
- /* The range bitmap of bandwidth for calculating common base */
- uint64_t range_bitmap;
-
- /* The common base unit for latencies or bandwidths */
- uint64_t base;
-
- /* Array to store the latencies or bandwidths */
- GArray *list;
-};
-typedef struct HMAT_LB_Info HMAT_LB_Info;
-
-struct NumaState {
- /* Number of NUMA nodes */
- int num_nodes;
-
- /* Allow setting NUMA distance for different NUMA nodes */
- bool have_numa_distance;
-
- /* Detect if HMAT support is enabled. */
- bool hmat_enabled;
-
- /* NUMA nodes information */
- NodeInfo nodes[MAX_NODES];
-
- /* NUMA nodes HMAT Locality Latency and Bandwidth Information */
- HMAT_LB_Info *hmat_lb[HMAT_LB_LEVELS][HMAT_LB_TYPES];
-
- /* Memory Side Cache Information Structure */
- NumaHmatCacheOptions *hmat_cache[MAX_NODES][HMAT_LB_LEVELS];
-};
-typedef struct NumaState NumaState;
-
-void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp);
-void parse_numa_opts(MachineState *ms);
-void parse_numa_hmat_lb(NumaState *numa_state, NumaHmatLBOptions *node,
- Error **errp);
-void parse_numa_hmat_cache(MachineState *ms, NumaHmatCacheOptions *node,
- Error **errp);
-void numa_complete_configuration(MachineState *ms);
-void query_numa_node_mem(NumaNodeMem node_mem[], MachineState *ms);
-extern QemuOptsList qemu_numa_opts;
-void numa_cpu_pre_plug(const struct CPUArchId *slot, DeviceState *dev,
- Error **errp);
-bool numa_uses_legacy_mem(void);
-
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2018-2019 Maxime Villard, All rights reserved.
- *
- * NetBSD Virtual Machine Monitor (NVMM) accelerator support.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-/* header to be included in non-NVMM-specific code */
-
-#ifndef QEMU_NVMM_H
-#define QEMU_NVMM_H
-
-#ifdef COMPILING_PER_TARGET
-
-#ifdef CONFIG_NVMM
-
-int nvmm_enabled(void);
-
-#else /* CONFIG_NVMM */
-
-#define nvmm_enabled() (0)
-
-#endif /* CONFIG_NVMM */
-
-#endif /* COMPILING_PER_TARGET */
-
-#endif /* QEMU_NVMM_H */
+++ /dev/null
-/*
- * posix specific declarations
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- * Copyright (c) 2010 Jes Sorensen <Jes.Sorensen@redhat.com>
- *
- * 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.
- */
-
-#ifndef QEMU_OS_POSIX_H
-#define QEMU_OS_POSIX_H
-
-#include <sys/mman.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/un.h>
-
-#ifdef CONFIG_SYSMACROS
-#include <sys/sysmacros.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void os_set_line_buffering(void);
-void os_setup_early_signal_handling(void);
-void os_set_proc_name(const char *s);
-void os_setup_signal_handling(void);
-int os_set_daemonize(bool d);
-bool is_daemonized(void);
-void os_daemonize(void);
-bool os_set_runas(const char *user_id);
-void os_set_chroot(const char *path);
-void os_setup_limits(void);
-void os_setup_post(void);
-int os_mlock(void);
-
-/**
- * qemu_alloc_stack:
- * @sz: pointer to a size_t holding the requested usable stack size
- *
- * Allocate memory that can be used as a stack, for instance for
- * coroutines. If the memory cannot be allocated, this function
- * will abort (like g_malloc()). This function also inserts an
- * additional guard page to catch a potential stack overflow.
- * Note that the memory required for the guard page and alignment
- * and minimal stack size restrictions will increase the value of sz.
- *
- * The allocated stack must be freed with qemu_free_stack().
- *
- * Returns: pointer to (the lowest address of) the stack memory.
- */
-void *qemu_alloc_stack(size_t *sz);
-
-/**
- * qemu_free_stack:
- * @stack: stack to free
- * @sz: size of stack in bytes
- *
- * Free a stack allocated via qemu_alloc_stack(). Note that sz must
- * be exactly the adjusted stack size returned by qemu_alloc_stack.
- */
-void qemu_free_stack(void *stack, size_t sz);
-
-/* POSIX and Mingw32 differ in the name of the stdio lock functions. */
-
-static inline void qemu_flockfile(FILE *f)
-{
- flockfile(f);
-}
-
-static inline void qemu_funlockfile(FILE *f)
-{
- funlockfile(f);
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-/*
- * win32 specific declarations
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- * Copyright (c) 2010 Jes Sorensen <Jes.Sorensen@redhat.com>
- *
- * 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.
- */
-
-#ifndef QEMU_OS_WIN32_H
-#define QEMU_OS_WIN32_H
-
-#include <winsock2.h>
-#include <windows.h>
-#include <ws2tcpip.h>
-#include "qemu/typedefs.h"
-
-#ifdef HAVE_AFUNIX_H
-#include <afunix.h>
-#else
-/*
- * Fallback definitions of things we need in afunix.h, if not available from
- * the used Windows SDK or MinGW headers.
- */
-#define UNIX_PATH_MAX 108
-
-typedef struct sockaddr_un {
- ADDRESS_FAMILY sun_family;
- char sun_path[UNIX_PATH_MAX];
-} SOCKADDR_UN, *PSOCKADDR_UN;
-
-#define SIO_AF_UNIX_GETPEERPID _WSAIOR(IOC_VENDOR, 256)
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined(__aarch64__)
-/*
- * On windows-arm64, setjmp is available in only one variant, and longjmp always
- * does stack unwinding. This crash with generated code.
- * Thus, we use another implementation of setjmp (not windows one), coming from
- * mingw, which never performs stack unwinding.
- */
-#undef setjmp
-#undef longjmp
-/*
- * These functions are not declared in setjmp.h because __aarch64__ defines
- * setjmp to _setjmpex instead. However, they are still defined in libmingwex.a,
- * which gets linked automatically.
- */
-int __mingw_setjmp(jmp_buf);
-void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int);
-#define setjmp(env) __mingw_setjmp(env)
-#define longjmp(env, val) __mingw_longjmp(env, val)
-#elif defined(_WIN64)
-/*
- * On windows-x64, setjmp is implemented by _setjmp which needs a second parameter.
- * If this parameter is NULL, longjump does no stack unwinding.
- * That is what we need for QEMU. Passing the value of register rsp (default)
- * lets longjmp try a stack unwinding which will crash with generated code.
- */
-# undef setjmp
-# define setjmp(env) _setjmp(env, NULL)
-#endif /* __aarch64__ */
-/* QEMU uses sigsetjmp()/siglongjmp() as the portable way to specify
- * "longjmp and don't touch the signal masks". Since we know that the
- * savemask parameter will always be zero we can safely define these
- * in terms of setjmp/longjmp on Win32.
- */
-#define sigjmp_buf jmp_buf
-#define sigsetjmp(env, savemask) setjmp(env)
-#define siglongjmp(env, val) longjmp(env, val)
-
-/* Missing POSIX functions. Don't use MinGW-w64 macros. */
-#ifndef _POSIX_THREAD_SAFE_FUNCTIONS
-#undef gmtime_r
-struct tm *gmtime_r(const time_t *timep, struct tm *result);
-#undef localtime_r
-struct tm *localtime_r(const time_t *timep, struct tm *result);
-#endif /* _POSIX_THREAD_SAFE_FUNCTIONS */
-
-static inline void os_setup_signal_handling(void) {}
-static inline void os_daemonize(void) {}
-static inline void os_setup_post(void) {}
-static inline void os_set_proc_name(const char *dummy) {}
-void os_set_line_buffering(void);
-void os_setup_early_signal_handling(void);
-
-int getpagesize(void);
-
-#if !defined(EPROTONOSUPPORT)
-# define EPROTONOSUPPORT EINVAL
-#endif
-
-static inline int os_set_daemonize(bool d)
-{
- if (d) {
- return -ENOTSUP;
- }
- return 0;
-}
-
-static inline bool is_daemonized(void)
-{
- return false;
-}
-
-static inline int os_mlock(void)
-{
- return -ENOSYS;
-}
-
-static inline void os_setup_limits(void)
-{
- return;
-}
-
-#define fsync _commit
-
-#if !defined(lseek)
-# define lseek _lseeki64
-#endif
-
-int qemu_ftruncate64(int, int64_t);
-
-#if !defined(ftruncate)
-# define ftruncate qemu_ftruncate64
-#endif
-
-static inline char *realpath(const char *path, char *resolved_path)
-{
- _fullpath(resolved_path, path, _MAX_PATH);
- return resolved_path;
-}
-
-/*
- * Older versions of MinGW do not import _lock_file and _unlock_file properly.
- * This was fixed for v6.0.0 with commit b48e3ac8969d.
- */
-static inline void qemu_flockfile(FILE *f)
-{
-#ifdef HAVE__LOCK_FILE
- _lock_file(f);
-#endif
-}
-
-static inline void qemu_funlockfile(FILE *f)
-{
-#ifdef HAVE__LOCK_FILE
- _unlock_file(f);
-#endif
-}
-
-/* Helper for WSAEventSelect, to report errors */
-bool qemu_socket_select(int sockfd, WSAEVENT hEventObject,
- long lNetworkEvents, Error **errp);
-
-bool qemu_socket_unselect(int sockfd, Error **errp);
-
-/* We wrap all the sockets functions so that we can set errno based on
- * WSAGetLastError(), and use file-descriptors instead of SOCKET.
- */
-
-/*
- * qemu_close_socket_osfhandle:
- * @fd: a file descriptor associated with a SOCKET
- *
- * Close only the C run-time file descriptor, leave the SOCKET opened.
- *
- * Returns zero on success. On error, -1 is returned, and errno is set to
- * indicate the error.
- */
-int qemu_close_socket_osfhandle(int fd);
-
-#undef close
-#define close qemu_close_wrap
-int qemu_close_wrap(int fd);
-
-#undef connect
-#define connect qemu_connect_wrap
-int qemu_connect_wrap(int sockfd, const struct sockaddr *addr,
- socklen_t addrlen);
-
-#undef listen
-#define listen qemu_listen_wrap
-int qemu_listen_wrap(int sockfd, int backlog);
-
-#undef bind
-#define bind qemu_bind_wrap
-int qemu_bind_wrap(int sockfd, const struct sockaddr *addr,
- socklen_t addrlen);
-
-#undef socket
-#define socket qemu_socket_wrap
-int qemu_socket_wrap(int domain, int type, int protocol);
-
-#undef accept
-#define accept qemu_accept_wrap
-int qemu_accept_wrap(int sockfd, struct sockaddr *addr,
- socklen_t *addrlen);
-
-#undef shutdown
-#define shutdown qemu_shutdown_wrap
-int qemu_shutdown_wrap(int sockfd, int how);
-
-#undef ioctlsocket
-#define ioctlsocket qemu_ioctlsocket_wrap
-int qemu_ioctlsocket_wrap(int fd, int req, void *val);
-
-#undef getsockopt
-#define getsockopt qemu_getsockopt_wrap
-int qemu_getsockopt_wrap(int sockfd, int level, int optname,
- void *optval, socklen_t *optlen);
-
-#undef setsockopt
-#define setsockopt qemu_setsockopt_wrap
-int qemu_setsockopt_wrap(int sockfd, int level, int optname,
- const void *optval, socklen_t optlen);
-
-#undef getpeername
-#define getpeername qemu_getpeername_wrap
-int qemu_getpeername_wrap(int sockfd, struct sockaddr *addr,
- socklen_t *addrlen);
-
-#undef getsockname
-#define getsockname qemu_getsockname_wrap
-int qemu_getsockname_wrap(int sockfd, struct sockaddr *addr,
- socklen_t *addrlen);
-
-#undef send
-#define send qemu_send_wrap
-ssize_t qemu_send_wrap(int sockfd, const void *buf, size_t len, int flags);
-
-#undef sendto
-#define sendto qemu_sendto_wrap
-ssize_t qemu_sendto_wrap(int sockfd, const void *buf, size_t len, int flags,
- const struct sockaddr *addr, socklen_t addrlen);
-
-#undef recv
-#define recv qemu_recv_wrap
-ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags);
-
-#undef recvfrom
-#define recvfrom qemu_recvfrom_wrap
-ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
- struct sockaddr *addr, socklen_t *addrlen);
-
-EXCEPTION_DISPOSITION
-win32_close_exception_handler(struct _EXCEPTION_RECORD*, void*,
- struct _CONTEXT*, void*);
-
-void *qemu_win32_map_alloc(size_t size, HANDLE *h, Error **errp);
-void qemu_win32_map_free(void *ptr, HANDLE h, Error **errp);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-/*
- * Test Server
- *
- * Copyright IBM, Corp. 2011
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#ifndef QTEST_H
-#define QTEST_H
-
-#include "chardev/char.h"
-
-extern bool qtest_allowed;
-
-static inline bool qtest_enabled(void)
-{
- return qtest_allowed;
-}
-
-#ifndef CONFIG_USER_ONLY
-void qtest_send_prefix(CharBackend *chr);
-void G_GNUC_PRINTF(2, 3) qtest_sendf(CharBackend *chr, const char *fmt, ...);
-void qtest_set_command_cb(bool (*pc_cb)(CharBackend *chr, gchar **words));
-bool qtest_driver(void);
-
-void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **errp);
-
-void qtest_server_set_send_handler(void (*send)(void *, const char *),
- void *opaque);
-void qtest_server_inproc_recv(void *opaque, const char *buf);
-#endif
-
-#endif
+++ /dev/null
-/*
- * QEMU replay (system interface)
- *
- * Copyright (c) 2010-2015 Institute for System Programming
- * of the Russian Academy of Sciences.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-#ifndef SYSEMU_REPLAY_H
-#define SYSEMU_REPLAY_H
-
-#ifdef CONFIG_USER_ONLY
-#error Cannot include this header from user emulation
-#endif
-
-#include "exec/replay-core.h"
-#include "qapi/qapi-types-misc.h"
-#include "qapi/qapi-types-run-state.h"
-#include "qapi/qapi-types-ui.h"
-#include "block/aio.h"
-
-/* replay clock kinds */
-enum ReplayClockKind {
- /* host_clock */
- REPLAY_CLOCK_HOST,
- /* virtual_rt_clock */
- REPLAY_CLOCK_VIRTUAL_RT,
- REPLAY_CLOCK_COUNT
-};
-typedef enum ReplayClockKind ReplayClockKind;
-
-/* IDs of the checkpoints */
-enum ReplayCheckpoint {
- CHECKPOINT_CLOCK_WARP_START,
- CHECKPOINT_CLOCK_WARP_ACCOUNT,
- CHECKPOINT_RESET_REQUESTED,
- CHECKPOINT_SUSPEND_REQUESTED,
- CHECKPOINT_CLOCK_VIRTUAL,
- CHECKPOINT_CLOCK_HOST,
- CHECKPOINT_CLOCK_VIRTUAL_RT,
- CHECKPOINT_INIT,
- CHECKPOINT_RESET,
- CHECKPOINT_COUNT
-};
-typedef enum ReplayCheckpoint ReplayCheckpoint;
-
-typedef struct ReplayNetState ReplayNetState;
-
-/* Name of the initial VM snapshot */
-extern char *replay_snapshot;
-
-/* Replay locking
- *
- * The locks are needed to protect the shared structures and log file
- * when doing record/replay. They also are the main sync-point between
- * the main-loop thread and the vCPU thread. This was a role
- * previously filled by the BQL which has been busy trying to reduce
- * its impact across the code. This ensures blocks of events stay
- * sequential and reproducible.
- */
-
-void replay_mutex_lock(void);
-void replay_mutex_unlock(void);
-
-/* Processing the instructions */
-
-/*! Returns number of executed instructions. */
-uint64_t replay_get_current_icount(void);
-/*! Returns number of instructions to execute in replay mode. */
-int replay_get_instructions(void);
-/*! Updates instructions counter in replay mode. */
-void replay_account_executed_instructions(void);
-
-/* Processing clocks and other time sources */
-
-/*! Save the specified clock */
-int64_t replay_save_clock(ReplayClockKind kind, int64_t clock,
- int64_t raw_icount);
-/*! Read the specified clock from the log or return cached data */
-int64_t replay_read_clock(ReplayClockKind kind, int64_t raw_icount);
-/*! Saves or reads the clock depending on the current replay mode. */
-#define REPLAY_CLOCK(clock, value) \
- !icount_enabled() ? (value) : \
- (replay_mode == REPLAY_MODE_PLAY \
- ? replay_read_clock((clock), icount_get_raw()) \
- : replay_mode == REPLAY_MODE_RECORD \
- ? replay_save_clock((clock), (value), icount_get_raw()) \
- : (value))
-#define REPLAY_CLOCK_LOCKED(clock, value) \
- !icount_enabled() ? (value) : \
- (replay_mode == REPLAY_MODE_PLAY \
- ? replay_read_clock((clock), icount_get_raw_locked()) \
- : replay_mode == REPLAY_MODE_RECORD \
- ? replay_save_clock((clock), (value), icount_get_raw_locked()) \
- : (value))
-
-/* Events */
-
-/*! Called when qemu shutdown is requested. */
-void replay_shutdown_request(ShutdownCause cause);
-/*! Should be called at check points in the execution.
- These check points are skipped, if they were not met.
- Saves checkpoint in the SAVE mode and validates in the PLAY mode.
- Returns 0 in PLAY mode if checkpoint was not found.
- Returns 1 in all other cases. */
-bool replay_checkpoint(ReplayCheckpoint checkpoint);
-/*! Used to determine that checkpoint or async event is pending.
- Does not proceed to the next event in the log. */
-bool replay_has_event(void);
-/*
- * Processes the async events added to the queue (while recording)
- * or reads the events from the file (while replaying).
- */
-void replay_async_events(void);
-
-/* Asynchronous events queue */
-
-/*! Enables storing events in the queue */
-void replay_enable_events(void);
-/*! Returns true when saving events is enabled */
-bool replay_events_enabled(void);
-/* Flushes events queue */
-void replay_flush_events(void);
-/*! Adds bottom half event to the queue */
-void replay_bh_schedule_event(QEMUBH *bh);
-/* Adds oneshot bottom half event to the queue */
-void replay_bh_schedule_oneshot_event(AioContext *ctx,
- QEMUBHFunc *cb, void *opaque);
-/*! Adds input event to the queue */
-void replay_input_event(QemuConsole *src, InputEvent *evt);
-/*! Adds input sync event to the queue */
-void replay_input_sync_event(void);
-/*! Adds block layer event to the queue */
-void replay_block_event(QEMUBH *bh, uint64_t id);
-/*! Returns ID for the next block event */
-uint64_t blkreplay_next_id(void);
-
-/* Character device */
-
-/*! Registers char driver to save it's events */
-void replay_register_char_driver(struct Chardev *chr);
-/*! Saves write to char device event to the log */
-void replay_chr_be_write(struct Chardev *s, const uint8_t *buf, int len);
-/*! Writes char write return value to the replay log. */
-void replay_char_write_event_save(int res, int offset);
-/*! Reads char write return value from the replay log. */
-void replay_char_write_event_load(int *res, int *offset);
-/*! Reads information about read_all character event. */
-int replay_char_read_all_load(uint8_t *buf);
-/*! Writes character read_all error code into the replay log. */
-void replay_char_read_all_save_error(int res);
-/*! Writes character read_all execution result into the replay log. */
-void replay_char_read_all_save_buf(uint8_t *buf, int offset);
-
-/* Network */
-
-/*! Registers replay network filter attached to some backend. */
-ReplayNetState *replay_register_net(NetFilterState *nfs);
-/*! Unregisters replay network filter. */
-void replay_unregister_net(ReplayNetState *rns);
-/*! Called to write network packet to the replay log. */
-void replay_net_packet_event(ReplayNetState *rns, unsigned flags,
- const struct iovec *iov, int iovcnt);
-
-/* Audio */
-
-/*! Saves/restores number of played samples of audio out operation. */
-void replay_audio_out(size_t *played);
-/*! Saves/restores recorded samples of audio in operation. */
-void replay_audio_in(size_t *recorded, void *samples, size_t *wpos, size_t size);
-
-/* VM state operations */
-
-/*! Called at the start of execution.
- Loads or saves initial vmstate depending on execution mode. */
-void replay_vmstate_init(void);
-/*! Called to ensure that replay state is consistent and VM snapshot
- can be created */
-bool replay_can_snapshot(void);
-
-#endif
+++ /dev/null
-/*
- * Reset handlers.
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- * Copyright (c) 2016 Red Hat, Inc.
- * Copyright (c) 2024 Linaro, Ltd.
- *
- * 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.
- */
-
-#ifndef QEMU_SYSEMU_RESET_H
-#define QEMU_SYSEMU_RESET_H
-
-#include "hw/resettable.h"
-#include "qapi/qapi-events-run-state.h"
-
-typedef void QEMUResetHandler(void *opaque);
-
-/**
- * qemu_register_resettable: Register an object to be reset
- * @obj: object to be reset: it must implement the Resettable interface
- *
- * Register @obj on the list of objects which will be reset when the
- * simulation is reset. These objects will be reset in the order
- * they were added, using the three-phase Resettable protocol,
- * so first all objects go through the enter phase, then all objects
- * go through the hold phase, and then finally all go through the
- * exit phase.
- *
- * It is not permitted to register or unregister reset functions or
- * resettable objects from within any of the reset phase methods of @obj.
- *
- * We assume that the caller holds the BQL.
- */
-void qemu_register_resettable(Object *obj);
-
-/**
- * qemu_unregister_resettable: Unregister an object to be reset
- * @obj: object to unregister
- *
- * Remove @obj from the list of objects which are reset when the
- * simulation is reset. It must have been previously added to
- * the list via qemu_register_resettable().
- *
- * We assume that the caller holds the BQL.
- */
-void qemu_unregister_resettable(Object *obj);
-
-/**
- * qemu_register_reset: Register a callback for system reset
- * @func: function to call
- * @opaque: opaque data to pass to @func
- *
- * Register @func on the list of functions which are called when the
- * entire system is reset. Functions registered with this API and
- * Resettable objects registered with qemu_register_resettable() are
- * handled together, in the order in which they were registered.
- * Functions registered with this API are called in the 'hold' phase
- * of the 3-phase reset.
- *
- * In general this function should not be used in new code where possible;
- * for instance, device model reset is better accomplished using the
- * methods on DeviceState.
- *
- * It is not permitted to register or unregister reset functions or
- * resettable objects from within the @func callback.
- *
- * We assume that the caller holds the BQL.
- */
-void qemu_register_reset(QEMUResetHandler *func, void *opaque);
-
-/**
- * qemu_register_reset_nosnapshotload: Register a callback for system reset
- * @func: function to call
- * @opaque: opaque data to pass to @func
- *
- * This is the same as qemu_register_reset(), except that @func is
- * not called if the reason that the system is being reset is to
- * put it into a clean state prior to loading a snapshot (i.e. for
- * SHUTDOWN_CAUSE_SNAPSHOT_LOAD).
- */
-void qemu_register_reset_nosnapshotload(QEMUResetHandler *func, void *opaque);
-
-/**
- * qemu_unregister_reset: Unregister a system reset callback
- * @func: function registered with qemu_register_reset()
- * @opaque: the same opaque data that was passed to qemu_register_reset()
- *
- * Undo the effects of a qemu_register_reset(). The @func and @opaque
- * must both match the arguments originally used with qemu_register_reset().
- *
- * We assume that the caller holds the BQL.
- */
-void qemu_unregister_reset(QEMUResetHandler *func, void *opaque);
-
-/**
- * qemu_devices_reset: Perform a complete system reset
- * @reason: type of the reset
- *
- * This function performs the low-level work needed to do a complete reset
- * of the system (calling all the callbacks registered with
- * qemu_register_reset() and resetting all the Resettable objects registered
- * with qemu_register_resettable()). It should only be called by the code in a
- * MachineClass reset method.
- *
- * If you want to trigger a system reset from, for instance, a device
- * model, don't use this function. Use qemu_system_reset_request().
- */
-void qemu_devices_reset(ResetType type);
-
-#endif
+++ /dev/null
-/*
- * QEMU Random Number Generator Backend
- *
- * Copyright IBM, Corp. 2012
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-#ifndef QEMU_RNG_RANDOM_H
-#define QEMU_RNG_RANDOM_H
-
-#include "qom/object.h"
-
-#define TYPE_RNG_RANDOM "rng-random"
-OBJECT_DECLARE_SIMPLE_TYPE(RngRandom, RNG_RANDOM)
-
-
-#endif
+++ /dev/null
-/*
- * QEMU Random Number Generator Backend
- *
- * Copyright IBM, Corp. 2012
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef QEMU_RNG_H
-#define QEMU_RNG_H
-
-#include "qemu/queue.h"
-#include "qom/object.h"
-
-#define TYPE_RNG_BACKEND "rng-backend"
-OBJECT_DECLARE_TYPE(RngBackend, RngBackendClass,
- RNG_BACKEND)
-
-#define TYPE_RNG_BUILTIN "rng-builtin"
-
-typedef struct RngRequest RngRequest;
-
-typedef void (EntropyReceiveFunc)(void *opaque,
- const void *data,
- size_t size);
-
-struct RngRequest
-{
- EntropyReceiveFunc *receive_entropy;
- uint8_t *data;
- void *opaque;
- size_t offset;
- size_t size;
- QSIMPLEQ_ENTRY(RngRequest) next;
-};
-
-struct RngBackendClass
-{
- ObjectClass parent_class;
-
- void (*request_entropy)(RngBackend *s, RngRequest *req);
-
- void (*opened)(RngBackend *s, Error **errp);
-};
-
-struct RngBackend
-{
- Object parent;
-
- /*< protected >*/
- bool opened;
- QSIMPLEQ_HEAD(, RngRequest) requests;
-};
-
-
-/**
- * rng_backend_request_entropy:
- * @s: the backend to request entropy from
- * @size: the number of bytes of data to request
- * @receive_entropy: a function to be invoked when entropy is available
- * @opaque: data that should be passed to @receive_entropy
- *
- * This function is used by the front-end to request entropy from an entropy
- * source. This function can be called multiple times before @receive_entropy
- * is invoked with different values of @receive_entropy and @opaque. The
- * backend will queue each request and handle appropriately.
- *
- * The backend does not need to pass the full amount of data to @receive_entropy
- * but will pass a value greater than 0.
- */
-void rng_backend_request_entropy(RngBackend *s, size_t size,
- EntropyReceiveFunc *receive_entropy,
- void *opaque);
-
-/**
- * rng_backend_free_request:
- * @s: the backend that created the request
- * @req: the request to finalize
- *
- * Used by child rng backend classes to finalize requests once they've been
- * processed. The request is removed from the list of active requests and
- * deleted.
- */
-void rng_backend_finalize_request(RngBackend *s, RngRequest *req);
-#endif
+++ /dev/null
-/*
- * RTC configuration and clock read
- *
- * Copyright (c) 2003-2021 QEMU contributors
- *
- * 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.
- */
-
-#ifndef SYSEMU_RTC_H
-#define SYSEMU_RTC_H
-
-/**
- * qemu_get_timedate: Get the current RTC time
- * @tm: struct tm to fill in with RTC time
- * @offset: offset in seconds to adjust the RTC time by before
- * converting to struct tm format.
- *
- * This function fills in @tm with the current RTC time, as adjusted
- * by @offset (for example, if @offset is 3600 then the returned time/date
- * will be one hour further ahead than the current RTC time).
- *
- * The usual use is by RTC device models, which should call this function
- * to find the time/date value that they should return to the guest
- * when it reads the RTC registers.
- *
- * The behaviour of the clock whose value this function returns will
- * depend on the -rtc command line option passed by the user.
- */
-void qemu_get_timedate(struct tm *tm, time_t offset);
-
-/**
- * qemu_timedate_diff: Return difference between a struct tm and the RTC
- * @tm: struct tm containing the date/time to compare against
- *
- * Returns the difference in seconds between the RTC clock time
- * and the date/time specified in @tm. For example, if @tm specifies
- * a timestamp one hour further ahead than the current RTC time
- * then this function will return 3600.
- */
-time_t qemu_timedate_diff(struct tm *tm);
-
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2020 Oracle and/or its affiliates.
- *
- * This work is licensed under the terms of the GNU GPL, version 2.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#ifndef RUNSTATE_ACTION_H
-#define RUNSTATE_ACTION_H
-
-#include "qapi/qapi-commands-run-state.h"
-
-/* in system/runstate-action.c */
-extern RebootAction reboot_action;
-extern ShutdownAction shutdown_action;
-extern PanicAction panic_action;
-
-#endif /* RUNSTATE_ACTION_H */
+++ /dev/null
-#ifndef SYSEMU_RUNSTATE_H
-#define SYSEMU_RUNSTATE_H
-
-#include "qapi/qapi-types-run-state.h"
-#include "qemu/notify.h"
-
-bool runstate_check(RunState state);
-void runstate_set(RunState new_state);
-RunState runstate_get(void);
-bool runstate_is_running(void);
-bool runstate_needs_reset(void);
-void runstate_replay_enable(void);
-
-typedef void VMChangeStateHandler(void *opaque, bool running, RunState state);
-
-VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
- void *opaque);
-VMChangeStateEntry *qemu_add_vm_change_state_handler_prio(
- VMChangeStateHandler *cb, void *opaque, int priority);
-VMChangeStateEntry *
-qemu_add_vm_change_state_handler_prio_full(VMChangeStateHandler *cb,
- VMChangeStateHandler *prepare_cb,
- void *opaque, int priority);
-VMChangeStateEntry *qdev_add_vm_change_state_handler(DeviceState *dev,
- VMChangeStateHandler *cb,
- void *opaque);
-VMChangeStateEntry *qdev_add_vm_change_state_handler_full(
- DeviceState *dev, VMChangeStateHandler *cb,
- VMChangeStateHandler *prepare_cb, void *opaque);
-void qemu_del_vm_change_state_handler(VMChangeStateEntry *e);
-/**
- * vm_state_notify: Notify the state of the VM
- *
- * @running: whether the VM is running or not.
- * @state: the #RunState of the VM.
- */
-void vm_state_notify(bool running, RunState state);
-
-static inline bool shutdown_caused_by_guest(ShutdownCause cause)
-{
- return cause >= SHUTDOWN_CAUSE_GUEST_SHUTDOWN;
-}
-
-/*
- * In a "live" state, the vcpu clock is ticking, and the runstate notifiers
- * think we are running.
- */
-static inline bool runstate_is_live(RunState state)
-{
- return state == RUN_STATE_RUNNING || state == RUN_STATE_SUSPENDED;
-}
-
-void vm_start(void);
-
-/**
- * vm_prepare_start: Prepare for starting/resuming the VM
- *
- * @step_pending: whether any of the CPUs is about to be single-stepped by gdb
- */
-int vm_prepare_start(bool step_pending);
-
-/**
- * vm_resume: If @state is a live state, start the vm and set the state,
- * else just set the state.
- *
- * @state: the state to restore
- */
-void vm_resume(RunState state);
-
-int vm_stop(RunState state);
-int vm_stop_force_state(RunState state);
-int vm_shutdown(void);
-void vm_set_suspended(bool suspended);
-bool vm_get_suspended(void);
-
-typedef enum WakeupReason {
- /* Always keep QEMU_WAKEUP_REASON_NONE = 0 */
- QEMU_WAKEUP_REASON_NONE = 0,
- QEMU_WAKEUP_REASON_RTC,
- QEMU_WAKEUP_REASON_PMTIMER,
- QEMU_WAKEUP_REASON_OTHER,
-} WakeupReason;
-
-void qemu_system_reset_request(ShutdownCause reason);
-void qemu_system_suspend_request(void);
-void qemu_register_suspend_notifier(Notifier *notifier);
-bool qemu_wakeup_suspend_enabled(void);
-void qemu_system_wakeup_request(WakeupReason reason, Error **errp);
-void qemu_system_wakeup_enable(WakeupReason reason, bool enabled);
-void qemu_register_wakeup_notifier(Notifier *notifier);
-void qemu_register_wakeup_support(void);
-void qemu_system_shutdown_request_with_code(ShutdownCause reason,
- int exit_code);
-void qemu_system_shutdown_request(ShutdownCause reason);
-void qemu_system_powerdown_request(void);
-void qemu_register_powerdown_notifier(Notifier *notifier);
-void qemu_register_shutdown_notifier(Notifier *notifier);
-void qemu_system_debug_request(void);
-void qemu_system_vmstop_request(RunState reason);
-void qemu_system_vmstop_request_prepare(void);
-bool qemu_vmstop_requested(RunState *r);
-ShutdownCause qemu_shutdown_requested_get(void);
-ShutdownCause qemu_reset_requested_get(void);
-void qemu_system_killed(int signal, pid_t pid);
-void qemu_system_reset(ShutdownCause reason);
-void qemu_system_guest_panicked(GuestPanicInformation *info);
-void qemu_system_guest_crashloaded(GuestPanicInformation *info);
-void qemu_system_guest_pvshutdown(void);
-bool qemu_system_dump_in_progress(void);
-
-#endif
-
+++ /dev/null
-/*
- * QEMU seccomp mode 2 support with libseccomp
- *
- * Copyright IBM, Corp. 2012
- *
- * Authors:
- * Eduardo Otubo <eotubo@br.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-#ifndef QEMU_SECCOMP_H
-#define QEMU_SECCOMP_H
-
-#define QEMU_SECCOMP_SET_DEFAULT (1 << 0)
-#define QEMU_SECCOMP_SET_OBSOLETE (1 << 1)
-#define QEMU_SECCOMP_SET_PRIVILEGED (1 << 2)
-#define QEMU_SECCOMP_SET_SPAWN (1 << 3)
-#define QEMU_SECCOMP_SET_RESOURCECTL (1 << 4)
-
-int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp);
-
-#endif
+++ /dev/null
-/*
- * QEMU SPDM socket support
- *
- * 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.
- */
-
-#ifndef SPDM_REQUESTER_H
-#define SPDM_REQUESTER_H
-
-/**
- * spdm_socket_connect: connect to an external SPDM socket
- * @port: port to connect to
- * @errp: error object handle
- *
- * This will connect to an external SPDM socket server. On error
- * it will return -1 and errp will be set. On success this function
- * will return the socket number.
- */
-int spdm_socket_connect(uint16_t port, Error **errp);
-
-/**
- * spdm_socket_rsp: send and receive a message to a SPDM server
- * @socket: socket returned from spdm_socket_connect()
- * @transport_type: SPDM_SOCKET_TRANSPORT_TYPE_* macro
- * @req: request buffer
- * @req_len: request buffer length
- * @rsp: response buffer
- * @rsp_len: response buffer length
- *
- * Send platform data to a SPDM server on socket and then receive
- * a response.
- */
-uint32_t spdm_socket_rsp(const int socket, uint32_t transport_type,
- void *req, uint32_t req_len,
- void *rsp, uint32_t rsp_len);
-
-/**
- * spdm_socket_close: send a shutdown command to the server
- * @socket: socket returned from spdm_socket_connect()
- * @transport_type: SPDM_SOCKET_TRANSPORT_TYPE_* macro
- *
- * This will issue a shutdown command to the server.
- */
-void spdm_socket_close(const int socket, uint32_t transport_type);
-
-#define SPDM_SOCKET_COMMAND_NORMAL 0x0001
-#define SPDM_SOCKET_COMMAND_OOB_ENCAP_KEY_UPDATE 0x8001
-#define SPDM_SOCKET_COMMAND_CONTINUE 0xFFFD
-#define SPDM_SOCKET_COMMAND_SHUTDOWN 0xFFFE
-#define SPDM_SOCKET_COMMAND_UNKOWN 0xFFFF
-#define SPDM_SOCKET_COMMAND_TEST 0xDEAD
-
-#define SPDM_SOCKET_TRANSPORT_TYPE_MCTP 0x01
-#define SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE 0x02
-
-#define SPDM_SOCKET_MAX_MESSAGE_BUFFER_SIZE 0x1200
-
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2022 Oracle and/or its affiliates.
- *
- * This work is licensed under the terms of the GNU GPL, version 2.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef STATS_H
-#define STATS_H
-
-#include "qapi/qapi-types-stats.h"
-
-typedef void StatRetrieveFunc(StatsResultList **result, StatsTarget target,
- strList *names, strList *targets, Error **errp);
-typedef void SchemaRetrieveFunc(StatsSchemaList **result, Error **errp);
-
-/*
- * Register callbacks for the QMP query-stats command.
- *
- * @provider: stats provider checked against QMP command arguments
- * @stats_fn: routine to query stats:
- * @schema_fn: routine to query stat schemas:
- */
-void add_stats_callbacks(StatsProvider provider,
- StatRetrieveFunc *stats_fn,
- SchemaRetrieveFunc *schemas_fn);
-
-/*
- * Helper routines for adding stats entries to the results lists.
- */
-void add_stats_entry(StatsResultList **, StatsProvider, const char *id,
- StatsList *stats_list);
-void add_stats_schema(StatsSchemaList **, StatsProvider, StatsTarget,
- StatsSchemaValueList *);
-
-/*
- * True if a string matches the filter passed to the stats_fn callback,
- * false otherwise.
- *
- * Note that an empty list means no filtering, i.e. all strings will
- * return true.
- */
-bool apply_str_list_filter(const char *string, strList *list);
-
-#endif /* STATS_H */
+++ /dev/null
-#ifndef SYSEMU_H
-#define SYSEMU_H
-/* Misc. things related to the system emulator. */
-
-#include "qemu/timer.h"
-#include "qemu/notify.h"
-#include "qemu/uuid.h"
-
-/* vl.c */
-
-extern int only_migratable;
-extern const char *qemu_name;
-extern QemuUUID qemu_uuid;
-extern bool qemu_uuid_set;
-
-const char *qemu_get_vm_name(void);
-
-void qemu_add_exit_notifier(Notifier *notify);
-void qemu_remove_exit_notifier(Notifier *notify);
-
-void qemu_add_machine_init_done_notifier(Notifier *notify);
-void qemu_remove_machine_init_done_notifier(Notifier *notify);
-
-void configure_rtc(QemuOpts *opts);
-
-void qemu_init_subsystems(void);
-
-extern int autostart;
-
-typedef enum {
- VGA_NONE, VGA_STD, VGA_CIRRUS, VGA_VMWARE, VGA_XENFB, VGA_QXL,
- VGA_TCX, VGA_CG3, VGA_DEVICE, VGA_VIRTIO,
- VGA_TYPE_MAX,
-} VGAInterfaceType;
-
-extern int vga_interface_type;
-extern bool vga_interface_created;
-
-extern int graphic_width;
-extern int graphic_height;
-extern int graphic_depth;
-extern int display_opengl;
-extern const char *keyboard_layout;
-extern int old_param;
-extern uint8_t *boot_splash_filedata;
-extern bool enable_mlock;
-extern bool enable_cpu_pm;
-extern QEMUClockType rtc_clock;
-
-#define MAX_OPTION_ROMS 16
-typedef struct QEMUOptionRom {
- const char *name;
- int32_t bootindex;
-} QEMUOptionRom;
-extern QEMUOptionRom option_rom[MAX_OPTION_ROMS];
-extern int nb_option_roms;
-
-#define MAX_PROM_ENVS 128
-extern const char *prom_envs[MAX_PROM_ENVS];
-extern unsigned int nb_prom_envs;
-
-/* serial ports */
-
-/* Return the Chardev for serial port i, or NULL if none */
-Chardev *serial_hd(int i);
-
-/* parallel ports */
-
-#define MAX_PARALLEL_PORTS 3
-
-extern Chardev *parallel_hds[MAX_PARALLEL_PORTS];
-
-void add_boot_device_path(int32_t bootindex, DeviceState *dev,
- const char *suffix);
-char *get_boot_devices_list(size_t *size);
-
-DeviceState *get_boot_device(uint32_t position);
-void check_boot_index(int32_t bootindex, Error **errp);
-void del_boot_device_path(DeviceState *dev, const char *suffix);
-void device_add_bootindex_property(Object *obj, int32_t *bootindex,
- const char *name, const char *suffix,
- DeviceState *dev);
-void restore_boot_order(void *opaque);
-void validate_bootdevices(const char *devices, Error **errp);
-void add_boot_device_lchs(DeviceState *dev, const char *suffix,
- uint32_t lcyls, uint32_t lheads, uint32_t lsecs);
-void del_boot_device_lchs(DeviceState *dev, const char *suffix);
-char *get_boot_devices_lchs_list(size_t *size);
-
-/* handler to set the boot_device order for a specific type of MachineClass */
-typedef void QEMUBootSetHandler(void *opaque, const char *boot_order,
- Error **errp);
-void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque);
-void qemu_boot_set(const char *boot_order, Error **errp);
-
-bool defaults_enabled(void);
-
-void qemu_init(int argc, char **argv);
-int qemu_main_loop(void);
-void qemu_cleanup(int);
-
-extern QemuOptsList qemu_legacy_drive_opts;
-extern QemuOptsList qemu_common_drive_opts;
-extern QemuOptsList qemu_drive_opts;
-extern QemuOptsList bdrv_runtime_opts;
-extern QemuOptsList qemu_chardev_opts;
-extern QemuOptsList qemu_device_opts;
-extern QemuOptsList qemu_netdev_opts;
-extern QemuOptsList qemu_nic_opts;
-extern QemuOptsList qemu_net_opts;
-extern QemuOptsList qemu_global_opts;
-extern QemuOptsList qemu_semihosting_config_opts;
-
-#endif
+++ /dev/null
-/*
- * QEMU TCG support
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-/* header to be included in non-TCG-specific code */
-
-#ifndef SYSEMU_TCG_H
-#define SYSEMU_TCG_H
-
-#ifdef CONFIG_TCG
-extern bool tcg_allowed;
-#define tcg_enabled() (tcg_allowed)
-#else
-#define tcg_enabled() 0
-#endif
-
-#endif
+++ /dev/null
-/*
- * Public TPM functions
- *
- * Copyright (C) 2011-2013 IBM Corporation
- *
- * Authors:
- * Stefan Berger <stefanb@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-#ifndef QEMU_TPM_H
-#define QEMU_TPM_H
-
-#include "qapi/qapi-types-tpm.h"
-#include "qom/object.h"
-
-#ifdef CONFIG_TPM
-
-int tpm_config_parse(QemuOptsList *opts_list, const char *optstr);
-int tpm_init(void);
-void tpm_cleanup(void);
-
-typedef enum TPMVersion {
- TPM_VERSION_UNSPEC = 0,
- TPM_VERSION_1_2 = 1,
- TPM_VERSION_2_0 = 2,
-} TPMVersion;
-
-#define TYPE_TPM_IF "tpm-if"
-typedef struct TPMIfClass TPMIfClass;
-DECLARE_CLASS_CHECKERS(TPMIfClass, TPM_IF,
- TYPE_TPM_IF)
-#define TPM_IF(obj) \
- INTERFACE_CHECK(TPMIf, (obj), TYPE_TPM_IF)
-
-typedef struct TPMIf TPMIf;
-
-struct TPMIfClass {
- InterfaceClass parent_class;
-
- enum TpmModel model;
- void (*request_completed)(TPMIf *obj, int ret);
- enum TPMVersion (*get_version)(TPMIf *obj);
-};
-
-#define TYPE_TPM_TIS_ISA "tpm-tis"
-#define TYPE_TPM_TIS_SYSBUS "tpm-tis-device"
-#define TYPE_TPM_CRB "tpm-crb"
-#define TYPE_TPM_SPAPR "tpm-spapr"
-#define TYPE_TPM_TIS_I2C "tpm-tis-i2c"
-
-#define TPM_IS_TIS_ISA(chr) \
- object_dynamic_cast(OBJECT(chr), TYPE_TPM_TIS_ISA)
-#define TPM_IS_TIS_SYSBUS(chr) \
- object_dynamic_cast(OBJECT(chr), TYPE_TPM_TIS_SYSBUS)
-#define TPM_IS_CRB(chr) \
- object_dynamic_cast(OBJECT(chr), TYPE_TPM_CRB)
-#define TPM_IS_SPAPR(chr) \
- object_dynamic_cast(OBJECT(chr), TYPE_TPM_SPAPR)
-#define TPM_IS_TIS_I2C(chr) \
- object_dynamic_cast(OBJECT(chr), TYPE_TPM_TIS_I2C)
-
-/* returns NULL unless there is exactly one TPM device */
-static inline TPMIf *tpm_find(void)
-{
- Object *obj = object_resolve_path_type("", TYPE_TPM_IF, NULL);
-
- return TPM_IF(obj);
-}
-
-static inline TPMVersion tpm_get_version(TPMIf *ti)
-{
- if (!ti) {
- return TPM_VERSION_UNSPEC;
- }
-
- return TPM_IF_GET_CLASS(ti)->get_version(ti);
-}
-
-#else /* CONFIG_TPM */
-
-#define tpm_init() (0)
-#define tpm_cleanup()
-
-/* needed for an alignment check in non-tpm code */
-static inline Object *TPM_IS_CRB(Object *obj)
-{
- return NULL;
-}
-
-#endif /* CONFIG_TPM */
-
-#endif /* QEMU_TPM_H */
+++ /dev/null
-/*
- * QEMU TPM Backend
- *
- * Copyright IBM, Corp. 2013
- *
- * Authors:
- * Stefan Berger <stefanb@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef TPM_BACKEND_H
-#define TPM_BACKEND_H
-
-#include "qom/object.h"
-#include "qemu/option.h"
-#include "sysemu/tpm.h"
-#include "qapi/error.h"
-
-#ifdef CONFIG_TPM
-
-#define TYPE_TPM_BACKEND "tpm-backend"
-OBJECT_DECLARE_TYPE(TPMBackend, TPMBackendClass,
- TPM_BACKEND)
-
-
-typedef struct TPMBackendCmd {
- uint8_t locty;
- const uint8_t *in;
- uint32_t in_len;
- uint8_t *out;
- uint32_t out_len;
- bool selftest_done;
-} TPMBackendCmd;
-
-struct TPMBackend {
- Object parent;
-
- /*< protected >*/
- TPMIf *tpmif;
- bool opened;
- bool had_startup_error;
- TPMBackendCmd *cmd;
-
- /* <public> */
- char *id;
-
- QLIST_ENTRY(TPMBackend) list;
-};
-
-struct TPMBackendClass {
- ObjectClass parent_class;
-
- enum TpmType type;
- const QemuOptDesc *opts;
- /* get a descriptive text of the backend to display to the user */
- const char *desc;
-
- TPMBackend *(*create)(QemuOpts *opts);
-
- /* start up the TPM on the backend - optional */
- int (*startup_tpm)(TPMBackend *t, size_t buffersize);
-
- /* optional */
- void (*reset)(TPMBackend *t);
-
- void (*cancel_cmd)(TPMBackend *t);
-
- /* optional */
- bool (*get_tpm_established_flag)(TPMBackend *t);
-
- /* optional */
- int (*reset_tpm_established_flag)(TPMBackend *t, uint8_t locty);
-
- TPMVersion (*get_tpm_version)(TPMBackend *t);
-
- size_t (*get_buffer_size)(TPMBackend *t);
-
- TpmTypeOptions *(*get_tpm_options)(TPMBackend *t);
-
- void (*handle_request)(TPMBackend *s, TPMBackendCmd *cmd, Error **errp);
-};
-
-/**
- * tpm_backend_get_type:
- * @s: the backend
- *
- * Returns the TpmType of the backend.
- */
-enum TpmType tpm_backend_get_type(TPMBackend *s);
-
-/**
- * tpm_backend_init:
- * @s: the backend to initialized
- * @tpmif: TPM interface
- * @datacb: callback for sending data to frontend
- * @errp: a pointer to return the #Error object if an error occurs.
- *
- * Initialize the backend with the given variables.
- *
- * Returns 0 on success.
- */
-int tpm_backend_init(TPMBackend *s, TPMIf *tpmif, Error **errp);
-
-/**
- * tpm_backend_startup_tpm:
- * @s: the backend whose TPM support is to be started
- * @buffersize: the buffer size the TPM is supposed to use,
- * 0 to leave it as-is
- *
- * Returns 0 on success.
- */
-int tpm_backend_startup_tpm(TPMBackend *s, size_t buffersize);
-
-/**
- * tpm_backend_had_startup_error:
- * @s: the backend to query for a startup error
- *
- * Check whether the backend had an error during startup. Returns
- * false if no error occurred and the backend can be used, true
- * otherwise.
- */
-bool tpm_backend_had_startup_error(TPMBackend *s);
-
-/**
- * tpm_backend_deliver_request:
- * @s: the backend to send the request to
- * @cmd: the command to deliver
- *
- * Send a request to the backend. The backend will then send the request
- * to the TPM implementation.
- */
-void tpm_backend_deliver_request(TPMBackend *s, TPMBackendCmd *cmd);
-
-/**
- * tpm_backend_reset:
- * @s: the backend to reset
- *
- * Reset the backend into a well defined state with all previous errors
- * reset.
- */
-void tpm_backend_reset(TPMBackend *s);
-
-/**
- * tpm_backend_cancel_cmd:
- * @s: the backend
- *
- * Cancel any ongoing command being processed by the TPM implementation
- * on behalf of the QEMU guest.
- */
-void tpm_backend_cancel_cmd(TPMBackend *s);
-
-/**
- * tpm_backend_get_tpm_established_flag:
- * @s: the backend
- *
- * Get the TPM establishment flag. This function may be called very
- * frequently by the frontend since for example in the TIS implementation
- * this flag is part of a register.
- */
-bool tpm_backend_get_tpm_established_flag(TPMBackend *s);
-
-/**
- * tpm_backend_reset_tpm_established_flag:
- * @s: the backend
- * @locty: the locality number
- *
- * Reset the TPM establishment flag.
- */
-int tpm_backend_reset_tpm_established_flag(TPMBackend *s, uint8_t locty);
-
-/**
- * tpm_backend_get_tpm_version:
- * @s: the backend to call into
- *
- * Get the TPM Version that is emulated at the backend.
- *
- * Returns TPMVersion.
- */
-TPMVersion tpm_backend_get_tpm_version(TPMBackend *s);
-
-/**
- * tpm_backend_get_buffer_size:
- * @s: the backend to call into
- *
- * Get the TPM's buffer size.
- *
- * Returns buffer size.
- */
-size_t tpm_backend_get_buffer_size(TPMBackend *s);
-
-/**
- * tpm_backend_finish_sync:
- * @s: the backend to call into
- *
- * Finish the pending command synchronously (this will call aio_poll()
- * on qemu main AIOContext until it ends)
- */
-void tpm_backend_finish_sync(TPMBackend *s);
-
-/**
- * tpm_backend_query_tpm:
- * @s: the backend
- *
- * Query backend tpm info
- *
- * Returns newly allocated TPMInfo
- */
-TPMInfo *tpm_backend_query_tpm(TPMBackend *s);
-
-TPMBackend *qemu_find_tpm_be(const char *id);
-
-#endif /* CONFIG_TPM */
-
-#endif /* TPM_BACKEND_H */
+++ /dev/null
-/*
- * TPM utility functions
- *
- * Copyright (c) 2010 - 2015 IBM Corporation
- * Authors:
- * Stefan Berger <stefanb@us.ibm.com>
- *
- * 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.1 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/>
- */
-
-#ifndef SYSEMU_TPM_UTIL_H
-#define SYSEMU_TPM_UTIL_H
-
-#include "sysemu/tpm.h"
-#include "qemu/bswap.h"
-
-void tpm_util_write_fatal_error_response(uint8_t *out, uint32_t out_len);
-
-bool tpm_util_is_selftest(const uint8_t *in, uint32_t in_len);
-
-int tpm_util_test_tpmdev(int tpm_fd, TPMVersion *tpm_version);
-
-static inline uint16_t tpm_cmd_get_tag(const void *b)
-{
- return lduw_be_p(b);
-}
-
-static inline void tpm_cmd_set_tag(void *b, uint16_t tag)
-{
- stw_be_p(b, tag);
-}
-
-static inline uint32_t tpm_cmd_get_size(const void *b)
-{
- return ldl_be_p(b + 2);
-}
-
-static inline void tpm_cmd_set_size(void *b, uint32_t size)
-{
- stl_be_p(b + 2, size);
-}
-
-static inline uint32_t tpm_cmd_get_ordinal(const void *b)
-{
- return ldl_be_p(b + 6);
-}
-
-static inline uint32_t tpm_cmd_get_errcode(const void *b)
-{
- return ldl_be_p(b + 6);
-}
-
-static inline void tpm_cmd_set_error(void *b, uint32_t error)
-{
- stl_be_p(b + 6, error);
-}
-
-void tpm_util_show_buffer(const unsigned char *buffer,
- size_t buffer_size, const char *string);
-
-#endif /* SYSEMU_TPM_UTIL_H */
+++ /dev/null
-/*
- * QEMU vhost-user backend
- *
- * Copyright (C) 2018 Red Hat Inc
- *
- * Authors:
- * Marc-André Lureau <marcandre.lureau@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-#ifndef QEMU_VHOST_USER_BACKEND_H
-#define QEMU_VHOST_USER_BACKEND_H
-
-#include "qom/object.h"
-#include "exec/memory.h"
-#include "qemu/option.h"
-#include "qemu/bitmap.h"
-#include "hw/virtio/vhost.h"
-#include "hw/virtio/vhost-user.h"
-#include "chardev/char-fe.h"
-#include "io/channel.h"
-
-#define TYPE_VHOST_USER_BACKEND "vhost-user-backend"
-OBJECT_DECLARE_SIMPLE_TYPE(VhostUserBackend,
- VHOST_USER_BACKEND)
-
-
-
-struct VhostUserBackend {
- /* private */
- Object parent;
-
- char *chr_name;
- CharBackend chr;
- VhostUserState vhost_user;
- struct vhost_dev dev;
- VirtIODevice *vdev;
- bool started;
- bool completed;
-};
-
-int vhost_user_backend_dev_init(VhostUserBackend *b, VirtIODevice *vdev,
- unsigned nvqs, Error **errp);
-void vhost_user_backend_start(VhostUserBackend *b);
-void vhost_user_backend_stop(VhostUserBackend *b);
-
-#endif
+++ /dev/null
-/*
- * Virtual hardware watchdog.
- *
- * Copyright (C) 2009 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * By Richard W.M. Jones (rjones@redhat.com).
- */
-
-#ifndef QEMU_WATCHDOG_H
-#define QEMU_WATCHDOG_H
-
-#include "qemu/queue.h"
-#include "qapi/qapi-types-run-state.h"
-
-/* in hw/watchdog.c */
-WatchdogAction get_watchdog_action(void);
-void watchdog_perform_action(void);
-
-#endif /* QEMU_WATCHDOG_H */
+++ /dev/null
-/*
- * QEMU Windows Hypervisor Platform accelerator (WHPX) support
- *
- * Copyright Microsoft, Corp. 2017
- *
- * Authors:
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-/* header to be included in non-WHPX-specific code */
-
-#ifndef QEMU_WHPX_H
-#define QEMU_WHPX_H
-
-#ifdef COMPILING_PER_TARGET
-
-#ifdef CONFIG_WHPX
-
-int whpx_enabled(void);
-bool whpx_apic_in_platform(void);
-
-#else /* CONFIG_WHPX */
-
-#define whpx_enabled() (0)
-#define whpx_apic_in_platform() (0)
-
-#endif /* CONFIG_WHPX */
-
-#endif /* COMPILING_PER_TARGET */
-
-#endif /* QEMU_WHPX_H */
+++ /dev/null
-/*
- * Copyright (C) 2011 Citrix Ltd.
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef XEN_MAPCACHE_H
-#define XEN_MAPCACHE_H
-
-#include "exec/cpu-common.h"
-#include "sysemu/xen.h"
-
-typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr phys_offset,
- ram_addr_t size);
-#ifdef CONFIG_XEN_IS_POSSIBLE
-
-void xen_map_cache_init(phys_offset_to_gaddr_t f,
- void *opaque);
-uint8_t *xen_map_cache(MemoryRegion *mr, hwaddr phys_addr, hwaddr size,
- ram_addr_t ram_addr_offset,
- uint8_t lock, bool dma,
- bool is_write);
-ram_addr_t xen_ram_addr_from_mapcache(void *ptr);
-void xen_invalidate_map_cache_entry(uint8_t *buffer);
-void xen_invalidate_map_cache(void);
-uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
- hwaddr new_phys_addr,
- hwaddr size);
-#else
-
-static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
- void *opaque)
-{
-}
-
-static inline uint8_t *xen_map_cache(MemoryRegion *mr,
- hwaddr phys_addr,
- hwaddr size,
- ram_addr_t ram_addr_offset,
- uint8_t lock,
- bool dma,
- bool is_write)
-{
- abort();
-}
-
-static inline ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
-{
- abort();
-}
-
-static inline void xen_invalidate_map_cache_entry(uint8_t *buffer)
-{
-}
-
-static inline void xen_invalidate_map_cache(void)
-{
-}
-
-static inline uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
- hwaddr new_phys_addr,
- hwaddr size)
-{
- abort();
-}
-
-#endif
-
-#endif /* XEN_MAPCACHE_H */
+++ /dev/null
-/*
- * QEMU Xen support
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-/* header to be included in non-Xen-specific code */
-
-#ifndef SYSEMU_XEN_H
-#define SYSEMU_XEN_H
-
-#ifdef CONFIG_USER_ONLY
-#error Cannot include sysemu/xen.h from user emulation
-#endif
-
-#include "exec/cpu-common.h"
-
-#ifdef COMPILING_PER_TARGET
-# ifdef CONFIG_XEN
-# define CONFIG_XEN_IS_POSSIBLE
-# endif
-#else
-# define CONFIG_XEN_IS_POSSIBLE
-#endif /* COMPILING_PER_TARGET */
-
-#ifdef CONFIG_XEN_IS_POSSIBLE
-
-extern bool xen_allowed;
-
-#define xen_enabled() (xen_allowed)
-
-void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length);
-void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
- struct MemoryRegion *mr, Error **errp);
-
-#else /* !CONFIG_XEN_IS_POSSIBLE */
-
-#define xen_enabled() 0
-static inline void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length)
-{
- /* nothing */
-}
-static inline void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
- MemoryRegion *mr, Error **errp)
-{
- g_assert_not_reached();
-}
-
-#endif /* CONFIG_XEN_IS_POSSIBLE */
-
-bool xen_mr_is_memory(MemoryRegion *mr);
-bool xen_mr_is_grants(MemoryRegion *mr);
-#endif
--- /dev/null
+/*
+ * Accelerator blocking API, to prevent new ioctls from starting and wait the
+ * running ones finish.
+ * This mechanism differs from pause/resume_all_vcpus() in that it does not
+ * release the BQL.
+ *
+ * Copyright (c) 2022 Red Hat Inc.
+ *
+ * Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef ACCEL_BLOCKER_H
+#define ACCEL_BLOCKER_H
+
+#include "system/cpus.h"
+
+void accel_blocker_init(void);
+
+/*
+ * accel_{cpu_}ioctl_begin/end:
+ * Mark when ioctl is about to run or just finished.
+ *
+ * accel_{cpu_}ioctl_begin will block after accel_ioctl_inhibit_begin() is
+ * called, preventing new ioctls to run. They will continue only after
+ * accel_ioctl_inibith_end().
+ */
+void accel_ioctl_begin(void);
+void accel_ioctl_end(void);
+void accel_cpu_ioctl_begin(CPUState *cpu);
+void accel_cpu_ioctl_end(CPUState *cpu);
+
+/*
+ * accel_ioctl_inhibit_begin: start critical section
+ *
+ * This function makes sure that:
+ * 1) incoming accel_{cpu_}ioctl_begin() calls block
+ * 2) wait that all ioctls that were already running reach
+ * accel_{cpu_}ioctl_end(), kicking vcpus if necessary.
+ *
+ * This allows the caller to access shared data or perform operations without
+ * worrying of concurrent vcpus accesses.
+ */
+void accel_ioctl_inhibit_begin(void);
+
+/*
+ * accel_ioctl_inhibit_end: end critical section started by
+ * accel_ioctl_inhibit_begin()
+ *
+ * This function allows blocked accel_{cpu_}ioctl_begin() to continue.
+ */
+void accel_ioctl_inhibit_end(void);
+
+#endif /* ACCEL_BLOCKER_H */
--- /dev/null
+/*
+ * Accelerator OPS, used for cpus.c module
+ *
+ * Copyright 2021 SUSE LLC
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef ACCEL_OPS_H
+#define ACCEL_OPS_H
+
+#include "exec/cpu-common.h"
+#include "qom/object.h"
+
+#define ACCEL_OPS_SUFFIX "-ops"
+#define TYPE_ACCEL_OPS "accel" ACCEL_OPS_SUFFIX
+#define ACCEL_OPS_NAME(name) (name "-" TYPE_ACCEL_OPS)
+
+typedef struct AccelOpsClass AccelOpsClass;
+DECLARE_CLASS_CHECKERS(AccelOpsClass, ACCEL_OPS, TYPE_ACCEL_OPS)
+
+/**
+ * struct AccelOpsClass - accelerator interfaces
+ *
+ * This structure is used to abstract accelerator differences from the
+ * core CPU code. Not all have to be implemented.
+ */
+struct AccelOpsClass {
+ /*< private >*/
+ ObjectClass parent_class;
+ /*< public >*/
+
+ /* initialization function called when accel is chosen */
+ void (*ops_init)(AccelOpsClass *ops);
+
+ bool (*cpus_are_resettable)(void);
+ void (*cpu_reset_hold)(CPUState *cpu);
+
+ void (*create_vcpu_thread)(CPUState *cpu); /* MANDATORY NON-NULL */
+ void (*kick_vcpu_thread)(CPUState *cpu);
+ bool (*cpu_thread_is_idle)(CPUState *cpu);
+
+ void (*synchronize_post_reset)(CPUState *cpu);
+ void (*synchronize_post_init)(CPUState *cpu);
+ void (*synchronize_state)(CPUState *cpu);
+ void (*synchronize_pre_loadvm)(CPUState *cpu);
+ void (*synchronize_pre_resume)(bool step_pending);
+
+ void (*handle_interrupt)(CPUState *cpu, int mask);
+
+ /**
+ * @get_virtual_clock: fetch virtual clock
+ * @set_virtual_clock: set virtual clock
+ *
+ * These allow the timer subsystem to defer to the accelerator to
+ * fetch time. The set function is needed if the accelerator wants
+ * to track the changes to time as the timer is warped through
+ * various timer events.
+ */
+ int64_t (*get_virtual_clock)(void);
+ void (*set_virtual_clock)(int64_t time);
+
+ int64_t (*get_elapsed_ticks)(void);
+
+ /* gdbstub hooks */
+ bool (*supports_guest_debug)(void);
+ int (*update_guest_debug)(CPUState *cpu);
+ int (*insert_breakpoint)(CPUState *cpu, int type, vaddr addr, vaddr len);
+ int (*remove_breakpoint)(CPUState *cpu, int type, vaddr addr, vaddr len);
+ void (*remove_all_breakpoints)(CPUState *cpu);
+};
+
+#endif /* ACCEL_OPS_H */
--- /dev/null
+#ifndef QEMU_ARCH_INIT_H
+#define QEMU_ARCH_INIT_H
+
+
+enum {
+ QEMU_ARCH_ALL = -1,
+ QEMU_ARCH_ALPHA = (1 << 0),
+ QEMU_ARCH_ARM = (1 << 1),
+ QEMU_ARCH_I386 = (1 << 3),
+ QEMU_ARCH_M68K = (1 << 4),
+ QEMU_ARCH_MICROBLAZE = (1 << 6),
+ QEMU_ARCH_MIPS = (1 << 7),
+ QEMU_ARCH_PPC = (1 << 8),
+ QEMU_ARCH_S390X = (1 << 9),
+ QEMU_ARCH_SH4 = (1 << 10),
+ QEMU_ARCH_SPARC = (1 << 11),
+ QEMU_ARCH_XTENSA = (1 << 12),
+ QEMU_ARCH_OPENRISC = (1 << 13),
+ QEMU_ARCH_TRICORE = (1 << 16),
+ QEMU_ARCH_HPPA = (1 << 18),
+ QEMU_ARCH_RISCV = (1 << 19),
+ QEMU_ARCH_RX = (1 << 20),
+ QEMU_ARCH_AVR = (1 << 21),
+ QEMU_ARCH_HEXAGON = (1 << 22),
+ QEMU_ARCH_LOONGARCH = (1 << 23),
+};
+
+extern const uint32_t arch_type;
+
+void qemu_init_arch_modules(void);
+
+#endif
--- /dev/null
+/*
+ * Balloon
+ *
+ * Copyright IBM, Corp. 2008
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_BALLOON_H
+#define QEMU_BALLOON_H
+
+#include "exec/cpu-common.h"
+#include "qapi/qapi-types-machine.h"
+
+typedef void (QEMUBalloonEvent)(void *opaque, ram_addr_t target);
+typedef void (QEMUBalloonStatus)(void *opaque, BalloonInfo *info);
+
+int qemu_add_balloon_handler(QEMUBalloonEvent *event_func,
+ QEMUBalloonStatus *stat_func, void *opaque);
+void qemu_remove_balloon_handler(void *opaque);
+
+#endif
--- /dev/null
+/*
+ * QEMU Block backends
+ *
+ * Copyright (C) 2014-2016 Red Hat, Inc.
+ *
+ * Authors:
+ * Markus Armbruster <armbru@redhat.com>,
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1
+ * or later. See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef BLOCK_BACKEND_COMMON_H
+#define BLOCK_BACKEND_COMMON_H
+
+#include "qemu/iov.h"
+#include "block/throttle-groups.h"
+
+/*
+ * TODO Have to include block/block.h for a bunch of block layer
+ * types. Unfortunately, this pulls in the whole BlockDriverState
+ * API, which we don't want used by many BlockBackend users. Some of
+ * the types belong here, and the rest should be split into a common
+ * header and one for the BlockDriverState API.
+ */
+#include "block/block.h"
+
+/* Callbacks for block device models */
+typedef struct BlockDevOps {
+
+ /*
+ * Global state (GS) API. These functions run under the BQL.
+ *
+ * See include/block/block-global-state.h for more information about
+ * the GS API.
+ */
+
+ /*
+ * Runs when virtual media changed (monitor commands eject, change)
+ * Argument load is true on load and false on eject.
+ * Beware: doesn't run when a host device's physical media
+ * changes. Sure would be useful if it did.
+ * Device models with removable media must implement this callback.
+ */
+ void (*change_media_cb)(void *opaque, bool load, Error **errp);
+ /*
+ * Runs when an eject request is issued from the monitor, the tray
+ * is closed, and the medium is locked.
+ * Device models that do not implement is_medium_locked will not need
+ * this callback. Device models that can lock the medium or tray might
+ * want to implement the callback and unlock the tray when "force" is
+ * true, even if they do not support eject requests.
+ */
+ void (*eject_request_cb)(void *opaque, bool force);
+
+ /*
+ * Is the virtual medium locked into the device?
+ * Device models implement this only when device has such a lock.
+ */
+ bool (*is_medium_locked)(void *opaque);
+
+ /*
+ * Runs when the backend receives a drain request.
+ */
+ void (*drained_begin)(void *opaque);
+ /*
+ * Runs when the backend's last drain request ends.
+ */
+ void (*drained_end)(void *opaque);
+ /*
+ * Is the device still busy?
+ */
+ bool (*drained_poll)(void *opaque);
+
+ /*
+ * I/O API functions. These functions are thread-safe.
+ *
+ * See include/block/block-io.h for more information about
+ * the I/O API.
+ */
+
+ /*
+ * Is the virtual tray open?
+ * Device models implement this only when the device has a tray.
+ */
+ bool (*is_tray_open)(void *opaque);
+
+ /*
+ * Runs when the size changed (e.g. monitor command block_resize)
+ */
+ void (*resize_cb)(void *opaque);
+} BlockDevOps;
+
+/*
+ * This struct is embedded in (the private) BlockBackend struct and contains
+ * fields that must be public. This is in particular for QLIST_ENTRY() and
+ * friends so that BlockBackends can be kept in lists outside block-backend.c
+ */
+typedef struct BlockBackendPublic {
+ ThrottleGroupMember throttle_group_member;
+} BlockBackendPublic;
+
+#endif /* BLOCK_BACKEND_COMMON_H */
--- /dev/null
+/*
+ * QEMU Block backends
+ *
+ * Copyright (C) 2014-2016 Red Hat, Inc.
+ *
+ * Authors:
+ * Markus Armbruster <armbru@redhat.com>,
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1
+ * or later. See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef BLOCK_BACKEND_GLOBAL_STATE_H
+#define BLOCK_BACKEND_GLOBAL_STATE_H
+
+#include "block-backend-common.h"
+
+/*
+ * Global state (GS) API. These functions run under the BQL.
+ *
+ * See include/block/block-global-state.h for more information about
+ * the GS API.
+ */
+
+BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm);
+
+BlockBackend * no_coroutine_fn
+blk_new_with_bs(BlockDriverState *bs, uint64_t perm, uint64_t shared_perm,
+ Error **errp);
+
+BlockBackend * coroutine_fn no_co_wrapper
+blk_co_new_with_bs(BlockDriverState *bs, uint64_t perm, uint64_t shared_perm,
+ Error **errp);
+
+BlockBackend * no_coroutine_fn
+blk_new_open(const char *filename, const char *reference, QDict *options,
+ int flags, Error **errp);
+
+BlockBackend * coroutine_fn no_co_wrapper
+blk_co_new_open(const char *filename, const char *reference, QDict *options,
+ int flags, Error **errp);
+
+int blk_get_refcnt(BlockBackend *blk);
+void blk_ref(BlockBackend *blk);
+
+void no_coroutine_fn blk_unref(BlockBackend *blk);
+void coroutine_fn no_co_wrapper blk_co_unref(BlockBackend *blk);
+
+void blk_remove_all_bs(void);
+BlockBackend *blk_by_name(const char *name);
+BlockBackend *blk_next(BlockBackend *blk);
+BlockBackend *blk_all_next(BlockBackend *blk);
+bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp);
+void monitor_remove_blk(BlockBackend *blk);
+
+BlockBackendPublic *blk_get_public(BlockBackend *blk);
+
+void blk_remove_bs(BlockBackend *blk);
+int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp);
+int blk_replace_bs(BlockBackend *blk, BlockDriverState *new_bs, Error **errp);
+bool GRAPH_RDLOCK bdrv_has_blk(BlockDriverState *bs);
+bool GRAPH_RDLOCK bdrv_is_root_node(BlockDriverState *bs);
+int GRAPH_UNLOCKED blk_set_perm(BlockBackend *blk, uint64_t perm,
+ uint64_t shared_perm, Error **errp);
+void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm);
+
+void blk_iostatus_enable(BlockBackend *blk);
+BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk);
+void blk_iostatus_reset(BlockBackend *blk);
+int blk_attach_dev(BlockBackend *blk, DeviceState *dev);
+void blk_detach_dev(BlockBackend *blk, DeviceState *dev);
+DeviceState *blk_get_attached_dev(BlockBackend *blk);
+BlockBackend *blk_by_dev(void *dev);
+BlockBackend *blk_by_qdev_id(const char *id, Error **errp);
+void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque);
+
+int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags);
+void blk_aio_cancel(BlockAIOCB *acb);
+int blk_commit_all(void);
+bool blk_in_drain(BlockBackend *blk);
+void blk_drain(BlockBackend *blk);
+void blk_drain_all(void);
+void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error,
+ BlockdevOnError on_write_error);
+bool blk_supports_write_perm(BlockBackend *blk);
+bool blk_is_sg(BlockBackend *blk);
+void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
+int blk_get_flags(BlockBackend *blk);
+bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp);
+int blk_set_aio_context(BlockBackend *blk, AioContext *new_context,
+ Error **errp);
+void blk_add_aio_context_notifier(BlockBackend *blk,
+ void (*attached_aio_context)(AioContext *new_context, void *opaque),
+ void (*detach_aio_context)(void *opaque), void *opaque);
+void blk_remove_aio_context_notifier(BlockBackend *blk,
+ void (*attached_aio_context)(AioContext *,
+ void *),
+ void (*detach_aio_context)(void *),
+ void *opaque);
+void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify);
+BlockBackendRootState *blk_get_root_state(BlockBackend *blk);
+void blk_update_root_state(BlockBackend *blk);
+bool blk_get_detect_zeroes_from_root_state(BlockBackend *blk);
+int blk_get_open_flags_from_root_state(BlockBackend *blk);
+
+int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
+ int64_t pos, int size);
+int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size);
+int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz);
+int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo);
+
+void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg);
+void blk_io_limits_disable(BlockBackend *blk);
+void blk_io_limits_enable(BlockBackend *blk, const char *group);
+void blk_io_limits_update_group(BlockBackend *blk, const char *group);
+void blk_set_force_allow_inactivate(BlockBackend *blk);
+
+bool blk_register_buf(BlockBackend *blk, void *host, size_t size, Error **errp);
+void blk_unregister_buf(BlockBackend *blk, void *host, size_t size);
+
+const BdrvChild *blk_root(BlockBackend *blk);
+
+int blk_make_empty(BlockBackend *blk, Error **errp);
+
+#endif /* BLOCK_BACKEND_GLOBAL_STATE_H */
--- /dev/null
+/*
+ * QEMU Block backends
+ *
+ * Copyright (C) 2014-2016 Red Hat, Inc.
+ *
+ * Authors:
+ * Markus Armbruster <armbru@redhat.com>,
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1
+ * or later. See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef BLOCK_BACKEND_IO_H
+#define BLOCK_BACKEND_IO_H
+
+#include "block-backend-common.h"
+#include "block/accounting.h"
+
+/*
+ * I/O API functions. These functions are thread-safe.
+ *
+ * See include/block/block-io.h for more information about
+ * the I/O API.
+ */
+
+const char *blk_name(const BlockBackend *blk);
+
+BlockDriverState *blk_bs(BlockBackend *blk);
+
+void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow);
+void blk_set_allow_aio_context_change(BlockBackend *blk, bool allow);
+void blk_set_disable_request_queuing(BlockBackend *blk, bool disable);
+bool blk_iostatus_is_enabled(const BlockBackend *blk);
+
+char *blk_get_attached_dev_id(BlockBackend *blk);
+
+BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
+ int64_t bytes, BdrvRequestFlags flags,
+ BlockCompletionFunc *cb, void *opaque);
+
+BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset,
+ QEMUIOVector *qiov, BdrvRequestFlags flags,
+ BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset,
+ QEMUIOVector *qiov, BdrvRequestFlags flags,
+ BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *blk_aio_flush(BlockBackend *blk,
+ BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *blk_aio_zone_report(BlockBackend *blk, int64_t offset,
+ unsigned int *nr_zones,
+ BlockZoneDescriptor *zones,
+ BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *blk_aio_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
+ int64_t offset, int64_t len,
+ BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *blk_aio_zone_append(BlockBackend *blk, int64_t *offset,
+ QEMUIOVector *qiov, BdrvRequestFlags flags,
+ BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes,
+ BlockCompletionFunc *cb, void *opaque);
+void blk_aio_cancel_async(BlockAIOCB *acb);
+BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
+ BlockCompletionFunc *cb, void *opaque);
+
+void blk_inc_in_flight(BlockBackend *blk);
+void blk_dec_in_flight(BlockBackend *blk);
+
+bool coroutine_fn GRAPH_RDLOCK blk_co_is_inserted(BlockBackend *blk);
+bool co_wrapper_mixed_bdrv_rdlock blk_is_inserted(BlockBackend *blk);
+
+bool coroutine_fn GRAPH_RDLOCK blk_co_is_available(BlockBackend *blk);
+bool co_wrapper_mixed_bdrv_rdlock blk_is_available(BlockBackend *blk);
+
+void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked);
+void co_wrapper blk_lock_medium(BlockBackend *blk, bool locked);
+
+void coroutine_fn blk_co_eject(BlockBackend *blk, bool eject_flag);
+void co_wrapper blk_eject(BlockBackend *blk, bool eject_flag);
+
+int64_t coroutine_fn blk_co_getlength(BlockBackend *blk);
+int64_t co_wrapper_mixed blk_getlength(BlockBackend *blk);
+
+void coroutine_fn blk_co_get_geometry(BlockBackend *blk,
+ uint64_t *nb_sectors_ptr);
+void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr);
+
+int64_t coroutine_fn blk_co_nb_sectors(BlockBackend *blk);
+int64_t blk_nb_sectors(BlockBackend *blk);
+
+void *blk_try_blockalign(BlockBackend *blk, size_t size);
+void *blk_blockalign(BlockBackend *blk, size_t size);
+bool blk_is_writable(BlockBackend *blk);
+bool blk_enable_write_cache(BlockBackend *blk);
+BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read);
+BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
+ int error);
+void blk_error_action(BlockBackend *blk, BlockErrorAction action,
+ bool is_read, int error);
+void blk_iostatus_set_err(BlockBackend *blk, int error);
+int blk_get_max_iov(BlockBackend *blk);
+int blk_get_max_hw_iov(BlockBackend *blk);
+
+AioContext *blk_get_aio_context(BlockBackend *blk);
+BlockAcctStats *blk_get_stats(BlockBackend *blk);
+void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
+ BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
+ BlockCompletionFunc *cb,
+ void *opaque, int ret);
+
+uint32_t blk_get_request_alignment(BlockBackend *blk);
+uint32_t blk_get_max_transfer(BlockBackend *blk);
+uint64_t blk_get_max_hw_transfer(BlockBackend *blk);
+
+int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
+ BlockBackend *blk_out, int64_t off_out,
+ int64_t bytes, BdrvRequestFlags read_flags,
+ BdrvRequestFlags write_flags);
+
+int coroutine_fn blk_co_block_status_above(BlockBackend *blk,
+ BlockDriverState *base,
+ int64_t offset, int64_t bytes,
+ int64_t *pnum, int64_t *map,
+ BlockDriverState **file);
+int coroutine_fn blk_co_is_allocated_above(BlockBackend *blk,
+ BlockDriverState *base,
+ bool include_base, int64_t offset,
+ int64_t bytes, int64_t *pnum);
+
+/*
+ * "I/O or GS" API functions. These functions can run without
+ * the BQL, but only in one specific iothread/main loop.
+ *
+ * See include/block/block-io.h for more information about
+ * the "I/O or GS" API.
+ */
+
+int co_wrapper_mixed blk_pread(BlockBackend *blk, int64_t offset,
+ int64_t bytes, void *buf,
+ BdrvRequestFlags flags);
+int coroutine_fn blk_co_pread(BlockBackend *blk, int64_t offset, int64_t bytes,
+ void *buf, BdrvRequestFlags flags);
+
+int co_wrapper_mixed blk_preadv(BlockBackend *blk, int64_t offset,
+ int64_t bytes, QEMUIOVector *qiov,
+ BdrvRequestFlags flags);
+int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
+ int64_t bytes, QEMUIOVector *qiov,
+ BdrvRequestFlags flags);
+
+int co_wrapper_mixed blk_preadv_part(BlockBackend *blk, int64_t offset,
+ int64_t bytes, QEMUIOVector *qiov,
+ size_t qiov_offset,
+ BdrvRequestFlags flags);
+int coroutine_fn blk_co_preadv_part(BlockBackend *blk, int64_t offset,
+ int64_t bytes, QEMUIOVector *qiov,
+ size_t qiov_offset, BdrvRequestFlags flags);
+
+int co_wrapper_mixed blk_pwrite(BlockBackend *blk, int64_t offset,
+ int64_t bytes, const void *buf,
+ BdrvRequestFlags flags);
+int coroutine_fn blk_co_pwrite(BlockBackend *blk, int64_t offset, int64_t bytes,
+ const void *buf, BdrvRequestFlags flags);
+
+int co_wrapper_mixed blk_pwritev(BlockBackend *blk, int64_t offset,
+ int64_t bytes, QEMUIOVector *qiov,
+ BdrvRequestFlags flags);
+int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
+ int64_t bytes, QEMUIOVector *qiov,
+ BdrvRequestFlags flags);
+
+int co_wrapper_mixed blk_pwritev_part(BlockBackend *blk, int64_t offset,
+ int64_t bytes, QEMUIOVector *qiov,
+ size_t qiov_offset,
+ BdrvRequestFlags flags);
+int coroutine_fn blk_co_pwritev_part(BlockBackend *blk, int64_t offset,
+ int64_t bytes,
+ QEMUIOVector *qiov, size_t qiov_offset,
+ BdrvRequestFlags flags);
+
+int co_wrapper_mixed blk_pwrite_compressed(BlockBackend *blk,
+ int64_t offset, int64_t bytes,
+ const void *buf);
+int coroutine_fn blk_co_pwrite_compressed(BlockBackend *blk, int64_t offset,
+ int64_t bytes, const void *buf);
+
+int co_wrapper_mixed blk_pwrite_zeroes(BlockBackend *blk, int64_t offset,
+ int64_t bytes,
+ BdrvRequestFlags flags);
+int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
+ int64_t bytes, BdrvRequestFlags flags);
+
+int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset,
+ unsigned int *nr_zones,
+ BlockZoneDescriptor *zones);
+int co_wrapper_mixed blk_zone_report(BlockBackend *blk, int64_t offset,
+ unsigned int *nr_zones,
+ BlockZoneDescriptor *zones);
+int coroutine_fn blk_co_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
+ int64_t offset, int64_t len);
+int co_wrapper_mixed blk_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
+ int64_t offset, int64_t len);
+int coroutine_fn blk_co_zone_append(BlockBackend *blk, int64_t *offset,
+ QEMUIOVector *qiov,
+ BdrvRequestFlags flags);
+int co_wrapper_mixed blk_zone_append(BlockBackend *blk, int64_t *offset,
+ QEMUIOVector *qiov,
+ BdrvRequestFlags flags);
+
+int co_wrapper_mixed blk_pdiscard(BlockBackend *blk, int64_t offset,
+ int64_t bytes);
+int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset,
+ int64_t bytes);
+
+int co_wrapper_mixed blk_flush(BlockBackend *blk);
+int coroutine_fn blk_co_flush(BlockBackend *blk);
+
+int co_wrapper_mixed blk_ioctl(BlockBackend *blk, unsigned long int req,
+ void *buf);
+int coroutine_fn blk_co_ioctl(BlockBackend *blk, unsigned long int req,
+ void *buf);
+
+int co_wrapper_mixed blk_truncate(BlockBackend *blk, int64_t offset,
+ bool exact, PreallocMode prealloc,
+ BdrvRequestFlags flags, Error **errp);
+int coroutine_fn blk_co_truncate(BlockBackend *blk, int64_t offset, bool exact,
+ PreallocMode prealloc, BdrvRequestFlags flags,
+ Error **errp);
+
+#endif /* BLOCK_BACKEND_IO_H */
--- /dev/null
+/*
+ * QEMU Block backends
+ *
+ * Copyright (C) 2014-2016 Red Hat, Inc.
+ *
+ * Authors:
+ * Markus Armbruster <armbru@redhat.com>,
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1
+ * or later. See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef BLOCK_BACKEND_H
+#define BLOCK_BACKEND_H
+
+#include "block-backend-global-state.h"
+#include "block-backend-io.h"
+
+/* DO NOT ADD ANYTHING IN HERE. USE ONE OF THE HEADERS INCLUDED ABOVE */
+
+#endif
--- /dev/null
+/*
+ * BlockBackend RAM Registrar
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef BLOCK_RAM_REGISTRAR_H
+#define BLOCK_RAM_REGISTRAR_H
+
+#include "exec/ramlist.h"
+
+/**
+ * struct BlockRAMRegistrar:
+ *
+ * Keeps RAMBlock memory registered with a BlockBackend using
+ * blk_register_buf() including hotplugged memory.
+ *
+ * Emulated devices or other BlockBackend users initialize a BlockRAMRegistrar
+ * with blk_ram_registrar_init() before submitting I/O requests with the
+ * BDRV_REQ_REGISTERED_BUF flag set.
+ */
+typedef struct {
+ BlockBackend *blk;
+ RAMBlockNotifier notifier;
+ bool ok;
+} BlockRAMRegistrar;
+
+void blk_ram_registrar_init(BlockRAMRegistrar *r, BlockBackend *blk);
+void blk_ram_registrar_destroy(BlockRAMRegistrar *r);
+
+/* Have all RAMBlocks been registered successfully? */
+static inline bool blk_ram_registrar_ok(BlockRAMRegistrar *r)
+{
+ return r->ok;
+}
+
+#endif /* BLOCK_RAM_REGISTRAR_H */
--- /dev/null
+/*
+ * QEMU host block devices
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later. See the COPYING file in the top-level directory.
+ */
+
+#ifndef BLOCKDEV_H
+#define BLOCKDEV_H
+
+#include "block/block.h"
+#include "qemu/queue.h"
+
+typedef enum {
+ IF_DEFAULT = -1, /* for use with drive_add() only */
+ /*
+ * IF_NONE must be zero, because we want MachineClass member
+ * block_default_type to default-initialize to IF_NONE
+ */
+ IF_NONE = 0,
+ IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD, IF_VIRTIO, IF_XEN,
+ IF_COUNT
+} BlockInterfaceType;
+
+struct DriveInfo {
+ BlockInterfaceType type;
+ int bus;
+ int unit;
+ int auto_del; /* see blockdev_mark_auto_del() */
+ bool is_default; /* Added by default_drive() ? */
+ int media_cd;
+ QemuOpts *opts;
+ QTAILQ_ENTRY(DriveInfo) next;
+};
+
+/*
+ * Global state (GS) API. These functions run under the BQL.
+ *
+ * See include/block/block-global-state.h for more information about
+ * the GS API.
+ */
+
+void blockdev_mark_auto_del(BlockBackend *blk);
+void blockdev_auto_del(BlockBackend *blk);
+
+DriveInfo *blk_legacy_dinfo(BlockBackend *blk);
+DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo);
+BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo);
+
+void override_max_devs(BlockInterfaceType type, int max_devs);
+
+DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
+void drive_check_orphaned(void);
+DriveInfo *drive_get_by_index(BlockInterfaceType type, int index);
+int drive_get_max_bus(BlockInterfaceType type);
+
+QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
+ const char *optstr);
+DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type,
+ Error **errp);
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
+ */
+
+#ifndef SYSTEM_CPU_THROTTLE_H
+#define SYSTEM_CPU_THROTTLE_H
+
+#include "qemu/timer.h"
+
+/**
+ * cpu_throttle_init:
+ *
+ * Initialize the CPU throttling API.
+ */
+void cpu_throttle_init(void);
+
+/**
+ * cpu_throttle_set:
+ * @new_throttle_pct: Percent of sleep time. Valid range is 1 to 99.
+ *
+ * Throttles all vcpus by forcing them to sleep for the given percentage of
+ * time. A throttle_percentage of 25 corresponds to a 75% duty cycle roughly.
+ * (example: 10ms sleep for every 30ms awake).
+ *
+ * cpu_throttle_set can be called as needed to adjust new_throttle_pct.
+ * Once the throttling starts, it will remain in effect until cpu_throttle_stop
+ * is called.
+ */
+void cpu_throttle_set(int new_throttle_pct);
+
+/**
+ * cpu_throttle_stop:
+ *
+ * Stops the vcpu throttling started by cpu_throttle_set.
+ */
+void cpu_throttle_stop(void);
+
+/**
+ * cpu_throttle_active:
+ *
+ * Returns: %true if the vcpus are currently being throttled, %false otherwise.
+ */
+bool cpu_throttle_active(void);
+
+/**
+ * cpu_throttle_get_percentage:
+ *
+ * Returns the vcpu throttle percentage. See cpu_throttle_set for details.
+ *
+ * Returns: The throttle percentage in range 1 to 99.
+ */
+int cpu_throttle_get_percentage(void);
+
+/**
+ * cpu_throttle_dirty_sync_timer_tick:
+ *
+ * Dirty sync timer hook.
+ */
+void cpu_throttle_dirty_sync_timer_tick(void *opaque);
+
+/**
+ * cpu_throttle_dirty_sync_timer:
+ *
+ * Start or stop the dirty sync timer.
+ */
+void cpu_throttle_dirty_sync_timer(bool enable);
+
+#endif /* SYSTEM_CPU_THROTTLE_H */
--- /dev/null
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * 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.
+ */
+
+#ifndef TIMERS_STATE_H
+#define TIMERS_STATE_H
+
+/* timers state, for sharing between icount and cpu-timers */
+
+typedef struct TimersState {
+ /* Protected by BQL. */
+ int64_t cpu_ticks_prev;
+ int64_t cpu_ticks_offset;
+
+ /*
+ * Protect fields that can be respectively read outside the
+ * BQL, and written from multiple threads.
+ */
+ QemuSeqLock vm_clock_seqlock;
+ QemuSpin vm_clock_lock;
+
+ int16_t cpu_ticks_enabled;
+
+ /* Conversion factor from emulated instructions to virtual clock ticks. */
+ int16_t icount_time_shift;
+ /* Icount delta used for shift auto adjust. */
+ int64_t last_delta;
+
+ /* Compensate for varying guest execution speed. */
+ aligned_int64_t qemu_icount_bias;
+
+ int64_t vm_clock_warp_start;
+ int64_t cpu_clock_offset;
+
+ /* Only written by TCG thread */
+ int64_t qemu_icount;
+
+ /* for adjusting icount */
+ QEMUTimer *icount_rt_timer;
+ QEMUTimer *icount_vm_timer;
+ QEMUTimer *icount_warp_timer;
+} TimersState;
+
+extern TimersState timers_state;
+
+/*
+ * icount needs this internal from cpu-timers when adjusting the icount shift.
+ */
+int64_t cpu_get_clock_locked(void);
+
+#endif /* TIMERS_STATE_H */
--- /dev/null
+/*
+ * CPU timers state API
+ *
+ * Copyright 2020 SUSE LLC
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+#ifndef SYSTEM_CPU_TIMERS_H
+#define SYSTEM_CPU_TIMERS_H
+
+#include "qemu/timer.h"
+
+/* init the whole cpu timers API, including icount, ticks, and cpu_throttle */
+void cpu_timers_init(void);
+
+/* icount - Instruction Counter API */
+
+/**
+ * ICountMode: icount enablement state:
+ *
+ * @ICOUNT_DISABLED: Disabled - Do not count executed instructions.
+ * @ICOUNT_PRECISE: Enabled - Fixed conversion of insn to ns via "shift" option
+ * @ICOUNT_ADAPTATIVE: Enabled - Runtime adaptive algorithm to compute shift
+ */
+typedef enum {
+ ICOUNT_DISABLED = 0,
+ ICOUNT_PRECISE,
+ ICOUNT_ADAPTATIVE,
+} ICountMode;
+
+#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
+extern ICountMode use_icount;
+#define icount_enabled() (use_icount)
+#else
+#define icount_enabled() ICOUNT_DISABLED
+#endif
+
+/*
+ * Update the icount with the executed instructions. Called by
+ * cpus-tcg vCPU thread so the main-loop can see time has moved forward.
+ */
+void icount_update(CPUState *cpu);
+
+/* get raw icount value */
+int64_t icount_get_raw(void);
+
+/* return the virtual CPU time in ns, based on the instruction counter. */
+int64_t icount_get(void);
+/*
+ * convert an instruction counter value to ns, based on the icount shift.
+ * This shift is set as a fixed value with the icount "shift" option
+ * (precise mode), or it is constantly approximated and corrected at
+ * runtime in adaptive mode.
+ */
+int64_t icount_to_ns(int64_t icount);
+
+/**
+ * icount_configure: configure the icount options, including "shift"
+ * @opts: Options to parse
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Return: true on success, else false setting @errp with error
+ */
+bool icount_configure(QemuOpts *opts, Error **errp);
+
+/* used by tcg vcpu thread to calc icount budget */
+int64_t icount_round(int64_t count);
+
+/* if the CPUs are idle, start accounting real time to virtual clock. */
+void icount_start_warp_timer(void);
+void icount_account_warp_timer(void);
+void icount_notify_exit(void);
+
+/*
+ * CPU Ticks and Clock
+ */
+
+/* Caller must hold BQL */
+void cpu_enable_ticks(void);
+/* Caller must hold BQL */
+void cpu_disable_ticks(void);
+
+/*
+ * return the time elapsed in VM between vm_start and vm_stop.
+ * cpu_get_ticks() uses units of the host CPU cycle counter.
+ */
+int64_t cpu_get_ticks(void);
+
+/*
+ * Returns the monotonic time elapsed in VM, i.e.,
+ * the time between vm_start and vm_stop
+ */
+int64_t cpu_get_clock(void);
+
+void qemu_timer_notify_cb(void *opaque, QEMUClockType type);
+
+/* get/set VIRTUAL clock and VM elapsed ticks via the cpus accel interface */
+int64_t cpus_get_virtual_clock(void);
+void cpus_set_virtual_clock(int64_t new_time);
+int64_t cpus_get_elapsed_ticks(void);
+
+#endif /* SYSTEM_CPU_TIMERS_H */
--- /dev/null
+#ifndef QEMU_CPUS_H
+#define QEMU_CPUS_H
+
+#include "system/accel-ops.h"
+
+/* register accel-specific operations */
+void cpus_register_accel(const AccelOpsClass *i);
+
+/* return registers ops */
+const AccelOpsClass *cpus_get_accel(void);
+
+/* accel/dummy-cpus.c */
+
+/* Create a dummy vcpu for AccelOpsClass->create_vcpu_thread */
+void dummy_start_vcpu_thread(CPUState *);
+
+/* interface available for cpus accelerator threads */
+
+/* For temporary buffers for forming a name */
+#define VCPU_THREAD_NAME_SIZE 16
+
+void cpus_kick_thread(CPUState *cpu);
+bool cpu_work_list_empty(CPUState *cpu);
+bool cpu_thread_is_idle(CPUState *cpu);
+bool all_cpu_threads_idle(void);
+bool cpu_can_run(CPUState *cpu);
+void qemu_wait_io_event_common(CPUState *cpu);
+void qemu_wait_io_event(CPUState *cpu);
+void cpu_thread_signal_created(CPUState *cpu);
+void cpu_thread_signal_destroyed(CPUState *cpu);
+void cpu_handle_guest_debug(CPUState *cpu);
+
+/* end interface for cpus accelerator threads */
+
+bool qemu_in_vcpu_thread(void);
+void qemu_init_cpu_loop(void);
+void resume_all_vcpus(void);
+void pause_all_vcpus(void);
+void cpu_stop_current(void);
+
+extern int icount_align_option;
+
+/* Unblock cpu */
+void qemu_cpu_kick_self(void);
+
+bool cpus_are_resettable(void);
+
+void cpu_synchronize_all_states(void);
+void cpu_synchronize_all_post_reset(void);
+void cpu_synchronize_all_post_init(void);
+void cpu_synchronize_all_pre_loadvm(void);
+
+#endif
--- /dev/null
+/*
+ * QEMU Crypto Device Common Vhost User Implement
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ * Gonglei <arei.gonglei@huawei.com>
+ *
+ * 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.1 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/>.
+ *
+ */
+
+#ifndef CRYPTODEV_VHOST_USER_H
+#define CRYPTODEV_VHOST_USER_H
+
+#include "system/cryptodev-vhost.h"
+
+#define VHOST_USER_MAX_AUTH_KEY_LEN 512
+#define VHOST_USER_MAX_CIPHER_KEY_LEN 64
+
+
+/**
+ * cryptodev_vhost_user_get_vhost:
+ * @cc: the client object for each queue
+ * @b: the cryptodev backend common vhost object
+ * @queue: the queue index
+ *
+ * Gets a new cryptodev backend common vhost object based on
+ * @b and @queue
+ *
+ * Returns: the cryptodev backend common vhost object
+ */
+CryptoDevBackendVhost *
+cryptodev_vhost_user_get_vhost(
+ CryptoDevBackendClient *cc,
+ CryptoDevBackend *b,
+ uint16_t queue);
+
+#endif /* CRYPTODEV_VHOST_USER_H */
--- /dev/null
+/*
+ * QEMU Crypto Device Common Vhost Implement
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ * Gonglei <arei.gonglei@huawei.com>
+ * Jay Zhou <jianjay.zhou@huawei.com>
+ *
+ * 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.1 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/>.
+ *
+ */
+#ifndef CRYPTODEV_VHOST_H
+#define CRYPTODEV_VHOST_H
+
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-backend.h"
+#include "chardev/char.h"
+
+#include "system/cryptodev.h"
+
+
+typedef struct CryptoDevBackendVhostOptions {
+ VhostBackendType backend_type;
+ void *opaque;
+ int total_queues;
+ CryptoDevBackendClient *cc;
+} CryptoDevBackendVhostOptions;
+
+typedef struct CryptoDevBackendVhost {
+ struct vhost_dev dev;
+ struct vhost_virtqueue vqs[1];
+ int backend;
+ CryptoDevBackendClient *cc;
+} CryptoDevBackendVhost;
+
+/**
+ * cryptodev_vhost_get_max_queues:
+ * @crypto: the cryptodev backend common vhost object
+ *
+ * Get the maximum queue number of @crypto.
+ *
+ *
+ * Returns: the maximum queue number
+ */
+uint64_t
+cryptodev_vhost_get_max_queues(
+ CryptoDevBackendVhost *crypto);
+
+
+/**
+ * cryptodev_vhost_init:
+ * @options: the common vhost object's option
+ *
+ * Creates a new cryptodev backend common vhost object
+ *
+ ** The returned object must be released with
+ * cryptodev_vhost_cleanup() when no
+ * longer required
+ *
+ * Returns: the cryptodev backend common vhost object
+ */
+struct CryptoDevBackendVhost *
+cryptodev_vhost_init(
+ CryptoDevBackendVhostOptions *options);
+
+/**
+ * cryptodev_vhost_cleanup:
+ * @crypto: the cryptodev backend common vhost object
+ *
+ * Clean the resource associated with @crypto that realizaed
+ * by cryptodev_vhost_init()
+ *
+ */
+void cryptodev_vhost_cleanup(
+ CryptoDevBackendVhost *crypto);
+
+/**
+ * cryptodev_get_vhost:
+ * @cc: the client object for each queue
+ * @b: the cryptodev backend common vhost object
+ * @queue: the cryptodev backend queue index
+ *
+ * Gets a new cryptodev backend common vhost object based on
+ * @b and @queue
+ *
+ * Returns: the cryptodev backend common vhost object
+ */
+CryptoDevBackendVhost *
+cryptodev_get_vhost(CryptoDevBackendClient *cc,
+ CryptoDevBackend *b,
+ uint16_t queue);
+/**
+ * cryptodev_vhost_start:
+ * @dev: the virtio crypto object
+ * @total_queues: the total count of queue
+ *
+ * Starts the vhost crypto logic
+ *
+ * Returns: 0 for success, negative for errors
+ */
+int cryptodev_vhost_start(VirtIODevice *dev, int total_queues);
+
+/**
+ * cryptodev_vhost_stop:
+ * @dev: the virtio crypto object
+ * @total_queues: the total count of queue
+ *
+ * Stops the vhost crypto logic
+ *
+ */
+void cryptodev_vhost_stop(VirtIODevice *dev, int total_queues);
+
+/**
+ * cryptodev_vhost_virtqueue_mask:
+ * @dev: the virtio crypto object
+ * @queue: the cryptodev backend queue index
+ * @idx: the virtqueue index
+ * @mask: mask or not (true or false)
+ *
+ * Mask/unmask events for @idx virtqueue on @dev device
+ *
+ */
+void cryptodev_vhost_virtqueue_mask(VirtIODevice *dev,
+ int queue,
+ int idx, bool mask);
+
+/**
+ * cryptodev_vhost_virtqueue_pending:
+ * @dev: the virtio crypto object
+ * @queue: the cryptodev backend queue index
+ * @idx: the virtqueue index
+ *
+ * Test and clear event pending status for @idx virtqueue on @dev device.
+ * Should be called after unmask to avoid losing events.
+ *
+ * Returns: true for success, false for errors
+ */
+bool cryptodev_vhost_virtqueue_pending(VirtIODevice *dev,
+ int queue, int idx);
+
+#endif /* CRYPTODEV_VHOST_H */
--- /dev/null
+/*
+ * QEMU Crypto Device Implementation
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ * Gonglei <arei.gonglei@huawei.com>
+ *
+ * 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.1 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/>.
+ *
+ */
+#ifndef CRYPTODEV_H
+#define CRYPTODEV_H
+
+#include "qemu/queue.h"
+#include "qemu/throttle.h"
+#include "qom/object.h"
+#include "qapi/qapi-types-cryptodev.h"
+
+/**
+ * CryptoDevBackend:
+ *
+ * The CryptoDevBackend object is an interface
+ * for different cryptodev backends, which provides crypto
+ * operation wrapper.
+ *
+ */
+
+#define TYPE_CRYPTODEV_BACKEND "cryptodev-backend"
+
+OBJECT_DECLARE_TYPE(CryptoDevBackend, CryptoDevBackendClass,
+ CRYPTODEV_BACKEND)
+
+
+#define MAX_CRYPTO_QUEUE_NUM 64
+
+typedef struct CryptoDevBackendConf CryptoDevBackendConf;
+typedef struct CryptoDevBackendPeers CryptoDevBackendPeers;
+typedef struct CryptoDevBackendClient
+ CryptoDevBackendClient;
+
+/**
+ * CryptoDevBackendSymSessionInfo:
+ *
+ * @cipher_alg: algorithm type of CIPHER
+ * @key_len: byte length of cipher key
+ * @hash_alg: algorithm type of HASH/MAC
+ * @hash_result_len: byte length of HASH operation result
+ * @auth_key_len: byte length of authenticated key
+ * @add_len: byte length of additional authenticated data
+ * @op_type: operation type (refer to virtio_crypto.h)
+ * @direction: encryption or direction for CIPHER
+ * @hash_mode: HASH mode for HASH operation (refer to virtio_crypto.h)
+ * @alg_chain_order: order of algorithm chaining (CIPHER then HASH,
+ * or HASH then CIPHER)
+ * @cipher_key: point to a key of CIPHER
+ * @auth_key: point to an authenticated key of MAC
+ *
+ */
+typedef struct CryptoDevBackendSymSessionInfo {
+ /* corresponding with virtio crypto spec */
+ uint32_t cipher_alg;
+ uint32_t key_len;
+ uint32_t hash_alg;
+ uint32_t hash_result_len;
+ uint32_t auth_key_len;
+ uint32_t add_len;
+ uint8_t op_type;
+ uint8_t direction;
+ uint8_t hash_mode;
+ uint8_t alg_chain_order;
+ uint8_t *cipher_key;
+ uint8_t *auth_key;
+} CryptoDevBackendSymSessionInfo;
+
+/**
+ * CryptoDevBackendAsymSessionInfo:
+ */
+typedef struct CryptoDevBackendRsaPara {
+ uint32_t padding_algo;
+ uint32_t hash_algo;
+} CryptoDevBackendRsaPara;
+
+typedef struct CryptoDevBackendAsymSessionInfo {
+ /* corresponding with virtio crypto spec */
+ uint32_t algo;
+ uint32_t keytype;
+ uint32_t keylen;
+ uint8_t *key;
+ union {
+ CryptoDevBackendRsaPara rsa;
+ } u;
+} CryptoDevBackendAsymSessionInfo;
+
+typedef struct CryptoDevBackendSessionInfo {
+ uint32_t op_code;
+ union {
+ CryptoDevBackendSymSessionInfo sym_sess_info;
+ CryptoDevBackendAsymSessionInfo asym_sess_info;
+ } u;
+ uint64_t session_id;
+} CryptoDevBackendSessionInfo;
+
+/**
+ * CryptoDevBackendSymOpInfo:
+ *
+ * @aad_len: byte length of additional authenticated data
+ * @iv_len: byte length of initialization vector or counter
+ * @src_len: byte length of source data
+ * @dst_len: byte length of destination data
+ * @digest_result_len: byte length of hash digest result
+ * @hash_start_src_offset: Starting point for hash processing, specified
+ * as number of bytes from start of packet in source data, only used for
+ * algorithm chain
+ * @cipher_start_src_offset: Starting point for cipher processing, specified
+ * as number of bytes from start of packet in source data, only used for
+ * algorithm chain
+ * @len_to_hash: byte length of source data on which the hash
+ * operation will be computed, only used for algorithm chain
+ * @len_to_cipher: byte length of source data on which the cipher
+ * operation will be computed, only used for algorithm chain
+ * @op_type: operation type (refer to virtio_crypto.h)
+ * @iv: point to the initialization vector or counter
+ * @src: point to the source data
+ * @dst: point to the destination data
+ * @aad_data: point to the additional authenticated data
+ * @digest_result: point to the digest result data
+ * @data[0]: point to the extensional memory by one memory allocation
+ *
+ */
+typedef struct CryptoDevBackendSymOpInfo {
+ uint32_t aad_len;
+ uint32_t iv_len;
+ uint32_t src_len;
+ uint32_t dst_len;
+ uint32_t digest_result_len;
+ uint32_t hash_start_src_offset;
+ uint32_t cipher_start_src_offset;
+ uint32_t len_to_hash;
+ uint32_t len_to_cipher;
+ uint8_t op_type;
+ uint8_t *iv;
+ uint8_t *src;
+ uint8_t *dst;
+ uint8_t *aad_data;
+ uint8_t *digest_result;
+ uint8_t data[];
+} CryptoDevBackendSymOpInfo;
+
+
+/**
+ * CryptoDevBackendAsymOpInfo:
+ *
+ * @src_len: byte length of source data
+ * @dst_len: byte length of destination data
+ * @src: point to the source data
+ * @dst: point to the destination data
+ *
+ */
+typedef struct CryptoDevBackendAsymOpInfo {
+ uint32_t src_len;
+ uint32_t dst_len;
+ uint8_t *src;
+ uint8_t *dst;
+} CryptoDevBackendAsymOpInfo;
+
+typedef void (*CryptoDevCompletionFunc) (void *opaque, int ret);
+
+typedef struct CryptoDevBackendOpInfo {
+ QCryptodevBackendAlgoType algtype;
+ uint32_t op_code;
+ uint32_t queue_index;
+ CryptoDevCompletionFunc cb;
+ void *opaque; /* argument for cb */
+ uint64_t session_id;
+ union {
+ CryptoDevBackendSymOpInfo *sym_op_info;
+ CryptoDevBackendAsymOpInfo *asym_op_info;
+ } u;
+ QTAILQ_ENTRY(CryptoDevBackendOpInfo) next;
+} CryptoDevBackendOpInfo;
+
+struct CryptoDevBackendClass {
+ ObjectClass parent_class;
+
+ void (*init)(CryptoDevBackend *backend, Error **errp);
+ void (*cleanup)(CryptoDevBackend *backend, Error **errp);
+
+ int (*create_session)(CryptoDevBackend *backend,
+ CryptoDevBackendSessionInfo *sess_info,
+ uint32_t queue_index,
+ CryptoDevCompletionFunc cb,
+ void *opaque);
+
+ int (*close_session)(CryptoDevBackend *backend,
+ uint64_t session_id,
+ uint32_t queue_index,
+ CryptoDevCompletionFunc cb,
+ void *opaque);
+
+ int (*do_op)(CryptoDevBackend *backend,
+ CryptoDevBackendOpInfo *op_info);
+};
+
+struct CryptoDevBackendClient {
+ QCryptodevBackendType type;
+ char *info_str;
+ unsigned int queue_index;
+ int vring_enable;
+ QTAILQ_ENTRY(CryptoDevBackendClient) next;
+};
+
+struct CryptoDevBackendPeers {
+ CryptoDevBackendClient *ccs[MAX_CRYPTO_QUEUE_NUM];
+ uint32_t queues;
+};
+
+struct CryptoDevBackendConf {
+ CryptoDevBackendPeers peers;
+
+ /* Supported service mask */
+ uint32_t crypto_services;
+
+ /* Detailed algorithms mask */
+ uint32_t cipher_algo_l;
+ uint32_t cipher_algo_h;
+ uint32_t hash_algo;
+ uint32_t mac_algo_l;
+ uint32_t mac_algo_h;
+ uint32_t aead_algo;
+ uint32_t akcipher_algo;
+ /* Maximum length of cipher key */
+ uint32_t max_cipher_key_len;
+ /* Maximum length of authenticated key */
+ uint32_t max_auth_key_len;
+ /* Maximum size of each crypto request's content */
+ uint64_t max_size;
+};
+
+typedef struct CryptodevBackendSymStat {
+ int64_t encrypt_ops;
+ int64_t decrypt_ops;
+ int64_t encrypt_bytes;
+ int64_t decrypt_bytes;
+} CryptodevBackendSymStat;
+
+typedef struct CryptodevBackendAsymStat {
+ int64_t encrypt_ops;
+ int64_t decrypt_ops;
+ int64_t sign_ops;
+ int64_t verify_ops;
+ int64_t encrypt_bytes;
+ int64_t decrypt_bytes;
+ int64_t sign_bytes;
+ int64_t verify_bytes;
+} CryptodevBackendAsymStat;
+
+struct CryptoDevBackend {
+ Object parent_obj;
+
+ bool ready;
+ /* Tag the cryptodev backend is used by virtio-crypto or not */
+ bool is_used;
+ CryptoDevBackendConf conf;
+ CryptodevBackendSymStat *sym_stat;
+ CryptodevBackendAsymStat *asym_stat;
+
+ ThrottleState ts;
+ ThrottleTimers tt;
+ ThrottleConfig tc;
+ QTAILQ_HEAD(, CryptoDevBackendOpInfo) opinfos;
+};
+
+#define CryptodevSymStatInc(be, op, bytes) do { \
+ be->sym_stat->op##_bytes += (bytes); \
+ be->sym_stat->op##_ops += 1; \
+} while (/*CONSTCOND*/0)
+
+#define CryptodevSymStatIncEncrypt(be, bytes) \
+ CryptodevSymStatInc(be, encrypt, bytes)
+
+#define CryptodevSymStatIncDecrypt(be, bytes) \
+ CryptodevSymStatInc(be, decrypt, bytes)
+
+#define CryptodevAsymStatInc(be, op, bytes) do { \
+ be->asym_stat->op##_bytes += (bytes); \
+ be->asym_stat->op##_ops += 1; \
+} while (/*CONSTCOND*/0)
+
+#define CryptodevAsymStatIncEncrypt(be, bytes) \
+ CryptodevAsymStatInc(be, encrypt, bytes)
+
+#define CryptodevAsymStatIncDecrypt(be, bytes) \
+ CryptodevAsymStatInc(be, decrypt, bytes)
+
+#define CryptodevAsymStatIncSign(be, bytes) \
+ CryptodevAsymStatInc(be, sign, bytes)
+
+#define CryptodevAsymStatIncVerify(be, bytes) \
+ CryptodevAsymStatInc(be, verify, bytes)
+
+
+/**
+ * cryptodev_backend_new_client:
+ *
+ * Creates a new cryptodev backend client object.
+ *
+ * The returned object must be released with
+ * cryptodev_backend_free_client() when no
+ * longer required
+ *
+ * Returns: a new cryptodev backend client object
+ */
+CryptoDevBackendClient *cryptodev_backend_new_client(void);
+
+/**
+ * cryptodev_backend_free_client:
+ * @cc: the cryptodev backend client object
+ *
+ * Release the memory associated with @cc that
+ * was previously allocated by cryptodev_backend_new_client()
+ */
+void cryptodev_backend_free_client(
+ CryptoDevBackendClient *cc);
+
+/**
+ * cryptodev_backend_cleanup:
+ * @backend: the cryptodev backend object
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Clean the resource associated with @backend that realizaed
+ * by the specific backend's init() callback
+ */
+void cryptodev_backend_cleanup(
+ CryptoDevBackend *backend,
+ Error **errp);
+
+/**
+ * cryptodev_backend_create_session:
+ * @backend: the cryptodev backend object
+ * @sess_info: parameters needed by session creating
+ * @queue_index: queue index of cryptodev backend client
+ * @errp: pointer to a NULL-initialized error object
+ * @cb: callback when session create is compeleted
+ * @opaque: parameter passed to callback
+ *
+ * Create a session for symmetric/asymmetric algorithms
+ *
+ * Returns: 0 for success and cb will be called when creation is completed,
+ * negative value for error, and cb will not be called.
+ */
+int cryptodev_backend_create_session(
+ CryptoDevBackend *backend,
+ CryptoDevBackendSessionInfo *sess_info,
+ uint32_t queue_index,
+ CryptoDevCompletionFunc cb,
+ void *opaque);
+
+/**
+ * cryptodev_backend_close_session:
+ * @backend: the cryptodev backend object
+ * @session_id: the session id
+ * @queue_index: queue index of cryptodev backend client
+ * @errp: pointer to a NULL-initialized error object
+ * @cb: callback when session create is compeleted
+ * @opaque: parameter passed to callback
+ *
+ * Close a session for which was previously
+ * created by cryptodev_backend_create_session()
+ *
+ * Returns: 0 for success and cb will be called when creation is completed,
+ * negative value for error, and cb will not be called.
+ */
+int cryptodev_backend_close_session(
+ CryptoDevBackend *backend,
+ uint64_t session_id,
+ uint32_t queue_index,
+ CryptoDevCompletionFunc cb,
+ void *opaque);
+
+/**
+ * cryptodev_backend_crypto_operation:
+ * @backend: the cryptodev backend object
+ * @op_info: pointer to a CryptoDevBackendOpInfo object
+ *
+ * Do crypto operation, such as encryption, decryption, signature and
+ * verification
+ *
+ * Returns: 0 for success and cb will be called when creation is completed,
+ * negative value for error, and cb will not be called.
+ */
+int cryptodev_backend_crypto_operation(
+ CryptoDevBackend *backend,
+ CryptoDevBackendOpInfo *op_info);
+
+/**
+ * cryptodev_backend_set_used:
+ * @backend: the cryptodev backend object
+ * @used: true or false
+ *
+ * Set the cryptodev backend is used by virtio-crypto or not
+ */
+void cryptodev_backend_set_used(CryptoDevBackend *backend, bool used);
+
+/**
+ * cryptodev_backend_is_used:
+ * @backend: the cryptodev backend object
+ *
+ * Return the status that the cryptodev backend is used
+ * by virtio-crypto or not
+ *
+ * Returns: true on used, or false on not used
+ */
+bool cryptodev_backend_is_used(CryptoDevBackend *backend);
+
+/**
+ * cryptodev_backend_set_ready:
+ * @backend: the cryptodev backend object
+ * @ready: true or false
+ *
+ * Set the cryptodev backend is ready or not, which is called
+ * by the children of the cryptodev banckend interface.
+ */
+void cryptodev_backend_set_ready(CryptoDevBackend *backend, bool ready);
+
+/**
+ * cryptodev_backend_is_ready:
+ * @backend: the cryptodev backend object
+ *
+ * Return the status that the cryptodev backend is ready or not
+ *
+ * Returns: true on ready, or false on not ready
+ */
+bool cryptodev_backend_is_ready(CryptoDevBackend *backend);
+
+#endif /* CRYPTODEV_H */
--- /dev/null
+/*
+ * Header with function prototypes to help device tree manipulation using
+ * libfdt. It also provides functions to read entries from device tree proc
+ * interface.
+ *
+ * Copyright 2008 IBM Corporation.
+ * Authors: Jerone Young <jyoung5@us.ibm.com>
+ * Hollis Blanchard <hollisb@us.ibm.com>
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ */
+
+#ifndef DEVICE_TREE_H
+#define DEVICE_TREE_H
+
+void *create_device_tree(int *sizep);
+void *load_device_tree(const char *filename_path, int *sizep);
+#ifdef CONFIG_LINUX
+/**
+ * load_device_tree_from_sysfs: reads the device tree information in the
+ * /proc/device-tree directory and return the corresponding binary blob
+ * buffer pointer. Asserts in case of error.
+ */
+void *load_device_tree_from_sysfs(void);
+#endif
+
+/**
+ * qemu_fdt_node_path: return the paths of nodes matching a given
+ * name and compat string
+ * @fdt: pointer to the dt blob
+ * @name: node name
+ * @compat: compatibility string
+ * @errp: handle to an error object
+ *
+ * returns a newly allocated NULL-terminated array of node paths.
+ * Use g_strfreev() to free it. If one or more nodes were found, the
+ * array contains the path of each node and the last element equals to
+ * NULL. If there is no error but no matching node was found, the
+ * returned array contains a single element equal to NULL. If an error
+ * was encountered when parsing the blob, the function returns NULL
+ *
+ * @name may be NULL to wildcard names and only match compatibility
+ * strings.
+ */
+char **qemu_fdt_node_path(void *fdt, const char *name, const char *compat,
+ Error **errp);
+
+/**
+ * qemu_fdt_node_unit_path: return the paths of nodes matching a given
+ * node-name, ie. node-name and node-name@unit-address
+ * @fdt: pointer to the dt blob
+ * @name: node name
+ * @errp: handle to an error object
+ *
+ * returns a newly allocated NULL-terminated array of node paths.
+ * Use g_strfreev() to free it. If one or more nodes were found, the
+ * array contains the path of each node and the last element equals to
+ * NULL. If there is no error but no matching node was found, the
+ * returned array contains a single element equal to NULL. If an error
+ * was encountered when parsing the blob, the function returns NULL
+ */
+char **qemu_fdt_node_unit_path(void *fdt, const char *name, Error **errp);
+
+int qemu_fdt_setprop(void *fdt, const char *node_path,
+ const char *property, const void *val, int size);
+int qemu_fdt_setprop_cell(void *fdt, const char *node_path,
+ const char *property, uint32_t val);
+int qemu_fdt_setprop_u64(void *fdt, const char *node_path,
+ const char *property, uint64_t val);
+int qemu_fdt_setprop_string(void *fdt, const char *node_path,
+ const char *property, const char *string);
+
+/**
+ * qemu_fdt_setprop_string_array: set a string array property
+ *
+ * @fdt: pointer to the dt blob
+ * @name: node name
+ * @prop: property array
+ * @array: pointer to an array of string pointers
+ * @len: length of array
+ *
+ * assigns a string array to a property. This function converts and
+ * array of strings to a sequential string with \0 separators before
+ * setting the property.
+ */
+int qemu_fdt_setprop_string_array(void *fdt, const char *node_path,
+ const char *prop, char **array, int len);
+
+int qemu_fdt_setprop_phandle(void *fdt, const char *node_path,
+ const char *property,
+ const char *target_node_path);
+/**
+ * qemu_fdt_getprop: retrieve the value of a given property
+ * @fdt: pointer to the device tree blob
+ * @node_path: node path
+ * @property: name of the property to find
+ * @lenp: fdt error if any or length of the property on success
+ * @errp: handle to an error object
+ *
+ * returns a pointer to the property on success and NULL on failure
+ */
+const void *qemu_fdt_getprop(void *fdt, const char *node_path,
+ const char *property, int *lenp,
+ Error **errp);
+/**
+ * qemu_fdt_getprop_cell: retrieve the value of a given 4 byte property
+ * @fdt: pointer to the device tree blob
+ * @node_path: node path
+ * @property: name of the property to find
+ * @lenp: fdt error if any or -EINVAL if the property size is different from
+ * 4 bytes, or 4 (expected length of the property) upon success.
+ * @errp: handle to an error object
+ *
+ * returns the property value on success
+ */
+uint32_t qemu_fdt_getprop_cell(void *fdt, const char *node_path,
+ const char *property, int *lenp,
+ Error **errp);
+uint32_t qemu_fdt_get_phandle(void *fdt, const char *path);
+uint32_t qemu_fdt_alloc_phandle(void *fdt);
+int qemu_fdt_nop_node(void *fdt, const char *node_path);
+int qemu_fdt_add_subnode(void *fdt, const char *name);
+int qemu_fdt_add_path(void *fdt, const char *path);
+
+#define qemu_fdt_setprop_cells(fdt, node_path, property, ...) \
+ do { \
+ uint32_t qdt_tmp[] = { __VA_ARGS__ }; \
+ for (unsigned i_ = 0; i_ < ARRAY_SIZE(qdt_tmp); i_++) { \
+ qdt_tmp[i_] = cpu_to_be32(qdt_tmp[i_]); \
+ } \
+ qemu_fdt_setprop(fdt, node_path, property, qdt_tmp, \
+ sizeof(qdt_tmp)); \
+ } while (0)
+
+void qemu_fdt_dumpdtb(void *fdt, int size);
+
+/**
+ * qemu_fdt_setprop_sized_cells_from_array:
+ * @fdt: device tree blob
+ * @node_path: node to set property on
+ * @property: property to set
+ * @numvalues: number of values
+ * @values: array of number-of-cells, value pairs
+ *
+ * Set the specified property on the specified node in the device tree
+ * to be an array of cells. The values of the cells are specified via
+ * the values list, which alternates between "number of cells used by
+ * this value" and "value".
+ * number-of-cells must be either 1 or 2 (other values will result in
+ * an error being returned). If a value is too large to fit in the
+ * number of cells specified for it, an error is returned.
+ *
+ * This function is useful because device tree nodes often have cell arrays
+ * which are either lists of addresses or lists of address,size tuples, but
+ * the number of cells used for each element vary depending on the
+ * #address-cells and #size-cells properties of their parent node.
+ * If you know all your cell elements are one cell wide you can use the
+ * simpler qemu_fdt_setprop_cells(). If you're not setting up the
+ * array programmatically, qemu_fdt_setprop_sized_cells may be more
+ * convenient.
+ *
+ * Return value: 0 on success, <0 on error.
+ */
+int qemu_fdt_setprop_sized_cells_from_array(void *fdt,
+ const char *node_path,
+ const char *property,
+ int numvalues,
+ uint64_t *values);
+
+/**
+ * qemu_fdt_setprop_sized_cells:
+ * @fdt: device tree blob
+ * @node_path: node to set property on
+ * @property: property to set
+ * @...: list of number-of-cells, value pairs
+ *
+ * Set the specified property on the specified node in the device tree
+ * to be an array of cells. The values of the cells are specified via
+ * the variable arguments, which alternates between "number of cells
+ * used by this value" and "value".
+ *
+ * This is a convenience wrapper for the function
+ * qemu_fdt_setprop_sized_cells_from_array().
+ *
+ * Return value: 0 on success, <0 on error.
+ */
+#define qemu_fdt_setprop_sized_cells(fdt, node_path, property, ...) \
+ ({ \
+ uint64_t qdt_tmp[] = { __VA_ARGS__ }; \
+ qemu_fdt_setprop_sized_cells_from_array(fdt, node_path, \
+ property, \
+ ARRAY_SIZE(qdt_tmp) / 2, \
+ qdt_tmp); \
+ })
+
+
+/**
+ * qemu_fdt_randomize_seeds:
+ * @fdt: device tree blob
+ *
+ * Re-randomize all "rng-seed" properties with new seeds.
+ */
+void qemu_fdt_randomize_seeds(void *fdt);
+
+#define FDT_PCI_RANGE_RELOCATABLE 0x80000000
+#define FDT_PCI_RANGE_PREFETCHABLE 0x40000000
+#define FDT_PCI_RANGE_ALIASED 0x20000000
+#define FDT_PCI_RANGE_TYPE_MASK 0x03000000
+#define FDT_PCI_RANGE_MMIO_64BIT 0x03000000
+#define FDT_PCI_RANGE_MMIO 0x02000000
+#define FDT_PCI_RANGE_IOPORT 0x01000000
+#define FDT_PCI_RANGE_CONFIG 0x00000000
+
+#endif /* DEVICE_TREE_H */
--- /dev/null
+/*
+ * Dirty page rate limit common functions
+ *
+ * Copyright (c) 2022 CHINA TELECOM CO.,LTD.
+ *
+ * Authors:
+ * Hyman Huang(黄勇) <huangy81@chinatelecom.cn>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef QEMU_DIRTYRLIMIT_H
+#define QEMU_DIRTYRLIMIT_H
+
+#define DIRTYLIMIT_CALC_TIME_MS 1000 /* 1000ms */
+
+int64_t vcpu_dirty_rate_get(int cpu_index);
+void vcpu_dirty_rate_stat_start(void);
+void vcpu_dirty_rate_stat_stop(void);
+void vcpu_dirty_rate_stat_initialize(void);
+void vcpu_dirty_rate_stat_finalize(void);
+
+void dirtylimit_state_lock(void);
+void dirtylimit_state_unlock(void);
+void dirtylimit_state_initialize(void);
+void dirtylimit_state_finalize(void);
+bool dirtylimit_in_service(void);
+bool dirtylimit_vcpu_index_valid(int cpu_index);
+void dirtylimit_process(void);
+void dirtylimit_change(bool start);
+void dirtylimit_set_vcpu(int cpu_index,
+ uint64_t quota,
+ bool enable);
+void dirtylimit_set_all(uint64_t quota,
+ bool enable);
+void dirtylimit_vcpu_execute(CPUState *cpu);
+uint64_t dirtylimit_throttle_time_per_round(void);
+uint64_t dirtylimit_ring_full_time(void);
+#endif
--- /dev/null
+/*
+ * dirty page rate helper functions
+ *
+ * Copyright (c) 2022 CHINA TELECOM CO.,LTD.
+ *
+ * Authors:
+ * Hyman Huang(黄勇) <huangy81@chinatelecom.cn>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef QEMU_DIRTYRATE_H
+#define QEMU_DIRTYRATE_H
+
+#include "qapi/qapi-types-migration.h"
+
+typedef struct VcpuStat {
+ int nvcpu; /* number of vcpu */
+ DirtyRateVcpu *rates; /* array of dirty rate for each vcpu */
+} VcpuStat;
+
+int64_t vcpu_calculate_dirtyrate(int64_t calc_time_ms,
+ VcpuStat *stat,
+ unsigned int flag,
+ bool one_shot);
+
+void global_dirty_log_change(unsigned int flag,
+ bool start);
+#endif
--- /dev/null
+/*
+ * DMA helper functions
+ *
+ * Copyright (c) 2009, 2020 Red Hat
+ *
+ * This work is licensed under the terms of the GNU General Public License
+ * (GNU GPL), version 2 or later.
+ */
+
+#ifndef DMA_H
+#define DMA_H
+
+#include "exec/memory.h"
+#include "exec/address-spaces.h"
+#include "block/block.h"
+#include "block/accounting.h"
+
+typedef enum {
+ DMA_DIRECTION_TO_DEVICE = 0,
+ DMA_DIRECTION_FROM_DEVICE = 1,
+} DMADirection;
+
+/*
+ * When an IOMMU is present, bus addresses become distinct from
+ * CPU/memory physical addresses and may be a different size. Because
+ * the IOVA size depends more on the bus than on the platform, we more
+ * or less have to treat these as 64-bit always to cover all (or at
+ * least most) cases.
+ */
+typedef uint64_t dma_addr_t;
+
+#define DMA_ADDR_BITS 64
+#define DMA_ADDR_FMT "%" PRIx64
+
+typedef struct ScatterGatherEntry ScatterGatherEntry;
+
+struct QEMUSGList {
+ ScatterGatherEntry *sg;
+ int nsg;
+ int nalloc;
+ dma_addr_t size;
+ DeviceState *dev;
+ AddressSpace *as;
+};
+
+static inline void dma_barrier(AddressSpace *as, DMADirection dir)
+{
+ /*
+ * This is called before DMA read and write operations
+ * unless the _relaxed form is used and is responsible
+ * for providing some sane ordering of accesses vs
+ * concurrently running VCPUs.
+ *
+ * Users of map(), unmap() or lower level st/ld_*
+ * operations are responsible for providing their own
+ * ordering via barriers.
+ *
+ * This primitive implementation does a simple smp_mb()
+ * before each operation which provides pretty much full
+ * ordering.
+ *
+ * A smarter implementation can be devised if needed to
+ * use lighter barriers based on the direction of the
+ * transfer, the DMA context, etc...
+ */
+ smp_mb();
+}
+
+/* Checks that the given range of addresses is valid for DMA. This is
+ * useful for certain cases, but usually you should just use
+ * dma_memory_{read,write}() and check for errors */
+static inline bool dma_memory_valid(AddressSpace *as,
+ dma_addr_t addr, dma_addr_t len,
+ DMADirection dir, MemTxAttrs attrs)
+{
+ return address_space_access_valid(as, addr, len,
+ dir == DMA_DIRECTION_FROM_DEVICE,
+ attrs);
+}
+
+static inline MemTxResult dma_memory_rw_relaxed(AddressSpace *as,
+ dma_addr_t addr,
+ void *buf, dma_addr_t len,
+ DMADirection dir,
+ MemTxAttrs attrs)
+{
+ return address_space_rw(as, addr, attrs,
+ buf, len, dir == DMA_DIRECTION_FROM_DEVICE);
+}
+
+static inline MemTxResult dma_memory_read_relaxed(AddressSpace *as,
+ dma_addr_t addr,
+ void *buf, dma_addr_t len)
+{
+ return dma_memory_rw_relaxed(as, addr, buf, len,
+ DMA_DIRECTION_TO_DEVICE,
+ MEMTXATTRS_UNSPECIFIED);
+}
+
+static inline MemTxResult dma_memory_write_relaxed(AddressSpace *as,
+ dma_addr_t addr,
+ const void *buf,
+ dma_addr_t len)
+{
+ return dma_memory_rw_relaxed(as, addr, (void *)buf, len,
+ DMA_DIRECTION_FROM_DEVICE,
+ MEMTXATTRS_UNSPECIFIED);
+}
+
+/**
+ * dma_memory_rw: Read from or write to an address space from DMA controller.
+ *
+ * Return a MemTxResult indicating whether the operation succeeded
+ * or failed (eg unassigned memory, device rejected the transaction,
+ * IOMMU fault).
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @buf: buffer with the data transferred
+ * @len: the number of bytes to read or write
+ * @dir: indicates the transfer direction
+ * @attrs: memory transaction attributes
+ */
+static inline MemTxResult dma_memory_rw(AddressSpace *as, dma_addr_t addr,
+ void *buf, dma_addr_t len,
+ DMADirection dir, MemTxAttrs attrs)
+{
+ dma_barrier(as, dir);
+
+ return dma_memory_rw_relaxed(as, addr, buf, len, dir, attrs);
+}
+
+/**
+ * dma_memory_read: Read from an address space from DMA controller.
+ *
+ * Return a MemTxResult indicating whether the operation succeeded
+ * or failed (eg unassigned memory, device rejected the transaction,
+ * IOMMU fault). Called within RCU critical section.
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @buf: buffer with the data transferred
+ * @len: length of the data transferred
+ * @attrs: memory transaction attributes
+ */
+static inline MemTxResult dma_memory_read(AddressSpace *as, dma_addr_t addr,
+ void *buf, dma_addr_t len,
+ MemTxAttrs attrs)
+{
+ return dma_memory_rw(as, addr, buf, len,
+ DMA_DIRECTION_TO_DEVICE, attrs);
+}
+
+/**
+ * dma_memory_write: Write to address space from DMA controller.
+ *
+ * Return a MemTxResult indicating whether the operation succeeded
+ * or failed (eg unassigned memory, device rejected the transaction,
+ * IOMMU fault).
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @buf: buffer with the data transferred
+ * @len: the number of bytes to write
+ * @attrs: memory transaction attributes
+ */
+static inline MemTxResult dma_memory_write(AddressSpace *as, dma_addr_t addr,
+ const void *buf, dma_addr_t len,
+ MemTxAttrs attrs)
+{
+ return dma_memory_rw(as, addr, (void *)buf, len,
+ DMA_DIRECTION_FROM_DEVICE, attrs);
+}
+
+/**
+ * dma_memory_set: Fill memory with a constant byte from DMA controller.
+ *
+ * Return a MemTxResult indicating whether the operation succeeded
+ * or failed (eg unassigned memory, device rejected the transaction,
+ * IOMMU fault).
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @c: constant byte to fill the memory
+ * @len: the number of bytes to fill with the constant byte
+ * @attrs: memory transaction attributes
+ */
+MemTxResult dma_memory_set(AddressSpace *as, dma_addr_t addr,
+ uint8_t c, dma_addr_t len, MemTxAttrs attrs);
+
+/**
+ * dma_memory_map: Map a physical memory region into a host virtual address.
+ *
+ * May map a subset of the requested range, given by and returned in @plen.
+ * May return %NULL and set *@plen to zero(0), if resources needed to perform
+ * the mapping are exhausted.
+ * Use only for reads OR writes - not for read-modify-write operations.
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @len: pointer to length of buffer; updated on return
+ * @dir: indicates the transfer direction
+ * @attrs: memory attributes
+ */
+static inline void *dma_memory_map(AddressSpace *as,
+ dma_addr_t addr, dma_addr_t *len,
+ DMADirection dir, MemTxAttrs attrs)
+{
+ hwaddr xlen = *len;
+ void *p;
+
+ p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE,
+ attrs);
+ *len = xlen;
+ return p;
+}
+
+/**
+ * dma_memory_unmap: Unmaps a memory region previously mapped by dma_memory_map()
+ *
+ * Will also mark the memory as dirty if @dir == %DMA_DIRECTION_FROM_DEVICE.
+ * @access_len gives the amount of memory that was actually read or written
+ * by the caller.
+ *
+ * @as: #AddressSpace used
+ * @buffer: host pointer as returned by dma_memory_map()
+ * @len: buffer length as returned by dma_memory_map()
+ * @dir: indicates the transfer direction
+ * @access_len: amount of data actually transferred
+ */
+static inline void dma_memory_unmap(AddressSpace *as,
+ void *buffer, dma_addr_t len,
+ DMADirection dir, dma_addr_t access_len)
+{
+ address_space_unmap(as, buffer, (hwaddr)len,
+ dir == DMA_DIRECTION_FROM_DEVICE, access_len);
+}
+
+#define DEFINE_LDST_DMA(_lname, _sname, _bits, _end) \
+ static inline MemTxResult ld##_lname##_##_end##_dma(AddressSpace *as, \
+ dma_addr_t addr, \
+ uint##_bits##_t *pval, \
+ MemTxAttrs attrs) \
+ { \
+ MemTxResult res = dma_memory_read(as, addr, pval, (_bits) / 8, attrs); \
+ _end##_bits##_to_cpus(pval); \
+ return res; \
+ } \
+ static inline MemTxResult st##_sname##_##_end##_dma(AddressSpace *as, \
+ dma_addr_t addr, \
+ uint##_bits##_t val, \
+ MemTxAttrs attrs) \
+ { \
+ val = cpu_to_##_end##_bits(val); \
+ return dma_memory_write(as, addr, &val, (_bits) / 8, attrs); \
+ }
+
+static inline MemTxResult ldub_dma(AddressSpace *as, dma_addr_t addr,
+ uint8_t *val, MemTxAttrs attrs)
+{
+ return dma_memory_read(as, addr, val, 1, attrs);
+}
+
+static inline MemTxResult stb_dma(AddressSpace *as, dma_addr_t addr,
+ uint8_t val, MemTxAttrs attrs)
+{
+ return dma_memory_write(as, addr, &val, 1, attrs);
+}
+
+DEFINE_LDST_DMA(uw, w, 16, le);
+DEFINE_LDST_DMA(l, l, 32, le);
+DEFINE_LDST_DMA(q, q, 64, le);
+DEFINE_LDST_DMA(uw, w, 16, be);
+DEFINE_LDST_DMA(l, l, 32, be);
+DEFINE_LDST_DMA(q, q, 64, be);
+
+#undef DEFINE_LDST_DMA
+
+struct ScatterGatherEntry {
+ dma_addr_t base;
+ dma_addr_t len;
+};
+
+void qemu_sglist_init(QEMUSGList *qsg, DeviceState *dev, int alloc_hint,
+ AddressSpace *as);
+void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len);
+void qemu_sglist_destroy(QEMUSGList *qsg);
+
+typedef BlockAIOCB *DMAIOFunc(int64_t offset, QEMUIOVector *iov,
+ BlockCompletionFunc *cb, void *cb_opaque,
+ void *opaque);
+
+BlockAIOCB *dma_blk_io(AioContext *ctx,
+ QEMUSGList *sg, uint64_t offset, uint32_t align,
+ DMAIOFunc *io_func, void *io_func_opaque,
+ BlockCompletionFunc *cb, void *opaque, DMADirection dir);
+BlockAIOCB *dma_blk_read(BlockBackend *blk,
+ QEMUSGList *sg, uint64_t offset, uint32_t align,
+ BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *dma_blk_write(BlockBackend *blk,
+ QEMUSGList *sg, uint64_t offset, uint32_t align,
+ BlockCompletionFunc *cb, void *opaque);
+MemTxResult dma_buf_read(void *ptr, dma_addr_t len, dma_addr_t *residual,
+ QEMUSGList *sg, MemTxAttrs attrs);
+MemTxResult dma_buf_write(void *ptr, dma_addr_t len, dma_addr_t *residual,
+ QEMUSGList *sg, MemTxAttrs attrs);
+
+void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,
+ QEMUSGList *sg, enum BlockAcctType type);
+
+/**
+ * dma_aligned_pow2_mask: Return the address bit mask of the largest
+ * power of 2 size less or equal than @end - @start + 1, aligned with @start,
+ * and bounded by 1 << @max_addr_bits bits.
+ *
+ * @start: range start address
+ * @end: range end address (greater than @start)
+ * @max_addr_bits: max address bits (<= 64)
+ */
+uint64_t dma_aligned_pow2_mask(uint64_t start, uint64_t end,
+ int max_addr_bits);
+
+#endif
--- /dev/null
+/*
+ * QEMU dump
+ *
+ * Copyright Fujitsu, Corp. 2011, 2012
+ *
+ * Authors:
+ * Wen Congyang <wency@cn.fujitsu.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef DUMP_ARCH_H
+#define DUMP_ARCH_H
+
+typedef struct ArchDumpInfo {
+ int d_machine; /* Architecture */
+ int d_endian; /* ELFDATA2LSB or ELFDATA2MSB */
+ int d_class; /* ELFCLASS32 or ELFCLASS64 */
+ uint32_t page_size; /* The target's page size. If it's variable and
+ * unknown, then this should be the maximum. */
+ uint64_t phys_base; /* The target's physmem base. */
+ void (*arch_sections_add_fn)(DumpState *s);
+ uint64_t (*arch_sections_write_hdr_fn)(DumpState *s, uint8_t *buff);
+ int (*arch_sections_write_fn)(DumpState *s, uint8_t *buff);
+ void (*arch_cleanup_fn)(DumpState *s);
+} ArchDumpInfo;
+
+struct GuestPhysBlockList; /* memory_mapping.h */
+int cpu_get_dump_info(ArchDumpInfo *info,
+ const struct GuestPhysBlockList *guest_phys_blocks);
+ssize_t cpu_get_note_size(int class, int machine, int nr_cpus);
+
+#endif
--- /dev/null
+/*
+ * QEMU dump
+ *
+ * Copyright Fujitsu, Corp. 2011, 2012
+ *
+ * Authors:
+ * Wen Congyang <wency@cn.fujitsu.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef DUMP_H
+#define DUMP_H
+
+#include "qapi/qapi-types-dump.h"
+#include "qemu/thread.h"
+
+#define MAKEDUMPFILE_SIGNATURE "makedumpfile"
+#define MAX_SIZE_MDF_HEADER (4096) /* max size of makedumpfile_header */
+#define TYPE_FLAT_HEADER (1) /* type of flattened format */
+#define VERSION_FLAT_HEADER (1) /* version of flattened format */
+#define END_FLAG_FLAT_HEADER (-1)
+
+#ifndef ARCH_PFN_OFFSET
+#define ARCH_PFN_OFFSET (0)
+#endif
+
+/*
+ * flag for compressed format
+ */
+#define DUMP_DH_COMPRESSED_ZLIB (0x1)
+#define DUMP_DH_COMPRESSED_LZO (0x2)
+#define DUMP_DH_COMPRESSED_SNAPPY (0x4)
+
+#define KDUMP_SIGNATURE "KDUMP "
+#define SIG_LEN (sizeof(KDUMP_SIGNATURE) - 1)
+#define DUMP_LEVEL (1)
+#define DISKDUMP_HEADER_BLOCKS (1)
+
+#include "system/dump-arch.h"
+#include "system/memory_mapping.h"
+
+typedef struct QEMU_PACKED MakedumpfileHeader {
+ char signature[16]; /* = "makedumpfile" */
+ int64_t type;
+ int64_t version;
+} MakedumpfileHeader;
+
+typedef struct QEMU_PACKED MakedumpfileDataHeader {
+ int64_t offset;
+ int64_t buf_size;
+} MakedumpfileDataHeader;
+
+typedef struct QEMU_PACKED NewUtsname {
+ char sysname[65];
+ char nodename[65];
+ char release[65];
+ char version[65];
+ char machine[65];
+ char domainname[65];
+} NewUtsname;
+
+typedef struct QEMU_PACKED DiskDumpHeader32 {
+ char signature[SIG_LEN]; /* = "KDUMP " */
+ uint32_t header_version; /* Dump header version */
+ NewUtsname utsname; /* copy of system_utsname */
+ char timestamp[10]; /* Time stamp */
+ uint32_t status; /* Above flags */
+ uint32_t block_size; /* Size of a block in byte */
+ uint32_t sub_hdr_size; /* Size of arch dependent header in block */
+ uint32_t bitmap_blocks; /* Size of Memory bitmap in block */
+ uint32_t max_mapnr; /* = max_mapnr ,
+ obsoleted in header_version 6 */
+ uint32_t total_ram_blocks; /* Number of blocks should be written */
+ uint32_t device_blocks; /* Number of total blocks in dump device */
+ uint32_t written_blocks; /* Number of written blocks */
+ uint32_t current_cpu; /* CPU# which handles dump */
+ uint32_t nr_cpus; /* Number of CPUs */
+} DiskDumpHeader32;
+
+typedef struct QEMU_PACKED DiskDumpHeader64 {
+ char signature[SIG_LEN]; /* = "KDUMP " */
+ uint32_t header_version; /* Dump header version */
+ NewUtsname utsname; /* copy of system_utsname */
+ char timestamp[22]; /* Time stamp */
+ uint32_t status; /* Above flags */
+ uint32_t block_size; /* Size of a block in byte */
+ uint32_t sub_hdr_size; /* Size of arch dependent header in block */
+ uint32_t bitmap_blocks; /* Size of Memory bitmap in block */
+ uint32_t max_mapnr; /* = max_mapnr,
+ obsoleted in header_version 6 */
+ uint32_t total_ram_blocks; /* Number of blocks should be written */
+ uint32_t device_blocks; /* Number of total blocks in dump device */
+ uint32_t written_blocks; /* Number of written blocks */
+ uint32_t current_cpu; /* CPU# which handles dump */
+ uint32_t nr_cpus; /* Number of CPUs */
+} DiskDumpHeader64;
+
+typedef struct QEMU_PACKED KdumpSubHeader32 {
+ uint32_t phys_base;
+ uint32_t dump_level; /* header_version 1 and later */
+ uint32_t split; /* header_version 2 and later */
+ uint32_t start_pfn; /* header_version 2 and later,
+ obsoleted in header_version 6 */
+ uint32_t end_pfn; /* header_version 2 and later,
+ obsoleted in header_version 6 */
+ uint64_t offset_vmcoreinfo; /* header_version 3 and later */
+ uint32_t size_vmcoreinfo; /* header_version 3 and later */
+ uint64_t offset_note; /* header_version 4 and later */
+ uint32_t note_size; /* header_version 4 and later */
+ uint64_t offset_eraseinfo; /* header_version 5 and later */
+ uint32_t size_eraseinfo; /* header_version 5 and later */
+ uint64_t start_pfn_64; /* header_version 6 and later */
+ uint64_t end_pfn_64; /* header_version 6 and later */
+ uint64_t max_mapnr_64; /* header_version 6 and later */
+} KdumpSubHeader32;
+
+typedef struct QEMU_PACKED KdumpSubHeader64 {
+ uint64_t phys_base;
+ uint32_t dump_level; /* header_version 1 and later */
+ uint32_t split; /* header_version 2 and later */
+ uint64_t start_pfn; /* header_version 2 and later,
+ obsoleted in header_version 6 */
+ uint64_t end_pfn; /* header_version 2 and later,
+ obsoleted in header_version 6 */
+ uint64_t offset_vmcoreinfo; /* header_version 3 and later */
+ uint64_t size_vmcoreinfo; /* header_version 3 and later */
+ uint64_t offset_note; /* header_version 4 and later */
+ uint64_t note_size; /* header_version 4 and later */
+ uint64_t offset_eraseinfo; /* header_version 5 and later */
+ uint64_t size_eraseinfo; /* header_version 5 and later */
+ uint64_t start_pfn_64; /* header_version 6 and later */
+ uint64_t end_pfn_64; /* header_version 6 and later */
+ uint64_t max_mapnr_64; /* header_version 6 and later */
+} KdumpSubHeader64;
+
+typedef struct DataCache {
+ DumpState *state; /* dump state related to this data */
+ uint8_t *buf; /* buffer for cached data */
+ size_t buf_size; /* size of the buf */
+ size_t data_size; /* size of cached data in buf */
+ off_t offset; /* offset of the file */
+} DataCache;
+
+typedef struct QEMU_PACKED PageDescriptor {
+ uint64_t offset; /* the offset of the page data*/
+ uint32_t size; /* the size of this dump page */
+ uint32_t flags; /* flags */
+ uint64_t page_flags; /* page flags */
+} PageDescriptor;
+
+typedef struct DumpState {
+ GuestPhysBlockList guest_phys_blocks;
+ ArchDumpInfo dump_info;
+ MemoryMappingList list;
+ bool resume;
+ bool detached;
+ bool kdump_raw;
+ hwaddr memory_offset;
+ int fd;
+
+ /*
+ * Dump filter area variables
+ *
+ * A filtered dump only contains the guest memory designated by
+ * the start address and length variables defined below.
+ *
+ * If length is 0, no filtering is applied.
+ */
+ int64_t filter_area_begin; /* Start address of partial guest memory area */
+ int64_t filter_area_length; /* Length of partial guest memory area */
+
+ /* Elf dump related data */
+ uint32_t phdr_num;
+ uint32_t shdr_num;
+ ssize_t note_size;
+ hwaddr shdr_offset;
+ hwaddr phdr_offset;
+ hwaddr section_offset;
+ hwaddr note_offset;
+
+ void *elf_section_hdrs; /* Pointer to section header buffer */
+ void *elf_section_data; /* Pointer to section data buffer */
+ uint64_t elf_section_data_size; /* Size of section data */
+ GArray *string_table_buf; /* String table data buffer */
+
+ uint8_t *note_buf; /* buffer for notes */
+ size_t note_buf_offset; /* the writing place in note_buf */
+ uint32_t nr_cpus; /* number of guest's cpu */
+ uint64_t max_mapnr; /* the biggest guest's phys-mem's number */
+ size_t len_dump_bitmap; /* the size of the place used to store
+ dump_bitmap in vmcore */
+ off_t offset_dump_bitmap; /* offset of dump_bitmap part in vmcore */
+ off_t offset_page; /* offset of page part in vmcore */
+ size_t num_dumpable; /* number of page that can be dumped */
+ uint32_t flag_compress; /* indicate the compression format */
+ DumpStatus status; /* current dump status */
+
+ bool has_format; /* whether format is provided */
+ DumpGuestMemoryFormat format; /* valid only if has_format == true */
+ QemuThread dump_thread; /* thread for detached dump */
+
+ int64_t total_size; /* total memory size (in bytes) to
+ * be dumped. When filter is
+ * enabled, this will only count
+ * those to be written. */
+ int64_t written_size; /* written memory size (in bytes),
+ * this could be used to calculate
+ * how much work we have
+ * finished. */
+ uint8_t *guest_note; /* ELF note content */
+ size_t guest_note_size;
+} DumpState;
+
+uint16_t cpu_to_dump16(DumpState *s, uint16_t val);
+uint32_t cpu_to_dump32(DumpState *s, uint32_t val);
+uint64_t cpu_to_dump64(DumpState *s, uint64_t val);
+
+int64_t dump_filtered_memblock_size(GuestPhysBlock *block, int64_t filter_area_start,
+ int64_t filter_area_length);
+int64_t dump_filtered_memblock_start(GuestPhysBlock *block, int64_t filter_area_start,
+ int64_t filter_area_length);
+#endif
--- /dev/null
+/*
+ * QEMU event-loop backend
+ *
+ * Copyright (C) 2022 Red Hat Inc
+ *
+ * Authors:
+ * Nicolas Saenz Julienne <nsaenzju@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef QEMU_EVENT_LOOP_BASE_H
+#define QEMU_EVENT_LOOP_BASE_H
+
+#include "qom/object.h"
+#include "block/aio.h"
+
+#define TYPE_EVENT_LOOP_BASE "event-loop-base"
+OBJECT_DECLARE_TYPE(EventLoopBase, EventLoopBaseClass,
+ EVENT_LOOP_BASE)
+
+struct EventLoopBaseClass {
+ ObjectClass parent_class;
+
+ void (*init)(EventLoopBase *base, Error **errp);
+ void (*update_params)(EventLoopBase *base, Error **errp);
+ bool (*can_be_deleted)(EventLoopBase *base);
+};
+
+struct EventLoopBase {
+ Object parent;
+
+ /* AioContext AIO engine parameters */
+ int64_t aio_max_batch;
+
+ /* AioContext thread pool parameters */
+ int64_t thread_pool_min;
+ int64_t thread_pool_max;
+};
+#endif
--- /dev/null
+/*
+ * Host IOMMU device abstract declaration
+ *
+ * Copyright (C) 2024 Intel Corporation.
+ *
+ * Authors: Zhenzhong Duan <zhenzhong.duan@intel.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+
+#ifndef HOST_IOMMU_DEVICE_H
+#define HOST_IOMMU_DEVICE_H
+
+#include "qom/object.h"
+#include "qapi/error.h"
+
+/**
+ * struct HostIOMMUDeviceCaps - Define host IOMMU device capabilities.
+ *
+ * @type: host platform IOMMU type.
+ *
+ * @hw_caps: host platform IOMMU capabilities (e.g. on IOMMUFD this represents
+ * the @out_capabilities value returned from IOMMU_GET_HW_INFO ioctl)
+ */
+typedef struct HostIOMMUDeviceCaps {
+ uint32_t type;
+ uint64_t hw_caps;
+} HostIOMMUDeviceCaps;
+
+#define TYPE_HOST_IOMMU_DEVICE "host-iommu-device"
+OBJECT_DECLARE_TYPE(HostIOMMUDevice, HostIOMMUDeviceClass, HOST_IOMMU_DEVICE)
+
+struct HostIOMMUDevice {
+ Object parent_obj;
+
+ char *name;
+ void *agent; /* pointer to agent device, ie. VFIO or VDPA device */
+ PCIBus *aliased_bus;
+ int aliased_devfn;
+ HostIOMMUDeviceCaps caps;
+};
+
+/**
+ * struct HostIOMMUDeviceClass - The base class for all host IOMMU devices.
+ *
+ * Different types of host devices (e.g., VFIO or VDPA device) or devices
+ * with different backend (e.g., VFIO legacy container or IOMMUFD backend)
+ * will have different implementations of the HostIOMMUDeviceClass.
+ */
+struct HostIOMMUDeviceClass {
+ ObjectClass parent_class;
+
+ /**
+ * @realize: initialize host IOMMU device instance further.
+ *
+ * Mandatory callback.
+ *
+ * @hiod: pointer to a host IOMMU device instance.
+ *
+ * @opaque: pointer to agent device of this host IOMMU device,
+ * e.g., VFIO base device or VDPA device.
+ *
+ * @errp: pass an Error out when realize fails.
+ *
+ * Returns: true on success, false on failure.
+ */
+ bool (*realize)(HostIOMMUDevice *hiod, void *opaque, Error **errp);
+ /**
+ * @get_cap: check if a host IOMMU device capability is supported.
+ *
+ * Optional callback, if not implemented, hint not supporting query
+ * of @cap.
+ *
+ * @hiod: pointer to a host IOMMU device instance.
+ *
+ * @cap: capability to check.
+ *
+ * @errp: pass an Error out when fails to query capability.
+ *
+ * Returns: <0 on failure, 0 if a @cap is unsupported, or else
+ * 1 or some positive value for some special @cap,
+ * i.e., HOST_IOMMU_DEVICE_CAP_AW_BITS.
+ */
+ int (*get_cap)(HostIOMMUDevice *hiod, int cap, Error **errp);
+ /**
+ * @get_iova_ranges: Return the list of usable iova_ranges along with
+ * @hiod Host IOMMU device
+ *
+ * @hiod: handle to the host IOMMU device
+ */
+ GList* (*get_iova_ranges)(HostIOMMUDevice *hiod);
+ /**
+ *
+ * @get_page_size_mask: Return the page size mask supported along this
+ * @hiod Host IOMMU device
+ *
+ * @hiod: handle to the host IOMMU device
+ */
+ uint64_t (*get_page_size_mask)(HostIOMMUDevice *hiod);
+};
+
+/*
+ * Host IOMMU device capability list.
+ */
+#define HOST_IOMMU_DEVICE_CAP_IOMMU_TYPE 0
+#define HOST_IOMMU_DEVICE_CAP_AW_BITS 1
+
+#define HOST_IOMMU_DEVICE_CAP_AW_BITS_MAX 64
+#endif
--- /dev/null
+/*
+ * QEMU Host Memory Backend
+ *
+ * Copyright (C) 2013-2014 Red Hat Inc
+ *
+ * Authors:
+ * Igor Mammedov <imammedo@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef SYSTEM_HOSTMEM_H
+#define SYSTEM_HOSTMEM_H
+
+#include "system/numa.h"
+#include "qapi/qapi-types-machine.h"
+#include "qom/object.h"
+#include "exec/memory.h"
+#include "qemu/bitmap.h"
+#include "qemu/thread-context.h"
+
+#define TYPE_MEMORY_BACKEND "memory-backend"
+OBJECT_DECLARE_TYPE(HostMemoryBackend, HostMemoryBackendClass,
+ MEMORY_BACKEND)
+
+/* hostmem-ram.c */
+/**
+ * @TYPE_MEMORY_BACKEND_RAM:
+ * name of backend that uses mmap on the anonymous RAM
+ */
+
+#define TYPE_MEMORY_BACKEND_RAM "memory-backend-ram"
+
+/* hostmem-file.c */
+/**
+ * @TYPE_MEMORY_BACKEND_FILE:
+ * name of backend that uses mmap on a file descriptor
+ */
+#define TYPE_MEMORY_BACKEND_FILE "memory-backend-file"
+
+#define TYPE_MEMORY_BACKEND_MEMFD "memory-backend-memfd"
+
+
+/**
+ * HostMemoryBackendClass:
+ * @parent_class: opaque parent class container
+ */
+struct HostMemoryBackendClass {
+ ObjectClass parent_class;
+
+ /**
+ * alloc: Allocate memory from backend.
+ *
+ * @backend: the #HostMemoryBackend.
+ * @errp: pointer to Error*, to store an error if it happens.
+ *
+ * Return: true on success, else false setting @errp with error.
+ */
+ bool (*alloc)(HostMemoryBackend *backend, Error **errp);
+};
+
+/**
+ * @HostMemoryBackend
+ *
+ * @parent: opaque parent object container
+ * @size: amount of memory backend provides
+ * @mr: MemoryRegion representing host memory belonging to backend
+ * @prealloc_threads: number of threads to be used for preallocatining RAM
+ */
+struct HostMemoryBackend {
+ /* private */
+ Object parent;
+
+ /* protected */
+ uint64_t size;
+ bool merge, dump, use_canonical_path;
+ bool prealloc, is_mapped, share, reserve;
+ bool guest_memfd, aligned;
+ uint32_t prealloc_threads;
+ ThreadContext *prealloc_context;
+ DECLARE_BITMAP(host_nodes, MAX_NODES + 1);
+ HostMemPolicy policy;
+
+ MemoryRegion mr;
+};
+
+bool host_memory_backend_mr_inited(HostMemoryBackend *backend);
+MemoryRegion *host_memory_backend_get_memory(HostMemoryBackend *backend);
+
+void host_memory_backend_set_mapped(HostMemoryBackend *backend, bool mapped);
+bool host_memory_backend_is_mapped(HostMemoryBackend *backend);
+size_t host_memory_backend_pagesize(HostMemoryBackend *memdev);
+char *host_memory_backend_get_name(HostMemoryBackend *backend);
+
+#endif
--- /dev/null
+/*
+ * QEMU Hypervisor.framework (HVF) support
+ *
+ * Copyright Google Inc., 2017
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+/* header to be included in non-HVF-specific code */
+
+#ifndef HVF_H
+#define HVF_H
+
+#include "qemu/accel.h"
+#include "qom/object.h"
+
+#ifdef COMPILING_PER_TARGET
+#include "cpu.h"
+
+#ifdef CONFIG_HVF
+extern bool hvf_allowed;
+#define hvf_enabled() (hvf_allowed)
+#else /* !CONFIG_HVF */
+#define hvf_enabled() 0
+#endif /* !CONFIG_HVF */
+
+#endif /* COMPILING_PER_TARGET */
+
+#define TYPE_HVF_ACCEL ACCEL_CLASS_NAME("hvf")
+
+typedef struct HVFState HVFState;
+DECLARE_INSTANCE_CHECKER(HVFState, HVF_STATE,
+ TYPE_HVF_ACCEL)
+
+#ifdef COMPILING_PER_TARGET
+struct hvf_sw_breakpoint {
+ vaddr pc;
+ vaddr saved_insn;
+ int use_count;
+ QTAILQ_ENTRY(hvf_sw_breakpoint) entry;
+};
+
+struct hvf_sw_breakpoint *hvf_find_sw_breakpoint(CPUState *cpu,
+ vaddr pc);
+int hvf_sw_breakpoints_active(CPUState *cpu);
+
+int hvf_arch_insert_sw_breakpoint(CPUState *cpu, struct hvf_sw_breakpoint *bp);
+int hvf_arch_remove_sw_breakpoint(CPUState *cpu, struct hvf_sw_breakpoint *bp);
+int hvf_arch_insert_hw_breakpoint(vaddr addr, vaddr len, int type);
+int hvf_arch_remove_hw_breakpoint(vaddr addr, vaddr len, int type);
+void hvf_arch_remove_all_hw_breakpoints(void);
+
+/*
+ * hvf_update_guest_debug:
+ * @cs: CPUState for the CPU to update
+ *
+ * Update guest to enable or disable debugging. Per-arch specifics will be
+ * handled by calling down to hvf_arch_update_guest_debug.
+ */
+int hvf_update_guest_debug(CPUState *cpu);
+void hvf_arch_update_guest_debug(CPUState *cpu);
+
+/*
+ * Return whether the guest supports debugging.
+ */
+bool hvf_arch_supports_guest_debug(void);
+#endif /* COMPILING_PER_TARGET */
+
+#endif
--- /dev/null
+/*
+ * QEMU Hypervisor.framework (HVF) support
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+/* header to be included in HVF-specific code */
+
+#ifndef HVF_INT_H
+#define HVF_INT_H
+
+#ifdef __aarch64__
+#include <Hypervisor/Hypervisor.h>
+typedef hv_vcpu_t hvf_vcpuid;
+#else
+#include <Hypervisor/hv.h>
+typedef hv_vcpuid_t hvf_vcpuid;
+#endif
+
+/* hvf_slot flags */
+#define HVF_SLOT_LOG (1 << 0)
+
+typedef struct hvf_slot {
+ uint64_t start;
+ uint64_t size;
+ uint8_t *mem;
+ int slot_id;
+ uint32_t flags;
+ MemoryRegion *region;
+} hvf_slot;
+
+typedef struct hvf_vcpu_caps {
+ uint64_t vmx_cap_pinbased;
+ uint64_t vmx_cap_procbased;
+ uint64_t vmx_cap_procbased2;
+ uint64_t vmx_cap_entry;
+ uint64_t vmx_cap_exit;
+ uint64_t vmx_cap_preemption_timer;
+} hvf_vcpu_caps;
+
+struct HVFState {
+ AccelState parent;
+ hvf_slot slots[32];
+ int num_slots;
+
+ hvf_vcpu_caps *hvf_caps;
+ uint64_t vtimer_offset;
+ QTAILQ_HEAD(, hvf_sw_breakpoint) hvf_sw_breakpoints;
+};
+extern HVFState *hvf_state;
+
+struct AccelCPUState {
+ hvf_vcpuid fd;
+ void *exit;
+ bool vtimer_masked;
+ sigset_t unblock_ipi_mask;
+ bool guest_debug_enabled;
+ bool dirty;
+};
+
+void assert_hvf_ok_impl(hv_return_t ret, const char *file, unsigned int line,
+ const char *exp);
+#define assert_hvf_ok(EX) assert_hvf_ok_impl((EX), __FILE__, __LINE__, #EX)
+const char *hvf_return_string(hv_return_t ret);
+int hvf_arch_init(void);
+hv_return_t hvf_arch_vm_create(MachineState *ms, uint32_t pa_range);
+int hvf_arch_init_vcpu(CPUState *cpu);
+void hvf_arch_vcpu_destroy(CPUState *cpu);
+int hvf_vcpu_exec(CPUState *);
+hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
+int hvf_put_registers(CPUState *);
+int hvf_get_registers(CPUState *);
+void hvf_kick_vcpu_thread(CPUState *cpu);
+
+#endif
--- /dev/null
+/*
+ * QEMU Hardware accelerators support
+ *
+ * Copyright 2016 Google, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_HW_ACCEL_H
+#define QEMU_HW_ACCEL_H
+
+#include "hw/core/cpu.h"
+#include "system/kvm.h"
+#include "system/hvf.h"
+#include "system/whpx.h"
+#include "system/nvmm.h"
+
+void cpu_synchronize_state(CPUState *cpu);
+void cpu_synchronize_post_reset(CPUState *cpu);
+void cpu_synchronize_post_init(CPUState *cpu);
+void cpu_synchronize_pre_loadvm(CPUState *cpu);
+
+#endif /* QEMU_HW_ACCEL_H */
--- /dev/null
+/*
+ * iommufd container backend declaration
+ *
+ * Copyright (C) 2024 Intel Corporation.
+ * Copyright Red Hat, Inc. 2024
+ *
+ * Authors: Yi Liu <yi.l.liu@intel.com>
+ * Eric Auger <eric.auger@redhat.com>
+ * Zhenzhong Duan <zhenzhong.duan@intel.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef SYSTEM_IOMMUFD_H
+#define SYSTEM_IOMMUFD_H
+
+#include "qom/object.h"
+#include "exec/hwaddr.h"
+#include "exec/cpu-common.h"
+#include "system/host_iommu_device.h"
+
+#define TYPE_IOMMUFD_BACKEND "iommufd"
+OBJECT_DECLARE_TYPE(IOMMUFDBackend, IOMMUFDBackendClass, IOMMUFD_BACKEND)
+
+struct IOMMUFDBackendClass {
+ ObjectClass parent_class;
+};
+
+struct IOMMUFDBackend {
+ Object parent;
+
+ /*< protected >*/
+ int fd; /* /dev/iommu file descriptor */
+ bool owned; /* is the /dev/iommu opened internally */
+ uint32_t users;
+
+ /*< public >*/
+};
+
+bool iommufd_backend_connect(IOMMUFDBackend *be, Error **errp);
+void iommufd_backend_disconnect(IOMMUFDBackend *be);
+
+bool iommufd_backend_alloc_ioas(IOMMUFDBackend *be, uint32_t *ioas_id,
+ Error **errp);
+void iommufd_backend_free_id(IOMMUFDBackend *be, uint32_t id);
+int iommufd_backend_map_dma(IOMMUFDBackend *be, uint32_t ioas_id, hwaddr iova,
+ ram_addr_t size, void *vaddr, bool readonly);
+int iommufd_backend_unmap_dma(IOMMUFDBackend *be, uint32_t ioas_id,
+ hwaddr iova, ram_addr_t size);
+bool iommufd_backend_get_device_info(IOMMUFDBackend *be, uint32_t devid,
+ uint32_t *type, void *data, uint32_t len,
+ uint64_t *caps, Error **errp);
+bool iommufd_backend_alloc_hwpt(IOMMUFDBackend *be, uint32_t dev_id,
+ uint32_t pt_id, uint32_t flags,
+ uint32_t data_type, uint32_t data_len,
+ void *data_ptr, uint32_t *out_hwpt,
+ Error **errp);
+bool iommufd_backend_set_dirty_tracking(IOMMUFDBackend *be, uint32_t hwpt_id,
+ bool start, Error **errp);
+bool iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be, uint32_t hwpt_id,
+ uint64_t iova, ram_addr_t size,
+ uint64_t page_size, uint64_t *data,
+ Error **errp);
+
+#define TYPE_HOST_IOMMU_DEVICE_IOMMUFD TYPE_HOST_IOMMU_DEVICE "-iommufd"
+#endif
--- /dev/null
+/*
+ * Event loop thread
+ *
+ * Copyright Red Hat Inc., 2013
+ *
+ * Authors:
+ * Stefan Hajnoczi <stefanha@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef IOTHREAD_H
+#define IOTHREAD_H
+
+#include "block/aio.h"
+#include "qemu/thread.h"
+#include "qom/object.h"
+#include "system/event-loop-base.h"
+
+#define TYPE_IOTHREAD "iothread"
+
+struct IOThread {
+ EventLoopBase parent_obj;
+
+ QemuThread thread;
+ AioContext *ctx;
+ bool run_gcontext; /* whether we should run gcontext */
+ GMainContext *worker_context;
+ GMainLoop *main_loop;
+ QemuSemaphore init_done_sem; /* is thread init done? */
+ bool stopping; /* has iothread_stop() been called? */
+ bool running; /* should iothread_run() continue? */
+ int thread_id;
+
+ /* AioContext poll parameters */
+ int64_t poll_max_ns;
+ int64_t poll_grow;
+ int64_t poll_shrink;
+};
+typedef struct IOThread IOThread;
+
+DECLARE_INSTANCE_CHECKER(IOThread, IOTHREAD,
+ TYPE_IOTHREAD)
+
+char *iothread_get_id(IOThread *iothread);
+IOThread *iothread_by_id(const char *id);
+AioContext *iothread_get_aio_context(IOThread *iothread);
+GMainContext *iothread_get_g_main_context(IOThread *iothread);
+
+/*
+ * Helpers used to allocate iothreads for internal use. These
+ * iothreads will not be seen by monitor clients when query using
+ * "query-iothreads".
+ */
+IOThread *iothread_create(const char *id, Error **errp);
+void iothread_stop(IOThread *iothread);
+void iothread_destroy(IOThread *iothread);
+
+/*
+ * Returns true if executing within IOThread context,
+ * false otherwise.
+ */
+bool qemu_in_iothread(void);
+
+#endif /* IOTHREAD_H */
--- /dev/null
+/*
+ * QEMU KVM support
+ *
+ * Copyright IBM, Corp. 2008
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+/* header to be included in non-KVM-specific code */
+
+#ifndef QEMU_KVM_H
+#define QEMU_KVM_H
+
+#include "exec/memattrs.h"
+#include "qemu/accel.h"
+#include "qom/object.h"
+
+#ifdef COMPILING_PER_TARGET
+# ifdef CONFIG_KVM
+# include <linux/kvm.h>
+# define CONFIG_KVM_IS_POSSIBLE
+# endif
+#else
+# define CONFIG_KVM_IS_POSSIBLE
+#endif
+
+#ifdef CONFIG_KVM_IS_POSSIBLE
+
+extern bool kvm_allowed;
+extern bool kvm_kernel_irqchip;
+extern bool kvm_split_irqchip;
+extern bool kvm_async_interrupts_allowed;
+extern bool kvm_halt_in_kernel_allowed;
+extern bool kvm_resamplefds_allowed;
+extern bool kvm_msi_via_irqfd_allowed;
+extern bool kvm_gsi_routing_allowed;
+extern bool kvm_gsi_direct_mapping;
+extern bool kvm_readonly_mem_allowed;
+extern bool kvm_msi_use_devid;
+
+#define kvm_enabled() (kvm_allowed)
+/**
+ * kvm_irqchip_in_kernel:
+ *
+ * Returns: true if an in-kernel irqchip was created.
+ * What this actually means is architecture and machine model
+ * specific: on PC, for instance, it means that the LAPIC
+ * is in kernel. This function should never be used from generic
+ * target-independent code: use one of the following functions or
+ * some other specific check instead.
+ */
+#define kvm_irqchip_in_kernel() (kvm_kernel_irqchip)
+
+/**
+ * kvm_irqchip_is_split:
+ *
+ * Returns: true if the irqchip implementation is split between
+ * user and kernel space. The details are architecture and
+ * machine specific. On PC, it means that the PIC, IOAPIC, and
+ * PIT are in user space while the LAPIC is in the kernel.
+ */
+#define kvm_irqchip_is_split() (kvm_split_irqchip)
+
+/**
+ * kvm_async_interrupts_enabled:
+ *
+ * Returns: true if we can deliver interrupts to KVM
+ * asynchronously (ie by ioctl from any thread at any time)
+ * rather than having to do interrupt delivery synchronously
+ * (where the vcpu must be stopped at a suitable point first).
+ */
+#define kvm_async_interrupts_enabled() (kvm_async_interrupts_allowed)
+
+/**
+ * kvm_halt_in_kernel
+ *
+ * Returns: true if halted cpus should still get a KVM_RUN ioctl to run
+ * inside of kernel space. This only works if MP state is implemented.
+ */
+#define kvm_halt_in_kernel() (kvm_halt_in_kernel_allowed)
+
+/**
+ * kvm_irqfds_enabled:
+ *
+ * Returns: true if we can use irqfds to inject interrupts into
+ * a KVM CPU (ie the kernel supports irqfds and we are running
+ * with a configuration where it is meaningful to use them).
+ *
+ * Always available if running with in-kernel irqchip.
+ */
+#define kvm_irqfds_enabled() kvm_irqchip_in_kernel()
+
+/**
+ * kvm_resamplefds_enabled:
+ *
+ * Returns: true if we can use resamplefds to inject interrupts into
+ * a KVM CPU (ie the kernel supports resamplefds and we are running
+ * with a configuration where it is meaningful to use them).
+ */
+#define kvm_resamplefds_enabled() (kvm_resamplefds_allowed)
+
+/**
+ * kvm_msi_via_irqfd_enabled:
+ *
+ * Returns: true if we can route a PCI MSI (Message Signaled Interrupt)
+ * to a KVM CPU via an irqfd. This requires that the kernel supports
+ * this and that we're running in a configuration that permits it.
+ */
+#define kvm_msi_via_irqfd_enabled() (kvm_msi_via_irqfd_allowed)
+
+/**
+ * kvm_gsi_routing_enabled:
+ *
+ * Returns: true if GSI routing is enabled (ie the kernel supports
+ * it and we're running in a configuration that permits it).
+ */
+#define kvm_gsi_routing_enabled() (kvm_gsi_routing_allowed)
+
+/**
+ * kvm_gsi_direct_mapping:
+ *
+ * Returns: true if GSI direct mapping is enabled.
+ */
+#define kvm_gsi_direct_mapping() (kvm_gsi_direct_mapping)
+
+/**
+ * kvm_readonly_mem_enabled:
+ *
+ * Returns: true if KVM readonly memory is enabled (ie the kernel
+ * supports it and we're running in a configuration that permits it).
+ */
+#define kvm_readonly_mem_enabled() (kvm_readonly_mem_allowed)
+
+/**
+ * kvm_msi_devid_required:
+ * Returns: true if KVM requires a device id to be provided while
+ * defining an MSI routing entry.
+ */
+#define kvm_msi_devid_required() (kvm_msi_use_devid)
+
+#else
+
+#define kvm_enabled() (0)
+#define kvm_irqchip_in_kernel() (false)
+#define kvm_irqchip_is_split() (false)
+#define kvm_async_interrupts_enabled() (false)
+#define kvm_halt_in_kernel() (false)
+#define kvm_irqfds_enabled() (false)
+#define kvm_resamplefds_enabled() (false)
+#define kvm_msi_via_irqfd_enabled() (false)
+#define kvm_gsi_routing_allowed() (false)
+#define kvm_gsi_direct_mapping() (false)
+#define kvm_readonly_mem_enabled() (false)
+#define kvm_msi_devid_required() (false)
+
+#endif /* CONFIG_KVM_IS_POSSIBLE */
+
+struct kvm_run;
+struct kvm_irq_routing_entry;
+
+typedef struct KVMCapabilityInfo {
+ const char *name;
+ int value;
+} KVMCapabilityInfo;
+
+#define KVM_CAP_INFO(CAP) { "KVM_CAP_" stringify(CAP), KVM_CAP_##CAP }
+#define KVM_CAP_LAST_INFO { NULL, 0 }
+
+struct KVMState;
+
+#define TYPE_KVM_ACCEL ACCEL_CLASS_NAME("kvm")
+typedef struct KVMState KVMState;
+DECLARE_INSTANCE_CHECKER(KVMState, KVM_STATE,
+ TYPE_KVM_ACCEL)
+
+extern KVMState *kvm_state;
+typedef struct Notifier Notifier;
+
+typedef struct KVMRouteChange {
+ KVMState *s;
+ int changes;
+} KVMRouteChange;
+
+/* external API */
+
+unsigned int kvm_get_max_memslots(void);
+unsigned int kvm_get_free_memslots(void);
+bool kvm_has_sync_mmu(void);
+int kvm_has_vcpu_events(void);
+int kvm_max_nested_state_length(void);
+int kvm_has_gsi_routing(void);
+
+/**
+ * kvm_arm_supports_user_irq
+ *
+ * Not all KVM implementations support notifications for kernel generated
+ * interrupt events to user space. This function indicates whether the current
+ * KVM implementation does support them.
+ *
+ * Returns: true if KVM supports using kernel generated IRQs from user space
+ */
+bool kvm_arm_supports_user_irq(void);
+
+
+int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr);
+int kvm_on_sigbus(int code, void *addr);
+
+#ifdef COMPILING_PER_TARGET
+#include "cpu.h"
+
+void kvm_flush_coalesced_mmio_buffer(void);
+
+/**
+ * kvm_update_guest_debug(): ensure KVM debug structures updated
+ * @cs: the CPUState for this cpu
+ * @reinject_trap: KVM trap injection control
+ *
+ * There are usually per-arch specifics which will be handled by
+ * calling down to kvm_arch_update_guest_debug after the generic
+ * fields have been set.
+ */
+#ifdef TARGET_KVM_HAVE_GUEST_DEBUG
+int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap);
+#else
+static inline int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap)
+{
+ return -EINVAL;
+}
+#endif
+
+/* internal API */
+
+int kvm_ioctl(KVMState *s, unsigned long type, ...);
+
+int kvm_vm_ioctl(KVMState *s, unsigned long type, ...);
+
+int kvm_vcpu_ioctl(CPUState *cpu, unsigned long type, ...);
+
+/**
+ * kvm_device_ioctl - call an ioctl on a kvm device
+ * @fd: The KVM device file descriptor as returned from KVM_CREATE_DEVICE
+ * @type: The device-ctrl ioctl number
+ *
+ * Returns: -errno on error, nonnegative on success
+ */
+int kvm_device_ioctl(int fd, unsigned long type, ...);
+
+/**
+ * kvm_vm_check_attr - check for existence of a specific vm attribute
+ * @s: The KVMState pointer
+ * @group: the group
+ * @attr: the attribute of that group to query for
+ *
+ * Returns: 1 if the attribute exists
+ * 0 if the attribute either does not exist or if the vm device
+ * interface is unavailable
+ */
+int kvm_vm_check_attr(KVMState *s, uint32_t group, uint64_t attr);
+
+/**
+ * kvm_device_check_attr - check for existence of a specific device attribute
+ * @fd: The device file descriptor
+ * @group: the group
+ * @attr: the attribute of that group to query for
+ *
+ * Returns: 1 if the attribute exists
+ * 0 if the attribute either does not exist or if the vm device
+ * interface is unavailable
+ */
+int kvm_device_check_attr(int fd, uint32_t group, uint64_t attr);
+
+/**
+ * kvm_device_access - set or get value of a specific device attribute
+ * @fd: The device file descriptor
+ * @group: the group
+ * @attr: the attribute of that group to set or get
+ * @val: pointer to a storage area for the value
+ * @write: true for set and false for get operation
+ * @errp: error object handle
+ *
+ * Returns: 0 on success
+ * < 0 on error
+ * Use kvm_device_check_attr() in order to check for the availability
+ * of optional attributes.
+ */
+int kvm_device_access(int fd, int group, uint64_t attr,
+ void *val, bool write, Error **errp);
+
+/**
+ * kvm_create_device - create a KVM device for the device control API
+ * @KVMState: The KVMState pointer
+ * @type: The KVM device type (see Documentation/virtual/kvm/devices in the
+ * kernel source)
+ * @test: If true, only test if device can be created, but don't actually
+ * create the device.
+ *
+ * Returns: -errno on error, nonnegative on success: @test ? 0 : device fd;
+ */
+int kvm_create_device(KVMState *s, uint64_t type, bool test);
+
+/**
+ * kvm_device_supported - probe whether KVM supports specific device
+ *
+ * @vmfd: The fd handler for VM
+ * @type: type of device
+ *
+ * @return: true if supported, otherwise false.
+ */
+bool kvm_device_supported(int vmfd, uint64_t type);
+
+/**
+ * kvm_create_vcpu - Gets a parked KVM vCPU or creates a KVM vCPU
+ * @cpu: QOM CPUState object for which KVM vCPU has to be fetched/created.
+ *
+ * @returns: 0 when success, errno (<0) when failed.
+ */
+int kvm_create_vcpu(CPUState *cpu);
+
+/**
+ * kvm_park_vcpu - Park QEMU KVM vCPU context
+ * @cpu: QOM CPUState object for which QEMU KVM vCPU context has to be parked.
+ *
+ * @returns: none
+ */
+void kvm_park_vcpu(CPUState *cpu);
+
+/**
+ * kvm_unpark_vcpu - unpark QEMU KVM vCPU context
+ * @s: KVM State
+ * @vcpu_id: Architecture vCPU ID of the parked vCPU
+ *
+ * @returns: KVM fd
+ */
+int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id);
+
+/**
+ * kvm_create_and_park_vcpu - Create and park a KVM vCPU
+ * @cpu: QOM CPUState object for which KVM vCPU has to be created and parked.
+ *
+ * @returns: 0 when success, errno (<0) when failed.
+ */
+int kvm_create_and_park_vcpu(CPUState *cpu);
+
+/* Arch specific hooks */
+
+extern const KVMCapabilityInfo kvm_arch_required_capabilities[];
+
+void kvm_arch_accel_class_init(ObjectClass *oc);
+
+void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run);
+MemTxAttrs kvm_arch_post_run(CPUState *cpu, struct kvm_run *run);
+
+int kvm_arch_handle_exit(CPUState *cpu, struct kvm_run *run);
+
+int kvm_arch_process_async_events(CPUState *cpu);
+
+int kvm_arch_get_registers(CPUState *cpu, Error **errp);
+
+/* state subset only touched by the VCPU itself during runtime */
+#define KVM_PUT_RUNTIME_STATE 1
+/* state subset modified during VCPU reset */
+#define KVM_PUT_RESET_STATE 2
+/* full state set, modified during initialization or on vmload */
+#define KVM_PUT_FULL_STATE 3
+
+int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp);
+
+int kvm_arch_get_default_type(MachineState *ms);
+
+int kvm_arch_init(MachineState *ms, KVMState *s);
+
+int kvm_arch_init_vcpu(CPUState *cpu);
+int kvm_arch_destroy_vcpu(CPUState *cpu);
+
+bool kvm_vcpu_id_is_valid(int vcpu_id);
+
+/* Returns VCPU ID to be used on KVM_CREATE_VCPU ioctl() */
+unsigned long kvm_arch_vcpu_id(CPUState *cpu);
+
+#ifdef KVM_HAVE_MCE_INJECTION
+void kvm_arch_on_sigbus_vcpu(CPUState *cpu, int code, void *addr);
+#endif
+
+void kvm_arch_init_irq_routing(KVMState *s);
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data, PCIDevice *dev);
+
+/* Notify arch about newly added MSI routes */
+int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
+ int vector, PCIDevice *dev);
+/* Notify arch about released MSI routes */
+int kvm_arch_release_virq_post(int virq);
+
+int kvm_arch_msi_data_to_gsi(uint32_t data);
+
+int kvm_set_irq(KVMState *s, int irq, int level);
+int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
+
+void kvm_irqchip_add_irq_route(KVMState *s, int gsi, int irqchip, int pin);
+
+void kvm_irqchip_add_change_notifier(Notifier *n);
+void kvm_irqchip_remove_change_notifier(Notifier *n);
+void kvm_irqchip_change_notify(void);
+
+struct kvm_guest_debug;
+struct kvm_debug_exit_arch;
+
+struct kvm_sw_breakpoint {
+ vaddr pc;
+ vaddr saved_insn;
+ int use_count;
+ QTAILQ_ENTRY(kvm_sw_breakpoint) entry;
+};
+
+struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *cpu,
+ vaddr pc);
+
+int kvm_sw_breakpoints_active(CPUState *cpu);
+
+int kvm_arch_insert_sw_breakpoint(CPUState *cpu,
+ struct kvm_sw_breakpoint *bp);
+int kvm_arch_remove_sw_breakpoint(CPUState *cpu,
+ struct kvm_sw_breakpoint *bp);
+int kvm_arch_insert_hw_breakpoint(vaddr addr, vaddr len, int type);
+int kvm_arch_remove_hw_breakpoint(vaddr addr, vaddr len, int type);
+void kvm_arch_remove_all_hw_breakpoints(void);
+
+void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg);
+
+bool kvm_arch_stop_on_emulation_error(CPUState *cpu);
+
+int kvm_check_extension(KVMState *s, unsigned int extension);
+
+int kvm_vm_check_extension(KVMState *s, unsigned int extension);
+
+#define kvm_vm_enable_cap(s, capability, cap_flags, ...) \
+ ({ \
+ struct kvm_enable_cap cap = { \
+ .cap = capability, \
+ .flags = cap_flags, \
+ }; \
+ uint64_t args_tmp[] = { __VA_ARGS__ }; \
+ size_t n = MIN(ARRAY_SIZE(args_tmp), ARRAY_SIZE(cap.args)); \
+ memcpy(cap.args, args_tmp, n * sizeof(cap.args[0])); \
+ kvm_vm_ioctl(s, KVM_ENABLE_CAP, &cap); \
+ })
+
+#define kvm_vcpu_enable_cap(cpu, capability, cap_flags, ...) \
+ ({ \
+ struct kvm_enable_cap cap = { \
+ .cap = capability, \
+ .flags = cap_flags, \
+ }; \
+ uint64_t args_tmp[] = { __VA_ARGS__ }; \
+ size_t n = MIN(ARRAY_SIZE(args_tmp), ARRAY_SIZE(cap.args)); \
+ memcpy(cap.args, args_tmp, n * sizeof(cap.args[0])); \
+ kvm_vcpu_ioctl(cpu, KVM_ENABLE_CAP, &cap); \
+ })
+
+void kvm_set_sigmask_len(KVMState *s, unsigned int sigmask_len);
+
+int kvm_physical_memory_addr_from_host(KVMState *s, void *ram_addr,
+ hwaddr *phys_addr);
+
+#endif /* COMPILING_PER_TARGET */
+
+void kvm_cpu_synchronize_state(CPUState *cpu);
+
+void kvm_init_cpu_signals(CPUState *cpu);
+
+/**
+ * kvm_irqchip_add_msi_route - Add MSI route for specific vector
+ * @c: KVMRouteChange instance.
+ * @vector: which vector to add. This can be either MSI/MSIX
+ * vector. The function will automatically detect whether
+ * MSI/MSIX is enabled, and fetch corresponding MSI
+ * message.
+ * @dev: Owner PCI device to add the route. If @dev is specified
+ * as @NULL, an empty MSI message will be inited.
+ * @return: virq (>=0) when success, errno (<0) when failed.
+ */
+int kvm_irqchip_add_msi_route(KVMRouteChange *c, int vector, PCIDevice *dev);
+int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg,
+ PCIDevice *dev);
+void kvm_irqchip_commit_routes(KVMState *s);
+
+static inline KVMRouteChange kvm_irqchip_begin_route_changes(KVMState *s)
+{
+ return (KVMRouteChange) { .s = s, .changes = 0 };
+}
+
+static inline void kvm_irqchip_commit_route_changes(KVMRouteChange *c)
+{
+ if (c->changes) {
+ kvm_irqchip_commit_routes(c->s);
+ c->changes = 0;
+ }
+}
+
+int kvm_irqchip_get_virq(KVMState *s);
+void kvm_irqchip_release_virq(KVMState *s, int virq);
+
+void kvm_add_routing_entry(KVMState *s,
+ struct kvm_irq_routing_entry *entry);
+
+int kvm_irqchip_add_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
+ EventNotifier *rn, int virq);
+int kvm_irqchip_remove_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
+ int virq);
+int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
+ EventNotifier *rn, qemu_irq irq);
+int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n,
+ qemu_irq irq);
+void kvm_irqchip_set_qemuirq_gsi(KVMState *s, qemu_irq irq, int gsi);
+void kvm_init_irq_routing(KVMState *s);
+
+bool kvm_kernel_irqchip_allowed(void);
+bool kvm_kernel_irqchip_required(void);
+bool kvm_kernel_irqchip_split(void);
+
+/**
+ * kvm_arch_irqchip_create:
+ * @KVMState: The KVMState pointer
+ *
+ * Allow architectures to create an in-kernel irq chip themselves.
+ *
+ * Returns: < 0: error
+ * 0: irq chip was not created
+ * > 0: irq chip was created
+ */
+int kvm_arch_irqchip_create(KVMState *s);
+
+/**
+ * kvm_set_one_reg - set a register value in KVM via KVM_SET_ONE_REG ioctl
+ * @id: The register ID
+ * @source: The pointer to the value to be set. It must point to a variable
+ * of the correct type/size for the register being accessed.
+ *
+ * Returns: 0 on success, or a negative errno on failure.
+ */
+int kvm_set_one_reg(CPUState *cs, uint64_t id, void *source);
+
+/**
+ * kvm_get_one_reg - get a register value from KVM via KVM_GET_ONE_REG ioctl
+ * @id: The register ID
+ * @target: The pointer where the value is to be stored. It must point to a
+ * variable of the correct type/size for the register being accessed.
+ *
+ * Returns: 0 on success, or a negative errno on failure.
+ */
+int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target);
+
+/* Notify resamplefd for EOI of specific interrupts. */
+void kvm_resample_fd_notify(int gsi);
+
+bool kvm_dirty_ring_enabled(void);
+
+uint32_t kvm_dirty_ring_size(void);
+
+void kvm_mark_guest_state_protected(void);
+
+/**
+ * kvm_hwpoisoned_mem - indicate if there is any hwpoisoned page
+ * reported for the VM.
+ */
+bool kvm_hwpoisoned_mem(void);
+
+int kvm_create_guest_memfd(uint64_t size, uint64_t flags, Error **errp);
+
+int kvm_set_memory_attributes_private(hwaddr start, uint64_t size);
+int kvm_set_memory_attributes_shared(hwaddr start, uint64_t size);
+
+int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private);
+
+#endif
--- /dev/null
+/*
+ * Internal definitions for a target's KVM support
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_KVM_INT_H
+#define QEMU_KVM_INT_H
+
+#include "exec/memory.h"
+#include "qapi/qapi-types-common.h"
+#include "qemu/accel.h"
+#include "qemu/queue.h"
+#include "system/kvm.h"
+#include "hw/boards.h"
+#include "hw/i386/topology.h"
+#include "io/channel-socket.h"
+
+typedef struct KVMSlot
+{
+ hwaddr start_addr;
+ ram_addr_t memory_size;
+ void *ram;
+ int slot;
+ int flags;
+ int old_flags;
+ /* Dirty bitmap cache for the slot */
+ unsigned long *dirty_bmap;
+ unsigned long dirty_bmap_size;
+ /* Cache of the address space ID */
+ int as_id;
+ /* Cache of the offset in ram address space */
+ ram_addr_t ram_start_offset;
+ int guest_memfd;
+ hwaddr guest_memfd_offset;
+} KVMSlot;
+
+typedef struct KVMMemoryUpdate {
+ QSIMPLEQ_ENTRY(KVMMemoryUpdate) next;
+ MemoryRegionSection section;
+} KVMMemoryUpdate;
+
+typedef struct KVMMemoryListener {
+ MemoryListener listener;
+ KVMSlot *slots;
+ unsigned int nr_slots_used;
+ unsigned int nr_slots_allocated;
+ int as_id;
+ QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_add;
+ QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_del;
+} KVMMemoryListener;
+
+#define KVM_MSI_HASHTAB_SIZE 256
+
+typedef struct KVMHostTopoInfo {
+ /* Number of package on the Host */
+ unsigned int maxpkgs;
+ /* Number of cpus on the Host */
+ unsigned int maxcpus;
+ /* Number of cpus on each different package */
+ unsigned int *pkg_cpu_count;
+ /* Each package can have different maxticks */
+ unsigned int *maxticks;
+} KVMHostTopoInfo;
+
+struct KVMMsrEnergy {
+ pid_t pid;
+ bool enable;
+ char *socket_path;
+ QIOChannelSocket *sioc;
+ QemuThread msr_thr;
+ unsigned int guest_vcpus;
+ unsigned int guest_vsockets;
+ X86CPUTopoInfo guest_topo_info;
+ KVMHostTopoInfo host_topo;
+ const CPUArchIdList *guest_cpu_list;
+ uint64_t *msr_value;
+ uint64_t msr_unit;
+ uint64_t msr_limit;
+ uint64_t msr_info;
+};
+
+enum KVMDirtyRingReaperState {
+ KVM_DIRTY_RING_REAPER_NONE = 0,
+ /* The reaper is sleeping */
+ KVM_DIRTY_RING_REAPER_WAIT,
+ /* The reaper is reaping for dirty pages */
+ KVM_DIRTY_RING_REAPER_REAPING,
+};
+
+/*
+ * KVM reaper instance, responsible for collecting the KVM dirty bits
+ * via the dirty ring.
+ */
+struct KVMDirtyRingReaper {
+ /* The reaper thread */
+ QemuThread reaper_thr;
+ volatile uint64_t reaper_iteration; /* iteration number of reaper thr */
+ volatile enum KVMDirtyRingReaperState reaper_state; /* reap thr state */
+};
+struct KVMState
+{
+ AccelState parent_obj;
+ /* Max number of KVM slots supported */
+ int nr_slots_max;
+ int fd;
+ int vmfd;
+ int coalesced_mmio;
+ int coalesced_pio;
+ struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
+ bool coalesced_flush_in_progress;
+ int vcpu_events;
+#ifdef TARGET_KVM_HAVE_GUEST_DEBUG
+ QTAILQ_HEAD(, kvm_sw_breakpoint) kvm_sw_breakpoints;
+#endif
+ int max_nested_state_len;
+ int kvm_shadow_mem;
+ bool kernel_irqchip_allowed;
+ bool kernel_irqchip_required;
+ OnOffAuto kernel_irqchip_split;
+ bool sync_mmu;
+ bool guest_state_protected;
+ uint64_t manual_dirty_log_protect;
+ /*
+ * Older POSIX says that ioctl numbers are signed int, but in
+ * practice they are not. (Newer POSIX doesn't specify ioctl
+ * at all.) Linux, glibc and *BSD all treat ioctl numbers as
+ * unsigned, and real-world ioctl values like KVM_GET_XSAVE have
+ * bit 31 set, which means that passing them via an 'int' will
+ * result in sign-extension when they get converted back to the
+ * 'unsigned long' which the ioctl() prototype uses. Luckily Linux
+ * always treats the argument as an unsigned 32-bit int, so any
+ * possible sign-extension is deliberately ignored, but for
+ * consistency we keep to the same type that glibc is using.
+ */
+ unsigned long irq_set_ioctl;
+ unsigned int sigmask_len;
+ GHashTable *gsimap;
+#ifdef KVM_CAP_IRQ_ROUTING
+ struct kvm_irq_routing *irq_routes;
+ int nr_allocated_irq_routes;
+ unsigned long *used_gsi_bitmap;
+ unsigned int gsi_count;
+#endif
+ KVMMemoryListener memory_listener;
+ QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus;
+
+ /* For "info mtree -f" to tell if an MR is registered in KVM */
+ int nr_as;
+ struct KVMAs {
+ KVMMemoryListener *ml;
+ AddressSpace *as;
+ } *as;
+ uint64_t kvm_dirty_ring_bytes; /* Size of the per-vcpu dirty ring */
+ uint32_t kvm_dirty_ring_size; /* Number of dirty GFNs per ring */
+ bool kvm_dirty_ring_with_bitmap;
+ uint64_t kvm_eager_split_size; /* Eager Page Splitting chunk size */
+ struct KVMDirtyRingReaper reaper;
+ struct KVMMsrEnergy msr_energy;
+ NotifyVmexitOption notify_vmexit;
+ uint32_t notify_window;
+ uint32_t xen_version;
+ uint32_t xen_caps;
+ uint16_t xen_gnttab_max_frames;
+ uint16_t xen_evtchn_max_pirq;
+ char *device;
+};
+
+void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml,
+ AddressSpace *as, int as_id, const char *name);
+
+void kvm_set_max_memslot_size(hwaddr max_slot_size);
+
+/**
+ * kvm_hwpoison_page_add:
+ *
+ * Parameters:
+ * @ram_addr: the address in the RAM for the poisoned page
+ *
+ * Add a poisoned page to the list
+ *
+ * Return: None.
+ */
+void kvm_hwpoison_page_add(ram_addr_t ram_addr);
+#endif
--- /dev/null
+/*
+ * Xen HVM emulation support in KVM
+ *
+ * Copyright © 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright © 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_SYSTEM_KVM_XEN_H
+#define QEMU_SYSTEM_KVM_XEN_H
+
+/* The KVM API uses these to indicate "no GPA" or "no GFN" */
+#define INVALID_GPA UINT64_MAX
+#define INVALID_GFN UINT64_MAX
+
+/* QEMU plays the rôle of dom0 for "interdomain" communication. */
+#define DOMID_QEMU 0
+
+int kvm_xen_soft_reset(void);
+uint32_t kvm_xen_get_caps(void);
+void *kvm_xen_get_vcpu_info_hva(uint32_t vcpu_id);
+bool kvm_xen_has_vcpu_callback_vector(void);
+void kvm_xen_inject_vcpu_callback_vector(uint32_t vcpu_id, int type);
+void kvm_xen_set_callback_asserted(void);
+int kvm_xen_set_vcpu_virq(uint32_t vcpu_id, uint16_t virq, uint16_t port);
+uint16_t kvm_xen_get_gnttab_max_frames(void);
+uint16_t kvm_xen_get_evtchn_max_pirq(void);
+
+#define kvm_xen_has_cap(cap) (!!(kvm_xen_get_caps() & \
+ KVM_XEN_HVM_CONFIG_ ## cap))
+
+#define XEN_SPECIAL_AREA_ADDR 0xfeff8000UL
+#define XEN_SPECIAL_AREA_SIZE 0x4000UL
+
+#define XEN_SPECIALPAGE_CONSOLE 0
+#define XEN_SPECIALPAGE_XENSTORE 1
+
+#define XEN_SPECIAL_PFN(x) ((XEN_SPECIAL_AREA_ADDR >> TARGET_PAGE_BITS) + \
+ XEN_SPECIALPAGE_##x)
+
+#endif /* QEMU_SYSTEM_KVM_XEN_H */
--- /dev/null
+/*
+ * QEMU memory mapping
+ *
+ * Copyright Fujitsu, Corp. 2011, 2012
+ *
+ * Authors:
+ * Wen Congyang <wency@cn.fujitsu.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef MEMORY_MAPPING_H
+#define MEMORY_MAPPING_H
+
+#include "qemu/queue.h"
+#include "exec/cpu-common.h"
+
+typedef struct GuestPhysBlock {
+ /* visible to guest, reflects PCI hole, etc */
+ hwaddr target_start;
+
+ /* implies size */
+ hwaddr target_end;
+
+ /* points into host memory */
+ uint8_t *host_addr;
+
+ /* points to the MemoryRegion that this block belongs to */
+ MemoryRegion *mr;
+
+ QTAILQ_ENTRY(GuestPhysBlock) next;
+} GuestPhysBlock;
+
+/* point-in-time snapshot of guest-visible physical mappings */
+typedef struct GuestPhysBlockList {
+ unsigned num;
+ QTAILQ_HEAD(, GuestPhysBlock) head;
+} GuestPhysBlockList;
+
+/* The physical and virtual address in the memory mapping are contiguous. */
+typedef struct MemoryMapping {
+ hwaddr phys_addr;
+ vaddr virt_addr;
+ ram_addr_t length;
+ QTAILQ_ENTRY(MemoryMapping) next;
+} MemoryMapping;
+
+struct MemoryMappingList {
+ unsigned int num;
+ MemoryMapping *last_mapping;
+ QTAILQ_HEAD(, MemoryMapping) head;
+};
+
+/*
+ * add or merge the memory region [phys_addr, phys_addr + length) into the
+ * memory mapping's list. The region's virtual address starts with virt_addr,
+ * and is contiguous. The list is sorted by phys_addr.
+ */
+void memory_mapping_list_add_merge_sorted(MemoryMappingList *list,
+ hwaddr phys_addr,
+ hwaddr virt_addr,
+ ram_addr_t length);
+
+void memory_mapping_list_free(MemoryMappingList *list);
+
+void memory_mapping_list_init(MemoryMappingList *list);
+
+void guest_phys_blocks_free(GuestPhysBlockList *list);
+void guest_phys_blocks_init(GuestPhysBlockList *list);
+void guest_phys_blocks_append(GuestPhysBlockList *list);
+
+bool qemu_get_guest_memory_mapping(MemoryMappingList *list,
+ const GuestPhysBlockList *guest_phys_blocks,
+ Error **errp);
+
+/* get guest's memory mapping without do paging(virtual address is 0). */
+void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list,
+ const GuestPhysBlockList *guest_phys_blocks);
+
+void memory_mapping_filter(MemoryMappingList *list, int64_t begin,
+ int64_t length);
+
+#endif
--- /dev/null
+#ifndef SYSTEM_NUMA_H
+#define SYSTEM_NUMA_H
+
+#include "qemu/bitmap.h"
+#include "qapi/qapi-types-machine.h"
+#include "exec/cpu-common.h"
+
+struct CPUArchId;
+
+#define MAX_NODES 128
+#define NUMA_NODE_UNASSIGNED MAX_NODES
+#define NUMA_DISTANCE_MIN 10
+#define NUMA_DISTANCE_DEFAULT 20
+#define NUMA_DISTANCE_MAX 254
+#define NUMA_DISTANCE_UNREACHABLE 255
+
+/* the value of AcpiHmatLBInfo flags */
+enum {
+ HMAT_LB_MEM_MEMORY = 0,
+ HMAT_LB_MEM_CACHE_1ST_LEVEL = 1,
+ HMAT_LB_MEM_CACHE_2ND_LEVEL = 2,
+ HMAT_LB_MEM_CACHE_3RD_LEVEL = 3,
+ HMAT_LB_LEVELS /* must be the last entry */
+};
+
+/* the value of AcpiHmatLBInfo data type */
+enum {
+ HMAT_LB_DATA_ACCESS_LATENCY = 0,
+ HMAT_LB_DATA_READ_LATENCY = 1,
+ HMAT_LB_DATA_WRITE_LATENCY = 2,
+ HMAT_LB_DATA_ACCESS_BANDWIDTH = 3,
+ HMAT_LB_DATA_READ_BANDWIDTH = 4,
+ HMAT_LB_DATA_WRITE_BANDWIDTH = 5,
+ HMAT_LB_TYPES /* must be the last entry */
+};
+
+#define UINT16_BITS 16
+
+typedef struct NodeInfo {
+ uint64_t node_mem;
+ struct HostMemoryBackend *node_memdev;
+ bool present;
+ bool has_cpu;
+ bool has_gi;
+ uint8_t lb_info_provided;
+ uint16_t initiator;
+ uint8_t distance[MAX_NODES];
+} NodeInfo;
+
+typedef struct NumaNodeMem {
+ uint64_t node_mem;
+ uint64_t node_plugged_mem;
+} NumaNodeMem;
+
+struct HMAT_LB_Data {
+ uint8_t initiator;
+ uint8_t target;
+ uint64_t data;
+};
+typedef struct HMAT_LB_Data HMAT_LB_Data;
+
+struct HMAT_LB_Info {
+ /* Indicates it's memory or the specified level memory side cache. */
+ uint8_t hierarchy;
+
+ /* Present the type of data, access/read/write latency or bandwidth. */
+ uint8_t data_type;
+
+ /* The range bitmap of bandwidth for calculating common base */
+ uint64_t range_bitmap;
+
+ /* The common base unit for latencies or bandwidths */
+ uint64_t base;
+
+ /* Array to store the latencies or bandwidths */
+ GArray *list;
+};
+typedef struct HMAT_LB_Info HMAT_LB_Info;
+
+struct NumaState {
+ /* Number of NUMA nodes */
+ int num_nodes;
+
+ /* Allow setting NUMA distance for different NUMA nodes */
+ bool have_numa_distance;
+
+ /* Detect if HMAT support is enabled. */
+ bool hmat_enabled;
+
+ /* NUMA nodes information */
+ NodeInfo nodes[MAX_NODES];
+
+ /* NUMA nodes HMAT Locality Latency and Bandwidth Information */
+ HMAT_LB_Info *hmat_lb[HMAT_LB_LEVELS][HMAT_LB_TYPES];
+
+ /* Memory Side Cache Information Structure */
+ NumaHmatCacheOptions *hmat_cache[MAX_NODES][HMAT_LB_LEVELS];
+};
+typedef struct NumaState NumaState;
+
+void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp);
+void parse_numa_opts(MachineState *ms);
+void parse_numa_hmat_lb(NumaState *numa_state, NumaHmatLBOptions *node,
+ Error **errp);
+void parse_numa_hmat_cache(MachineState *ms, NumaHmatCacheOptions *node,
+ Error **errp);
+void numa_complete_configuration(MachineState *ms);
+void query_numa_node_mem(NumaNodeMem node_mem[], MachineState *ms);
+extern QemuOptsList qemu_numa_opts;
+void numa_cpu_pre_plug(const struct CPUArchId *slot, DeviceState *dev,
+ Error **errp);
+bool numa_uses_legacy_mem(void);
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2018-2019 Maxime Villard, All rights reserved.
+ *
+ * NetBSD Virtual Machine Monitor (NVMM) accelerator support.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+/* header to be included in non-NVMM-specific code */
+
+#ifndef QEMU_NVMM_H
+#define QEMU_NVMM_H
+
+#ifdef COMPILING_PER_TARGET
+
+#ifdef CONFIG_NVMM
+
+int nvmm_enabled(void);
+
+#else /* CONFIG_NVMM */
+
+#define nvmm_enabled() (0)
+
+#endif /* CONFIG_NVMM */
+
+#endif /* COMPILING_PER_TARGET */
+
+#endif /* QEMU_NVMM_H */
--- /dev/null
+/*
+ * posix specific declarations
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2010 Jes Sorensen <Jes.Sorensen@redhat.com>
+ *
+ * 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.
+ */
+
+#ifndef QEMU_OS_POSIX_H
+#define QEMU_OS_POSIX_H
+
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/un.h>
+
+#ifdef CONFIG_SYSMACROS
+#include <sys/sysmacros.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void os_set_line_buffering(void);
+void os_setup_early_signal_handling(void);
+void os_set_proc_name(const char *s);
+void os_setup_signal_handling(void);
+int os_set_daemonize(bool d);
+bool is_daemonized(void);
+void os_daemonize(void);
+bool os_set_runas(const char *user_id);
+void os_set_chroot(const char *path);
+void os_setup_limits(void);
+void os_setup_post(void);
+int os_mlock(void);
+
+/**
+ * qemu_alloc_stack:
+ * @sz: pointer to a size_t holding the requested usable stack size
+ *
+ * Allocate memory that can be used as a stack, for instance for
+ * coroutines. If the memory cannot be allocated, this function
+ * will abort (like g_malloc()). This function also inserts an
+ * additional guard page to catch a potential stack overflow.
+ * Note that the memory required for the guard page and alignment
+ * and minimal stack size restrictions will increase the value of sz.
+ *
+ * The allocated stack must be freed with qemu_free_stack().
+ *
+ * Returns: pointer to (the lowest address of) the stack memory.
+ */
+void *qemu_alloc_stack(size_t *sz);
+
+/**
+ * qemu_free_stack:
+ * @stack: stack to free
+ * @sz: size of stack in bytes
+ *
+ * Free a stack allocated via qemu_alloc_stack(). Note that sz must
+ * be exactly the adjusted stack size returned by qemu_alloc_stack.
+ */
+void qemu_free_stack(void *stack, size_t sz);
+
+/* POSIX and Mingw32 differ in the name of the stdio lock functions. */
+
+static inline void qemu_flockfile(FILE *f)
+{
+ flockfile(f);
+}
+
+static inline void qemu_funlockfile(FILE *f)
+{
+ funlockfile(f);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+/*
+ * win32 specific declarations
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2010 Jes Sorensen <Jes.Sorensen@redhat.com>
+ *
+ * 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.
+ */
+
+#ifndef QEMU_OS_WIN32_H
+#define QEMU_OS_WIN32_H
+
+#include <winsock2.h>
+#include <windows.h>
+#include <ws2tcpip.h>
+#include "qemu/typedefs.h"
+
+#ifdef HAVE_AFUNIX_H
+#include <afunix.h>
+#else
+/*
+ * Fallback definitions of things we need in afunix.h, if not available from
+ * the used Windows SDK or MinGW headers.
+ */
+#define UNIX_PATH_MAX 108
+
+typedef struct sockaddr_un {
+ ADDRESS_FAMILY sun_family;
+ char sun_path[UNIX_PATH_MAX];
+} SOCKADDR_UN, *PSOCKADDR_UN;
+
+#define SIO_AF_UNIX_GETPEERPID _WSAIOR(IOC_VENDOR, 256)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__aarch64__)
+/*
+ * On windows-arm64, setjmp is available in only one variant, and longjmp always
+ * does stack unwinding. This crash with generated code.
+ * Thus, we use another implementation of setjmp (not windows one), coming from
+ * mingw, which never performs stack unwinding.
+ */
+#undef setjmp
+#undef longjmp
+/*
+ * These functions are not declared in setjmp.h because __aarch64__ defines
+ * setjmp to _setjmpex instead. However, they are still defined in libmingwex.a,
+ * which gets linked automatically.
+ */
+int __mingw_setjmp(jmp_buf);
+void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int);
+#define setjmp(env) __mingw_setjmp(env)
+#define longjmp(env, val) __mingw_longjmp(env, val)
+#elif defined(_WIN64)
+/*
+ * On windows-x64, setjmp is implemented by _setjmp which needs a second parameter.
+ * If this parameter is NULL, longjump does no stack unwinding.
+ * That is what we need for QEMU. Passing the value of register rsp (default)
+ * lets longjmp try a stack unwinding which will crash with generated code.
+ */
+# undef setjmp
+# define setjmp(env) _setjmp(env, NULL)
+#endif /* __aarch64__ */
+/* QEMU uses sigsetjmp()/siglongjmp() as the portable way to specify
+ * "longjmp and don't touch the signal masks". Since we know that the
+ * savemask parameter will always be zero we can safely define these
+ * in terms of setjmp/longjmp on Win32.
+ */
+#define sigjmp_buf jmp_buf
+#define sigsetjmp(env, savemask) setjmp(env)
+#define siglongjmp(env, val) longjmp(env, val)
+
+/* Missing POSIX functions. Don't use MinGW-w64 macros. */
+#ifndef _POSIX_THREAD_SAFE_FUNCTIONS
+#undef gmtime_r
+struct tm *gmtime_r(const time_t *timep, struct tm *result);
+#undef localtime_r
+struct tm *localtime_r(const time_t *timep, struct tm *result);
+#endif /* _POSIX_THREAD_SAFE_FUNCTIONS */
+
+static inline void os_setup_signal_handling(void) {}
+static inline void os_daemonize(void) {}
+static inline void os_setup_post(void) {}
+static inline void os_set_proc_name(const char *dummy) {}
+void os_set_line_buffering(void);
+void os_setup_early_signal_handling(void);
+
+int getpagesize(void);
+
+#if !defined(EPROTONOSUPPORT)
+# define EPROTONOSUPPORT EINVAL
+#endif
+
+static inline int os_set_daemonize(bool d)
+{
+ if (d) {
+ return -ENOTSUP;
+ }
+ return 0;
+}
+
+static inline bool is_daemonized(void)
+{
+ return false;
+}
+
+static inline int os_mlock(void)
+{
+ return -ENOSYS;
+}
+
+static inline void os_setup_limits(void)
+{
+ return;
+}
+
+#define fsync _commit
+
+#if !defined(lseek)
+# define lseek _lseeki64
+#endif
+
+int qemu_ftruncate64(int, int64_t);
+
+#if !defined(ftruncate)
+# define ftruncate qemu_ftruncate64
+#endif
+
+static inline char *realpath(const char *path, char *resolved_path)
+{
+ _fullpath(resolved_path, path, _MAX_PATH);
+ return resolved_path;
+}
+
+/*
+ * Older versions of MinGW do not import _lock_file and _unlock_file properly.
+ * This was fixed for v6.0.0 with commit b48e3ac8969d.
+ */
+static inline void qemu_flockfile(FILE *f)
+{
+#ifdef HAVE__LOCK_FILE
+ _lock_file(f);
+#endif
+}
+
+static inline void qemu_funlockfile(FILE *f)
+{
+#ifdef HAVE__LOCK_FILE
+ _unlock_file(f);
+#endif
+}
+
+/* Helper for WSAEventSelect, to report errors */
+bool qemu_socket_select(int sockfd, WSAEVENT hEventObject,
+ long lNetworkEvents, Error **errp);
+
+bool qemu_socket_unselect(int sockfd, Error **errp);
+
+/* We wrap all the sockets functions so that we can set errno based on
+ * WSAGetLastError(), and use file-descriptors instead of SOCKET.
+ */
+
+/*
+ * qemu_close_socket_osfhandle:
+ * @fd: a file descriptor associated with a SOCKET
+ *
+ * Close only the C run-time file descriptor, leave the SOCKET opened.
+ *
+ * Returns zero on success. On error, -1 is returned, and errno is set to
+ * indicate the error.
+ */
+int qemu_close_socket_osfhandle(int fd);
+
+#undef close
+#define close qemu_close_wrap
+int qemu_close_wrap(int fd);
+
+#undef connect
+#define connect qemu_connect_wrap
+int qemu_connect_wrap(int sockfd, const struct sockaddr *addr,
+ socklen_t addrlen);
+
+#undef listen
+#define listen qemu_listen_wrap
+int qemu_listen_wrap(int sockfd, int backlog);
+
+#undef bind
+#define bind qemu_bind_wrap
+int qemu_bind_wrap(int sockfd, const struct sockaddr *addr,
+ socklen_t addrlen);
+
+#undef socket
+#define socket qemu_socket_wrap
+int qemu_socket_wrap(int domain, int type, int protocol);
+
+#undef accept
+#define accept qemu_accept_wrap
+int qemu_accept_wrap(int sockfd, struct sockaddr *addr,
+ socklen_t *addrlen);
+
+#undef shutdown
+#define shutdown qemu_shutdown_wrap
+int qemu_shutdown_wrap(int sockfd, int how);
+
+#undef ioctlsocket
+#define ioctlsocket qemu_ioctlsocket_wrap
+int qemu_ioctlsocket_wrap(int fd, int req, void *val);
+
+#undef getsockopt
+#define getsockopt qemu_getsockopt_wrap
+int qemu_getsockopt_wrap(int sockfd, int level, int optname,
+ void *optval, socklen_t *optlen);
+
+#undef setsockopt
+#define setsockopt qemu_setsockopt_wrap
+int qemu_setsockopt_wrap(int sockfd, int level, int optname,
+ const void *optval, socklen_t optlen);
+
+#undef getpeername
+#define getpeername qemu_getpeername_wrap
+int qemu_getpeername_wrap(int sockfd, struct sockaddr *addr,
+ socklen_t *addrlen);
+
+#undef getsockname
+#define getsockname qemu_getsockname_wrap
+int qemu_getsockname_wrap(int sockfd, struct sockaddr *addr,
+ socklen_t *addrlen);
+
+#undef send
+#define send qemu_send_wrap
+ssize_t qemu_send_wrap(int sockfd, const void *buf, size_t len, int flags);
+
+#undef sendto
+#define sendto qemu_sendto_wrap
+ssize_t qemu_sendto_wrap(int sockfd, const void *buf, size_t len, int flags,
+ const struct sockaddr *addr, socklen_t addrlen);
+
+#undef recv
+#define recv qemu_recv_wrap
+ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags);
+
+#undef recvfrom
+#define recvfrom qemu_recvfrom_wrap
+ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
+ struct sockaddr *addr, socklen_t *addrlen);
+
+EXCEPTION_DISPOSITION
+win32_close_exception_handler(struct _EXCEPTION_RECORD*, void*,
+ struct _CONTEXT*, void*);
+
+void *qemu_win32_map_alloc(size_t size, HANDLE *h, Error **errp);
+void qemu_win32_map_free(void *ptr, HANDLE h, Error **errp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+/*
+ * Test Server
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QTEST_H
+#define QTEST_H
+
+#include "chardev/char.h"
+
+extern bool qtest_allowed;
+
+static inline bool qtest_enabled(void)
+{
+ return qtest_allowed;
+}
+
+#ifndef CONFIG_USER_ONLY
+void qtest_send_prefix(CharBackend *chr);
+void G_GNUC_PRINTF(2, 3) qtest_sendf(CharBackend *chr, const char *fmt, ...);
+void qtest_set_command_cb(bool (*pc_cb)(CharBackend *chr, gchar **words));
+bool qtest_driver(void);
+
+void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **errp);
+
+void qtest_server_set_send_handler(void (*send)(void *, const char *),
+ void *opaque);
+void qtest_server_inproc_recv(void *opaque, const char *buf);
+#endif
+
+#endif
--- /dev/null
+/*
+ * QEMU replay (system interface)
+ *
+ * Copyright (c) 2010-2015 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+#ifndef SYSTEM_REPLAY_H
+#define SYSTEM_REPLAY_H
+
+#ifdef CONFIG_USER_ONLY
+#error Cannot include this header from user emulation
+#endif
+
+#include "exec/replay-core.h"
+#include "qapi/qapi-types-misc.h"
+#include "qapi/qapi-types-run-state.h"
+#include "qapi/qapi-types-ui.h"
+#include "block/aio.h"
+
+/* replay clock kinds */
+enum ReplayClockKind {
+ /* host_clock */
+ REPLAY_CLOCK_HOST,
+ /* virtual_rt_clock */
+ REPLAY_CLOCK_VIRTUAL_RT,
+ REPLAY_CLOCK_COUNT
+};
+typedef enum ReplayClockKind ReplayClockKind;
+
+/* IDs of the checkpoints */
+enum ReplayCheckpoint {
+ CHECKPOINT_CLOCK_WARP_START,
+ CHECKPOINT_CLOCK_WARP_ACCOUNT,
+ CHECKPOINT_RESET_REQUESTED,
+ CHECKPOINT_SUSPEND_REQUESTED,
+ CHECKPOINT_CLOCK_VIRTUAL,
+ CHECKPOINT_CLOCK_HOST,
+ CHECKPOINT_CLOCK_VIRTUAL_RT,
+ CHECKPOINT_INIT,
+ CHECKPOINT_RESET,
+ CHECKPOINT_COUNT
+};
+typedef enum ReplayCheckpoint ReplayCheckpoint;
+
+typedef struct ReplayNetState ReplayNetState;
+
+/* Name of the initial VM snapshot */
+extern char *replay_snapshot;
+
+/* Replay locking
+ *
+ * The locks are needed to protect the shared structures and log file
+ * when doing record/replay. They also are the main sync-point between
+ * the main-loop thread and the vCPU thread. This was a role
+ * previously filled by the BQL which has been busy trying to reduce
+ * its impact across the code. This ensures blocks of events stay
+ * sequential and reproducible.
+ */
+
+void replay_mutex_lock(void);
+void replay_mutex_unlock(void);
+
+/* Processing the instructions */
+
+/*! Returns number of executed instructions. */
+uint64_t replay_get_current_icount(void);
+/*! Returns number of instructions to execute in replay mode. */
+int replay_get_instructions(void);
+/*! Updates instructions counter in replay mode. */
+void replay_account_executed_instructions(void);
+
+/* Processing clocks and other time sources */
+
+/*! Save the specified clock */
+int64_t replay_save_clock(ReplayClockKind kind, int64_t clock,
+ int64_t raw_icount);
+/*! Read the specified clock from the log or return cached data */
+int64_t replay_read_clock(ReplayClockKind kind, int64_t raw_icount);
+/*! Saves or reads the clock depending on the current replay mode. */
+#define REPLAY_CLOCK(clock, value) \
+ !icount_enabled() ? (value) : \
+ (replay_mode == REPLAY_MODE_PLAY \
+ ? replay_read_clock((clock), icount_get_raw()) \
+ : replay_mode == REPLAY_MODE_RECORD \
+ ? replay_save_clock((clock), (value), icount_get_raw()) \
+ : (value))
+#define REPLAY_CLOCK_LOCKED(clock, value) \
+ !icount_enabled() ? (value) : \
+ (replay_mode == REPLAY_MODE_PLAY \
+ ? replay_read_clock((clock), icount_get_raw_locked()) \
+ : replay_mode == REPLAY_MODE_RECORD \
+ ? replay_save_clock((clock), (value), icount_get_raw_locked()) \
+ : (value))
+
+/* Events */
+
+/*! Called when qemu shutdown is requested. */
+void replay_shutdown_request(ShutdownCause cause);
+/*! Should be called at check points in the execution.
+ These check points are skipped, if they were not met.
+ Saves checkpoint in the SAVE mode and validates in the PLAY mode.
+ Returns 0 in PLAY mode if checkpoint was not found.
+ Returns 1 in all other cases. */
+bool replay_checkpoint(ReplayCheckpoint checkpoint);
+/*! Used to determine that checkpoint or async event is pending.
+ Does not proceed to the next event in the log. */
+bool replay_has_event(void);
+/*
+ * Processes the async events added to the queue (while recording)
+ * or reads the events from the file (while replaying).
+ */
+void replay_async_events(void);
+
+/* Asynchronous events queue */
+
+/*! Enables storing events in the queue */
+void replay_enable_events(void);
+/*! Returns true when saving events is enabled */
+bool replay_events_enabled(void);
+/* Flushes events queue */
+void replay_flush_events(void);
+/*! Adds bottom half event to the queue */
+void replay_bh_schedule_event(QEMUBH *bh);
+/* Adds oneshot bottom half event to the queue */
+void replay_bh_schedule_oneshot_event(AioContext *ctx,
+ QEMUBHFunc *cb, void *opaque);
+/*! Adds input event to the queue */
+void replay_input_event(QemuConsole *src, InputEvent *evt);
+/*! Adds input sync event to the queue */
+void replay_input_sync_event(void);
+/*! Adds block layer event to the queue */
+void replay_block_event(QEMUBH *bh, uint64_t id);
+/*! Returns ID for the next block event */
+uint64_t blkreplay_next_id(void);
+
+/* Character device */
+
+/*! Registers char driver to save it's events */
+void replay_register_char_driver(struct Chardev *chr);
+/*! Saves write to char device event to the log */
+void replay_chr_be_write(struct Chardev *s, const uint8_t *buf, int len);
+/*! Writes char write return value to the replay log. */
+void replay_char_write_event_save(int res, int offset);
+/*! Reads char write return value from the replay log. */
+void replay_char_write_event_load(int *res, int *offset);
+/*! Reads information about read_all character event. */
+int replay_char_read_all_load(uint8_t *buf);
+/*! Writes character read_all error code into the replay log. */
+void replay_char_read_all_save_error(int res);
+/*! Writes character read_all execution result into the replay log. */
+void replay_char_read_all_save_buf(uint8_t *buf, int offset);
+
+/* Network */
+
+/*! Registers replay network filter attached to some backend. */
+ReplayNetState *replay_register_net(NetFilterState *nfs);
+/*! Unregisters replay network filter. */
+void replay_unregister_net(ReplayNetState *rns);
+/*! Called to write network packet to the replay log. */
+void replay_net_packet_event(ReplayNetState *rns, unsigned flags,
+ const struct iovec *iov, int iovcnt);
+
+/* Audio */
+
+/*! Saves/restores number of played samples of audio out operation. */
+void replay_audio_out(size_t *played);
+/*! Saves/restores recorded samples of audio in operation. */
+void replay_audio_in(size_t *recorded, void *samples, size_t *wpos, size_t size);
+
+/* VM state operations */
+
+/*! Called at the start of execution.
+ Loads or saves initial vmstate depending on execution mode. */
+void replay_vmstate_init(void);
+/*! Called to ensure that replay state is consistent and VM snapshot
+ can be created */
+bool replay_can_snapshot(void);
+
+#endif
--- /dev/null
+/*
+ * Reset handlers.
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2016 Red Hat, Inc.
+ * Copyright (c) 2024 Linaro, Ltd.
+ *
+ * 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.
+ */
+
+#ifndef QEMU_SYSTEM_RESET_H
+#define QEMU_SYSTEM_RESET_H
+
+#include "hw/resettable.h"
+#include "qapi/qapi-events-run-state.h"
+
+typedef void QEMUResetHandler(void *opaque);
+
+/**
+ * qemu_register_resettable: Register an object to be reset
+ * @obj: object to be reset: it must implement the Resettable interface
+ *
+ * Register @obj on the list of objects which will be reset when the
+ * simulation is reset. These objects will be reset in the order
+ * they were added, using the three-phase Resettable protocol,
+ * so first all objects go through the enter phase, then all objects
+ * go through the hold phase, and then finally all go through the
+ * exit phase.
+ *
+ * It is not permitted to register or unregister reset functions or
+ * resettable objects from within any of the reset phase methods of @obj.
+ *
+ * We assume that the caller holds the BQL.
+ */
+void qemu_register_resettable(Object *obj);
+
+/**
+ * qemu_unregister_resettable: Unregister an object to be reset
+ * @obj: object to unregister
+ *
+ * Remove @obj from the list of objects which are reset when the
+ * simulation is reset. It must have been previously added to
+ * the list via qemu_register_resettable().
+ *
+ * We assume that the caller holds the BQL.
+ */
+void qemu_unregister_resettable(Object *obj);
+
+/**
+ * qemu_register_reset: Register a callback for system reset
+ * @func: function to call
+ * @opaque: opaque data to pass to @func
+ *
+ * Register @func on the list of functions which are called when the
+ * entire system is reset. Functions registered with this API and
+ * Resettable objects registered with qemu_register_resettable() are
+ * handled together, in the order in which they were registered.
+ * Functions registered with this API are called in the 'hold' phase
+ * of the 3-phase reset.
+ *
+ * In general this function should not be used in new code where possible;
+ * for instance, device model reset is better accomplished using the
+ * methods on DeviceState.
+ *
+ * It is not permitted to register or unregister reset functions or
+ * resettable objects from within the @func callback.
+ *
+ * We assume that the caller holds the BQL.
+ */
+void qemu_register_reset(QEMUResetHandler *func, void *opaque);
+
+/**
+ * qemu_register_reset_nosnapshotload: Register a callback for system reset
+ * @func: function to call
+ * @opaque: opaque data to pass to @func
+ *
+ * This is the same as qemu_register_reset(), except that @func is
+ * not called if the reason that the system is being reset is to
+ * put it into a clean state prior to loading a snapshot (i.e. for
+ * SHUTDOWN_CAUSE_SNAPSHOT_LOAD).
+ */
+void qemu_register_reset_nosnapshotload(QEMUResetHandler *func, void *opaque);
+
+/**
+ * qemu_unregister_reset: Unregister a system reset callback
+ * @func: function registered with qemu_register_reset()
+ * @opaque: the same opaque data that was passed to qemu_register_reset()
+ *
+ * Undo the effects of a qemu_register_reset(). The @func and @opaque
+ * must both match the arguments originally used with qemu_register_reset().
+ *
+ * We assume that the caller holds the BQL.
+ */
+void qemu_unregister_reset(QEMUResetHandler *func, void *opaque);
+
+/**
+ * qemu_devices_reset: Perform a complete system reset
+ * @reason: type of the reset
+ *
+ * This function performs the low-level work needed to do a complete reset
+ * of the system (calling all the callbacks registered with
+ * qemu_register_reset() and resetting all the Resettable objects registered
+ * with qemu_register_resettable()). It should only be called by the code in a
+ * MachineClass reset method.
+ *
+ * If you want to trigger a system reset from, for instance, a device
+ * model, don't use this function. Use qemu_system_reset_request().
+ */
+void qemu_devices_reset(ResetType type);
+
+#endif
--- /dev/null
+/*
+ * QEMU Random Number Generator Backend
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef QEMU_RNG_RANDOM_H
+#define QEMU_RNG_RANDOM_H
+
+#include "qom/object.h"
+
+#define TYPE_RNG_RANDOM "rng-random"
+OBJECT_DECLARE_SIMPLE_TYPE(RngRandom, RNG_RANDOM)
+
+
+#endif
--- /dev/null
+/*
+ * QEMU Random Number Generator Backend
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef QEMU_RNG_H
+#define QEMU_RNG_H
+
+#include "qemu/queue.h"
+#include "qom/object.h"
+
+#define TYPE_RNG_BACKEND "rng-backend"
+OBJECT_DECLARE_TYPE(RngBackend, RngBackendClass,
+ RNG_BACKEND)
+
+#define TYPE_RNG_BUILTIN "rng-builtin"
+
+typedef struct RngRequest RngRequest;
+
+typedef void (EntropyReceiveFunc)(void *opaque,
+ const void *data,
+ size_t size);
+
+struct RngRequest
+{
+ EntropyReceiveFunc *receive_entropy;
+ uint8_t *data;
+ void *opaque;
+ size_t offset;
+ size_t size;
+ QSIMPLEQ_ENTRY(RngRequest) next;
+};
+
+struct RngBackendClass
+{
+ ObjectClass parent_class;
+
+ void (*request_entropy)(RngBackend *s, RngRequest *req);
+
+ void (*opened)(RngBackend *s, Error **errp);
+};
+
+struct RngBackend
+{
+ Object parent;
+
+ /*< protected >*/
+ bool opened;
+ QSIMPLEQ_HEAD(, RngRequest) requests;
+};
+
+
+/**
+ * rng_backend_request_entropy:
+ * @s: the backend to request entropy from
+ * @size: the number of bytes of data to request
+ * @receive_entropy: a function to be invoked when entropy is available
+ * @opaque: data that should be passed to @receive_entropy
+ *
+ * This function is used by the front-end to request entropy from an entropy
+ * source. This function can be called multiple times before @receive_entropy
+ * is invoked with different values of @receive_entropy and @opaque. The
+ * backend will queue each request and handle appropriately.
+ *
+ * The backend does not need to pass the full amount of data to @receive_entropy
+ * but will pass a value greater than 0.
+ */
+void rng_backend_request_entropy(RngBackend *s, size_t size,
+ EntropyReceiveFunc *receive_entropy,
+ void *opaque);
+
+/**
+ * rng_backend_free_request:
+ * @s: the backend that created the request
+ * @req: the request to finalize
+ *
+ * Used by child rng backend classes to finalize requests once they've been
+ * processed. The request is removed from the list of active requests and
+ * deleted.
+ */
+void rng_backend_finalize_request(RngBackend *s, RngRequest *req);
+#endif
--- /dev/null
+/*
+ * RTC configuration and clock read
+ *
+ * Copyright (c) 2003-2021 QEMU contributors
+ *
+ * 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.
+ */
+
+#ifndef SYSTEM_RTC_H
+#define SYSTEM_RTC_H
+
+/**
+ * qemu_get_timedate: Get the current RTC time
+ * @tm: struct tm to fill in with RTC time
+ * @offset: offset in seconds to adjust the RTC time by before
+ * converting to struct tm format.
+ *
+ * This function fills in @tm with the current RTC time, as adjusted
+ * by @offset (for example, if @offset is 3600 then the returned time/date
+ * will be one hour further ahead than the current RTC time).
+ *
+ * The usual use is by RTC device models, which should call this function
+ * to find the time/date value that they should return to the guest
+ * when it reads the RTC registers.
+ *
+ * The behaviour of the clock whose value this function returns will
+ * depend on the -rtc command line option passed by the user.
+ */
+void qemu_get_timedate(struct tm *tm, time_t offset);
+
+/**
+ * qemu_timedate_diff: Return difference between a struct tm and the RTC
+ * @tm: struct tm containing the date/time to compare against
+ *
+ * Returns the difference in seconds between the RTC clock time
+ * and the date/time specified in @tm. For example, if @tm specifies
+ * a timestamp one hour further ahead than the current RTC time
+ * then this function will return 3600.
+ */
+time_t qemu_timedate_diff(struct tm *tm);
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2020 Oracle and/or its affiliates.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef RUNSTATE_ACTION_H
+#define RUNSTATE_ACTION_H
+
+#include "qapi/qapi-commands-run-state.h"
+
+/* in system/runstate-action.c */
+extern RebootAction reboot_action;
+extern ShutdownAction shutdown_action;
+extern PanicAction panic_action;
+
+#endif /* RUNSTATE_ACTION_H */
--- /dev/null
+#ifndef SYSTEM_RUNSTATE_H
+#define SYSTEM_RUNSTATE_H
+
+#include "qapi/qapi-types-run-state.h"
+#include "qemu/notify.h"
+
+bool runstate_check(RunState state);
+void runstate_set(RunState new_state);
+RunState runstate_get(void);
+bool runstate_is_running(void);
+bool runstate_needs_reset(void);
+void runstate_replay_enable(void);
+
+typedef void VMChangeStateHandler(void *opaque, bool running, RunState state);
+
+VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
+ void *opaque);
+VMChangeStateEntry *qemu_add_vm_change_state_handler_prio(
+ VMChangeStateHandler *cb, void *opaque, int priority);
+VMChangeStateEntry *
+qemu_add_vm_change_state_handler_prio_full(VMChangeStateHandler *cb,
+ VMChangeStateHandler *prepare_cb,
+ void *opaque, int priority);
+VMChangeStateEntry *qdev_add_vm_change_state_handler(DeviceState *dev,
+ VMChangeStateHandler *cb,
+ void *opaque);
+VMChangeStateEntry *qdev_add_vm_change_state_handler_full(
+ DeviceState *dev, VMChangeStateHandler *cb,
+ VMChangeStateHandler *prepare_cb, void *opaque);
+void qemu_del_vm_change_state_handler(VMChangeStateEntry *e);
+/**
+ * vm_state_notify: Notify the state of the VM
+ *
+ * @running: whether the VM is running or not.
+ * @state: the #RunState of the VM.
+ */
+void vm_state_notify(bool running, RunState state);
+
+static inline bool shutdown_caused_by_guest(ShutdownCause cause)
+{
+ return cause >= SHUTDOWN_CAUSE_GUEST_SHUTDOWN;
+}
+
+/*
+ * In a "live" state, the vcpu clock is ticking, and the runstate notifiers
+ * think we are running.
+ */
+static inline bool runstate_is_live(RunState state)
+{
+ return state == RUN_STATE_RUNNING || state == RUN_STATE_SUSPENDED;
+}
+
+void vm_start(void);
+
+/**
+ * vm_prepare_start: Prepare for starting/resuming the VM
+ *
+ * @step_pending: whether any of the CPUs is about to be single-stepped by gdb
+ */
+int vm_prepare_start(bool step_pending);
+
+/**
+ * vm_resume: If @state is a live state, start the vm and set the state,
+ * else just set the state.
+ *
+ * @state: the state to restore
+ */
+void vm_resume(RunState state);
+
+int vm_stop(RunState state);
+int vm_stop_force_state(RunState state);
+int vm_shutdown(void);
+void vm_set_suspended(bool suspended);
+bool vm_get_suspended(void);
+
+typedef enum WakeupReason {
+ /* Always keep QEMU_WAKEUP_REASON_NONE = 0 */
+ QEMU_WAKEUP_REASON_NONE = 0,
+ QEMU_WAKEUP_REASON_RTC,
+ QEMU_WAKEUP_REASON_PMTIMER,
+ QEMU_WAKEUP_REASON_OTHER,
+} WakeupReason;
+
+void qemu_system_reset_request(ShutdownCause reason);
+void qemu_system_suspend_request(void);
+void qemu_register_suspend_notifier(Notifier *notifier);
+bool qemu_wakeup_suspend_enabled(void);
+void qemu_system_wakeup_request(WakeupReason reason, Error **errp);
+void qemu_system_wakeup_enable(WakeupReason reason, bool enabled);
+void qemu_register_wakeup_notifier(Notifier *notifier);
+void qemu_register_wakeup_support(void);
+void qemu_system_shutdown_request_with_code(ShutdownCause reason,
+ int exit_code);
+void qemu_system_shutdown_request(ShutdownCause reason);
+void qemu_system_powerdown_request(void);
+void qemu_register_powerdown_notifier(Notifier *notifier);
+void qemu_register_shutdown_notifier(Notifier *notifier);
+void qemu_system_debug_request(void);
+void qemu_system_vmstop_request(RunState reason);
+void qemu_system_vmstop_request_prepare(void);
+bool qemu_vmstop_requested(RunState *r);
+ShutdownCause qemu_shutdown_requested_get(void);
+ShutdownCause qemu_reset_requested_get(void);
+void qemu_system_killed(int signal, pid_t pid);
+void qemu_system_reset(ShutdownCause reason);
+void qemu_system_guest_panicked(GuestPanicInformation *info);
+void qemu_system_guest_crashloaded(GuestPanicInformation *info);
+void qemu_system_guest_pvshutdown(void);
+bool qemu_system_dump_in_progress(void);
+
+#endif
+
--- /dev/null
+/*
+ * QEMU seccomp mode 2 support with libseccomp
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ * Eduardo Otubo <eotubo@br.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+#ifndef QEMU_SECCOMP_H
+#define QEMU_SECCOMP_H
+
+#define QEMU_SECCOMP_SET_DEFAULT (1 << 0)
+#define QEMU_SECCOMP_SET_OBSOLETE (1 << 1)
+#define QEMU_SECCOMP_SET_PRIVILEGED (1 << 2)
+#define QEMU_SECCOMP_SET_SPAWN (1 << 3)
+#define QEMU_SECCOMP_SET_RESOURCECTL (1 << 4)
+
+int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp);
+
+#endif
--- /dev/null
+/*
+ * QEMU SPDM socket support
+ *
+ * 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.
+ */
+
+#ifndef SPDM_REQUESTER_H
+#define SPDM_REQUESTER_H
+
+/**
+ * spdm_socket_connect: connect to an external SPDM socket
+ * @port: port to connect to
+ * @errp: error object handle
+ *
+ * This will connect to an external SPDM socket server. On error
+ * it will return -1 and errp will be set. On success this function
+ * will return the socket number.
+ */
+int spdm_socket_connect(uint16_t port, Error **errp);
+
+/**
+ * spdm_socket_rsp: send and receive a message to a SPDM server
+ * @socket: socket returned from spdm_socket_connect()
+ * @transport_type: SPDM_SOCKET_TRANSPORT_TYPE_* macro
+ * @req: request buffer
+ * @req_len: request buffer length
+ * @rsp: response buffer
+ * @rsp_len: response buffer length
+ *
+ * Send platform data to a SPDM server on socket and then receive
+ * a response.
+ */
+uint32_t spdm_socket_rsp(const int socket, uint32_t transport_type,
+ void *req, uint32_t req_len,
+ void *rsp, uint32_t rsp_len);
+
+/**
+ * spdm_socket_close: send a shutdown command to the server
+ * @socket: socket returned from spdm_socket_connect()
+ * @transport_type: SPDM_SOCKET_TRANSPORT_TYPE_* macro
+ *
+ * This will issue a shutdown command to the server.
+ */
+void spdm_socket_close(const int socket, uint32_t transport_type);
+
+#define SPDM_SOCKET_COMMAND_NORMAL 0x0001
+#define SPDM_SOCKET_COMMAND_OOB_ENCAP_KEY_UPDATE 0x8001
+#define SPDM_SOCKET_COMMAND_CONTINUE 0xFFFD
+#define SPDM_SOCKET_COMMAND_SHUTDOWN 0xFFFE
+#define SPDM_SOCKET_COMMAND_UNKOWN 0xFFFF
+#define SPDM_SOCKET_COMMAND_TEST 0xDEAD
+
+#define SPDM_SOCKET_TRANSPORT_TYPE_MCTP 0x01
+#define SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE 0x02
+
+#define SPDM_SOCKET_MAX_MESSAGE_BUFFER_SIZE 0x1200
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef STATS_H
+#define STATS_H
+
+#include "qapi/qapi-types-stats.h"
+
+typedef void StatRetrieveFunc(StatsResultList **result, StatsTarget target,
+ strList *names, strList *targets, Error **errp);
+typedef void SchemaRetrieveFunc(StatsSchemaList **result, Error **errp);
+
+/*
+ * Register callbacks for the QMP query-stats command.
+ *
+ * @provider: stats provider checked against QMP command arguments
+ * @stats_fn: routine to query stats:
+ * @schema_fn: routine to query stat schemas:
+ */
+void add_stats_callbacks(StatsProvider provider,
+ StatRetrieveFunc *stats_fn,
+ SchemaRetrieveFunc *schemas_fn);
+
+/*
+ * Helper routines for adding stats entries to the results lists.
+ */
+void add_stats_entry(StatsResultList **, StatsProvider, const char *id,
+ StatsList *stats_list);
+void add_stats_schema(StatsSchemaList **, StatsProvider, StatsTarget,
+ StatsSchemaValueList *);
+
+/*
+ * True if a string matches the filter passed to the stats_fn callback,
+ * false otherwise.
+ *
+ * Note that an empty list means no filtering, i.e. all strings will
+ * return true.
+ */
+bool apply_str_list_filter(const char *string, strList *list);
+
+#endif /* STATS_H */
--- /dev/null
+#ifndef SYSTEM_H
+#define SYSTEM_H
+/* Misc. things related to the system emulator. */
+
+#include "qemu/timer.h"
+#include "qemu/notify.h"
+#include "qemu/uuid.h"
+
+/* vl.c */
+
+extern int only_migratable;
+extern const char *qemu_name;
+extern QemuUUID qemu_uuid;
+extern bool qemu_uuid_set;
+
+const char *qemu_get_vm_name(void);
+
+void qemu_add_exit_notifier(Notifier *notify);
+void qemu_remove_exit_notifier(Notifier *notify);
+
+void qemu_add_machine_init_done_notifier(Notifier *notify);
+void qemu_remove_machine_init_done_notifier(Notifier *notify);
+
+void configure_rtc(QemuOpts *opts);
+
+void qemu_init_subsystems(void);
+
+extern int autostart;
+
+typedef enum {
+ VGA_NONE, VGA_STD, VGA_CIRRUS, VGA_VMWARE, VGA_XENFB, VGA_QXL,
+ VGA_TCX, VGA_CG3, VGA_DEVICE, VGA_VIRTIO,
+ VGA_TYPE_MAX,
+} VGAInterfaceType;
+
+extern int vga_interface_type;
+extern bool vga_interface_created;
+
+extern int graphic_width;
+extern int graphic_height;
+extern int graphic_depth;
+extern int display_opengl;
+extern const char *keyboard_layout;
+extern int old_param;
+extern uint8_t *boot_splash_filedata;
+extern bool enable_mlock;
+extern bool enable_cpu_pm;
+extern QEMUClockType rtc_clock;
+
+#define MAX_OPTION_ROMS 16
+typedef struct QEMUOptionRom {
+ const char *name;
+ int32_t bootindex;
+} QEMUOptionRom;
+extern QEMUOptionRom option_rom[MAX_OPTION_ROMS];
+extern int nb_option_roms;
+
+#define MAX_PROM_ENVS 128
+extern const char *prom_envs[MAX_PROM_ENVS];
+extern unsigned int nb_prom_envs;
+
+/* serial ports */
+
+/* Return the Chardev for serial port i, or NULL if none */
+Chardev *serial_hd(int i);
+
+/* parallel ports */
+
+#define MAX_PARALLEL_PORTS 3
+
+extern Chardev *parallel_hds[MAX_PARALLEL_PORTS];
+
+void add_boot_device_path(int32_t bootindex, DeviceState *dev,
+ const char *suffix);
+char *get_boot_devices_list(size_t *size);
+
+DeviceState *get_boot_device(uint32_t position);
+void check_boot_index(int32_t bootindex, Error **errp);
+void del_boot_device_path(DeviceState *dev, const char *suffix);
+void device_add_bootindex_property(Object *obj, int32_t *bootindex,
+ const char *name, const char *suffix,
+ DeviceState *dev);
+void restore_boot_order(void *opaque);
+void validate_bootdevices(const char *devices, Error **errp);
+void add_boot_device_lchs(DeviceState *dev, const char *suffix,
+ uint32_t lcyls, uint32_t lheads, uint32_t lsecs);
+void del_boot_device_lchs(DeviceState *dev, const char *suffix);
+char *get_boot_devices_lchs_list(size_t *size);
+
+/* handler to set the boot_device order for a specific type of MachineClass */
+typedef void QEMUBootSetHandler(void *opaque, const char *boot_order,
+ Error **errp);
+void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque);
+void qemu_boot_set(const char *boot_order, Error **errp);
+
+bool defaults_enabled(void);
+
+void qemu_init(int argc, char **argv);
+int qemu_main_loop(void);
+void qemu_cleanup(int);
+
+extern QemuOptsList qemu_legacy_drive_opts;
+extern QemuOptsList qemu_common_drive_opts;
+extern QemuOptsList qemu_drive_opts;
+extern QemuOptsList bdrv_runtime_opts;
+extern QemuOptsList qemu_chardev_opts;
+extern QemuOptsList qemu_device_opts;
+extern QemuOptsList qemu_netdev_opts;
+extern QemuOptsList qemu_nic_opts;
+extern QemuOptsList qemu_net_opts;
+extern QemuOptsList qemu_global_opts;
+extern QemuOptsList qemu_semihosting_config_opts;
+
+#endif
--- /dev/null
+/*
+ * QEMU TCG support
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+/* header to be included in non-TCG-specific code */
+
+#ifndef SYSTEM_TCG_H
+#define SYSTEM_TCG_H
+
+#ifdef CONFIG_TCG
+extern bool tcg_allowed;
+#define tcg_enabled() (tcg_allowed)
+#else
+#define tcg_enabled() 0
+#endif
+
+#endif
--- /dev/null
+/*
+ * Public TPM functions
+ *
+ * Copyright (C) 2011-2013 IBM Corporation
+ *
+ * Authors:
+ * Stefan Berger <stefanb@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef QEMU_TPM_H
+#define QEMU_TPM_H
+
+#include "qapi/qapi-types-tpm.h"
+#include "qom/object.h"
+
+#ifdef CONFIG_TPM
+
+int tpm_config_parse(QemuOptsList *opts_list, const char *optstr);
+int tpm_init(void);
+void tpm_cleanup(void);
+
+typedef enum TPMVersion {
+ TPM_VERSION_UNSPEC = 0,
+ TPM_VERSION_1_2 = 1,
+ TPM_VERSION_2_0 = 2,
+} TPMVersion;
+
+#define TYPE_TPM_IF "tpm-if"
+typedef struct TPMIfClass TPMIfClass;
+DECLARE_CLASS_CHECKERS(TPMIfClass, TPM_IF,
+ TYPE_TPM_IF)
+#define TPM_IF(obj) \
+ INTERFACE_CHECK(TPMIf, (obj), TYPE_TPM_IF)
+
+typedef struct TPMIf TPMIf;
+
+struct TPMIfClass {
+ InterfaceClass parent_class;
+
+ enum TpmModel model;
+ void (*request_completed)(TPMIf *obj, int ret);
+ enum TPMVersion (*get_version)(TPMIf *obj);
+};
+
+#define TYPE_TPM_TIS_ISA "tpm-tis"
+#define TYPE_TPM_TIS_SYSBUS "tpm-tis-device"
+#define TYPE_TPM_CRB "tpm-crb"
+#define TYPE_TPM_SPAPR "tpm-spapr"
+#define TYPE_TPM_TIS_I2C "tpm-tis-i2c"
+
+#define TPM_IS_TIS_ISA(chr) \
+ object_dynamic_cast(OBJECT(chr), TYPE_TPM_TIS_ISA)
+#define TPM_IS_TIS_SYSBUS(chr) \
+ object_dynamic_cast(OBJECT(chr), TYPE_TPM_TIS_SYSBUS)
+#define TPM_IS_CRB(chr) \
+ object_dynamic_cast(OBJECT(chr), TYPE_TPM_CRB)
+#define TPM_IS_SPAPR(chr) \
+ object_dynamic_cast(OBJECT(chr), TYPE_TPM_SPAPR)
+#define TPM_IS_TIS_I2C(chr) \
+ object_dynamic_cast(OBJECT(chr), TYPE_TPM_TIS_I2C)
+
+/* returns NULL unless there is exactly one TPM device */
+static inline TPMIf *tpm_find(void)
+{
+ Object *obj = object_resolve_path_type("", TYPE_TPM_IF, NULL);
+
+ return TPM_IF(obj);
+}
+
+static inline TPMVersion tpm_get_version(TPMIf *ti)
+{
+ if (!ti) {
+ return TPM_VERSION_UNSPEC;
+ }
+
+ return TPM_IF_GET_CLASS(ti)->get_version(ti);
+}
+
+#else /* CONFIG_TPM */
+
+#define tpm_init() (0)
+#define tpm_cleanup()
+
+/* needed for an alignment check in non-tpm code */
+static inline Object *TPM_IS_CRB(Object *obj)
+{
+ return NULL;
+}
+
+#endif /* CONFIG_TPM */
+
+#endif /* QEMU_TPM_H */
--- /dev/null
+/*
+ * QEMU TPM Backend
+ *
+ * Copyright IBM, Corp. 2013
+ *
+ * Authors:
+ * Stefan Berger <stefanb@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef TPM_BACKEND_H
+#define TPM_BACKEND_H
+
+#include "qom/object.h"
+#include "qemu/option.h"
+#include "system/tpm.h"
+#include "qapi/error.h"
+
+#ifdef CONFIG_TPM
+
+#define TYPE_TPM_BACKEND "tpm-backend"
+OBJECT_DECLARE_TYPE(TPMBackend, TPMBackendClass,
+ TPM_BACKEND)
+
+
+typedef struct TPMBackendCmd {
+ uint8_t locty;
+ const uint8_t *in;
+ uint32_t in_len;
+ uint8_t *out;
+ uint32_t out_len;
+ bool selftest_done;
+} TPMBackendCmd;
+
+struct TPMBackend {
+ Object parent;
+
+ /*< protected >*/
+ TPMIf *tpmif;
+ bool opened;
+ bool had_startup_error;
+ TPMBackendCmd *cmd;
+
+ /* <public> */
+ char *id;
+
+ QLIST_ENTRY(TPMBackend) list;
+};
+
+struct TPMBackendClass {
+ ObjectClass parent_class;
+
+ enum TpmType type;
+ const QemuOptDesc *opts;
+ /* get a descriptive text of the backend to display to the user */
+ const char *desc;
+
+ TPMBackend *(*create)(QemuOpts *opts);
+
+ /* start up the TPM on the backend - optional */
+ int (*startup_tpm)(TPMBackend *t, size_t buffersize);
+
+ /* optional */
+ void (*reset)(TPMBackend *t);
+
+ void (*cancel_cmd)(TPMBackend *t);
+
+ /* optional */
+ bool (*get_tpm_established_flag)(TPMBackend *t);
+
+ /* optional */
+ int (*reset_tpm_established_flag)(TPMBackend *t, uint8_t locty);
+
+ TPMVersion (*get_tpm_version)(TPMBackend *t);
+
+ size_t (*get_buffer_size)(TPMBackend *t);
+
+ TpmTypeOptions *(*get_tpm_options)(TPMBackend *t);
+
+ void (*handle_request)(TPMBackend *s, TPMBackendCmd *cmd, Error **errp);
+};
+
+/**
+ * tpm_backend_get_type:
+ * @s: the backend
+ *
+ * Returns the TpmType of the backend.
+ */
+enum TpmType tpm_backend_get_type(TPMBackend *s);
+
+/**
+ * tpm_backend_init:
+ * @s: the backend to initialized
+ * @tpmif: TPM interface
+ * @datacb: callback for sending data to frontend
+ * @errp: a pointer to return the #Error object if an error occurs.
+ *
+ * Initialize the backend with the given variables.
+ *
+ * Returns 0 on success.
+ */
+int tpm_backend_init(TPMBackend *s, TPMIf *tpmif, Error **errp);
+
+/**
+ * tpm_backend_startup_tpm:
+ * @s: the backend whose TPM support is to be started
+ * @buffersize: the buffer size the TPM is supposed to use,
+ * 0 to leave it as-is
+ *
+ * Returns 0 on success.
+ */
+int tpm_backend_startup_tpm(TPMBackend *s, size_t buffersize);
+
+/**
+ * tpm_backend_had_startup_error:
+ * @s: the backend to query for a startup error
+ *
+ * Check whether the backend had an error during startup. Returns
+ * false if no error occurred and the backend can be used, true
+ * otherwise.
+ */
+bool tpm_backend_had_startup_error(TPMBackend *s);
+
+/**
+ * tpm_backend_deliver_request:
+ * @s: the backend to send the request to
+ * @cmd: the command to deliver
+ *
+ * Send a request to the backend. The backend will then send the request
+ * to the TPM implementation.
+ */
+void tpm_backend_deliver_request(TPMBackend *s, TPMBackendCmd *cmd);
+
+/**
+ * tpm_backend_reset:
+ * @s: the backend to reset
+ *
+ * Reset the backend into a well defined state with all previous errors
+ * reset.
+ */
+void tpm_backend_reset(TPMBackend *s);
+
+/**
+ * tpm_backend_cancel_cmd:
+ * @s: the backend
+ *
+ * Cancel any ongoing command being processed by the TPM implementation
+ * on behalf of the QEMU guest.
+ */
+void tpm_backend_cancel_cmd(TPMBackend *s);
+
+/**
+ * tpm_backend_get_tpm_established_flag:
+ * @s: the backend
+ *
+ * Get the TPM establishment flag. This function may be called very
+ * frequently by the frontend since for example in the TIS implementation
+ * this flag is part of a register.
+ */
+bool tpm_backend_get_tpm_established_flag(TPMBackend *s);
+
+/**
+ * tpm_backend_reset_tpm_established_flag:
+ * @s: the backend
+ * @locty: the locality number
+ *
+ * Reset the TPM establishment flag.
+ */
+int tpm_backend_reset_tpm_established_flag(TPMBackend *s, uint8_t locty);
+
+/**
+ * tpm_backend_get_tpm_version:
+ * @s: the backend to call into
+ *
+ * Get the TPM Version that is emulated at the backend.
+ *
+ * Returns TPMVersion.
+ */
+TPMVersion tpm_backend_get_tpm_version(TPMBackend *s);
+
+/**
+ * tpm_backend_get_buffer_size:
+ * @s: the backend to call into
+ *
+ * Get the TPM's buffer size.
+ *
+ * Returns buffer size.
+ */
+size_t tpm_backend_get_buffer_size(TPMBackend *s);
+
+/**
+ * tpm_backend_finish_sync:
+ * @s: the backend to call into
+ *
+ * Finish the pending command synchronously (this will call aio_poll()
+ * on qemu main AIOContext until it ends)
+ */
+void tpm_backend_finish_sync(TPMBackend *s);
+
+/**
+ * tpm_backend_query_tpm:
+ * @s: the backend
+ *
+ * Query backend tpm info
+ *
+ * Returns newly allocated TPMInfo
+ */
+TPMInfo *tpm_backend_query_tpm(TPMBackend *s);
+
+TPMBackend *qemu_find_tpm_be(const char *id);
+
+#endif /* CONFIG_TPM */
+
+#endif /* TPM_BACKEND_H */
--- /dev/null
+/*
+ * TPM utility functions
+ *
+ * Copyright (c) 2010 - 2015 IBM Corporation
+ * Authors:
+ * Stefan Berger <stefanb@us.ibm.com>
+ *
+ * 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.1 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/>
+ */
+
+#ifndef SYSTEM_TPM_UTIL_H
+#define SYSTEM_TPM_UTIL_H
+
+#include "system/tpm.h"
+#include "qemu/bswap.h"
+
+void tpm_util_write_fatal_error_response(uint8_t *out, uint32_t out_len);
+
+bool tpm_util_is_selftest(const uint8_t *in, uint32_t in_len);
+
+int tpm_util_test_tpmdev(int tpm_fd, TPMVersion *tpm_version);
+
+static inline uint16_t tpm_cmd_get_tag(const void *b)
+{
+ return lduw_be_p(b);
+}
+
+static inline void tpm_cmd_set_tag(void *b, uint16_t tag)
+{
+ stw_be_p(b, tag);
+}
+
+static inline uint32_t tpm_cmd_get_size(const void *b)
+{
+ return ldl_be_p(b + 2);
+}
+
+static inline void tpm_cmd_set_size(void *b, uint32_t size)
+{
+ stl_be_p(b + 2, size);
+}
+
+static inline uint32_t tpm_cmd_get_ordinal(const void *b)
+{
+ return ldl_be_p(b + 6);
+}
+
+static inline uint32_t tpm_cmd_get_errcode(const void *b)
+{
+ return ldl_be_p(b + 6);
+}
+
+static inline void tpm_cmd_set_error(void *b, uint32_t error)
+{
+ stl_be_p(b + 6, error);
+}
+
+void tpm_util_show_buffer(const unsigned char *buffer,
+ size_t buffer_size, const char *string);
+
+#endif /* SYSTEM_TPM_UTIL_H */
--- /dev/null
+/*
+ * QEMU vhost-user backend
+ *
+ * Copyright (C) 2018 Red Hat Inc
+ *
+ * Authors:
+ * Marc-André Lureau <marcandre.lureau@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef QEMU_VHOST_USER_BACKEND_H
+#define QEMU_VHOST_USER_BACKEND_H
+
+#include "qom/object.h"
+#include "exec/memory.h"
+#include "qemu/option.h"
+#include "qemu/bitmap.h"
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-user.h"
+#include "chardev/char-fe.h"
+#include "io/channel.h"
+
+#define TYPE_VHOST_USER_BACKEND "vhost-user-backend"
+OBJECT_DECLARE_SIMPLE_TYPE(VhostUserBackend,
+ VHOST_USER_BACKEND)
+
+
+
+struct VhostUserBackend {
+ /* private */
+ Object parent;
+
+ char *chr_name;
+ CharBackend chr;
+ VhostUserState vhost_user;
+ struct vhost_dev dev;
+ VirtIODevice *vdev;
+ bool started;
+ bool completed;
+};
+
+int vhost_user_backend_dev_init(VhostUserBackend *b, VirtIODevice *vdev,
+ unsigned nvqs, Error **errp);
+void vhost_user_backend_start(VhostUserBackend *b);
+void vhost_user_backend_stop(VhostUserBackend *b);
+
+#endif
--- /dev/null
+/*
+ * Virtual hardware watchdog.
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * By Richard W.M. Jones (rjones@redhat.com).
+ */
+
+#ifndef QEMU_WATCHDOG_H
+#define QEMU_WATCHDOG_H
+
+#include "qemu/queue.h"
+#include "qapi/qapi-types-run-state.h"
+
+/* in hw/watchdog.c */
+WatchdogAction get_watchdog_action(void);
+void watchdog_perform_action(void);
+
+#endif /* QEMU_WATCHDOG_H */
--- /dev/null
+/*
+ * QEMU Windows Hypervisor Platform accelerator (WHPX) support
+ *
+ * Copyright Microsoft, Corp. 2017
+ *
+ * Authors:
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+/* header to be included in non-WHPX-specific code */
+
+#ifndef QEMU_WHPX_H
+#define QEMU_WHPX_H
+
+#ifdef COMPILING_PER_TARGET
+
+#ifdef CONFIG_WHPX
+
+int whpx_enabled(void);
+bool whpx_apic_in_platform(void);
+
+#else /* CONFIG_WHPX */
+
+#define whpx_enabled() (0)
+#define whpx_apic_in_platform() (0)
+
+#endif /* CONFIG_WHPX */
+
+#endif /* COMPILING_PER_TARGET */
+
+#endif /* QEMU_WHPX_H */
--- /dev/null
+/*
+ * Copyright (C) 2011 Citrix Ltd.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef XEN_MAPCACHE_H
+#define XEN_MAPCACHE_H
+
+#include "exec/cpu-common.h"
+#include "system/xen.h"
+
+typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr phys_offset,
+ ram_addr_t size);
+#ifdef CONFIG_XEN_IS_POSSIBLE
+
+void xen_map_cache_init(phys_offset_to_gaddr_t f,
+ void *opaque);
+uint8_t *xen_map_cache(MemoryRegion *mr, hwaddr phys_addr, hwaddr size,
+ ram_addr_t ram_addr_offset,
+ uint8_t lock, bool dma,
+ bool is_write);
+ram_addr_t xen_ram_addr_from_mapcache(void *ptr);
+void xen_invalidate_map_cache_entry(uint8_t *buffer);
+void xen_invalidate_map_cache(void);
+uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
+ hwaddr new_phys_addr,
+ hwaddr size);
+#else
+
+static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
+ void *opaque)
+{
+}
+
+static inline uint8_t *xen_map_cache(MemoryRegion *mr,
+ hwaddr phys_addr,
+ hwaddr size,
+ ram_addr_t ram_addr_offset,
+ uint8_t lock,
+ bool dma,
+ bool is_write)
+{
+ abort();
+}
+
+static inline ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
+{
+ abort();
+}
+
+static inline void xen_invalidate_map_cache_entry(uint8_t *buffer)
+{
+}
+
+static inline void xen_invalidate_map_cache(void)
+{
+}
+
+static inline uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
+ hwaddr new_phys_addr,
+ hwaddr size)
+{
+ abort();
+}
+
+#endif
+
+#endif /* XEN_MAPCACHE_H */
--- /dev/null
+/*
+ * QEMU Xen support
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+/* header to be included in non-Xen-specific code */
+
+#ifndef SYSTEM_XEN_H
+#define SYSTEM_XEN_H
+
+#ifdef CONFIG_USER_ONLY
+#error Cannot include system/xen.h from user emulation
+#endif
+
+#include "exec/cpu-common.h"
+
+#ifdef COMPILING_PER_TARGET
+# ifdef CONFIG_XEN
+# define CONFIG_XEN_IS_POSSIBLE
+# endif
+#else
+# define CONFIG_XEN_IS_POSSIBLE
+#endif /* COMPILING_PER_TARGET */
+
+#ifdef CONFIG_XEN_IS_POSSIBLE
+
+extern bool xen_allowed;
+
+#define xen_enabled() (xen_allowed)
+
+void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length);
+void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
+ struct MemoryRegion *mr, Error **errp);
+
+#else /* !CONFIG_XEN_IS_POSSIBLE */
+
+#define xen_enabled() 0
+static inline void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length)
+{
+ /* nothing */
+}
+static inline void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
+ MemoryRegion *mr, Error **errp)
+{
+ g_assert_not_reached();
+}
+
+#endif /* CONFIG_XEN_IS_POSSIBLE */
+
+bool xen_mr_is_memory(MemoryRegion *mr);
+bool xen_mr_is_grants(MemoryRegion *mr);
+#endif
#include "qemu/module.h"
#include "block/aio.h"
#include "block/block.h"
-#include "sysemu/event-loop-base.h"
-#include "sysemu/iothread.h"
+#include "system/event-loop-base.h"
+#include "system/iothread.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-misc.h"
#include "qemu/error-report.h"
#include "block/block.h"
#include "block/block_int.h"
#include "block/dirty-bitmap.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/runstate.h"
+#include "system/block-backend.h"
+#include "system/runstate.h"
#include "qemu/main-loop.h"
#include "qemu/error-report.h"
#include "migration/misc.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-migration.h"
#include "migration.h"
#include "net/colo.h"
#include "block/block.h"
#include "qapi/qapi-events-migration.h"
-#include "sysemu/cpus.h"
-#include "sysemu/runstate.h"
+#include "system/cpus.h"
+#include "system/runstate.h"
#include "net/filter.h"
#include "options.h"
#include "qemu/thread.h"
#include "hw/core/cpu.h"
#include "qemu/main-loop.h"
-#include "sysemu/cpus.h"
-#include "sysemu/cpu-throttle.h"
+#include "system/cpus.h"
+#include "system/cpu-throttle.h"
#include "migration.h"
#include "migration-stats.h"
#include "trace.h"
#include "monitor/hmp.h"
#include "monitor/monitor.h"
#include "qapi/qmp/qdict.h"
-#include "sysemu/kvm.h"
-#include "sysemu/runstate.h"
+#include "system/kvm.h"
+#include "system/runstate.h"
#include "exec/memory.h"
#include "qemu/xxhash.h"
#include "migration.h"
#ifndef QEMU_MIGRATION_DIRTYRATE_H
#define QEMU_MIGRATION_DIRTYRATE_H
-#include "sysemu/dirtyrate.h"
+#include "system/dirtyrate.h"
/*
* Sample 512 pages per GB as default.
#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "qemu/error-report.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "qapi/error.h"
#include "migration.h"
#include "migration/global_state.h"
#include "qemu/cutils.h"
#include "qemu/error-report.h"
#include "qemu/sockets.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "ui/qemu-spice.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "options.h"
#include "migration.h"
#include "fd.h"
#include "file.h"
#include "socket.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/cpu-throttle.h"
+#include "system/runstate.h"
+#include "system/system.h"
+#include "system/cpu-throttle.h"
#include "rdma.h"
#include "ram.h"
#include "migration/global_state.h"
#include "multifd.h"
#include "threadinfo.h"
#include "qemu/yank.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
#include "yank_functions.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
#include "options.h"
-#include "sysemu/dirtylimit.h"
+#include "system/dirtylimit.h"
#include "qemu/sockets.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#define NOTIFIER_ELEM_INIT(array, elem) \
[elem] = NOTIFIER_WITH_RETURN_LIST_INITIALIZER((array)[elem])
#include "net/announce.h"
#include "qom/object.h"
#include "postcopy-ram.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "migration/misc.h"
#define MIGRATION_THREAD_SNAPSHOT "mig/snapshot"
#include "qemu/cutils.h"
#include "qemu/rcu.h"
#include "exec/target_page.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "exec/ramblock.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qapi/qapi-visit-migration.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qnull.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "migration/colo.h"
#include "migration/misc.h"
#include "migration.h"
#include "qemu-file.h"
#include "ram.h"
#include "options.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
/* Maximum migrate downtime set to 2000 seconds */
#define MAX_MIGRATE_DOWNTIME_SECONDS 2000
#include "qapi/error.h"
#include "qemu/notify.h"
#include "qemu/rcu.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qemu/error-report.h"
#include "trace.h"
#include "hw/boards.h"
#include "exec/target_page.h"
#include "qemu/rcu_queue.h"
#include "migration/colo.h"
-#include "sysemu/cpu-throttle.h"
+#include "system/cpu-throttle.h"
#include "savevm.h"
#include "qemu/iov.h"
#include "multifd.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "rdma.h"
#include "options.h"
-#include "sysemu/dirtylimit.h"
-#include "sysemu/kvm.h"
+#include "system/dirtylimit.h"
+#include "system/kvm.h"
#include "hw/boards.h" /* for machine_dump_guest_core() */
#include "qapi/clone-visitor.h"
#include "qapi/qapi-builtin-visit.h"
#include "qemu/error-report.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
#include "exec/memory.h"
#include "exec/target_page.h"
#include "trace.h"
#include "qemu/cutils.h"
#include "io/channel-buffer.h"
#include "io/channel-file.h"
-#include "sysemu/replay.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/xen.h"
+#include "system/replay.h"
+#include "system/runstate.h"
+#include "system/system.h"
+#include "system/xen.h"
#include "migration/colo.h"
#include "qemu/bitmap.h"
#include "net/announce.h"
#include "qemu/yank.h"
#include "yank_functions.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
#include "options.h"
const unsigned int postcopy_ram_discard_version;
#include "qapi/qmp/qerror.h"
#include "qemu/ctype.h"
#include "qemu/cutils.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
/* file descriptors passed via SCM_RIGHTS */
typedef struct mon_fd_t mon_fd_t;
#include "monitor/monitor-internal.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
-#include "sysemu/hw_accel.h"
+#include "system/hw_accel.h"
/* Set the current CPU defined by the user. Callers must hold BQL. */
int monitor_set_cpu(Monitor *mon, int cpu_index)
#include "qapi/qmp/qdict.h"
#include "qemu/cutils.h"
#include "qemu/log.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
bool hmp_handle_error(Monitor *mon, Error *err)
{
#include "monitor-internal.h"
#include "monitor/qdev.h"
#include "net/slirp.h"
-#include "sysemu/device_tree.h"
+#include "system/device_tree.h"
#include "monitor/hmp-target.h"
#include "monitor/hmp.h"
#include "block/block-hmp-cmds.h"
#include "qemu/log.h"
#include "qemu/option.h"
#include "qemu/units.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "trace.h"
static void monitor_command_cb(void *opaque, const char *cmdline,
#include "qapi/qmp/dispatch.h"
#include "qapi/qmp/json-parser.h"
#include "qemu/readline.h"
-#include "sysemu/iothread.h"
+#include "system/iothread.h"
/*
* Supported types:
#include "qapi/qmp/qdict.h"
#include "qemu/error-report.h"
#include "qemu/option.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
#include "trace.h"
/*
/*
- * QMP commands related to the monitor (common to sysemu and tools)
+ * QMP commands related to the monitor (common to system and tools)
*
* Copyright (c) 2003-2004 Fabrice Bellard
*
#include "monitor-internal.h"
#include "monitor/qdev.h"
#include "monitor/qmp-helpers.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/kvm.h"
-#include "sysemu/runstate.h"
-#include "sysemu/runstate-action.h"
-#include "sysemu/block-backend.h"
+#include "system/system.h"
+#include "system/kvm.h"
+#include "system/runstate.h"
+#include "system/runstate-action.h"
+#include "system/block-backend.h"
#include "qapi/error.h"
#include "qapi/qapi-init-commands.h"
#include "qapi/qapi-commands-control.h"
#ifndef NBD_INTERNAL_H
#define NBD_INTERNAL_H
#include "block/nbd.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "io/channel-tls.h"
#include "qemu/iov.h"
#include "chardev/char-fe.h"
#include "qemu/sockets.h"
#include "colo.h"
-#include "sysemu/iothread.h"
+#include "system/iothread.h"
#include "net/colo-compare.h"
#include "migration/colo.h"
#include "util.h"
#include "qapi/visitor.h"
#include "net/filter.h"
#include "qom/object.h"
-#include "sysemu/rtc.h"
+#include "system/rtc.h"
typedef struct DumpState {
int64_t start_ts;
#include "qemu/timer.h"
#include "qapi/visitor.h"
#include "net/filter.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "qom/object.h"
#define TYPE_FILTER_REPLAY "filter-replay"
#include "hub.h"
#include "qemu/iov.h"
#include "qemu/error-report.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
/*
* A hub broadcasts incoming packets to all its ports except the source port.
#include "qemu/keyval.h"
#include "qapi/error.h"
#include "qapi/opts-visitor.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "net/colo-compare.h"
#include "net/filter.h"
#include "qapi/string-output-visitor.h"
#include "qemu/sockets.h"
#include <libslirp.h>
#include "chardev/char-fe.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "net/net.h"
#include "clients.h"
#include "monitor/monitor.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qapi/error.h"
#include "qemu/cutils.h"
#include "qemu/error-report.h"
#include "clients.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include <vmnet/vmnet.h>
#include <dispatch/dispatch.h>
#include "qemu/error-report.h"
#include "qemu/log.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "qemu/cutils.h"
#ifdef CONFIG_LINUX
#include "qemu/osdep.h"
#include <windows.h>
#include <mmsystem.h>
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
static BOOL WINAPI qemu_ctrl_handler(DWORD type)
{
#include "qemu/units.h"
#include "qemu/memalign.h"
#include "qom/object_interfaces.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "block/block_int.h"
#include "block/blockjob.h"
#include "block/dirty-bitmap.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "qemu-io.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "block/block.h"
#include "block/block_int.h" /* for info_f() */
#include "block/qapi.h"
#include "qapi/qmp/qstring.h"
#include "qapi/qmp/qdict.h"
#include "qom/object_interfaces.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "block/block_int.h"
#include "trace/control.h"
#include "crypto/init.h"
#include "qemu/help-texts.h"
#include "qapi/error.h"
#include "qemu/cutils.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/runstate.h" /* for qemu_system_killed() prototype */
+#include "system/block-backend.h"
+#include "system/runstate.h" /* for qemu_system_killed() prototype */
#include "block/block_int.h"
#include "block/nbd.h"
#include "qemu/main-loop.h"
#include "qemu/osdep.h"
#include "qemu/error-report.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "replay-internal.h"
#include "audio/audio.h"
#include "qemu/osdep.h"
#include "qemu/error-report.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "replay-internal.h"
#include "chardev/char.h"
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "sysemu/replay.h"
-#include "sysemu/runstate.h"
+#include "system/replay.h"
+#include "system/runstate.h"
#include "replay-internal.h"
#include "monitor/hmp.h"
#include "monitor/monitor.h"
#include "qemu/osdep.h"
#include "qemu/error-report.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "replay-internal.h"
#include "block/aio.h"
#include "ui/input.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "replay-internal.h"
#include "qemu/notify.h"
#include "ui/input.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/replay.h"
-#include "sysemu/runstate.h"
+#include "system/replay.h"
+#include "system/runstate.h"
#include "replay-internal.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qemu/osdep.h"
#include "qemu/error-report.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "replay-internal.h"
#include "net/net.h"
#include "net/filter.h"
#include "qemu/osdep.h"
#include "qemu/error-report.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "replay-internal.h"
void replay_save_random(int ret, void *buf, size_t len)
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "replay-internal.h"
#include "monitor/monitor.h"
#include "qapi/qmp/qstring.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "replay-internal.h"
#include "qemu/error-report.h"
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "sysemu/cpu-timers.h"
-#include "sysemu/replay.h"
-#include "sysemu/runstate.h"
+#include "system/cpu-timers.h"
+#include "system/replay.h"
+#include "system/runstate.h"
#include "replay-internal.h"
#include "qemu/main-loop.h"
#include "qemu/option.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
#include "qemu/error-report.h"
/* Current version of the replay mechanism.
#include "qemu/osdep.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "ui/input.h"
void replay_input_event(QemuConsole *src, InputEvent *evt)
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "qemu-io.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/sysbus.h"
#include "exec/memory.h"
#include "chardev/char-fe.h"
*include/qemu/compiler.h | \
*include/qemu/qemu-plugin.h | \
*include/glib-compat.h | \
- *include/sysemu/os-posix.h | \
- *include/sysemu/os-win32.h | \
+ *include/system/os-posix.h | \
+ *include/system/os-win32.h | \
*include/standard-headers/ )
# Removing include lines from osdep.h itself would be counterproductive.
echo "SKIPPING $f (special case header)"
<limits.h> <unistd.h> <time.h> <ctype.h> <errno.h> <fcntl.h>
<sys/stat.h> <sys/time.h> <assert.h> <signal.h> <glib.h>
<sys/stat.h> <sys/time.h> <assert.h> <signal.h> <glib.h> <sys/mman.h>
- "sysemu/os-posix.h, sysemu/os-win32.h "glib-compat.h"
+ "system/os-posix.h, system/os-win32.h "glib-compat.h"
"qemu/typedefs.h"
))' "$f"
#include "hw/pci/pci.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
-#include "sysemu/dma.h"
+#include "system/dma.h"
/* Missing stuff:
SCTRL_P[12](END|ST)INC
m = InitialIncludes.domatch(c)
assert m
print(repr(m.group(0)))
- assert m.group(0).endswith('#include "sysemu/dma.h"\n')
+ assert m.group(0).endswith('#include "system/dma.h"\n')
~ .*/qemu((/include)?/chardev/.*)
crypto
- ~ .*/qemu((/include)?/crypto/.*|/hw/.*/.*crypto.*|(/include/sysemu|/backends)/cryptodev.*|/host/include/.*/host/crypto/.*)
+ ~ .*/qemu((/include)?/crypto/.*|/hw/.*/.*crypto.*|(/include/system|/backends)/cryptodev.*|/host/include/.*/host/crypto/.*)
disas
~ .*/qemu((/include)?/disas.*)
tcg
~ .*/qemu(/accel/tcg|/replay|/tcg)/.*
-sysemu
+system
~ .*/qemu(/system/.*|/accel/.*)
(headers)
*/
#include "qemu/osdep.h"
-#include "sysemu/stats.h"
+#include "system/stats.h"
#include "qapi/qapi-commands-stats.h"
#include "qemu/queue.h"
#include "qapi/error.h"
#include "storage-daemon/qapi/qapi-commands.h"
#include "storage-daemon/qapi/qapi-init-commands.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "trace/control.h"
static const char *pid_file;
#include "qemu/osdep.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
int blk_commit_all(void)
{
#include "qemu/osdep.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
void *opaque)
#include "qemu/osdep.h"
-#include "sysemu/cpu-timers.h"
+#include "system/cpu-timers.h"
#include "qemu/main-loop.h"
int64_t cpu_get_clock(void)
#include "qemu/osdep.h"
-#include "sysemu/hw_accel.h"
+#include "system/hw_accel.h"
void cpu_synchronize_state(CPUState *cpu)
{
#include "qemu/osdep.h"
-#include "sysemu/cpu-timers.h"
+#include "system/cpu-timers.h"
#include "qemu/main-loop.h"
int64_t cpus_get_virtual_clock(void)
*/
#include "qemu/osdep.h"
-#include "sysemu/dump-arch.h"
+#include "system/dump-arch.h"
int cpu_get_dump_info(ArchDumpInfo *info,
const struct GuestPhysBlockList *guest_phys_blocks)
#include "qemu/osdep.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
const char *qemu_get_vm_name(void)
{
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "sysemu/cpu-timers.h"
+#include "system/cpu-timers.h"
/* icount - Instruction Counter API */
#include "qemu/osdep.h"
-#include "sysemu/cpu-timers.h"
+#include "system/cpu-timers.h"
#include "qemu/main-loop.h"
void qemu_timer_notify_cb(void *opaque, QEMUClockType type)
*/
#include "qemu/osdep.h"
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
/* Needed for qtest_allowed() */
bool qtest_allowed;
#include "qemu/osdep.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
ReplayMode replay_mode;
#include "qemu/osdep.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "block/aio.h"
bool replay_events_enabled(void)
#include "qemu/osdep.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
bool runstate_check(RunState state)
{
return state == RUN_STATE_PRELAUNCH;
#include "qemu/osdep.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
void qemu_system_vmstop_request_prepare(void)
{
abort();
*/
#include "qemu/osdep.h"
#include "qemu/module.h"
-#include "sysemu/arch_init.h"
+#include "system/arch_init.h"
#ifdef TARGET_SPARC
int graphic_width = 1024;
#include "qemu/osdep.h"
#include "qemu/atomic.h"
-#include "sysemu/kvm.h"
-#include "sysemu/balloon.h"
+#include "system/kvm.h"
+#include "system/balloon.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-machine.h"
#include "qapi/qmp/qerror.h"
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qapi/visitor.h"
#include "qemu/error-report.h"
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "hw/qdev-core.h"
#include "hw/boards.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
#include "qemu/main-loop.h"
#include "qemu/option.h"
#include "qemu/seqlock.h"
-#include "sysemu/replay.h"
-#include "sysemu/runstate.h"
+#include "system/replay.h"
+#include "system/runstate.h"
#include "hw/core/cpu.h"
-#include "sysemu/cpu-timers.h"
-#include "sysemu/cpu-timers-internal.h"
+#include "system/cpu-timers.h"
+#include "system/cpu-timers-internal.h"
/* clock and ticks */
#include "qapi/qapi-events-run-state.h"
#include "qapi/qmp/qerror.h"
#include "exec/gdbstub.h"
-#include "sysemu/hw_accel.h"
+#include "system/hw_accel.h"
#include "exec/cpu-common.h"
#include "qemu/thread.h"
#include "qemu/main-loop.h"
#include "qemu/plugin.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
#include "qemu/guest-random.h"
#include "hw/nmi.h"
-#include "sysemu/replay.h"
-#include "sysemu/runstate.h"
-#include "sysemu/cpu-timers.h"
-#include "sysemu/whpx.h"
+#include "system/replay.h"
+#include "system/runstate.h"
+#include "system/cpu-timers.h"
+#include "system/whpx.h"
#include "hw/boards.h"
#include "hw/hw.h"
#include "trace.h"
#include "qemu/bswap.h"
#include "qemu/cutils.h"
#include "qemu/guest-random.h"
-#include "sysemu/device_tree.h"
+#include "system/device_tree.h"
#include "hw/loader.h"
#include "hw/boards.h"
#include "qemu/config-file.h"
#include "qapi/qapi-commands-migration.h"
#include "qapi/qmp/qdict.h"
#include "qapi/error.h"
-#include "sysemu/dirtyrate.h"
-#include "sysemu/dirtylimit.h"
+#include "system/dirtyrate.h"
+#include "system/dirtylimit.h"
#include "monitor/hmp.h"
#include "monitor/monitor.h"
#include "exec/memory.h"
#include "exec/target_page.h"
#include "hw/boards.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "trace.h"
#include "migration/misc.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/dma.h"
+#include "system/block-backend.h"
+#include "system/dma.h"
#include "trace.h"
#include "qemu/thread.h"
#include "qemu/main-loop.h"
-#include "sysemu/cpu-timers.h"
+#include "system/cpu-timers.h"
#include "qemu/range.h"
/* #define DEBUG_IOMMU */
#include "hw/loader.h"
#include "hw/xen/xen.h"
#include "net/net.h"
-#include "sysemu/cpus.h"
-#include "sysemu/sysemu.h"
+#include "system/cpus.h"
+#include "system/system.h"
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
int display_opengl;
#include "qemu/osdep.h"
#include "qemu-main.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#ifdef CONFIG_SDL
#include <SDL.h>
#include "exec/memory-internal.h"
#include "exec/ram_addr.h"
-#include "sysemu/kvm.h"
-#include "sysemu/runstate.h"
-#include "sysemu/tcg.h"
+#include "system/kvm.h"
+#include "system/runstate.h"
+#include "system/tcg.h"
#include "qemu/accel.h"
#include "hw/boards.h"
#include "migration/vmstate.h"
#include "qemu/range.h"
#include "qapi/error.h"
-#include "sysemu/memory_mapping.h"
+#include "system/memory_mapping.h"
#include "exec/memory.h"
#include "exec/address-spaces.h"
#include "hw/core/cpu.h"
#include "hw/qdev-core.h"
#include "hw/qdev-properties.h"
#include "hw/boards.h"
-#include "sysemu/xen.h"
-#include "sysemu/kvm.h"
-#include "sysemu/tcg.h"
-#include "sysemu/qtest.h"
+#include "system/xen.h"
+#include "system/kvm.h"
+#include "system/tcg.h"
+#include "system/qtest.h"
#include "qemu/timer.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "qemu/memalign.h"
#include "exec/memory.h"
#include "exec/ioport.h"
-#include "sysemu/dma.h"
-#include "sysemu/hostmem.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/xen-mapcache.h"
+#include "system/dma.h"
+#include "system/hostmem.h"
+#include "system/hw_accel.h"
+#include "system/xen-mapcache.h"
#include "trace.h"
#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
#include "qemu/rcu_queue.h"
#include "qemu/main-loop.h"
#include "exec/translate-all.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "exec/memory-internal.h"
#include "exec/ram_addr.h"
#include "monitor/hmp.h"
#include "monitor/monitor.h"
#include "monitor/qdev.h"
-#include "sysemu/arch_init.h"
-#include "sysemu/runstate.h"
+#include "system/arch_init.h"
+#include "system/runstate.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-qdev.h"
#include "qapi/qmp/dispatch.h"
#include "qemu/option.h"
#include "qemu/qemu-print.h"
#include "qemu/option_int.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "migration/misc.h"
#include "qemu/cutils.h"
#include "hw/qdev-properties.h"
#include "qemu/module.h"
#include <sys/prctl.h>
#include <seccomp.h>
-#include "sysemu/seccomp.h"
+#include "system/seccomp.h"
#include <linux/seccomp.h>
/* For some architectures (notably ARM) cacheflush is not supported until
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "sysemu/qtest.h"
-#include "sysemu/runstate.h"
+#include "system/qtest.h"
+#include "system/runstate.h"
#include "chardev/char-fe.h"
#include "exec/ioport.h"
#include "exec/memory.h"
#include "hw/irq.h"
#include "hw/core/cpu.h"
#include "qemu/accel.h"
-#include "sysemu/cpu-timers.h"
+#include "system/cpu-timers.h"
#include "qemu/config-file.h"
#include "qemu/option.h"
#include "qemu/error-report.h"
#include "qemu/option.h"
#include "qemu/timer.h"
#include "qom/object.h"
-#include "sysemu/replay.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/rtc.h"
+#include "system/replay.h"
+#include "system/system.h"
+#include "system/rtc.h"
#include "hw/rtc/mc146818rtc.h"
static enum {
*/
#include "qemu/osdep.h"
-#include "sysemu/runstate-action.h"
-#include "sysemu/watchdog.h"
+#include "system/runstate-action.h"
+#include "system/watchdog.h"
#include "qemu/config-file.h"
#include "qapi/error.h"
#include "qemu/option_int.h"
#include "qemu/thread.h"
#include "qom/object.h"
#include "qom/object_interfaces.h"
-#include "sysemu/cpus.h"
-#include "sysemu/qtest.h"
-#include "sysemu/replay.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
-#include "sysemu/runstate-action.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/tpm.h"
+#include "system/cpus.h"
+#include "system/qtest.h"
+#include "system/replay.h"
+#include "system/reset.h"
+#include "system/runstate.h"
+#include "system/runstate-action.h"
+#include "system/system.h"
+#include "system/tpm.h"
#include "trace.h"
static NotifierList exit_notifiers =
#include "qapi/error.h"
#include "qapi/qapi-commands-tpm.h"
#include "qapi/qmp/qerror.h"
-#include "sysemu/tpm_backend.h"
-#include "sysemu/tpm.h"
+#include "system/tpm_backend.h"
+#include "system/tpm.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "qemu/help_option.h"
#include "qemu/hw-version.h"
#include "qemu/uuid.h"
-#include "sysemu/reset.h"
-#include "sysemu/runstate.h"
-#include "sysemu/runstate-action.h"
-#include "sysemu/seccomp.h"
-#include "sysemu/tcg.h"
-#include "sysemu/xen.h"
+#include "system/reset.h"
+#include "system/runstate.h"
+#include "system/runstate-action.h"
+#include "system/seccomp.h"
+#include "system/tcg.h"
+#include "system/xen.h"
#include "qemu/error-report.h"
#include "qemu/sockets.h"
#include "monitor/monitor.h"
#include "ui/console.h"
#include "ui/input.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/numa.h"
-#include "sysemu/hostmem.h"
+#include "system/system.h"
+#include "system/numa.h"
+#include "system/hostmem.h"
#include "exec/gdbstub.h"
#include "gdbstub/enums.h"
#include "qemu/timer.h"
#include "chardev/char.h"
#include "qemu/bitmap.h"
#include "qemu/log.h"
-#include "sysemu/blockdev.h"
+#include "system/blockdev.h"
#include "hw/block/block.h"
#include "hw/i386/x86.h"
#include "hw/i386/pc.h"
#include "migration/misc.h"
#include "migration/snapshot.h"
-#include "sysemu/tpm.h"
-#include "sysemu/dma.h"
+#include "system/tpm.h"
+#include "system/dma.h"
#include "hw/audio/soundhw.h"
#include "audio/audio.h"
-#include "sysemu/cpus.h"
-#include "sysemu/cpu-timers.h"
+#include "system/cpus.h"
+#include "system/cpu-timers.h"
#include "migration/colo.h"
#include "migration/postcopy-ram.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "qapi/qobject-input-visitor.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
#ifdef CONFIG_VIRTFS
#include "fsdev/qemu-fsdev.h"
#endif
-#include "sysemu/qtest.h"
+#include "system/qtest.h"
#ifdef CONFIG_TCG
#include "tcg/perf.h"
#endif
#include "trace/control.h"
#include "qemu/plugin.h"
#include "qemu/queue.h"
-#include "sysemu/arch_init.h"
+#include "system/arch_init.h"
#include "exec/confidential-guest-support.h"
#include "ui/qemu-spice.h"
#include "qom/object_interfaces.h"
#include "semihosting/semihost.h"
#include "crypto/init.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
#include "qapi/qapi-events-run-state.h"
#include "qapi/qapi-types-audio.h"
#include "qapi/qapi-visit-audio.h"
#include "qapi/qapi-commands-ui.h"
#include "block/qdict.h"
#include "qapi/qmp/qerror.h"
-#include "sysemu/iothread.h"
+#include "system/iothread.h"
#include "qemu/guest-random.h"
#include "qemu/keyval.h"
#include "exec/exec-all.h"
#include "exec/tb-flush.h"
#include "exec/helper-proto.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
+#include "system/runstate.h"
+#include "system/system.h"
#include "qemu/timer.h"
#include "qemu/osdep.h"
#include "cpu.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
#include "qemu/host-utils.h"
#include "exec/exec-all.h"
#include "tcg/tcg-op.h"
#include "qemu/osdep.h"
#include "cpu.h"
#include "elf.h"
-#include "sysemu/dump.h"
+#include "system/dump.h"
#include "cpu-features.h"
/* struct user_pt_regs from arch/arm64/include/uapi/asm/ptrace.h */
#include "arm-powerctl.h"
#include "qemu/log.h"
#include "qemu/main-loop.h"
-#include "sysemu/tcg.h"
+#include "system/tcg.h"
#include "target/arm/multiprocessing.h"
#ifndef DEBUG_ARM_POWERCTL
#include "hw/intc/armv7m_nvic.h"
#endif /* CONFIG_TCG */
#endif /* !CONFIG_USER_ONLY */
-#include "sysemu/tcg.h"
-#include "sysemu/qtest.h"
-#include "sysemu/hw_accel.h"
+#include "system/tcg.h"
+#include "system/qtest.h"
+#include "system/hw_accel.h"
#include "kvm_arm.h"
#include "disas/capstone.h"
#include "fpu/softfloat.h"
#include "cpregs.h"
#include "qemu/module.h"
#include "qemu/units.h"
-#include "sysemu/kvm.h"
-#include "sysemu/hvf.h"
-#include "sysemu/qtest.h"
-#include "sysemu/tcg.h"
+#include "system/kvm.h"
+#include "system/hvf.h"
+#include "system/qtest.h"
+#include "system/tcg.h"
#include "kvm_arm.h"
#include "hvf_arm.h"
#include "qapi/visitor.h"
#include "cpregs.h"
#include "exec/exec-all.h"
#include "exec/helper-proto.h"
-#include "sysemu/tcg.h"
+#include "system/tcg.h"
#ifdef CONFIG_TCG
/* Return the Exception Level targeted by debug exceptions. */
#include "exec/gdbstub.h"
#include "gdbstub/helpers.h"
#include "gdbstub/commands.h"
-#include "sysemu/tcg.h"
+#include "system/tcg.h"
#include "internals.h"
#include "cpu-features.h"
#include "cpregs.h"
#include "exec/exec-all.h"
#include <zlib.h> /* for crc32 */
#include "hw/irq.h"
-#include "sysemu/cpu-timers.h"
-#include "sysemu/kvm.h"
-#include "sysemu/tcg.h"
+#include "system/cpu-timers.h"
+#include "system/kvm.h"
+#include "system/tcg.h"
#include "qapi/error.h"
#include "qemu/guest-random.h"
#ifdef CONFIG_TCG
#include "qemu/error-report.h"
#include "qemu/log.h"
-#include "sysemu/runstate.h"
-#include "sysemu/hvf.h"
-#include "sysemu/hvf_int.h"
-#include "sysemu/hw_accel.h"
+#include "system/runstate.h"
+#include "system/hvf.h"
+#include "system/hvf_int.h"
+#include "system/hw_accel.h"
#include "hvf_arm.h"
#include "cpregs.h"
#include "hw/boards.h"
#include "hw/irq.h"
#include "qemu/main-loop.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
#include "arm-powerctl.h"
#include "target/arm/cpu.h"
#include "target/arm/internals.h"
#include "qemu/main-loop.h"
#include "qom/object.h"
#include "qapi/error.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/runstate.h"
-#include "sysemu/kvm.h"
-#include "sysemu/kvm_int.h"
+#include "system/system.h"
+#include "system/runstate.h"
+#include "system/kvm.h"
+#include "system/kvm_int.h"
#include "kvm_arm.h"
#include "cpu.h"
#include "trace.h"
#ifndef QEMU_KVM_ARM_H
#define QEMU_KVM_ARM_H
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#define KVM_ARM_VGIC_V2 (1 << 0)
#define KVM_ARM_VGIC_V3 (1 << 1)
#include "qemu/osdep.h"
#include "cpu.h"
#include "qemu/error-report.h"
-#include "sysemu/kvm.h"
-#include "sysemu/tcg.h"
+#include "system/kvm.h"
+#include "system/tcg.h"
#include "kvm_arm.h"
#include "internals.h"
#include "cpu-features.h"
#include "exec/helper-proto.h"
#include "kvm-consts.h"
#include "qemu/main-loop.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "internals.h"
#include "arm-powerctl.h"
#include "target/arm/multiprocessing.h"
#include "exec/exec-all.h"
#include "exec/helper-proto.h"
#include "qemu/timer.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
+#include "system/runstate.h"
+#include "system/system.h"
#include "chardev/char-fe.h"
void HELPER(write_interval_timer)(CPUHPPAState *env, target_ulong val)
#include "qemu/osdep.h"
#include "cpu.h"
-#include "sysemu/dump.h"
+#include "system/dump.h"
#include "elf.h"
-#include "sysemu/memory_mapping.h"
+#include "system/memory_mapping.h"
#define ELF_NOTE_SIZE(hdr_size, name_size, desc_size) \
((DIV_ROUND_UP((hdr_size), 4) \
#include "qemu/osdep.h"
#include "cpu.h"
-#include "sysemu/memory_mapping.h"
+#include "system/memory_mapping.h"
/* PAE Paging or IA-32e Paging */
static void walk_pte(MemoryMappingList *list, AddressSpace *as,
#include "qapi/error.h"
#include "monitor/monitor.h"
#include "monitor/hmp-target.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/kvm.h"
-#include "sysemu/xen.h"
+#include "system/hw_accel.h"
+#include "system/kvm.h"
+#include "system/xen.h"
#include "exec/address-spaces.h"
#include "hw/qdev-properties.h"
#include "hw/i386/apic_internal.h"
/*
- * i386 CPU internal definitions to be shared between cpu.c and cpu-sysemu.c
+ * i386 CPU internal definitions to be shared between cpu.c and cpu-system.c
*
* Copyright (c) 2003 Fabrice Bellard
*
+++ /dev/null
-/*
- * i386 CPUID, CPU class, definitions, models: sysemu-only code
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * 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.1 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 "qapi/error.h"
-#include "qapi/qapi-visit-run-state.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi/qobject-input-visitor.h"
-#include "qom/qom-qobject.h"
-#include "qapi/qapi-commands-machine-target.h"
-
-#include "cpu-internal.h"
-
-/* Return a QDict containing keys for all properties that can be included
- * in static expansion of CPU models. All properties set by x86_cpu_load_model()
- * must be included in the dictionary.
- */
-static QDict *x86_cpu_static_props(void)
-{
- FeatureWord w;
- int i;
- static const char *props[] = {
- "min-level",
- "min-xlevel",
- "family",
- "model",
- "stepping",
- "model-id",
- "vendor",
- "lmce",
- NULL,
- };
- static QDict *d;
-
- if (d) {
- return d;
- }
-
- d = qdict_new();
- for (i = 0; props[i]; i++) {
- qdict_put_null(d, props[i]);
- }
-
- for (w = 0; w < FEATURE_WORDS; w++) {
- FeatureWordInfo *fi = &feature_word_info[w];
- int bit;
- for (bit = 0; bit < 64; bit++) {
- if (!fi->feat_names[bit]) {
- continue;
- }
- qdict_put_null(d, fi->feat_names[bit]);
- }
- }
-
- return d;
-}
-
-/* Add an entry to @props dict, with the value for property. */
-static void x86_cpu_expand_prop(X86CPU *cpu, QDict *props, const char *prop)
-{
- QObject *value = object_property_get_qobject(OBJECT(cpu), prop,
- &error_abort);
-
- qdict_put_obj(props, prop, value);
-}
-
-/* Convert CPU model data from X86CPU object to a property dictionary
- * that can recreate exactly the same CPU model.
- */
-static void x86_cpu_to_dict(X86CPU *cpu, QDict *props)
-{
- QDict *sprops = x86_cpu_static_props();
- const QDictEntry *e;
-
- for (e = qdict_first(sprops); e; e = qdict_next(sprops, e)) {
- const char *prop = qdict_entry_key(e);
- x86_cpu_expand_prop(cpu, props, prop);
- }
-}
-
-/* Convert CPU model data from X86CPU object to a property dictionary
- * that can recreate exactly the same CPU model, including every
- * writable QOM property.
- */
-static void x86_cpu_to_dict_full(X86CPU *cpu, QDict *props)
-{
- ObjectPropertyIterator iter;
- ObjectProperty *prop;
-
- object_property_iter_init(&iter, OBJECT(cpu));
- while ((prop = object_property_iter_next(&iter))) {
- /* skip read-only or write-only properties */
- if (!prop->get || !prop->set) {
- continue;
- }
-
- /* "hotplugged" is the only property that is configurable
- * on the command-line but will be set differently on CPUs
- * created using "-cpu ... -smp ..." and by CPUs created
- * on the fly by x86_cpu_from_model() for querying. Skip it.
- */
- if (!strcmp(prop->name, "hotplugged")) {
- continue;
- }
- x86_cpu_expand_prop(cpu, props, prop->name);
- }
-}
-
-static void object_apply_props(Object *obj, QObject *props,
- const char *props_arg_name, Error **errp)
-{
- Visitor *visitor;
- QDict *qdict;
- const QDictEntry *prop;
-
- visitor = qobject_input_visitor_new(props);
- if (!visit_start_struct(visitor, props_arg_name, NULL, 0, errp)) {
- visit_free(visitor);
- return;
- }
-
- qdict = qobject_to(QDict, props);
- for (prop = qdict_first(qdict); prop; prop = qdict_next(qdict, prop)) {
- if (!object_property_set(obj, qdict_entry_key(prop),
- visitor, errp)) {
- goto out;
- }
- }
-
- visit_check_struct(visitor, errp);
-out:
- visit_end_struct(visitor, NULL);
- visit_free(visitor);
-}
-
-/* Create X86CPU object according to model+props specification */
-static X86CPU *x86_cpu_from_model(const char *model, QObject *props,
- const char *props_arg_name, Error **errp)
-{
- X86CPU *xc = NULL;
- X86CPUClass *xcc;
- Error *err = NULL;
-
- xcc = X86_CPU_CLASS(cpu_class_by_name(TYPE_X86_CPU, model));
- if (xcc == NULL) {
- error_setg(&err, "CPU model '%s' not found", model);
- goto out;
- }
-
- xc = X86_CPU(object_new_with_class(OBJECT_CLASS(xcc)));
- if (props) {
- object_apply_props(OBJECT(xc), props, props_arg_name, &err);
- if (err) {
- goto out;
- }
- }
-
- x86_cpu_expand_features(xc, &err);
- if (err) {
- goto out;
- }
-
-out:
- if (err) {
- error_propagate(errp, err);
- object_unref(OBJECT(xc));
- xc = NULL;
- }
- return xc;
-}
-
-CpuModelExpansionInfo *
-qmp_query_cpu_model_expansion(CpuModelExpansionType type,
- CpuModelInfo *model,
- Error **errp)
-{
- X86CPU *xc = NULL;
- Error *err = NULL;
- CpuModelExpansionInfo *ret = g_new0(CpuModelExpansionInfo, 1);
- QDict *props = NULL;
- const char *base_name;
-
- xc = x86_cpu_from_model(model->name, model->props, "model.props", &err);
- if (err) {
- goto out;
- }
-
- props = qdict_new();
- ret->model = g_new0(CpuModelInfo, 1);
- ret->model->props = QOBJECT(props);
-
- switch (type) {
- case CPU_MODEL_EXPANSION_TYPE_STATIC:
- /* Static expansion will be based on "base" only */
- base_name = "base";
- x86_cpu_to_dict(xc, props);
- break;
- case CPU_MODEL_EXPANSION_TYPE_FULL:
- /* As we don't return every single property, full expansion needs
- * to keep the original model name+props, and add extra
- * properties on top of that.
- */
- base_name = model->name;
- x86_cpu_to_dict_full(xc, props);
- break;
- default:
- error_setg(&err, "Unsupported expansion type");
- goto out;
- }
-
- x86_cpu_to_dict(xc, props);
-
- ret->model->name = g_strdup(base_name);
-
-out:
- object_unref(OBJECT(xc));
- if (err) {
- error_propagate(errp, err);
- qapi_free_CpuModelExpansionInfo(ret);
- ret = NULL;
- }
- return ret;
-}
-
-void cpu_clear_apic_feature(CPUX86State *env)
-{
- env->features[FEAT_1_EDX] &= ~CPUID_APIC;
-}
-
-void cpu_set_apic_feature(CPUX86State *env)
-{
- env->features[FEAT_1_EDX] |= CPUID_APIC;
-}
-
-bool cpu_has_x2apic_feature(CPUX86State *env)
-{
- return env->features[FEAT_1_ECX] & CPUID_EXT_X2APIC;
-}
-
-bool cpu_is_bsp(X86CPU *cpu)
-{
- return cpu_get_apic_base(cpu->apic_state) & MSR_IA32_APICBASE_BSP;
-}
-
-/* TODO: remove me, when reset over QOM tree is implemented */
-void x86_cpu_machine_reset_cb(void *opaque)
-{
- X86CPU *cpu = opaque;
- cpu_reset(CPU(cpu));
-}
-
-GuestPanicInformation *x86_cpu_get_crash_info(CPUState *cs)
-{
- X86CPU *cpu = X86_CPU(cs);
- CPUX86State *env = &cpu->env;
- GuestPanicInformation *panic_info = NULL;
-
- if (hyperv_feat_enabled(cpu, HYPERV_FEAT_CRASH)) {
- panic_info = g_new0(GuestPanicInformation, 1);
-
- panic_info->type = GUEST_PANIC_INFORMATION_TYPE_HYPER_V;
-
- assert(HV_CRASH_PARAMS >= 5);
- panic_info->u.hyper_v.arg1 = env->msr_hv_crash_params[0];
- panic_info->u.hyper_v.arg2 = env->msr_hv_crash_params[1];
- panic_info->u.hyper_v.arg3 = env->msr_hv_crash_params[2];
- panic_info->u.hyper_v.arg4 = env->msr_hv_crash_params[3];
- panic_info->u.hyper_v.arg5 = env->msr_hv_crash_params[4];
- }
-
- return panic_info;
-}
-void x86_cpu_get_crash_info_qom(Object *obj, Visitor *v,
- const char *name, void *opaque,
- Error **errp)
-{
- CPUState *cs = CPU(obj);
- GuestPanicInformation *panic_info;
-
- if (!cs->crash_occurred) {
- error_setg(errp, "No crash occurred");
- return;
- }
-
- panic_info = x86_cpu_get_crash_info(cs);
- if (panic_info == NULL) {
- error_setg(errp, "No crash information");
- return;
- }
-
- visit_type_GuestPanicInformation(v, "crash-information", &panic_info,
- errp);
- qapi_free_GuestPanicInformation(panic_info);
-}
--- /dev/null
+/*
+ * i386 CPUID, CPU class, definitions, models: system-only code
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * 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.1 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 "qapi/error.h"
+#include "qapi/qapi-visit-run-state.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qobject-input-visitor.h"
+#include "qom/qom-qobject.h"
+#include "qapi/qapi-commands-machine-target.h"
+
+#include "cpu-internal.h"
+
+/* Return a QDict containing keys for all properties that can be included
+ * in static expansion of CPU models. All properties set by x86_cpu_load_model()
+ * must be included in the dictionary.
+ */
+static QDict *x86_cpu_static_props(void)
+{
+ FeatureWord w;
+ int i;
+ static const char *props[] = {
+ "min-level",
+ "min-xlevel",
+ "family",
+ "model",
+ "stepping",
+ "model-id",
+ "vendor",
+ "lmce",
+ NULL,
+ };
+ static QDict *d;
+
+ if (d) {
+ return d;
+ }
+
+ d = qdict_new();
+ for (i = 0; props[i]; i++) {
+ qdict_put_null(d, props[i]);
+ }
+
+ for (w = 0; w < FEATURE_WORDS; w++) {
+ FeatureWordInfo *fi = &feature_word_info[w];
+ int bit;
+ for (bit = 0; bit < 64; bit++) {
+ if (!fi->feat_names[bit]) {
+ continue;
+ }
+ qdict_put_null(d, fi->feat_names[bit]);
+ }
+ }
+
+ return d;
+}
+
+/* Add an entry to @props dict, with the value for property. */
+static void x86_cpu_expand_prop(X86CPU *cpu, QDict *props, const char *prop)
+{
+ QObject *value = object_property_get_qobject(OBJECT(cpu), prop,
+ &error_abort);
+
+ qdict_put_obj(props, prop, value);
+}
+
+/* Convert CPU model data from X86CPU object to a property dictionary
+ * that can recreate exactly the same CPU model.
+ */
+static void x86_cpu_to_dict(X86CPU *cpu, QDict *props)
+{
+ QDict *sprops = x86_cpu_static_props();
+ const QDictEntry *e;
+
+ for (e = qdict_first(sprops); e; e = qdict_next(sprops, e)) {
+ const char *prop = qdict_entry_key(e);
+ x86_cpu_expand_prop(cpu, props, prop);
+ }
+}
+
+/* Convert CPU model data from X86CPU object to a property dictionary
+ * that can recreate exactly the same CPU model, including every
+ * writable QOM property.
+ */
+static void x86_cpu_to_dict_full(X86CPU *cpu, QDict *props)
+{
+ ObjectPropertyIterator iter;
+ ObjectProperty *prop;
+
+ object_property_iter_init(&iter, OBJECT(cpu));
+ while ((prop = object_property_iter_next(&iter))) {
+ /* skip read-only or write-only properties */
+ if (!prop->get || !prop->set) {
+ continue;
+ }
+
+ /* "hotplugged" is the only property that is configurable
+ * on the command-line but will be set differently on CPUs
+ * created using "-cpu ... -smp ..." and by CPUs created
+ * on the fly by x86_cpu_from_model() for querying. Skip it.
+ */
+ if (!strcmp(prop->name, "hotplugged")) {
+ continue;
+ }
+ x86_cpu_expand_prop(cpu, props, prop->name);
+ }
+}
+
+static void object_apply_props(Object *obj, QObject *props,
+ const char *props_arg_name, Error **errp)
+{
+ Visitor *visitor;
+ QDict *qdict;
+ const QDictEntry *prop;
+
+ visitor = qobject_input_visitor_new(props);
+ if (!visit_start_struct(visitor, props_arg_name, NULL, 0, errp)) {
+ visit_free(visitor);
+ return;
+ }
+
+ qdict = qobject_to(QDict, props);
+ for (prop = qdict_first(qdict); prop; prop = qdict_next(qdict, prop)) {
+ if (!object_property_set(obj, qdict_entry_key(prop),
+ visitor, errp)) {
+ goto out;
+ }
+ }
+
+ visit_check_struct(visitor, errp);
+out:
+ visit_end_struct(visitor, NULL);
+ visit_free(visitor);
+}
+
+/* Create X86CPU object according to model+props specification */
+static X86CPU *x86_cpu_from_model(const char *model, QObject *props,
+ const char *props_arg_name, Error **errp)
+{
+ X86CPU *xc = NULL;
+ X86CPUClass *xcc;
+ Error *err = NULL;
+
+ xcc = X86_CPU_CLASS(cpu_class_by_name(TYPE_X86_CPU, model));
+ if (xcc == NULL) {
+ error_setg(&err, "CPU model '%s' not found", model);
+ goto out;
+ }
+
+ xc = X86_CPU(object_new_with_class(OBJECT_CLASS(xcc)));
+ if (props) {
+ object_apply_props(OBJECT(xc), props, props_arg_name, &err);
+ if (err) {
+ goto out;
+ }
+ }
+
+ x86_cpu_expand_features(xc, &err);
+ if (err) {
+ goto out;
+ }
+
+out:
+ if (err) {
+ error_propagate(errp, err);
+ object_unref(OBJECT(xc));
+ xc = NULL;
+ }
+ return xc;
+}
+
+CpuModelExpansionInfo *
+qmp_query_cpu_model_expansion(CpuModelExpansionType type,
+ CpuModelInfo *model,
+ Error **errp)
+{
+ X86CPU *xc = NULL;
+ Error *err = NULL;
+ CpuModelExpansionInfo *ret = g_new0(CpuModelExpansionInfo, 1);
+ QDict *props = NULL;
+ const char *base_name;
+
+ xc = x86_cpu_from_model(model->name, model->props, "model.props", &err);
+ if (err) {
+ goto out;
+ }
+
+ props = qdict_new();
+ ret->model = g_new0(CpuModelInfo, 1);
+ ret->model->props = QOBJECT(props);
+
+ switch (type) {
+ case CPU_MODEL_EXPANSION_TYPE_STATIC:
+ /* Static expansion will be based on "base" only */
+ base_name = "base";
+ x86_cpu_to_dict(xc, props);
+ break;
+ case CPU_MODEL_EXPANSION_TYPE_FULL:
+ /* As we don't return every single property, full expansion needs
+ * to keep the original model name+props, and add extra
+ * properties on top of that.
+ */
+ base_name = model->name;
+ x86_cpu_to_dict_full(xc, props);
+ break;
+ default:
+ error_setg(&err, "Unsupported expansion type");
+ goto out;
+ }
+
+ x86_cpu_to_dict(xc, props);
+
+ ret->model->name = g_strdup(base_name);
+
+out:
+ object_unref(OBJECT(xc));
+ if (err) {
+ error_propagate(errp, err);
+ qapi_free_CpuModelExpansionInfo(ret);
+ ret = NULL;
+ }
+ return ret;
+}
+
+void cpu_clear_apic_feature(CPUX86State *env)
+{
+ env->features[FEAT_1_EDX] &= ~CPUID_APIC;
+}
+
+void cpu_set_apic_feature(CPUX86State *env)
+{
+ env->features[FEAT_1_EDX] |= CPUID_APIC;
+}
+
+bool cpu_has_x2apic_feature(CPUX86State *env)
+{
+ return env->features[FEAT_1_ECX] & CPUID_EXT_X2APIC;
+}
+
+bool cpu_is_bsp(X86CPU *cpu)
+{
+ return cpu_get_apic_base(cpu->apic_state) & MSR_IA32_APICBASE_BSP;
+}
+
+/* TODO: remove me, when reset over QOM tree is implemented */
+void x86_cpu_machine_reset_cb(void *opaque)
+{
+ X86CPU *cpu = opaque;
+ cpu_reset(CPU(cpu));
+}
+
+GuestPanicInformation *x86_cpu_get_crash_info(CPUState *cs)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+ GuestPanicInformation *panic_info = NULL;
+
+ if (hyperv_feat_enabled(cpu, HYPERV_FEAT_CRASH)) {
+ panic_info = g_new0(GuestPanicInformation, 1);
+
+ panic_info->type = GUEST_PANIC_INFORMATION_TYPE_HYPER_V;
+
+ assert(HV_CRASH_PARAMS >= 5);
+ panic_info->u.hyper_v.arg1 = env->msr_hv_crash_params[0];
+ panic_info->u.hyper_v.arg2 = env->msr_hv_crash_params[1];
+ panic_info->u.hyper_v.arg3 = env->msr_hv_crash_params[2];
+ panic_info->u.hyper_v.arg4 = env->msr_hv_crash_params[3];
+ panic_info->u.hyper_v.arg5 = env->msr_hv_crash_params[4];
+ }
+
+ return panic_info;
+}
+void x86_cpu_get_crash_info_qom(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ CPUState *cs = CPU(obj);
+ GuestPanicInformation *panic_info;
+
+ if (!cs->crash_occurred) {
+ error_setg(errp, "No crash occurred");
+ return;
+ }
+
+ panic_info = x86_cpu_get_crash_info(cs);
+ if (panic_info == NULL) {
+ error_setg(errp, "No crash information");
+ return;
+ }
+
+ visit_type_GuestPanicInformation(v, "crash-information", &panic_info,
+ errp);
+ qapi_free_GuestPanicInformation(panic_info);
+}
#include "qemu/hw-version.h"
#include "cpu.h"
#include "tcg/helper-tcg.h"
-#include "sysemu/hvf.h"
+#include "system/hvf.h"
#include "hvf/hvf-i386.h"
#include "kvm/kvm_i386.h"
#include "sev.h"
#include "hw/qdev-properties.h"
#include "hw/i386/topology.h"
#ifndef CONFIG_USER_ONLY
-#include "sysemu/reset.h"
+#include "system/reset.h"
#include "qapi/qapi-commands-machine-target.h"
#include "exec/address-spaces.h"
#include "hw/boards.h"
#ifndef I386_CPU_H
#define I386_CPU_H
-#include "sysemu/tcg.h"
+#include "system/tcg.h"
#include "cpu-qom.h"
#include "kvm/hyperv-proto.h"
#include "exec/cpu-defs.h"
#include "qapi/qapi-events-run-state.h"
#include "cpu.h"
#include "exec/exec-all.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#ifndef CONFIG_USER_ONLY
-#include "sysemu/hw_accel.h"
+#include "system/hw_accel.h"
#include "monitor/monitor.h"
#include "kvm/kvm_i386.h"
#endif
#include "host-cpu.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
/* Note: Only safe for use on x86(-64) hosts */
static uint32_t host_cpu_phys_bits(void)
#include "cpu.h"
#include "host-cpu.h"
#include "qapi/error.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/boards.h"
-#include "sysemu/hvf.h"
+#include "system/hvf.h"
#include "hw/core/accel-cpu.h"
#include "hvf-i386.h"
#include "qapi/error.h"
#include "migration/blocker.h"
-#include "sysemu/hvf.h"
-#include "sysemu/hvf_int.h"
-#include "sysemu/runstate.h"
-#include "sysemu/cpus.h"
+#include "system/hvf.h"
+#include "system/hvf_int.h"
+#include "system/runstate.h"
+#include "system/cpus.h"
#include "hvf-i386.h"
#include "vmcs.h"
#include "vmx.h"
#include "vmcs.h"
#include "cpu.h"
#include "x86.h"
-#include "sysemu/hvf.h"
-#include "sysemu/hvf_int.h"
+#include "system/hvf.h"
+#include "system/hvf_int.h"
#include "exec/address-spaces.h"
#include "cpu.h"
#include "x86.h"
#include "vmx.h"
-#include "sysemu/hvf.h"
+#include "system/hvf.h"
#include "hvf-i386.h"
static bool cached_xcr0;
#include "panic.h"
#include "qemu/error-report.h"
-#include "sysemu/hvf.h"
+#include "system/hvf.h"
#include "hvf-i386.h"
#include "vmcs.h"
#include "vmx.h"
#include "cpu.h"
#include "x86_descr.h"
#include "x86_decode.h"
-#include "sysemu/hw_accel.h"
+#include "system/hw_accel.h"
#include "hw/i386/apic_internal.h"
#define TARGET_I386_HYPERV_H
#include "cpu.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "hw/hyperv/hyperv.h"
#ifdef CONFIG_KVM
#include "cpu.h"
#include "host-cpu.h"
#include "qapi/error.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/boards.h"
#include "kvm_i386.h"
#include "cpu.h"
#include "host-cpu.h"
#include "vmsr_energy.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/kvm_int.h"
-#include "sysemu/runstate.h"
+#include "system/system.h"
+#include "system/hw_accel.h"
+#include "system/kvm_int.h"
+#include "system/runstate.h"
#include "kvm_i386.h"
#include "../confidential-guest.h"
#include "sev.h"
#ifndef QEMU_KVM_I386_H
#define QEMU_KVM_I386_H
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
/* always false if !CONFIG_KVM */
#define kvm_pit_in_kernel() \
#include "qemu/main-loop.h"
#include "qemu/error-report.h"
#include "hw/xen/xen.h"
-#include "sysemu/kvm_int.h"
-#include "sysemu/kvm_xen.h"
+#include "system/kvm_int.h"
+#include "system/kvm_xen.h"
#include "kvm/kvm_i386.h"
#include "exec/address-spaces.h"
#include "xen-emu.h"
#include "trace.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "hw/pci/msi.h"
#include "hw/i386/apic-msidef.h"
#include "kvm/kvm_i386.h"
#include "hw/xen/xen.h"
-#include "sysemu/kvm.h"
-#include "sysemu/kvm_xen.h"
-#include "sysemu/tcg.h"
+#include "system/kvm.h"
+#include "system/kvm_xen.h"
+#include "system/tcg.h"
#include "qemu/error-report.h"
'machine.c',
'monitor.c',
'cpu-apic.c',
- 'cpu-sysemu.c',
+ 'cpu-system.c',
))
-i386_system_ss.add(when: 'CONFIG_SEV', if_true: files('sev.c'), if_false: files('sev-sysemu-stub.c'))
+i386_system_ss.add(when: 'CONFIG_SEV', if_true: files('sev.c'),
+ if_false: files('sev-system-stub.c'))
i386_user_ss = ss.source_set()
*/
#include "qemu/osdep.h"
-#include "sysemu/kvm_int.h"
+#include "system/kvm_int.h"
#include "qemu/main-loop.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
#include "qemu/guest-random.h"
-#include "sysemu/nvmm.h"
+#include "system/nvmm.h"
#include "nvmm-accel-ops.h"
static void *qemu_nvmm_cpu_thread_fn(void *arg)
#ifndef TARGET_I386_NVMM_ACCEL_OPS_H
#define TARGET_I386_NVMM_ACCEL_OPS_H
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
int nvmm_init_vcpu(CPUState *cpu);
int nvmm_vcpu_exec(CPUState *cpu);
#include "exec/address-spaces.h"
#include "exec/ioport.h"
#include "qemu/accel.h"
-#include "sysemu/nvmm.h"
-#include "sysemu/cpus.h"
-#include "sysemu/runstate.h"
+#include "system/nvmm.h"
+#include "system/cpus.h"
+#include "system/runstate.h"
#include "qemu/main-loop.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
+++ /dev/null
-/*
- * QEMU SEV system stub
- *
- * Copyright Advanced Micro Devices 2018
- *
- * Authors:
- * Brijesh Singh <brijesh.singh@amd.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu/osdep.h"
-#include "monitor/monitor.h"
-#include "monitor/hmp-target.h"
-#include "qapi/qapi-commands-misc-target.h"
-#include "qapi/error.h"
-#include "sev.h"
-
-SevInfo *qmp_query_sev(Error **errp)
-{
- error_setg(errp, "SEV is not available in this QEMU");
- return NULL;
-}
-
-SevLaunchMeasureInfo *qmp_query_sev_launch_measure(Error **errp)
-{
- error_setg(errp, "SEV is not available in this QEMU");
- return NULL;
-}
-
-SevCapability *qmp_query_sev_capabilities(Error **errp)
-{
- error_setg(errp, "SEV is not available in this QEMU");
- return NULL;
-}
-
-void qmp_sev_inject_launch_secret(const char *packet_header, const char *secret,
- bool has_gpa, uint64_t gpa, Error **errp)
-{
- error_setg(errp, "SEV is not available in this QEMU");
-}
-
-int sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp)
-{
- g_assert_not_reached();
-}
-
-void sev_es_set_reset_vector(CPUState *cpu)
-{
-}
-
-int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size)
-{
- g_assert_not_reached();
-}
-
-SevAttestationReport *qmp_query_sev_attestation_report(const char *mnonce,
- Error **errp)
-{
- error_setg(errp, "SEV is not available in this QEMU");
- return NULL;
-}
-
-void hmp_info_sev(Monitor *mon, const QDict *qdict)
-{
- monitor_printf(mon, "SEV is not available in this QEMU\n");
-}
-
-void pc_system_parse_sev_metadata(uint8_t *flash_ptr, size_t flash_size)
-{
-}
--- /dev/null
+/*
+ * QEMU SEV system stub
+ *
+ * Copyright Advanced Micro Devices 2018
+ *
+ * Authors:
+ * Brijesh Singh <brijesh.singh@amd.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "monitor/monitor.h"
+#include "monitor/hmp-target.h"
+#include "qapi/qapi-commands-misc-target.h"
+#include "qapi/error.h"
+#include "sev.h"
+
+SevInfo *qmp_query_sev(Error **errp)
+{
+ error_setg(errp, "SEV is not available in this QEMU");
+ return NULL;
+}
+
+SevLaunchMeasureInfo *qmp_query_sev_launch_measure(Error **errp)
+{
+ error_setg(errp, "SEV is not available in this QEMU");
+ return NULL;
+}
+
+SevCapability *qmp_query_sev_capabilities(Error **errp)
+{
+ error_setg(errp, "SEV is not available in this QEMU");
+ return NULL;
+}
+
+void qmp_sev_inject_launch_secret(const char *packet_header, const char *secret,
+ bool has_gpa, uint64_t gpa, Error **errp)
+{
+ error_setg(errp, "SEV is not available in this QEMU");
+}
+
+int sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp)
+{
+ g_assert_not_reached();
+}
+
+void sev_es_set_reset_vector(CPUState *cpu)
+{
+}
+
+int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size)
+{
+ g_assert_not_reached();
+}
+
+SevAttestationReport *qmp_query_sev_attestation_report(const char *mnonce,
+ Error **errp)
+{
+ error_setg(errp, "SEV is not available in this QEMU");
+ return NULL;
+}
+
+void hmp_info_sev(Monitor *mon, const QDict *qdict)
+{
+ monitor_printf(mon, "SEV is not available in this QEMU\n");
+}
+
+void pc_system_parse_sev_metadata(uint8_t *flash_ptr, size_t flash_size)
+{
+}
#include "qemu/uuid.h"
#include "qemu/error-report.h"
#include "crypto/hash.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "kvm/kvm_i386.h"
#include "sev.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/runstate.h"
+#include "system/system.h"
+#include "system/runstate.h"
#include "trace.h"
#include "migration/blocker.h"
#include "qom/object.h"
#include "cpu.h"
#include "exec/exec-all.h"
#include "qemu/log.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "exec/helper-proto.h"
#include "helper-tcg.h"
'tcg-cpu.c',
'translate.c'), if_false: files('tcg-stub.c'))
-subdir('sysemu')
+subdir('system')
subdir('user')
+++ /dev/null
-/*
- * i386 breakpoint helpers - sysemu code
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * 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.1 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/exec-all.h"
-#include "exec/helper-proto.h"
-#include "tcg/helper-tcg.h"
-
-
-static inline bool hw_local_breakpoint_enabled(unsigned long dr7, int index)
-{
- return (dr7 >> (index * 2)) & 1;
-}
-
-static inline bool hw_global_breakpoint_enabled(unsigned long dr7, int index)
-{
- return (dr7 >> (index * 2)) & 2;
-
-}
-static inline bool hw_breakpoint_enabled(unsigned long dr7, int index)
-{
- return hw_global_breakpoint_enabled(dr7, index) ||
- hw_local_breakpoint_enabled(dr7, index);
-}
-
-static inline int hw_breakpoint_type(unsigned long dr7, int index)
-{
- return (dr7 >> (DR7_TYPE_SHIFT + (index * 4))) & 3;
-}
-
-static inline int hw_breakpoint_len(unsigned long dr7, int index)
-{
- int len = ((dr7 >> (DR7_LEN_SHIFT + (index * 4))) & 3);
- return (len == 2) ? 8 : len + 1;
-}
-
-static int hw_breakpoint_insert(CPUX86State *env, int index)
-{
- CPUState *cs = env_cpu(env);
- target_ulong dr7 = env->dr[7];
- target_ulong drN = env->dr[index];
- int err = 0;
-
- switch (hw_breakpoint_type(dr7, index)) {
- case DR7_TYPE_BP_INST:
- if (hw_breakpoint_enabled(dr7, index)) {
- err = cpu_breakpoint_insert(cs, drN, BP_CPU,
- &env->cpu_breakpoint[index]);
- }
- break;
-
- case DR7_TYPE_IO_RW:
- /* Notice when we should enable calls to bpt_io. */
- return hw_breakpoint_enabled(env->dr[7], index)
- ? HF_IOBPT_MASK : 0;
-
- case DR7_TYPE_DATA_WR:
- if (hw_breakpoint_enabled(dr7, index)) {
- err = cpu_watchpoint_insert(cs, drN,
- hw_breakpoint_len(dr7, index),
- BP_CPU | BP_MEM_WRITE,
- &env->cpu_watchpoint[index]);
- }
- break;
-
- case DR7_TYPE_DATA_RW:
- if (hw_breakpoint_enabled(dr7, index)) {
- err = cpu_watchpoint_insert(cs, drN,
- hw_breakpoint_len(dr7, index),
- BP_CPU | BP_MEM_ACCESS,
- &env->cpu_watchpoint[index]);
- }
- break;
- }
- if (err) {
- env->cpu_breakpoint[index] = NULL;
- }
- return 0;
-}
-
-static void hw_breakpoint_remove(CPUX86State *env, int index)
-{
- CPUState *cs = env_cpu(env);
-
- switch (hw_breakpoint_type(env->dr[7], index)) {
- case DR7_TYPE_BP_INST:
- if (env->cpu_breakpoint[index]) {
- cpu_breakpoint_remove_by_ref(cs, env->cpu_breakpoint[index]);
- env->cpu_breakpoint[index] = NULL;
- }
- break;
-
- case DR7_TYPE_DATA_WR:
- case DR7_TYPE_DATA_RW:
- if (env->cpu_watchpoint[index]) {
- cpu_watchpoint_remove_by_ref(cs, env->cpu_watchpoint[index]);
- env->cpu_watchpoint[index] = NULL;
- }
- break;
-
- case DR7_TYPE_IO_RW:
- /* HF_IOBPT_MASK cleared elsewhere. */
- break;
- }
-}
-
-void cpu_x86_update_dr7(CPUX86State *env, uint32_t new_dr7)
-{
- target_ulong old_dr7 = env->dr[7];
- int iobpt = 0;
- int i;
-
- new_dr7 |= DR7_FIXED_1;
-
- /* If nothing is changing except the global/local enable bits,
- then we can make the change more efficient. */
- if (((old_dr7 ^ new_dr7) & ~0xff) == 0) {
- /* Fold the global and local enable bits together into the
- global fields, then xor to show which registers have
- changed collective enable state. */
- int mod = ((old_dr7 | old_dr7 * 2) ^ (new_dr7 | new_dr7 * 2)) & 0xff;
-
- for (i = 0; i < DR7_MAX_BP; i++) {
- if ((mod & (2 << i * 2)) && !hw_breakpoint_enabled(new_dr7, i)) {
- hw_breakpoint_remove(env, i);
- }
- }
- env->dr[7] = new_dr7;
- for (i = 0; i < DR7_MAX_BP; i++) {
- if (mod & (2 << i * 2) && hw_breakpoint_enabled(new_dr7, i)) {
- iobpt |= hw_breakpoint_insert(env, i);
- } else if (hw_breakpoint_type(new_dr7, i) == DR7_TYPE_IO_RW
- && hw_breakpoint_enabled(new_dr7, i)) {
- iobpt |= HF_IOBPT_MASK;
- }
- }
- } else {
- for (i = 0; i < DR7_MAX_BP; i++) {
- hw_breakpoint_remove(env, i);
- }
- env->dr[7] = new_dr7;
- for (i = 0; i < DR7_MAX_BP; i++) {
- iobpt |= hw_breakpoint_insert(env, i);
- }
- }
-
- env->hflags = (env->hflags & ~HF_IOBPT_MASK) | iobpt;
-}
-
-bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update)
-{
- target_ulong dr6;
- int reg;
- bool hit_enabled = false;
-
- dr6 = env->dr[6] & ~0xf;
- for (reg = 0; reg < DR7_MAX_BP; reg++) {
- bool bp_match = false;
- bool wp_match = false;
-
- switch (hw_breakpoint_type(env->dr[7], reg)) {
- case DR7_TYPE_BP_INST:
- if (env->dr[reg] == env->eip) {
- bp_match = true;
- }
- break;
- case DR7_TYPE_DATA_WR:
- case DR7_TYPE_DATA_RW:
- if (env->cpu_watchpoint[reg] &&
- env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT) {
- wp_match = true;
- }
- break;
- case DR7_TYPE_IO_RW:
- break;
- }
- if (bp_match || wp_match) {
- dr6 |= 1 << reg;
- if (hw_breakpoint_enabled(env->dr[7], reg)) {
- hit_enabled = true;
- }
- }
- }
-
- if (hit_enabled || force_dr6_update) {
- env->dr[6] = dr6;
- }
-
- return hit_enabled;
-}
-
-void breakpoint_handler(CPUState *cs)
-{
- X86CPU *cpu = X86_CPU(cs);
- CPUX86State *env = &cpu->env;
-
- if (cs->watchpoint_hit) {
- if (cs->watchpoint_hit->flags & BP_CPU) {
- cs->watchpoint_hit = NULL;
- if (check_hw_breakpoints(env, false)) {
- /*
- * FIXME: #DB should be delayed by one instruction if
- * INHIBIT_IRQ is set (STI cannot trigger a watchpoint).
- * The delayed #DB should also fuse with one generated
- * by ICEBP (aka INT1).
- */
- raise_exception(env, EXCP01_DB);
- } else {
- cpu_loop_exit_noexc(cs);
- }
- }
- } else {
- if (cpu_breakpoint_test(cs, env->eip, BP_CPU)) {
- check_hw_breakpoints(env, true);
- raise_exception(env, EXCP01_DB);
- }
- }
-}
-
-target_ulong helper_get_dr(CPUX86State *env, int reg)
-{
- if (reg >= 4 && reg < 6) {
- if (env->cr[4] & CR4_DE_MASK) {
- raise_exception_ra(env, EXCP06_ILLOP, GETPC());
- } else {
- reg += 2;
- }
- }
-
- if (env->dr[7] & DR7_GD) {
- env->dr[7] &= ~DR7_GD;
- env->dr[6] |= DR6_BD;
- raise_exception_ra(env, EXCP01_DB, GETPC());
- }
-
- return env->dr[reg];
-}
-
-void helper_set_dr(CPUX86State *env, int reg, target_ulong t0)
-{
- if (reg >= 4 && reg < 6) {
- if (env->cr[4] & CR4_DE_MASK) {
- raise_exception_ra(env, EXCP06_ILLOP, GETPC());
- } else {
- reg += 2;
- }
- }
-
- if (env->dr[7] & DR7_GD) {
- env->dr[7] &= ~DR7_GD;
- env->dr[6] |= DR6_BD;
- raise_exception_ra(env, EXCP01_DB, GETPC());
- }
-
- if (reg < 4) {
- if (hw_breakpoint_enabled(env->dr[7], reg)
- && hw_breakpoint_type(env->dr[7], reg) != DR7_TYPE_IO_RW) {
- hw_breakpoint_remove(env, reg);
- env->dr[reg] = t0;
- hw_breakpoint_insert(env, reg);
- } else {
- env->dr[reg] = t0;
- }
- } else {
- if (t0 & DR_RESERVED_MASK) {
- raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
- }
- if (reg == 6) {
- env->dr[6] = t0 | DR6_FIXED_1;
- } else {
- cpu_x86_update_dr7(env, t0);
- }
- }
-}
-
-/* Check if Port I/O is trapped by a breakpoint. */
-void helper_bpt_io(CPUX86State *env, uint32_t port,
- uint32_t size, target_ulong next_eip)
-{
- target_ulong dr7 = env->dr[7];
- int i, hit = 0;
-
- for (i = 0; i < DR7_MAX_BP; ++i) {
- if (hw_breakpoint_type(dr7, i) == DR7_TYPE_IO_RW
- && hw_breakpoint_enabled(dr7, i)) {
- int bpt_len = hw_breakpoint_len(dr7, i);
- if (port + size - 1 >= env->dr[i]
- && port <= env->dr[i] + bpt_len - 1) {
- hit |= 1 << i;
- }
- }
- }
-
- if (hit) {
- env->dr[6] = (env->dr[6] & ~0xf) | hit;
- env->eip = next_eip;
- raise_exception(env, EXCP01_DB);
- }
-}
+++ /dev/null
-/*
- * x86 exception helpers - sysemu code
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * 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.1 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/cpu_ldst.h"
-#include "exec/exec-all.h"
-#include "exec/page-protection.h"
-#include "tcg/helper-tcg.h"
-
-typedef struct TranslateParams {
- target_ulong addr;
- target_ulong cr3;
- int pg_mode;
- int mmu_idx;
- int ptw_idx;
- MMUAccessType access_type;
-} TranslateParams;
-
-typedef struct TranslateResult {
- hwaddr paddr;
- int prot;
- int page_size;
-} TranslateResult;
-
-typedef enum TranslateFaultStage2 {
- S2_NONE,
- S2_GPA,
- S2_GPT,
-} TranslateFaultStage2;
-
-typedef struct TranslateFault {
- int exception_index;
- int error_code;
- target_ulong cr2;
- TranslateFaultStage2 stage2;
-} TranslateFault;
-
-typedef struct PTETranslate {
- CPUX86State *env;
- TranslateFault *err;
- int ptw_idx;
- void *haddr;
- hwaddr gaddr;
-} PTETranslate;
-
-static bool ptw_translate(PTETranslate *inout, hwaddr addr)
-{
- int flags;
-
- inout->gaddr = addr;
- flags = probe_access_full_mmu(inout->env, addr, 0, MMU_DATA_STORE,
- inout->ptw_idx, &inout->haddr, NULL);
-
- if (unlikely(flags & TLB_INVALID_MASK)) {
- TranslateFault *err = inout->err;
-
- assert(inout->ptw_idx == MMU_NESTED_IDX);
- *err = (TranslateFault){
- .error_code = inout->env->error_code,
- .cr2 = addr,
- .stage2 = S2_GPT,
- };
- return false;
- }
- return true;
-}
-
-static inline uint32_t ptw_ldl(const PTETranslate *in, uint64_t ra)
-{
- if (likely(in->haddr)) {
- return ldl_p(in->haddr);
- }
- return cpu_ldl_mmuidx_ra(in->env, in->gaddr, in->ptw_idx, ra);
-}
-
-static inline uint64_t ptw_ldq(const PTETranslate *in, uint64_t ra)
-{
- if (likely(in->haddr)) {
- return ldq_p(in->haddr);
- }
- return cpu_ldq_mmuidx_ra(in->env, in->gaddr, in->ptw_idx, ra);
-}
-
-/*
- * Note that we can use a 32-bit cmpxchg for all page table entries,
- * even 64-bit ones, because PG_PRESENT_MASK, PG_ACCESSED_MASK and
- * PG_DIRTY_MASK are all in the low 32 bits.
- */
-static bool ptw_setl_slow(const PTETranslate *in, uint32_t old, uint32_t new)
-{
- uint32_t cmp;
-
- CPUState *cpu = env_cpu(in->env);
- /* We are in cpu_exec, and start_exclusive can't be called directly.*/
- g_assert(cpu->running);
- cpu_exec_end(cpu);
- /* Does x86 really perform a rmw cycle on mmio for ptw? */
- start_exclusive();
- cmp = cpu_ldl_mmuidx_ra(in->env, in->gaddr, in->ptw_idx, 0);
- if (cmp == old) {
- cpu_stl_mmuidx_ra(in->env, in->gaddr, new, in->ptw_idx, 0);
- }
- end_exclusive();
- cpu_exec_start(cpu);
- return cmp == old;
-}
-
-static inline bool ptw_setl(const PTETranslate *in, uint32_t old, uint32_t set)
-{
- if (set & ~old) {
- uint32_t new = old | set;
- if (likely(in->haddr)) {
- old = cpu_to_le32(old);
- new = cpu_to_le32(new);
- return qatomic_cmpxchg((uint32_t *)in->haddr, old, new) == old;
- }
- return ptw_setl_slow(in, old, new);
- }
- return true;
-}
-
-static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
- TranslateResult *out, TranslateFault *err,
- uint64_t ra)
-{
- const target_ulong addr = in->addr;
- const int pg_mode = in->pg_mode;
- const bool is_user = is_mmu_index_user(in->mmu_idx);
- const MMUAccessType access_type = in->access_type;
- uint64_t ptep, pte, rsvd_mask;
- PTETranslate pte_trans = {
- .env = env,
- .err = err,
- .ptw_idx = in->ptw_idx,
- };
- hwaddr pte_addr, paddr;
- uint32_t pkr;
- int page_size;
- int error_code;
- int prot;
-
- restart_all:
- rsvd_mask = ~MAKE_64BIT_MASK(0, env_archcpu(env)->phys_bits);
- rsvd_mask &= PG_ADDRESS_MASK;
- if (!(pg_mode & PG_MODE_NXE)) {
- rsvd_mask |= PG_NX_MASK;
- }
-
- if (pg_mode & PG_MODE_PAE) {
-#ifdef TARGET_X86_64
- if (pg_mode & PG_MODE_LMA) {
- if (pg_mode & PG_MODE_LA57) {
- /*
- * Page table level 5
- */
- pte_addr = (in->cr3 & ~0xfff) + (((addr >> 48) & 0x1ff) << 3);
- if (!ptw_translate(&pte_trans, pte_addr)) {
- return false;
- }
- restart_5:
- pte = ptw_ldq(&pte_trans, ra);
- if (!(pte & PG_PRESENT_MASK)) {
- goto do_fault;
- }
- if (pte & (rsvd_mask | PG_PSE_MASK)) {
- goto do_fault_rsvd;
- }
- if (!ptw_setl(&pte_trans, pte, PG_ACCESSED_MASK)) {
- goto restart_5;
- }
- ptep = pte ^ PG_NX_MASK;
- } else {
- pte = in->cr3;
- ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
- }
-
- /*
- * Page table level 4
- */
- pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 39) & 0x1ff) << 3);
- if (!ptw_translate(&pte_trans, pte_addr)) {
- return false;
- }
- restart_4:
- pte = ptw_ldq(&pte_trans, ra);
- if (!(pte & PG_PRESENT_MASK)) {
- goto do_fault;
- }
- if (pte & (rsvd_mask | PG_PSE_MASK)) {
- goto do_fault_rsvd;
- }
- if (!ptw_setl(&pte_trans, pte, PG_ACCESSED_MASK)) {
- goto restart_4;
- }
- ptep &= pte ^ PG_NX_MASK;
-
- /*
- * Page table level 3
- */
- pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 30) & 0x1ff) << 3);
- if (!ptw_translate(&pte_trans, pte_addr)) {
- return false;
- }
- restart_3_lma:
- pte = ptw_ldq(&pte_trans, ra);
- if (!(pte & PG_PRESENT_MASK)) {
- goto do_fault;
- }
- if (pte & rsvd_mask) {
- goto do_fault_rsvd;
- }
- if (!ptw_setl(&pte_trans, pte, PG_ACCESSED_MASK)) {
- goto restart_3_lma;
- }
- ptep &= pte ^ PG_NX_MASK;
- if (pte & PG_PSE_MASK) {
- /* 1 GB page */
- page_size = 1024 * 1024 * 1024;
- goto do_check_protect;
- }
- } else
-#endif
- {
- /*
- * Page table level 3
- */
- pte_addr = (in->cr3 & 0xffffffe0ULL) + ((addr >> 27) & 0x18);
- if (!ptw_translate(&pte_trans, pte_addr)) {
- return false;
- }
- rsvd_mask |= PG_HI_USER_MASK;
- restart_3_nolma:
- pte = ptw_ldq(&pte_trans, ra);
- if (!(pte & PG_PRESENT_MASK)) {
- goto do_fault;
- }
- if (pte & (rsvd_mask | PG_NX_MASK)) {
- goto do_fault_rsvd;
- }
- if (!ptw_setl(&pte_trans, pte, PG_ACCESSED_MASK)) {
- goto restart_3_nolma;
- }
- ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
- }
-
- /*
- * Page table level 2
- */
- pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 21) & 0x1ff) << 3);
- if (!ptw_translate(&pte_trans, pte_addr)) {
- return false;
- }
- restart_2_pae:
- pte = ptw_ldq(&pte_trans, ra);
- if (!(pte & PG_PRESENT_MASK)) {
- goto do_fault;
- }
- if (pte & rsvd_mask) {
- goto do_fault_rsvd;
- }
- if (pte & PG_PSE_MASK) {
- /* 2 MB page */
- page_size = 2048 * 1024;
- ptep &= pte ^ PG_NX_MASK;
- goto do_check_protect;
- }
- if (!ptw_setl(&pte_trans, pte, PG_ACCESSED_MASK)) {
- goto restart_2_pae;
- }
- ptep &= pte ^ PG_NX_MASK;
-
- /*
- * Page table level 1
- */
- pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 12) & 0x1ff) << 3);
- if (!ptw_translate(&pte_trans, pte_addr)) {
- return false;
- }
- pte = ptw_ldq(&pte_trans, ra);
- if (!(pte & PG_PRESENT_MASK)) {
- goto do_fault;
- }
- if (pte & rsvd_mask) {
- goto do_fault_rsvd;
- }
- /* combine pde and pte nx, user and rw protections */
- ptep &= pte ^ PG_NX_MASK;
- page_size = 4096;
- } else if (pg_mode & PG_MODE_PG) {
- /*
- * Page table level 2
- */
- pte_addr = (in->cr3 & 0xfffff000ULL) + ((addr >> 20) & 0xffc);
- if (!ptw_translate(&pte_trans, pte_addr)) {
- return false;
- }
- restart_2_nopae:
- pte = ptw_ldl(&pte_trans, ra);
- if (!(pte & PG_PRESENT_MASK)) {
- goto do_fault;
- }
- ptep = pte | PG_NX_MASK;
-
- /* if PSE bit is set, then we use a 4MB page */
- if ((pte & PG_PSE_MASK) && (pg_mode & PG_MODE_PSE)) {
- page_size = 4096 * 1024;
- /*
- * Bits 20-13 provide bits 39-32 of the address, bit 21 is reserved.
- * Leave bits 20-13 in place for setting accessed/dirty bits below.
- */
- pte = (uint32_t)pte | ((pte & 0x1fe000LL) << (32 - 13));
- rsvd_mask = 0x200000;
- goto do_check_protect_pse36;
- }
- if (!ptw_setl(&pte_trans, pte, PG_ACCESSED_MASK)) {
- goto restart_2_nopae;
- }
-
- /*
- * Page table level 1
- */
- pte_addr = (pte & ~0xfffu) + ((addr >> 10) & 0xffc);
- if (!ptw_translate(&pte_trans, pte_addr)) {
- return false;
- }
- pte = ptw_ldl(&pte_trans, ra);
- if (!(pte & PG_PRESENT_MASK)) {
- goto do_fault;
- }
- /* combine pde and pte user and rw protections */
- ptep &= pte | PG_NX_MASK;
- page_size = 4096;
- rsvd_mask = 0;
- } else {
- /*
- * No paging (real mode), let's tentatively resolve the address as 1:1
- * here, but conditionally still perform an NPT walk on it later.
- */
- page_size = 0x40000000;
- paddr = in->addr;
- prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- goto stage2;
- }
-
-do_check_protect:
- rsvd_mask |= (page_size - 1) & PG_ADDRESS_MASK & ~PG_PSE_PAT_MASK;
-do_check_protect_pse36:
- if (pte & rsvd_mask) {
- goto do_fault_rsvd;
- }
- ptep ^= PG_NX_MASK;
-
- /* can the page can be put in the TLB? prot will tell us */
- if (is_user && !(ptep & PG_USER_MASK)) {
- goto do_fault_protect;
- }
-
- prot = 0;
- if (!is_mmu_index_smap(in->mmu_idx) || !(ptep & PG_USER_MASK)) {
- prot |= PAGE_READ;
- if ((ptep & PG_RW_MASK) || !(is_user || (pg_mode & PG_MODE_WP))) {
- prot |= PAGE_WRITE;
- }
- }
- if (!(ptep & PG_NX_MASK) &&
- (is_user ||
- !((pg_mode & PG_MODE_SMEP) && (ptep & PG_USER_MASK)))) {
- prot |= PAGE_EXEC;
- }
-
- if (ptep & PG_USER_MASK) {
- pkr = pg_mode & PG_MODE_PKE ? env->pkru : 0;
- } else {
- pkr = pg_mode & PG_MODE_PKS ? env->pkrs : 0;
- }
- if (pkr) {
- uint32_t pk = (pte & PG_PKRU_MASK) >> PG_PKRU_BIT;
- uint32_t pkr_ad = (pkr >> pk * 2) & 1;
- uint32_t pkr_wd = (pkr >> pk * 2) & 2;
- uint32_t pkr_prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
-
- if (pkr_ad) {
- pkr_prot &= ~(PAGE_READ | PAGE_WRITE);
- } else if (pkr_wd && (is_user || (pg_mode & PG_MODE_WP))) {
- pkr_prot &= ~PAGE_WRITE;
- }
- if ((pkr_prot & (1 << access_type)) == 0) {
- goto do_fault_pk_protect;
- }
- prot &= pkr_prot;
- }
-
- if ((prot & (1 << access_type)) == 0) {
- goto do_fault_protect;
- }
-
- /* yes, it can! */
- {
- uint32_t set = PG_ACCESSED_MASK;
- if (access_type == MMU_DATA_STORE) {
- set |= PG_DIRTY_MASK;
- } else if (!(pte & PG_DIRTY_MASK)) {
- /*
- * Only set write access if already dirty...
- * otherwise wait for dirty access.
- */
- prot &= ~PAGE_WRITE;
- }
- if (!ptw_setl(&pte_trans, pte, set)) {
- /*
- * We can arrive here from any of 3 levels and 2 formats.
- * The only safe thing is to restart the entire lookup.
- */
- goto restart_all;
- }
- }
-
- /* merge offset within page */
- paddr = (pte & PG_ADDRESS_MASK & ~(page_size - 1)) | (addr & (page_size - 1));
- stage2:
-
- /*
- * Note that NPT is walked (for both paging structures and final guest
- * addresses) using the address with the A20 bit set.
- */
- if (in->ptw_idx == MMU_NESTED_IDX) {
- CPUTLBEntryFull *full;
- int flags, nested_page_size;
-
- flags = probe_access_full_mmu(env, paddr, 0, access_type,
- MMU_NESTED_IDX, &pte_trans.haddr, &full);
- if (unlikely(flags & TLB_INVALID_MASK)) {
- *err = (TranslateFault){
- .error_code = env->error_code,
- .cr2 = paddr,
- .stage2 = S2_GPA,
- };
- return false;
- }
-
- /* Merge stage1 & stage2 protection bits. */
- prot &= full->prot;
-
- /* Re-verify resulting protection. */
- if ((prot & (1 << access_type)) == 0) {
- goto do_fault_protect;
- }
-
- /* Merge stage1 & stage2 addresses to final physical address. */
- nested_page_size = 1 << full->lg_page_size;
- paddr = (full->phys_addr & ~(nested_page_size - 1))
- | (paddr & (nested_page_size - 1));
-
- /*
- * Use the larger of stage1 & stage2 page sizes, so that
- * invalidation works.
- */
- if (nested_page_size > page_size) {
- page_size = nested_page_size;
- }
- }
-
- out->paddr = paddr & x86_get_a20_mask(env);
- out->prot = prot;
- out->page_size = page_size;
- return true;
-
- do_fault_rsvd:
- error_code = PG_ERROR_RSVD_MASK;
- goto do_fault_cont;
- do_fault_protect:
- error_code = PG_ERROR_P_MASK;
- goto do_fault_cont;
- do_fault_pk_protect:
- assert(access_type != MMU_INST_FETCH);
- error_code = PG_ERROR_PK_MASK | PG_ERROR_P_MASK;
- goto do_fault_cont;
- do_fault:
- error_code = 0;
- do_fault_cont:
- if (is_user) {
- error_code |= PG_ERROR_U_MASK;
- }
- switch (access_type) {
- case MMU_DATA_LOAD:
- break;
- case MMU_DATA_STORE:
- error_code |= PG_ERROR_W_MASK;
- break;
- case MMU_INST_FETCH:
- if (pg_mode & (PG_MODE_NXE | PG_MODE_SMEP)) {
- error_code |= PG_ERROR_I_D_MASK;
- }
- break;
- }
- *err = (TranslateFault){
- .exception_index = EXCP0E_PAGE,
- .error_code = error_code,
- .cr2 = addr,
- };
- return false;
-}
-
-static G_NORETURN void raise_stage2(CPUX86State *env, TranslateFault *err,
- uintptr_t retaddr)
-{
- uint64_t exit_info_1 = err->error_code;
-
- switch (err->stage2) {
- case S2_GPT:
- exit_info_1 |= SVM_NPTEXIT_GPT;
- break;
- case S2_GPA:
- exit_info_1 |= SVM_NPTEXIT_GPA;
- break;
- default:
- g_assert_not_reached();
- }
-
- x86_stq_phys(env_cpu(env),
- env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
- err->cr2);
- cpu_vmexit(env, SVM_EXIT_NPF, exit_info_1, retaddr);
-}
-
-static bool get_physical_address(CPUX86State *env, vaddr addr,
- MMUAccessType access_type, int mmu_idx,
- TranslateResult *out, TranslateFault *err,
- uint64_t ra)
-{
- TranslateParams in;
- bool use_stage2 = env->hflags2 & HF2_NPT_MASK;
-
- in.addr = addr;
- in.access_type = access_type;
-
- switch (mmu_idx) {
- case MMU_PHYS_IDX:
- break;
-
- case MMU_NESTED_IDX:
- if (likely(use_stage2)) {
- in.cr3 = env->nested_cr3;
- in.pg_mode = env->nested_pg_mode;
- in.mmu_idx =
- env->nested_pg_mode & PG_MODE_LMA ? MMU_USER64_IDX : MMU_USER32_IDX;
- in.ptw_idx = MMU_PHYS_IDX;
-
- if (!mmu_translate(env, &in, out, err, ra)) {
- err->stage2 = S2_GPA;
- return false;
- }
- return true;
- }
- break;
-
- default:
- if (is_mmu_index_32(mmu_idx)) {
- addr = (uint32_t)addr;
- }
-
- if (likely(env->cr[0] & CR0_PG_MASK || use_stage2)) {
- in.cr3 = env->cr[3];
- in.mmu_idx = mmu_idx;
- in.ptw_idx = use_stage2 ? MMU_NESTED_IDX : MMU_PHYS_IDX;
- in.pg_mode = get_pg_mode(env);
-
- if (in.pg_mode & PG_MODE_LMA) {
- /* test virtual address sign extension */
- int shift = in.pg_mode & PG_MODE_LA57 ? 56 : 47;
- int64_t sext = (int64_t)addr >> shift;
- if (sext != 0 && sext != -1) {
- *err = (TranslateFault){
- .exception_index = EXCP0D_GPF,
- .cr2 = addr,
- };
- return false;
- }
- }
- return mmu_translate(env, &in, out, err, ra);
- }
- break;
- }
-
- /* No translation needed. */
- out->paddr = addr & x86_get_a20_mask(env);
- out->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- out->page_size = TARGET_PAGE_SIZE;
- return true;
-}
-
-bool x86_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr)
-{
- CPUX86State *env = cpu_env(cs);
- TranslateResult out;
- TranslateFault err;
-
- if (get_physical_address(env, addr, access_type, mmu_idx, &out, &err,
- retaddr)) {
- /*
- * Even if 4MB pages, we map only one 4KB page in the cache to
- * avoid filling it too fast.
- */
- assert(out.prot & (1 << access_type));
- tlb_set_page_with_attrs(cs, addr & TARGET_PAGE_MASK,
- out.paddr & TARGET_PAGE_MASK,
- cpu_get_mem_attrs(env),
- out.prot, mmu_idx, out.page_size);
- return true;
- }
-
- if (probe) {
- /* This will be used if recursing for stage2 translation. */
- env->error_code = err.error_code;
- return false;
- }
-
- if (err.stage2 != S2_NONE) {
- raise_stage2(env, &err, retaddr);
- }
-
- if (env->intercept_exceptions & (1 << err.exception_index)) {
- /* cr2 is not modified in case of exceptions */
- x86_stq_phys(cs, env->vm_vmcb +
- offsetof(struct vmcb, control.exit_info_2),
- err.cr2);
- } else {
- env->cr[2] = err.cr2;
- }
- raise_exception_err_ra(env, err.exception_index, err.error_code, retaddr);
-}
-
-G_NORETURN void x86_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
- MMUAccessType access_type,
- int mmu_idx, uintptr_t retaddr)
-{
- X86CPU *cpu = X86_CPU(cs);
- handle_unaligned_access(&cpu->env, vaddr, access_type, retaddr);
-}
+++ /dev/null
-/*
- * x86 FPU, MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4/PNI helpers (sysemu code)
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * 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.1 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 "qemu/main-loop.h"
-#include "cpu.h"
-#include "hw/irq.h"
-
-static qemu_irq ferr_irq;
-
-void x86_register_ferr_irq(qemu_irq irq)
-{
- ferr_irq = irq;
-}
-
-void fpu_check_raise_ferr_irq(CPUX86State *env)
-{
- if (ferr_irq && !(env->hflags2 & HF2_IGNNE_MASK)) {
- bql_lock();
- qemu_irq_raise(ferr_irq);
- bql_unlock();
- return;
- }
-}
-
-void cpu_clear_ignne(void)
-{
- CPUX86State *env = &X86_CPU(first_cpu)->env;
- env->hflags2 &= ~HF2_IGNNE_MASK;
-}
-
-void cpu_set_ignne(void)
-{
- CPUX86State *env = &X86_CPU(first_cpu)->env;
-
- assert(bql_locked());
-
- env->hflags2 |= HF2_IGNNE_MASK;
- /*
- * We get here in response to a write to port F0h. The chipset should
- * deassert FP_IRQ and FERR# instead should stay signaled until FPSW_SE is
- * cleared, because FERR# and FP_IRQ are two separate pins on real
- * hardware. However, we don't model FERR# as a qemu_irq, so we just
- * do directly what the chipset would do, i.e. deassert FP_IRQ.
- */
- qemu_irq_lower(ferr_irq);
-}
+++ /dev/null
-i386_system_ss.add(when: ['CONFIG_TCG', 'CONFIG_SYSTEM_ONLY'], if_true: files(
- 'tcg-cpu.c',
- 'smm_helper.c',
- 'excp_helper.c',
- 'bpt_helper.c',
- 'misc_helper.c',
- 'fpu_helper.c',
- 'svm_helper.c',
- 'seg_helper.c',
-))
+++ /dev/null
-/*
- * x86 misc helpers - sysemu code
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * 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.1 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 "qemu/main-loop.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-#include "exec/cpu_ldst.h"
-#include "exec/address-spaces.h"
-#include "exec/exec-all.h"
-#include "tcg/helper-tcg.h"
-#include "hw/i386/apic.h"
-
-void helper_outb(CPUX86State *env, uint32_t port, uint32_t data)
-{
- address_space_stb(&address_space_io, port, data,
- cpu_get_mem_attrs(env), NULL);
-}
-
-target_ulong helper_inb(CPUX86State *env, uint32_t port)
-{
- return address_space_ldub(&address_space_io, port,
- cpu_get_mem_attrs(env), NULL);
-}
-
-void helper_outw(CPUX86State *env, uint32_t port, uint32_t data)
-{
- address_space_stw(&address_space_io, port, data,
- cpu_get_mem_attrs(env), NULL);
-}
-
-target_ulong helper_inw(CPUX86State *env, uint32_t port)
-{
- return address_space_lduw(&address_space_io, port,
- cpu_get_mem_attrs(env), NULL);
-}
-
-void helper_outl(CPUX86State *env, uint32_t port, uint32_t data)
-{
- address_space_stl(&address_space_io, port, data,
- cpu_get_mem_attrs(env), NULL);
-}
-
-target_ulong helper_inl(CPUX86State *env, uint32_t port)
-{
- return address_space_ldl(&address_space_io, port,
- cpu_get_mem_attrs(env), NULL);
-}
-
-target_ulong helper_read_cr8(CPUX86State *env)
-{
- if (!(env->hflags2 & HF2_VINTR_MASK)) {
- return cpu_get_apic_tpr(env_archcpu(env)->apic_state);
- } else {
- return env->int_ctl & V_TPR_MASK;
- }
-}
-
-void helper_write_crN(CPUX86State *env, int reg, target_ulong t0)
-{
- switch (reg) {
- case 0:
- /*
- * If we reach this point, the CR0 write intercept is disabled.
- * But we could still exit if the hypervisor has requested the selective
- * intercept for bits other than TS and MP
- */
- if (cpu_svm_has_intercept(env, SVM_EXIT_CR0_SEL_WRITE) &&
- ((env->cr[0] ^ t0) & ~(CR0_TS_MASK | CR0_MP_MASK))) {
- cpu_vmexit(env, SVM_EXIT_CR0_SEL_WRITE, 0, GETPC());
- }
- cpu_x86_update_cr0(env, t0);
- break;
- case 3:
- if ((env->efer & MSR_EFER_LMA) &&
- (t0 & ((~0ULL) << env_archcpu(env)->phys_bits))) {
- cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
- }
- if (!(env->efer & MSR_EFER_LMA)) {
- t0 &= 0xffffffffUL;
- }
- cpu_x86_update_cr3(env, t0);
- break;
- case 4:
- if (t0 & cr4_reserved_bits(env)) {
- cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
- }
- if (((t0 ^ env->cr[4]) & CR4_LA57_MASK) &&
- (env->hflags & HF_CS64_MASK)) {
- raise_exception_ra(env, EXCP0D_GPF, GETPC());
- }
- cpu_x86_update_cr4(env, t0);
- break;
- case 8:
- if (!(env->hflags2 & HF2_VINTR_MASK)) {
- bql_lock();
- cpu_set_apic_tpr(env_archcpu(env)->apic_state, t0);
- bql_unlock();
- }
- env->int_ctl = (env->int_ctl & ~V_TPR_MASK) | (t0 & V_TPR_MASK);
-
- CPUState *cs = env_cpu(env);
- if (ctl_has_irq(env)) {
- cpu_interrupt(cs, CPU_INTERRUPT_VIRQ);
- } else {
- cpu_reset_interrupt(cs, CPU_INTERRUPT_VIRQ);
- }
- break;
- default:
- env->cr[reg] = t0;
- break;
- }
-}
-
-void helper_wrmsr(CPUX86State *env)
-{
- uint64_t val;
- CPUState *cs = env_cpu(env);
-
- cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1, GETPC());
-
- val = ((uint32_t)env->regs[R_EAX]) |
- ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
-
- switch ((uint32_t)env->regs[R_ECX]) {
- case MSR_IA32_SYSENTER_CS:
- env->sysenter_cs = val & 0xffff;
- break;
- case MSR_IA32_SYSENTER_ESP:
- env->sysenter_esp = val;
- break;
- case MSR_IA32_SYSENTER_EIP:
- env->sysenter_eip = val;
- break;
- case MSR_IA32_APICBASE: {
- int ret;
-
- if (val & MSR_IA32_APICBASE_RESERVED) {
- goto error;
- }
-
- ret = cpu_set_apic_base(env_archcpu(env)->apic_state, val);
- if (ret < 0) {
- goto error;
- }
- break;
- }
- case MSR_EFER:
- {
- uint64_t update_mask;
-
- update_mask = 0;
- if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_SYSCALL) {
- update_mask |= MSR_EFER_SCE;
- }
- if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
- update_mask |= MSR_EFER_LME;
- }
- if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) {
- update_mask |= MSR_EFER_FFXSR;
- }
- if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_NX) {
- update_mask |= MSR_EFER_NXE;
- }
- if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
- update_mask |= MSR_EFER_SVME;
- }
- if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) {
- update_mask |= MSR_EFER_FFXSR;
- }
- cpu_load_efer(env, (env->efer & ~update_mask) |
- (val & update_mask));
- }
- break;
- case MSR_STAR:
- env->star = val;
- break;
- case MSR_PAT:
- env->pat = val;
- break;
- case MSR_IA32_PKRS:
- if (val & 0xFFFFFFFF00000000ull) {
- goto error;
- }
- env->pkrs = val;
- tlb_flush(cs);
- break;
- case MSR_VM_HSAVE_PA:
- if (val & (0xfff | ((~0ULL) << env_archcpu(env)->phys_bits))) {
- goto error;
- }
- env->vm_hsave = val;
- break;
-#ifdef TARGET_X86_64
- case MSR_LSTAR:
- env->lstar = val;
- break;
- case MSR_CSTAR:
- env->cstar = val;
- break;
- case MSR_FMASK:
- env->fmask = val;
- break;
- case MSR_FSBASE:
- env->segs[R_FS].base = val;
- break;
- case MSR_GSBASE:
- env->segs[R_GS].base = val;
- break;
- case MSR_KERNELGSBASE:
- env->kernelgsbase = val;
- break;
-#endif
- case MSR_MTRRphysBase(0):
- case MSR_MTRRphysBase(1):
- case MSR_MTRRphysBase(2):
- case MSR_MTRRphysBase(3):
- case MSR_MTRRphysBase(4):
- case MSR_MTRRphysBase(5):
- case MSR_MTRRphysBase(6):
- case MSR_MTRRphysBase(7):
- env->mtrr_var[((uint32_t)env->regs[R_ECX] -
- MSR_MTRRphysBase(0)) / 2].base = val;
- break;
- case MSR_MTRRphysMask(0):
- case MSR_MTRRphysMask(1):
- case MSR_MTRRphysMask(2):
- case MSR_MTRRphysMask(3):
- case MSR_MTRRphysMask(4):
- case MSR_MTRRphysMask(5):
- case MSR_MTRRphysMask(6):
- case MSR_MTRRphysMask(7):
- env->mtrr_var[((uint32_t)env->regs[R_ECX] -
- MSR_MTRRphysMask(0)) / 2].mask = val;
- break;
- case MSR_MTRRfix64K_00000:
- env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
- MSR_MTRRfix64K_00000] = val;
- break;
- case MSR_MTRRfix16K_80000:
- case MSR_MTRRfix16K_A0000:
- env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
- MSR_MTRRfix16K_80000 + 1] = val;
- break;
- case MSR_MTRRfix4K_C0000:
- case MSR_MTRRfix4K_C8000:
- case MSR_MTRRfix4K_D0000:
- case MSR_MTRRfix4K_D8000:
- case MSR_MTRRfix4K_E0000:
- case MSR_MTRRfix4K_E8000:
- case MSR_MTRRfix4K_F0000:
- case MSR_MTRRfix4K_F8000:
- env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
- MSR_MTRRfix4K_C0000 + 3] = val;
- break;
- case MSR_MTRRdefType:
- env->mtrr_deftype = val;
- break;
- case MSR_MCG_STATUS:
- env->mcg_status = val;
- break;
- case MSR_MCG_CTL:
- if ((env->mcg_cap & MCG_CTL_P)
- && (val == 0 || val == ~(uint64_t)0)) {
- env->mcg_ctl = val;
- }
- break;
- case MSR_TSC_AUX:
- env->tsc_aux = val;
- break;
- case MSR_IA32_MISC_ENABLE:
- env->msr_ia32_misc_enable = val;
- break;
- case MSR_IA32_BNDCFGS:
- /* FIXME: #GP if reserved bits are set. */
- /* FIXME: Extend highest implemented bit of linear address. */
- env->msr_bndcfgs = val;
- cpu_sync_bndcs_hflags(env);
- break;
- case MSR_APIC_START ... MSR_APIC_END: {
- int ret;
- int index = (uint32_t)env->regs[R_ECX] - MSR_APIC_START;
-
- bql_lock();
- ret = apic_msr_write(index, val);
- bql_unlock();
- if (ret < 0) {
- goto error;
- }
-
- break;
- }
- default:
- if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL
- && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL +
- (4 * env->mcg_cap & 0xff)) {
- uint32_t offset = (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL;
- if ((offset & 0x3) != 0
- || (val == 0 || val == ~(uint64_t)0)) {
- env->mce_banks[offset] = val;
- }
- break;
- }
- /* XXX: exception? */
- break;
- }
- return;
-error:
- raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
-}
-
-void helper_rdmsr(CPUX86State *env)
-{
- X86CPU *x86_cpu = env_archcpu(env);
- uint64_t val;
-
- cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0, GETPC());
-
- switch ((uint32_t)env->regs[R_ECX]) {
- case MSR_IA32_SYSENTER_CS:
- val = env->sysenter_cs;
- break;
- case MSR_IA32_SYSENTER_ESP:
- val = env->sysenter_esp;
- break;
- case MSR_IA32_SYSENTER_EIP:
- val = env->sysenter_eip;
- break;
- case MSR_IA32_APICBASE:
- val = cpu_get_apic_base(env_archcpu(env)->apic_state);
- break;
- case MSR_EFER:
- val = env->efer;
- break;
- case MSR_STAR:
- val = env->star;
- break;
- case MSR_PAT:
- val = env->pat;
- break;
- case MSR_IA32_PKRS:
- val = env->pkrs;
- break;
- case MSR_VM_HSAVE_PA:
- val = env->vm_hsave;
- break;
- case MSR_IA32_PERF_STATUS:
- /* tsc_increment_by_tick */
- val = 1000ULL;
- /* CPU multiplier */
- val |= (((uint64_t)4ULL) << 40);
- break;
-#ifdef TARGET_X86_64
- case MSR_LSTAR:
- val = env->lstar;
- break;
- case MSR_CSTAR:
- val = env->cstar;
- break;
- case MSR_FMASK:
- val = env->fmask;
- break;
- case MSR_FSBASE:
- val = env->segs[R_FS].base;
- break;
- case MSR_GSBASE:
- val = env->segs[R_GS].base;
- break;
- case MSR_KERNELGSBASE:
- val = env->kernelgsbase;
- break;
- case MSR_TSC_AUX:
- val = env->tsc_aux;
- break;
-#endif
- case MSR_SMI_COUNT:
- val = env->msr_smi_count;
- break;
- case MSR_MTRRphysBase(0):
- case MSR_MTRRphysBase(1):
- case MSR_MTRRphysBase(2):
- case MSR_MTRRphysBase(3):
- case MSR_MTRRphysBase(4):
- case MSR_MTRRphysBase(5):
- case MSR_MTRRphysBase(6):
- case MSR_MTRRphysBase(7):
- val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
- MSR_MTRRphysBase(0)) / 2].base;
- break;
- case MSR_MTRRphysMask(0):
- case MSR_MTRRphysMask(1):
- case MSR_MTRRphysMask(2):
- case MSR_MTRRphysMask(3):
- case MSR_MTRRphysMask(4):
- case MSR_MTRRphysMask(5):
- case MSR_MTRRphysMask(6):
- case MSR_MTRRphysMask(7):
- val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
- MSR_MTRRphysMask(0)) / 2].mask;
- break;
- case MSR_MTRRfix64K_00000:
- val = env->mtrr_fixed[0];
- break;
- case MSR_MTRRfix16K_80000:
- case MSR_MTRRfix16K_A0000:
- val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
- MSR_MTRRfix16K_80000 + 1];
- break;
- case MSR_MTRRfix4K_C0000:
- case MSR_MTRRfix4K_C8000:
- case MSR_MTRRfix4K_D0000:
- case MSR_MTRRfix4K_D8000:
- case MSR_MTRRfix4K_E0000:
- case MSR_MTRRfix4K_E8000:
- case MSR_MTRRfix4K_F0000:
- case MSR_MTRRfix4K_F8000:
- val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
- MSR_MTRRfix4K_C0000 + 3];
- break;
- case MSR_MTRRdefType:
- val = env->mtrr_deftype;
- break;
- case MSR_MTRRcap:
- if (env->features[FEAT_1_EDX] & CPUID_MTRR) {
- val = MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT |
- MSR_MTRRcap_WC_SUPPORTED;
- } else {
- /* XXX: exception? */
- val = 0;
- }
- break;
- case MSR_MCG_CAP:
- val = env->mcg_cap;
- break;
- case MSR_MCG_CTL:
- if (env->mcg_cap & MCG_CTL_P) {
- val = env->mcg_ctl;
- } else {
- val = 0;
- }
- break;
- case MSR_MCG_STATUS:
- val = env->mcg_status;
- break;
- case MSR_IA32_MISC_ENABLE:
- val = env->msr_ia32_misc_enable;
- break;
- case MSR_IA32_BNDCFGS:
- val = env->msr_bndcfgs;
- break;
- case MSR_IA32_UCODE_REV:
- val = x86_cpu->ucode_rev;
- break;
- case MSR_CORE_THREAD_COUNT: {
- CPUState *cs = CPU(x86_cpu);
- val = (cs->nr_threads * cs->nr_cores) | (cs->nr_cores << 16);
- break;
- }
- case MSR_APIC_START ... MSR_APIC_END: {
- int ret;
- int index = (uint32_t)env->regs[R_ECX] - MSR_APIC_START;
-
- bql_lock();
- ret = apic_msr_read(index, &val);
- bql_unlock();
- if (ret < 0) {
- raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
- }
-
- break;
- }
- default:
- if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL
- && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL +
- (4 * env->mcg_cap & 0xff)) {
- uint32_t offset = (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL;
- val = env->mce_banks[offset];
- break;
- }
- /* XXX: exception? */
- val = 0;
- break;
- }
- env->regs[R_EAX] = (uint32_t)(val);
- env->regs[R_EDX] = (uint32_t)(val >> 32);
-}
-
-void helper_flush_page(CPUX86State *env, target_ulong addr)
-{
- tlb_flush_page(env_cpu(env), addr);
-}
-
-G_NORETURN void helper_hlt(CPUX86State *env)
-{
- CPUState *cs = env_cpu(env);
-
- do_end_instruction(env);
- cs->halted = 1;
- cs->exception_index = EXCP_HLT;
- cpu_loop_exit(cs);
-}
-
-void helper_monitor(CPUX86State *env, target_ulong ptr)
-{
- if ((uint32_t)env->regs[R_ECX] != 0) {
- raise_exception_ra(env, EXCP0D_GPF, GETPC());
- }
- /* XXX: store address? */
- cpu_svm_check_intercept_param(env, SVM_EXIT_MONITOR, 0, GETPC());
-}
-
-G_NORETURN void helper_mwait(CPUX86State *env, int next_eip_addend)
-{
- CPUState *cs = env_cpu(env);
-
- if ((uint32_t)env->regs[R_ECX] != 0) {
- raise_exception_ra(env, EXCP0D_GPF, GETPC());
- }
- cpu_svm_check_intercept_param(env, SVM_EXIT_MWAIT, 0, GETPC());
- env->eip += next_eip_addend;
-
- /* XXX: not complete but not completely erroneous */
- if (cs->cpu_index != 0 || CPU_NEXT(cs) != NULL) {
- helper_pause(env);
- } else {
- helper_hlt(env);
- }
-}
+++ /dev/null
-/*
- * x86 segmentation related helpers: (sysemu-only code)
- * TSS, interrupts, system calls, jumps and call/task gates, descriptors
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * 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.1 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 "qemu/log.h"
-#include "qemu/main-loop.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-#include "exec/cpu_ldst.h"
-#include "tcg/helper-tcg.h"
-#include "../seg_helper.h"
-
-void helper_syscall(CPUX86State *env, int next_eip_addend)
-{
- int selector;
-
- if (!(env->efer & MSR_EFER_SCE)) {
- raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC());
- }
- selector = (env->star >> 32) & 0xffff;
-#ifdef TARGET_X86_64
- if (env->hflags & HF_LMA_MASK) {
- int code64;
-
- env->regs[R_ECX] = env->eip + next_eip_addend;
- env->regs[11] = cpu_compute_eflags(env) & ~RF_MASK;
-
- code64 = env->hflags & HF_CS64_MASK;
-
- env->eflags &= ~(env->fmask | RF_MASK);
- cpu_load_eflags(env, env->eflags, 0);
- cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_P_MASK |
- DESC_S_MASK |
- DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK |
- DESC_L_MASK);
- cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK |
- DESC_W_MASK | DESC_A_MASK);
- if (code64) {
- env->eip = env->lstar;
- } else {
- env->eip = env->cstar;
- }
- } else
-#endif
- {
- env->regs[R_ECX] = (uint32_t)(env->eip + next_eip_addend);
-
- env->eflags &= ~(IF_MASK | RF_MASK | VM_MASK);
- cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK |
- DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
- cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
- 0, 0xffffffff,
- DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
- DESC_S_MASK |
- DESC_W_MASK | DESC_A_MASK);
- env->eip = (uint32_t)env->star;
- }
-}
-
-void handle_even_inj(CPUX86State *env, int intno, int is_int,
- int error_code, int is_hw, int rm)
-{
- CPUState *cs = env_cpu(env);
- uint32_t event_inj = x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
- control.event_inj));
-
- if (!(event_inj & SVM_EVTINJ_VALID)) {
- int type;
-
- if (is_int) {
- type = SVM_EVTINJ_TYPE_SOFT;
- } else {
- type = SVM_EVTINJ_TYPE_EXEPT;
- }
- event_inj = intno | type | SVM_EVTINJ_VALID;
- if (!rm && exception_has_error_code(intno)) {
- event_inj |= SVM_EVTINJ_VALID_ERR;
- x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
- control.event_inj_err),
- error_code);
- }
- x86_stl_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, control.event_inj),
- event_inj);
- }
-}
-
-void x86_cpu_do_interrupt(CPUState *cs)
-{
- X86CPU *cpu = X86_CPU(cs);
- CPUX86State *env = &cpu->env;
-
- if (cs->exception_index == EXCP_VMEXIT) {
- assert(env->old_exception == -1);
- do_vmexit(env);
- } else {
- do_interrupt_all(cpu, cs->exception_index,
- env->exception_is_int,
- env->error_code,
- env->exception_next_eip, 0);
- /* successfully delivered */
- env->old_exception = -1;
- }
-}
-
-bool x86_cpu_exec_halt(CPUState *cpu)
-{
- X86CPU *x86_cpu = X86_CPU(cpu);
- CPUX86State *env = &x86_cpu->env;
-
- if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
- bql_lock();
- apic_poll_irq(x86_cpu->apic_state);
- cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL);
- bql_unlock();
- }
-
- if (!cpu_has_work(cpu)) {
- return false;
- }
-
- /* Complete HLT instruction. */
- if (env->eflags & TF_MASK) {
- env->dr[6] |= DR6_BS;
- do_interrupt_all(x86_cpu, EXCP01_DB, 0, 0, env->eip, 0);
- }
- return true;
-}
-
-bool x86_need_replay_interrupt(int interrupt_request)
-{
- /*
- * CPU_INTERRUPT_POLL is a virtual event which gets converted into a
- * "real" interrupt event later. It does not need to be recorded for
- * replay purposes.
- */
- return !(interrupt_request & CPU_INTERRUPT_POLL);
-}
-
-bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
-{
- X86CPU *cpu = X86_CPU(cs);
- CPUX86State *env = &cpu->env;
- int intno;
-
- interrupt_request = x86_cpu_pending_interrupt(cs, interrupt_request);
- if (!interrupt_request) {
- return false;
- }
-
- /* Don't process multiple interrupt requests in a single call.
- * This is required to make icount-driven execution deterministic.
- */
- switch (interrupt_request) {
- case CPU_INTERRUPT_POLL:
- cs->interrupt_request &= ~CPU_INTERRUPT_POLL;
- apic_poll_irq(cpu->apic_state);
- break;
- case CPU_INTERRUPT_SIPI:
- do_cpu_sipi(cpu);
- break;
- case CPU_INTERRUPT_SMI:
- cpu_svm_check_intercept_param(env, SVM_EXIT_SMI, 0, 0);
- cs->interrupt_request &= ~CPU_INTERRUPT_SMI;
- do_smm_enter(cpu);
- break;
- case CPU_INTERRUPT_NMI:
- cpu_svm_check_intercept_param(env, SVM_EXIT_NMI, 0, 0);
- cs->interrupt_request &= ~CPU_INTERRUPT_NMI;
- env->hflags2 |= HF2_NMI_MASK;
- do_interrupt_x86_hardirq(env, EXCP02_NMI, 1);
- break;
- case CPU_INTERRUPT_MCE:
- cs->interrupt_request &= ~CPU_INTERRUPT_MCE;
- do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0);
- break;
- case CPU_INTERRUPT_HARD:
- cpu_svm_check_intercept_param(env, SVM_EXIT_INTR, 0, 0);
- cs->interrupt_request &= ~(CPU_INTERRUPT_HARD |
- CPU_INTERRUPT_VIRQ);
- intno = cpu_get_pic_interrupt(env);
- qemu_log_mask(CPU_LOG_INT,
- "Servicing hardware INT=0x%02x\n", intno);
- do_interrupt_x86_hardirq(env, intno, 1);
- break;
- case CPU_INTERRUPT_VIRQ:
- cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR, 0, 0);
- intno = x86_ldl_phys(cs, env->vm_vmcb
- + offsetof(struct vmcb, control.int_vector));
- qemu_log_mask(CPU_LOG_INT,
- "Servicing virtual hardware INT=0x%02x\n", intno);
- do_interrupt_x86_hardirq(env, intno, 1);
- cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
- env->int_ctl &= ~V_IRQ_MASK;
- break;
- }
-
- /* Ensure that no TB jump will be modified as the program flow was changed. */
- return true;
-}
-
-/* check if Port I/O is allowed in TSS */
-void helper_check_io(CPUX86State *env, uint32_t addr, uint32_t size)
-{
- uintptr_t retaddr = GETPC();
- uint32_t io_offset, val, mask;
-
- /* TSS must be a valid 32 bit one */
- if (!(env->tr.flags & DESC_P_MASK) ||
- ((env->tr.flags >> DESC_TYPE_SHIFT) & 0xf) != 9 ||
- env->tr.limit < 103) {
- goto fail;
- }
- io_offset = cpu_lduw_kernel_ra(env, env->tr.base + 0x66, retaddr);
- io_offset += (addr >> 3);
- /* Note: the check needs two bytes */
- if ((io_offset + 1) > env->tr.limit) {
- goto fail;
- }
- val = cpu_lduw_kernel_ra(env, env->tr.base + io_offset, retaddr);
- val >>= (addr & 7);
- mask = (1 << size) - 1;
- /* all bits must be zero to allow the I/O */
- if ((val & mask) != 0) {
- fail:
- raise_exception_err_ra(env, EXCP0D_GPF, 0, retaddr);
- }
-}
+++ /dev/null
-/*
- * x86 SMM helpers (sysemu-only)
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * 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.1 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"
-#include "exec/log.h"
-#include "tcg/helper-tcg.h"
-
-
-/* SMM support */
-
-#ifdef TARGET_X86_64
-#define SMM_REVISION_ID 0x00020064
-#else
-#define SMM_REVISION_ID 0x00020000
-#endif
-
-void do_smm_enter(X86CPU *cpu)
-{
- CPUX86State *env = &cpu->env;
- CPUState *cs = CPU(cpu);
- target_ulong sm_state;
- SegmentCache *dt;
- int i, offset;
-
- qemu_log_mask(CPU_LOG_INT, "SMM: enter\n");
- log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), CPU_DUMP_CCOP);
-
- env->msr_smi_count++;
- env->hflags |= HF_SMM_MASK;
- if (env->hflags2 & HF2_NMI_MASK) {
- env->hflags2 |= HF2_SMM_INSIDE_NMI_MASK;
- } else {
- env->hflags2 |= HF2_NMI_MASK;
- }
-
- sm_state = env->smbase + 0x8000;
-
-#ifdef TARGET_X86_64
- for (i = 0; i < 6; i++) {
- dt = &env->segs[i];
- offset = 0x7e00 + i * 16;
- x86_stw_phys(cs, sm_state + offset, dt->selector);
- x86_stw_phys(cs, sm_state + offset + 2, (dt->flags >> 8) & 0xf0ff);
- x86_stl_phys(cs, sm_state + offset + 4, dt->limit);
- x86_stq_phys(cs, sm_state + offset + 8, dt->base);
- }
-
- x86_stq_phys(cs, sm_state + 0x7e68, env->gdt.base);
- x86_stl_phys(cs, sm_state + 0x7e64, env->gdt.limit);
-
- x86_stw_phys(cs, sm_state + 0x7e70, env->ldt.selector);
- x86_stq_phys(cs, sm_state + 0x7e78, env->ldt.base);
- x86_stl_phys(cs, sm_state + 0x7e74, env->ldt.limit);
- x86_stw_phys(cs, sm_state + 0x7e72, (env->ldt.flags >> 8) & 0xf0ff);
-
- x86_stq_phys(cs, sm_state + 0x7e88, env->idt.base);
- x86_stl_phys(cs, sm_state + 0x7e84, env->idt.limit);
-
- x86_stw_phys(cs, sm_state + 0x7e90, env->tr.selector);
- x86_stq_phys(cs, sm_state + 0x7e98, env->tr.base);
- x86_stl_phys(cs, sm_state + 0x7e94, env->tr.limit);
- x86_stw_phys(cs, sm_state + 0x7e92, (env->tr.flags >> 8) & 0xf0ff);
-
- /* ??? Vol 1, 16.5.6 Intel MPX and SMM says that IA32_BNDCFGS
- is saved at offset 7ED0. Vol 3, 34.4.1.1, Table 32-2, has
- 7EA0-7ED7 as "reserved". What's this, and what's really
- supposed to happen? */
- x86_stq_phys(cs, sm_state + 0x7ed0, env->efer);
-
- x86_stq_phys(cs, sm_state + 0x7ff8, env->regs[R_EAX]);
- x86_stq_phys(cs, sm_state + 0x7ff0, env->regs[R_ECX]);
- x86_stq_phys(cs, sm_state + 0x7fe8, env->regs[R_EDX]);
- x86_stq_phys(cs, sm_state + 0x7fe0, env->regs[R_EBX]);
- x86_stq_phys(cs, sm_state + 0x7fd8, env->regs[R_ESP]);
- x86_stq_phys(cs, sm_state + 0x7fd0, env->regs[R_EBP]);
- x86_stq_phys(cs, sm_state + 0x7fc8, env->regs[R_ESI]);
- x86_stq_phys(cs, sm_state + 0x7fc0, env->regs[R_EDI]);
- for (i = 8; i < 16; i++) {
- x86_stq_phys(cs, sm_state + 0x7ff8 - i * 8, env->regs[i]);
- }
- x86_stq_phys(cs, sm_state + 0x7f78, env->eip);
- x86_stl_phys(cs, sm_state + 0x7f70, cpu_compute_eflags(env));
- x86_stl_phys(cs, sm_state + 0x7f68, env->dr[6]);
- x86_stl_phys(cs, sm_state + 0x7f60, env->dr[7]);
-
- x86_stl_phys(cs, sm_state + 0x7f48, env->cr[4]);
- x86_stq_phys(cs, sm_state + 0x7f50, env->cr[3]);
- x86_stl_phys(cs, sm_state + 0x7f58, env->cr[0]);
-
- x86_stl_phys(cs, sm_state + 0x7efc, SMM_REVISION_ID);
- x86_stl_phys(cs, sm_state + 0x7f00, env->smbase);
-#else
- x86_stl_phys(cs, sm_state + 0x7ffc, env->cr[0]);
- x86_stl_phys(cs, sm_state + 0x7ff8, env->cr[3]);
- x86_stl_phys(cs, sm_state + 0x7ff4, cpu_compute_eflags(env));
- x86_stl_phys(cs, sm_state + 0x7ff0, env->eip);
- x86_stl_phys(cs, sm_state + 0x7fec, env->regs[R_EDI]);
- x86_stl_phys(cs, sm_state + 0x7fe8, env->regs[R_ESI]);
- x86_stl_phys(cs, sm_state + 0x7fe4, env->regs[R_EBP]);
- x86_stl_phys(cs, sm_state + 0x7fe0, env->regs[R_ESP]);
- x86_stl_phys(cs, sm_state + 0x7fdc, env->regs[R_EBX]);
- x86_stl_phys(cs, sm_state + 0x7fd8, env->regs[R_EDX]);
- x86_stl_phys(cs, sm_state + 0x7fd4, env->regs[R_ECX]);
- x86_stl_phys(cs, sm_state + 0x7fd0, env->regs[R_EAX]);
- x86_stl_phys(cs, sm_state + 0x7fcc, env->dr[6]);
- x86_stl_phys(cs, sm_state + 0x7fc8, env->dr[7]);
-
- x86_stl_phys(cs, sm_state + 0x7fc4, env->tr.selector);
- x86_stl_phys(cs, sm_state + 0x7f64, env->tr.base);
- x86_stl_phys(cs, sm_state + 0x7f60, env->tr.limit);
- x86_stl_phys(cs, sm_state + 0x7f5c, (env->tr.flags >> 8) & 0xf0ff);
-
- x86_stl_phys(cs, sm_state + 0x7fc0, env->ldt.selector);
- x86_stl_phys(cs, sm_state + 0x7f80, env->ldt.base);
- x86_stl_phys(cs, sm_state + 0x7f7c, env->ldt.limit);
- x86_stl_phys(cs, sm_state + 0x7f78, (env->ldt.flags >> 8) & 0xf0ff);
-
- x86_stl_phys(cs, sm_state + 0x7f74, env->gdt.base);
- x86_stl_phys(cs, sm_state + 0x7f70, env->gdt.limit);
-
- x86_stl_phys(cs, sm_state + 0x7f58, env->idt.base);
- x86_stl_phys(cs, sm_state + 0x7f54, env->idt.limit);
-
- for (i = 0; i < 6; i++) {
- dt = &env->segs[i];
- if (i < 3) {
- offset = 0x7f84 + i * 12;
- } else {
- offset = 0x7f2c + (i - 3) * 12;
- }
- x86_stl_phys(cs, sm_state + 0x7fa8 + i * 4, dt->selector);
- x86_stl_phys(cs, sm_state + offset + 8, dt->base);
- x86_stl_phys(cs, sm_state + offset + 4, dt->limit);
- x86_stl_phys(cs, sm_state + offset, (dt->flags >> 8) & 0xf0ff);
- }
- x86_stl_phys(cs, sm_state + 0x7f14, env->cr[4]);
-
- x86_stl_phys(cs, sm_state + 0x7efc, SMM_REVISION_ID);
- x86_stl_phys(cs, sm_state + 0x7ef8, env->smbase);
-#endif
- /* init SMM cpu state */
-
-#ifdef TARGET_X86_64
- cpu_load_efer(env, 0);
-#endif
- cpu_load_eflags(env, 0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C |
- DF_MASK));
- env->eip = 0x00008000;
- cpu_x86_update_cr0(env,
- env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK |
- CR0_PG_MASK));
- cpu_x86_update_cr4(env, 0);
- env->dr[7] = 0x00000400;
-
- cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase,
- 0xffffffff,
- DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
- DESC_G_MASK | DESC_A_MASK);
- cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffffffff,
- DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
- DESC_G_MASK | DESC_A_MASK);
- cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffffffff,
- DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
- DESC_G_MASK | DESC_A_MASK);
- cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffffffff,
- DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
- DESC_G_MASK | DESC_A_MASK);
- cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffffffff,
- DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
- DESC_G_MASK | DESC_A_MASK);
- cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff,
- DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
- DESC_G_MASK | DESC_A_MASK);
-}
-
-void helper_rsm(CPUX86State *env)
-{
- X86CPU *cpu = env_archcpu(env);
- CPUState *cs = env_cpu(env);
- target_ulong sm_state;
- int i, offset;
- uint32_t val;
-
- sm_state = env->smbase + 0x8000;
-#ifdef TARGET_X86_64
- cpu_load_efer(env, x86_ldq_phys(cs, sm_state + 0x7ed0));
-
- env->gdt.base = x86_ldq_phys(cs, sm_state + 0x7e68);
- env->gdt.limit = x86_ldl_phys(cs, sm_state + 0x7e64);
-
- env->ldt.selector = x86_lduw_phys(cs, sm_state + 0x7e70);
- env->ldt.base = x86_ldq_phys(cs, sm_state + 0x7e78);
- env->ldt.limit = x86_ldl_phys(cs, sm_state + 0x7e74);
- env->ldt.flags = (x86_lduw_phys(cs, sm_state + 0x7e72) & 0xf0ff) << 8;
-
- env->idt.base = x86_ldq_phys(cs, sm_state + 0x7e88);
- env->idt.limit = x86_ldl_phys(cs, sm_state + 0x7e84);
-
- env->tr.selector = x86_lduw_phys(cs, sm_state + 0x7e90);
- env->tr.base = x86_ldq_phys(cs, sm_state + 0x7e98);
- env->tr.limit = x86_ldl_phys(cs, sm_state + 0x7e94);
- env->tr.flags = (x86_lduw_phys(cs, sm_state + 0x7e92) & 0xf0ff) << 8;
-
- env->regs[R_EAX] = x86_ldq_phys(cs, sm_state + 0x7ff8);
- env->regs[R_ECX] = x86_ldq_phys(cs, sm_state + 0x7ff0);
- env->regs[R_EDX] = x86_ldq_phys(cs, sm_state + 0x7fe8);
- env->regs[R_EBX] = x86_ldq_phys(cs, sm_state + 0x7fe0);
- env->regs[R_ESP] = x86_ldq_phys(cs, sm_state + 0x7fd8);
- env->regs[R_EBP] = x86_ldq_phys(cs, sm_state + 0x7fd0);
- env->regs[R_ESI] = x86_ldq_phys(cs, sm_state + 0x7fc8);
- env->regs[R_EDI] = x86_ldq_phys(cs, sm_state + 0x7fc0);
- for (i = 8; i < 16; i++) {
- env->regs[i] = x86_ldq_phys(cs, sm_state + 0x7ff8 - i * 8);
- }
- env->eip = x86_ldq_phys(cs, sm_state + 0x7f78);
- cpu_load_eflags(env, x86_ldl_phys(cs, sm_state + 0x7f70),
- ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
- env->dr[6] = x86_ldl_phys(cs, sm_state + 0x7f68);
- env->dr[7] = x86_ldl_phys(cs, sm_state + 0x7f60);
-
- cpu_x86_update_cr4(env, x86_ldl_phys(cs, sm_state + 0x7f48));
- cpu_x86_update_cr3(env, x86_ldq_phys(cs, sm_state + 0x7f50));
- cpu_x86_update_cr0(env, x86_ldl_phys(cs, sm_state + 0x7f58));
-
- for (i = 0; i < 6; i++) {
- offset = 0x7e00 + i * 16;
- cpu_x86_load_seg_cache(env, i,
- x86_lduw_phys(cs, sm_state + offset),
- x86_ldq_phys(cs, sm_state + offset + 8),
- x86_ldl_phys(cs, sm_state + offset + 4),
- (x86_lduw_phys(cs, sm_state + offset + 2) &
- 0xf0ff) << 8);
- }
-
- val = x86_ldl_phys(cs, sm_state + 0x7efc); /* revision ID */
- if (val & 0x20000) {
- env->smbase = x86_ldl_phys(cs, sm_state + 0x7f00);
- }
-#else
- cpu_x86_update_cr0(env, x86_ldl_phys(cs, sm_state + 0x7ffc));
- cpu_x86_update_cr3(env, x86_ldl_phys(cs, sm_state + 0x7ff8));
- cpu_load_eflags(env, x86_ldl_phys(cs, sm_state + 0x7ff4),
- ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
- env->eip = x86_ldl_phys(cs, sm_state + 0x7ff0);
- env->regs[R_EDI] = x86_ldl_phys(cs, sm_state + 0x7fec);
- env->regs[R_ESI] = x86_ldl_phys(cs, sm_state + 0x7fe8);
- env->regs[R_EBP] = x86_ldl_phys(cs, sm_state + 0x7fe4);
- env->regs[R_ESP] = x86_ldl_phys(cs, sm_state + 0x7fe0);
- env->regs[R_EBX] = x86_ldl_phys(cs, sm_state + 0x7fdc);
- env->regs[R_EDX] = x86_ldl_phys(cs, sm_state + 0x7fd8);
- env->regs[R_ECX] = x86_ldl_phys(cs, sm_state + 0x7fd4);
- env->regs[R_EAX] = x86_ldl_phys(cs, sm_state + 0x7fd0);
- env->dr[6] = x86_ldl_phys(cs, sm_state + 0x7fcc);
- env->dr[7] = x86_ldl_phys(cs, sm_state + 0x7fc8);
-
- env->tr.selector = x86_ldl_phys(cs, sm_state + 0x7fc4) & 0xffff;
- env->tr.base = x86_ldl_phys(cs, sm_state + 0x7f64);
- env->tr.limit = x86_ldl_phys(cs, sm_state + 0x7f60);
- env->tr.flags = (x86_ldl_phys(cs, sm_state + 0x7f5c) & 0xf0ff) << 8;
-
- env->ldt.selector = x86_ldl_phys(cs, sm_state + 0x7fc0) & 0xffff;
- env->ldt.base = x86_ldl_phys(cs, sm_state + 0x7f80);
- env->ldt.limit = x86_ldl_phys(cs, sm_state + 0x7f7c);
- env->ldt.flags = (x86_ldl_phys(cs, sm_state + 0x7f78) & 0xf0ff) << 8;
-
- env->gdt.base = x86_ldl_phys(cs, sm_state + 0x7f74);
- env->gdt.limit = x86_ldl_phys(cs, sm_state + 0x7f70);
-
- env->idt.base = x86_ldl_phys(cs, sm_state + 0x7f58);
- env->idt.limit = x86_ldl_phys(cs, sm_state + 0x7f54);
-
- for (i = 0; i < 6; i++) {
- if (i < 3) {
- offset = 0x7f84 + i * 12;
- } else {
- offset = 0x7f2c + (i - 3) * 12;
- }
- cpu_x86_load_seg_cache(env, i,
- x86_ldl_phys(cs,
- sm_state + 0x7fa8 + i * 4) & 0xffff,
- x86_ldl_phys(cs, sm_state + offset + 8),
- x86_ldl_phys(cs, sm_state + offset + 4),
- (x86_ldl_phys(cs,
- sm_state + offset) & 0xf0ff) << 8);
- }
- cpu_x86_update_cr4(env, x86_ldl_phys(cs, sm_state + 0x7f14));
-
- val = x86_ldl_phys(cs, sm_state + 0x7efc); /* revision ID */
- if (val & 0x20000) {
- env->smbase = x86_ldl_phys(cs, sm_state + 0x7ef8);
- }
-#endif
- if ((env->hflags2 & HF2_SMM_INSIDE_NMI_MASK) == 0) {
- env->hflags2 &= ~HF2_NMI_MASK;
- }
- env->hflags2 &= ~HF2_SMM_INSIDE_NMI_MASK;
- env->hflags &= ~HF_SMM_MASK;
-
- qemu_log_mask(CPU_LOG_INT, "SMM: after RSM\n");
- log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), CPU_DUMP_CCOP);
-}
+++ /dev/null
-/*
- * x86 SVM helpers (sysemu only)
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * 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.1 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 "qemu/log.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-#include "exec/exec-all.h"
-#include "exec/cpu_ldst.h"
-#include "tcg/helper-tcg.h"
-
-/* Secure Virtual Machine helpers */
-
-static void svm_save_seg(CPUX86State *env, int mmu_idx, hwaddr addr,
- const SegmentCache *sc)
-{
- cpu_stw_mmuidx_ra(env, addr + offsetof(struct vmcb_seg, selector),
- sc->selector, mmu_idx, 0);
- cpu_stq_mmuidx_ra(env, addr + offsetof(struct vmcb_seg, base),
- sc->base, mmu_idx, 0);
- cpu_stl_mmuidx_ra(env, addr + offsetof(struct vmcb_seg, limit),
- sc->limit, mmu_idx, 0);
- cpu_stw_mmuidx_ra(env, addr + offsetof(struct vmcb_seg, attrib),
- ((sc->flags >> 8) & 0xff)
- | ((sc->flags >> 12) & 0x0f00),
- mmu_idx, 0);
-}
-
-/*
- * VMRUN and VMLOAD canonicalizes (i.e., sign-extend to bit 63) all base
- * addresses in the segment registers that have been loaded.
- */
-static inline void svm_canonicalization(CPUX86State *env, target_ulong *seg_base)
-{
- uint16_t shift_amt = 64 - cpu_x86_virtual_addr_width(env);
- *seg_base = ((((long) *seg_base) << shift_amt) >> shift_amt);
-}
-
-static void svm_load_seg(CPUX86State *env, int mmu_idx, hwaddr addr,
- SegmentCache *sc)
-{
- unsigned int flags;
-
- sc->selector =
- cpu_lduw_mmuidx_ra(env, addr + offsetof(struct vmcb_seg, selector),
- mmu_idx, 0);
- sc->base =
- cpu_ldq_mmuidx_ra(env, addr + offsetof(struct vmcb_seg, base),
- mmu_idx, 0);
- sc->limit =
- cpu_ldl_mmuidx_ra(env, addr + offsetof(struct vmcb_seg, limit),
- mmu_idx, 0);
- flags =
- cpu_lduw_mmuidx_ra(env, addr + offsetof(struct vmcb_seg, attrib),
- mmu_idx, 0);
- sc->flags = ((flags & 0xff) << 8) | ((flags & 0x0f00) << 12);
-
- svm_canonicalization(env, &sc->base);
-}
-
-static void svm_load_seg_cache(CPUX86State *env, int mmu_idx,
- hwaddr addr, int seg_reg)
-{
- SegmentCache sc;
-
- svm_load_seg(env, mmu_idx, addr, &sc);
- cpu_x86_load_seg_cache(env, seg_reg, sc.selector,
- sc.base, sc.limit, sc.flags);
-}
-
-static inline bool is_efer_invalid_state (CPUX86State *env)
-{
- if (!(env->efer & MSR_EFER_SVME)) {
- return true;
- }
-
- if (env->efer & MSR_EFER_RESERVED) {
- return true;
- }
-
- if ((env->efer & (MSR_EFER_LMA | MSR_EFER_LME)) &&
- !(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM)) {
- return true;
- }
-
- if ((env->efer & MSR_EFER_LME) && (env->cr[0] & CR0_PG_MASK)
- && !(env->cr[4] & CR4_PAE_MASK)) {
- return true;
- }
-
- if ((env->efer & MSR_EFER_LME) && (env->cr[0] & CR0_PG_MASK)
- && !(env->cr[0] & CR0_PE_MASK)) {
- return true;
- }
-
- if ((env->efer & MSR_EFER_LME) && (env->cr[0] & CR0_PG_MASK)
- && (env->cr[4] & CR4_PAE_MASK)
- && (env->segs[R_CS].flags & DESC_L_MASK)
- && (env->segs[R_CS].flags & DESC_B_MASK)) {
- return true;
- }
-
- return false;
-}
-
-static inline bool virtual_gif_enabled(CPUX86State *env)
-{
- if (likely(env->hflags & HF_GUEST_MASK)) {
- return (env->features[FEAT_SVM] & CPUID_SVM_VGIF)
- && (env->int_ctl & V_GIF_ENABLED_MASK);
- }
- return false;
-}
-
-static inline bool virtual_vm_load_save_enabled(CPUX86State *env, uint32_t exit_code, uintptr_t retaddr)
-{
- uint64_t lbr_ctl;
-
- if (likely(env->hflags & HF_GUEST_MASK)) {
- if (likely(!(env->hflags2 & HF2_NPT_MASK)) || !(env->efer & MSR_EFER_LMA)) {
- cpu_vmexit(env, exit_code, 0, retaddr);
- }
-
- lbr_ctl = x86_ldl_phys(env_cpu(env), env->vm_vmcb + offsetof(struct vmcb,
- control.lbr_ctl));
- return (env->features[FEAT_SVM] & CPUID_SVM_V_VMSAVE_VMLOAD)
- && (lbr_ctl & V_VMLOAD_VMSAVE_ENABLED_MASK);
-
- }
-
- return false;
-}
-
-static inline bool virtual_gif_set(CPUX86State *env)
-{
- return !virtual_gif_enabled(env) || (env->int_ctl & V_GIF_MASK);
-}
-
-void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
-{
- CPUState *cs = env_cpu(env);
- X86CPU *cpu = env_archcpu(env);
- target_ulong addr;
- uint64_t nested_ctl;
- uint32_t event_inj;
- uint32_t asid;
- uint64_t new_cr0;
- uint64_t new_cr3;
- uint64_t new_cr4;
- uint64_t new_dr6;
- uint64_t new_dr7;
-
- if (aflag == 2) {
- addr = env->regs[R_EAX];
- } else {
- addr = (uint32_t)env->regs[R_EAX];
- }
-
- /* Exceptions are checked before the intercept. */
- if (addr & (0xfff | ((~0ULL) << env_archcpu(env)->phys_bits))) {
- raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
- }
-
- cpu_svm_check_intercept_param(env, SVM_EXIT_VMRUN, 0, GETPC());
-
- qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmrun! " TARGET_FMT_lx "\n", addr);
-
- env->vm_vmcb = addr;
-
- /* save the current CPU state in the hsave page */
- x86_stq_phys(cs, env->vm_hsave + offsetof(struct vmcb, save.gdtr.base),
- env->gdt.base);
- x86_stl_phys(cs, env->vm_hsave + offsetof(struct vmcb, save.gdtr.limit),
- env->gdt.limit);
-
- x86_stq_phys(cs, env->vm_hsave + offsetof(struct vmcb, save.idtr.base),
- env->idt.base);
- x86_stl_phys(cs, env->vm_hsave + offsetof(struct vmcb, save.idtr.limit),
- env->idt.limit);
-
- x86_stq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb, save.cr0), env->cr[0]);
- x86_stq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb, save.cr2), env->cr[2]);
- x86_stq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb, save.cr3), env->cr[3]);
- x86_stq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb, save.cr4), env->cr[4]);
- x86_stq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb, save.dr6), env->dr[6]);
- x86_stq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb, save.dr7), env->dr[7]);
-
- x86_stq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb, save.efer), env->efer);
- x86_stq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb, save.rflags),
- cpu_compute_eflags(env));
-
- svm_save_seg(env, MMU_PHYS_IDX,
- env->vm_hsave + offsetof(struct vmcb, save.es),
- &env->segs[R_ES]);
- svm_save_seg(env, MMU_PHYS_IDX,
- env->vm_hsave + offsetof(struct vmcb, save.cs),
- &env->segs[R_CS]);
- svm_save_seg(env, MMU_PHYS_IDX,
- env->vm_hsave + offsetof(struct vmcb, save.ss),
- &env->segs[R_SS]);
- svm_save_seg(env, MMU_PHYS_IDX,
- env->vm_hsave + offsetof(struct vmcb, save.ds),
- &env->segs[R_DS]);
-
- x86_stq_phys(cs, env->vm_hsave + offsetof(struct vmcb, save.rip),
- env->eip + next_eip_addend);
- x86_stq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb, save.rsp), env->regs[R_ESP]);
- x86_stq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb, save.rax), env->regs[R_EAX]);
-
- /* load the interception bitmaps so we do not need to access the
- vmcb in svm mode */
- env->intercept = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
- control.intercept));
- env->intercept_cr_read = x86_lduw_phys(cs, env->vm_vmcb +
- offsetof(struct vmcb,
- control.intercept_cr_read));
- env->intercept_cr_write = x86_lduw_phys(cs, env->vm_vmcb +
- offsetof(struct vmcb,
- control.intercept_cr_write));
- env->intercept_dr_read = x86_lduw_phys(cs, env->vm_vmcb +
- offsetof(struct vmcb,
- control.intercept_dr_read));
- env->intercept_dr_write = x86_lduw_phys(cs, env->vm_vmcb +
- offsetof(struct vmcb,
- control.intercept_dr_write));
- env->intercept_exceptions = x86_ldl_phys(cs, env->vm_vmcb +
- offsetof(struct vmcb,
- control.intercept_exceptions
- ));
-
- env->hflags &= ~HF_INHIBIT_IRQ_MASK;
- if (x86_ldl_phys(cs, env->vm_vmcb +
- offsetof(struct vmcb, control.int_state)) &
- SVM_INTERRUPT_SHADOW_MASK) {
- env->hflags |= HF_INHIBIT_IRQ_MASK;
- }
-
- nested_ctl = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
- control.nested_ctl));
- asid = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
- control.asid));
-
- uint64_t msrpm_base_pa = x86_ldq_phys(cs, env->vm_vmcb +
- offsetof(struct vmcb,
- control.msrpm_base_pa));
- uint64_t iopm_base_pa = x86_ldq_phys(cs, env->vm_vmcb +
- offsetof(struct vmcb, control.iopm_base_pa));
-
- if ((msrpm_base_pa & ~0xfff) >= (1ull << cpu->phys_bits) - SVM_MSRPM_SIZE) {
- cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
- }
-
- if ((iopm_base_pa & ~0xfff) >= (1ull << cpu->phys_bits) - SVM_IOPM_SIZE) {
- cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
- }
-
- env->nested_pg_mode = 0;
-
- if (!cpu_svm_has_intercept(env, SVM_EXIT_VMRUN)) {
- cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
- }
- if (asid == 0) {
- cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
- }
-
- if (nested_ctl & SVM_NPT_ENABLED) {
- env->nested_cr3 = x86_ldq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb,
- control.nested_cr3));
- env->hflags2 |= HF2_NPT_MASK;
-
- env->nested_pg_mode = get_pg_mode(env) & PG_MODE_SVM_MASK;
-
- tlb_flush_by_mmuidx(cs, 1 << MMU_NESTED_IDX);
- }
-
- /* enable intercepts */
- env->hflags |= HF_GUEST_MASK;
-
- env->tsc_offset = x86_ldq_phys(cs, env->vm_vmcb +
- offsetof(struct vmcb, control.tsc_offset));
-
- new_cr0 = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.cr0));
- if (new_cr0 & SVM_CR0_RESERVED_MASK) {
- cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
- }
- if ((new_cr0 & CR0_NW_MASK) && !(new_cr0 & CR0_CD_MASK)) {
- cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
- }
- new_cr3 = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.cr3));
- if ((env->efer & MSR_EFER_LMA) &&
- (new_cr3 & ((~0ULL) << cpu->phys_bits))) {
- cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
- }
- new_cr4 = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.cr4));
- if (new_cr4 & cr4_reserved_bits(env)) {
- cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
- }
- /* clear exit_info_2 so we behave like the real hardware */
- x86_stq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 0);
-
- cpu_x86_update_cr0(env, new_cr0);
- cpu_x86_update_cr4(env, new_cr4);
- cpu_x86_update_cr3(env, new_cr3);
- env->cr[2] = x86_ldq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, save.cr2));
- env->int_ctl = x86_ldl_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
- env->hflags2 &= ~(HF2_HIF_MASK | HF2_VINTR_MASK);
- if (env->int_ctl & V_INTR_MASKING_MASK) {
- env->hflags2 |= HF2_VINTR_MASK;
- if (env->eflags & IF_MASK) {
- env->hflags2 |= HF2_HIF_MASK;
- }
- }
-
- cpu_load_efer(env,
- x86_ldq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, save.efer)));
- env->eflags = 0;
- cpu_load_eflags(env, x86_ldq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb,
- save.rflags)),
- ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
-
- svm_load_seg_cache(env, MMU_PHYS_IDX,
- env->vm_vmcb + offsetof(struct vmcb, save.es), R_ES);
- svm_load_seg_cache(env, MMU_PHYS_IDX,
- env->vm_vmcb + offsetof(struct vmcb, save.cs), R_CS);
- svm_load_seg_cache(env, MMU_PHYS_IDX,
- env->vm_vmcb + offsetof(struct vmcb, save.ss), R_SS);
- svm_load_seg_cache(env, MMU_PHYS_IDX,
- env->vm_vmcb + offsetof(struct vmcb, save.ds), R_DS);
- svm_load_seg(env, MMU_PHYS_IDX,
- env->vm_vmcb + offsetof(struct vmcb, save.idtr), &env->idt);
- svm_load_seg(env, MMU_PHYS_IDX,
- env->vm_vmcb + offsetof(struct vmcb, save.gdtr), &env->gdt);
-
- env->eip = x86_ldq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, save.rip));
-
- env->regs[R_ESP] = x86_ldq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, save.rsp));
- env->regs[R_EAX] = x86_ldq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, save.rax));
-
- new_dr7 = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.dr7));
- new_dr6 = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.dr6));
-
-#ifdef TARGET_X86_64
- if (new_dr7 & DR_RESERVED_MASK) {
- cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
- }
- if (new_dr6 & DR_RESERVED_MASK) {
- cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
- }
-#endif
-
- cpu_x86_update_dr7(env, new_dr7);
- env->dr[6] = new_dr6;
-
- if (is_efer_invalid_state(env)) {
- cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
- }
-
- switch (x86_ldub_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, control.tlb_ctl))) {
- case TLB_CONTROL_DO_NOTHING:
- break;
- case TLB_CONTROL_FLUSH_ALL_ASID:
- /* FIXME: this is not 100% correct but should work for now */
- tlb_flush(cs);
- break;
- }
-
- env->hflags2 |= HF2_GIF_MASK;
-
- if (ctl_has_irq(env)) {
- cs->interrupt_request |= CPU_INTERRUPT_VIRQ;
- }
-
- if (virtual_gif_set(env)) {
- env->hflags2 |= HF2_VGIF_MASK;
- }
-
- /* maybe we need to inject an event */
- event_inj = x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
- control.event_inj));
- if (event_inj & SVM_EVTINJ_VALID) {
- uint8_t vector = event_inj & SVM_EVTINJ_VEC_MASK;
- uint16_t valid_err = event_inj & SVM_EVTINJ_VALID_ERR;
- uint32_t event_inj_err = x86_ldl_phys(cs, env->vm_vmcb +
- offsetof(struct vmcb,
- control.event_inj_err));
-
- qemu_log_mask(CPU_LOG_TB_IN_ASM, "Injecting(%#hx): ", valid_err);
- /* FIXME: need to implement valid_err */
- switch (event_inj & SVM_EVTINJ_TYPE_MASK) {
- case SVM_EVTINJ_TYPE_INTR:
- cs->exception_index = vector;
- env->error_code = event_inj_err;
- env->exception_is_int = 0;
- env->exception_next_eip = -1;
- qemu_log_mask(CPU_LOG_TB_IN_ASM, "INTR");
- /* XXX: is it always correct? */
- do_interrupt_x86_hardirq(env, vector, 1);
- break;
- case SVM_EVTINJ_TYPE_NMI:
- cs->exception_index = EXCP02_NMI;
- env->error_code = event_inj_err;
- env->exception_is_int = 0;
- env->exception_next_eip = env->eip;
- qemu_log_mask(CPU_LOG_TB_IN_ASM, "NMI");
- cpu_loop_exit(cs);
- break;
- case SVM_EVTINJ_TYPE_EXEPT:
- if (vector == EXCP02_NMI || vector >= 31) {
- cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
- }
- cs->exception_index = vector;
- env->error_code = event_inj_err;
- env->exception_is_int = 0;
- env->exception_next_eip = -1;
- qemu_log_mask(CPU_LOG_TB_IN_ASM, "EXEPT");
- cpu_loop_exit(cs);
- break;
- case SVM_EVTINJ_TYPE_SOFT:
- cs->exception_index = vector;
- env->error_code = event_inj_err;
- env->exception_is_int = 1;
- env->exception_next_eip = env->eip;
- qemu_log_mask(CPU_LOG_TB_IN_ASM, "SOFT");
- cpu_loop_exit(cs);
- break;
- default:
- cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
- break;
- }
- qemu_log_mask(CPU_LOG_TB_IN_ASM, " %#x %#x\n", cs->exception_index,
- env->error_code);
- }
-}
-
-void helper_vmmcall(CPUX86State *env)
-{
- cpu_svm_check_intercept_param(env, SVM_EXIT_VMMCALL, 0, GETPC());
- raise_exception(env, EXCP06_ILLOP);
-}
-
-void helper_vmload(CPUX86State *env, int aflag)
-{
- int mmu_idx = MMU_PHYS_IDX;
- target_ulong addr;
-
- if (aflag == 2) {
- addr = env->regs[R_EAX];
- } else {
- addr = (uint32_t)env->regs[R_EAX];
- }
-
- /* Exceptions are checked before the intercept. */
- if (addr & (0xfff | ((~0ULL) << env_archcpu(env)->phys_bits))) {
- raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
- }
-
- cpu_svm_check_intercept_param(env, SVM_EXIT_VMLOAD, 0, GETPC());
-
- if (virtual_vm_load_save_enabled(env, SVM_EXIT_VMLOAD, GETPC())) {
- mmu_idx = MMU_NESTED_IDX;
- }
-
- svm_load_seg_cache(env, mmu_idx,
- addr + offsetof(struct vmcb, save.fs), R_FS);
- svm_load_seg_cache(env, mmu_idx,
- addr + offsetof(struct vmcb, save.gs), R_GS);
- svm_load_seg(env, mmu_idx,
- addr + offsetof(struct vmcb, save.tr), &env->tr);
- svm_load_seg(env, mmu_idx,
- addr + offsetof(struct vmcb, save.ldtr), &env->ldt);
-
-#ifdef TARGET_X86_64
- env->kernelgsbase =
- cpu_ldq_mmuidx_ra(env,
- addr + offsetof(struct vmcb, save.kernel_gs_base),
- mmu_idx, 0);
- env->lstar =
- cpu_ldq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.lstar),
- mmu_idx, 0);
- env->cstar =
- cpu_ldq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.cstar),
- mmu_idx, 0);
- env->fmask =
- cpu_ldq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.sfmask),
- mmu_idx, 0);
- svm_canonicalization(env, &env->kernelgsbase);
-#endif
- env->star =
- cpu_ldq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.star),
- mmu_idx, 0);
- env->sysenter_cs =
- cpu_ldq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.sysenter_cs),
- mmu_idx, 0);
- env->sysenter_esp =
- cpu_ldq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.sysenter_esp),
- mmu_idx, 0);
- env->sysenter_eip =
- cpu_ldq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.sysenter_eip),
- mmu_idx, 0);
-}
-
-void helper_vmsave(CPUX86State *env, int aflag)
-{
- int mmu_idx = MMU_PHYS_IDX;
- target_ulong addr;
-
- if (aflag == 2) {
- addr = env->regs[R_EAX];
- } else {
- addr = (uint32_t)env->regs[R_EAX];
- }
-
- /* Exceptions are checked before the intercept. */
- if (addr & (0xfff | ((~0ULL) << env_archcpu(env)->phys_bits))) {
- raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
- }
-
- cpu_svm_check_intercept_param(env, SVM_EXIT_VMSAVE, 0, GETPC());
-
- if (virtual_vm_load_save_enabled(env, SVM_EXIT_VMSAVE, GETPC())) {
- mmu_idx = MMU_NESTED_IDX;
- }
-
- svm_save_seg(env, mmu_idx, addr + offsetof(struct vmcb, save.fs),
- &env->segs[R_FS]);
- svm_save_seg(env, mmu_idx, addr + offsetof(struct vmcb, save.gs),
- &env->segs[R_GS]);
- svm_save_seg(env, mmu_idx, addr + offsetof(struct vmcb, save.tr),
- &env->tr);
- svm_save_seg(env, mmu_idx, addr + offsetof(struct vmcb, save.ldtr),
- &env->ldt);
-
-#ifdef TARGET_X86_64
- cpu_stq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.kernel_gs_base),
- env->kernelgsbase, mmu_idx, 0);
- cpu_stq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.lstar),
- env->lstar, mmu_idx, 0);
- cpu_stq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.cstar),
- env->cstar, mmu_idx, 0);
- cpu_stq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.sfmask),
- env->fmask, mmu_idx, 0);
-#endif
- cpu_stq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.star),
- env->star, mmu_idx, 0);
- cpu_stq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.sysenter_cs),
- env->sysenter_cs, mmu_idx, 0);
- cpu_stq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.sysenter_esp),
- env->sysenter_esp, mmu_idx, 0);
- cpu_stq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.sysenter_eip),
- env->sysenter_eip, mmu_idx, 0);
-}
-
-void helper_stgi(CPUX86State *env)
-{
- cpu_svm_check_intercept_param(env, SVM_EXIT_STGI, 0, GETPC());
-
- if (virtual_gif_enabled(env)) {
- env->int_ctl |= V_GIF_MASK;
- env->hflags2 |= HF2_VGIF_MASK;
- } else {
- env->hflags2 |= HF2_GIF_MASK;
- }
-}
-
-void helper_clgi(CPUX86State *env)
-{
- cpu_svm_check_intercept_param(env, SVM_EXIT_CLGI, 0, GETPC());
-
- if (virtual_gif_enabled(env)) {
- env->int_ctl &= ~V_GIF_MASK;
- env->hflags2 &= ~HF2_VGIF_MASK;
- } else {
- env->hflags2 &= ~HF2_GIF_MASK;
- }
-}
-
-bool cpu_svm_has_intercept(CPUX86State *env, uint32_t type)
-{
- switch (type) {
- case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR0 + 8:
- if (env->intercept_cr_read & (1 << (type - SVM_EXIT_READ_CR0))) {
- return true;
- }
- break;
- case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR0 + 8:
- if (env->intercept_cr_write & (1 << (type - SVM_EXIT_WRITE_CR0))) {
- return true;
- }
- break;
- case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR0 + 7:
- if (env->intercept_dr_read & (1 << (type - SVM_EXIT_READ_DR0))) {
- return true;
- }
- break;
- case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR0 + 7:
- if (env->intercept_dr_write & (1 << (type - SVM_EXIT_WRITE_DR0))) {
- return true;
- }
- break;
- case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 31:
- if (env->intercept_exceptions & (1 << (type - SVM_EXIT_EXCP_BASE))) {
- return true;
- }
- break;
- default:
- if (env->intercept & (1ULL << (type - SVM_EXIT_INTR))) {
- return true;
- }
- break;
- }
- return false;
-}
-
-void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type,
- uint64_t param, uintptr_t retaddr)
-{
- CPUState *cs = env_cpu(env);
-
- if (likely(!(env->hflags & HF_GUEST_MASK))) {
- return;
- }
-
- if (!cpu_svm_has_intercept(env, type)) {
- return;
- }
-
- if (type == SVM_EXIT_MSR) {
- /* FIXME: this should be read in at vmrun (faster this way?) */
- uint64_t addr = x86_ldq_phys(cs, env->vm_vmcb +
- offsetof(struct vmcb,
- control.msrpm_base_pa));
- uint32_t t0, t1;
-
- switch ((uint32_t)env->regs[R_ECX]) {
- case 0 ... 0x1fff:
- t0 = (env->regs[R_ECX] * 2) % 8;
- t1 = (env->regs[R_ECX] * 2) / 8;
- break;
- case 0xc0000000 ... 0xc0001fff:
- t0 = (8192 + env->regs[R_ECX] - 0xc0000000) * 2;
- t1 = (t0 / 8);
- t0 %= 8;
- break;
- case 0xc0010000 ... 0xc0011fff:
- t0 = (16384 + env->regs[R_ECX] - 0xc0010000) * 2;
- t1 = (t0 / 8);
- t0 %= 8;
- break;
- default:
- cpu_vmexit(env, type, param, retaddr);
- t0 = 0;
- t1 = 0;
- break;
- }
- if (x86_ldub_phys(cs, addr + t1) & ((1 << param) << t0)) {
- cpu_vmexit(env, type, param, retaddr);
- }
- return;
- }
-
- cpu_vmexit(env, type, param, retaddr);
-}
-
-void helper_svm_check_intercept(CPUX86State *env, uint32_t type)
-{
- cpu_svm_check_intercept_param(env, type, 0, GETPC());
-}
-
-void helper_svm_check_io(CPUX86State *env, uint32_t port, uint32_t param,
- uint32_t next_eip_addend)
-{
- CPUState *cs = env_cpu(env);
-
- if (env->intercept & (1ULL << (SVM_EXIT_IOIO - SVM_EXIT_INTR))) {
- /* FIXME: this should be read in at vmrun (faster this way?) */
- uint64_t addr = x86_ldq_phys(cs, env->vm_vmcb +
- offsetof(struct vmcb, control.iopm_base_pa));
- uint16_t mask = (1 << ((param >> 4) & 7)) - 1;
-
- if (x86_lduw_phys(cs, addr + port / 8) & (mask << (port & 7))) {
- /* next env->eip */
- x86_stq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
- env->eip + next_eip_addend);
- cpu_vmexit(env, SVM_EXIT_IOIO, param | (port << 16), GETPC());
- }
- }
-}
-
-void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1,
- uintptr_t retaddr)
-{
- CPUState *cs = env_cpu(env);
-
- cpu_restore_state(cs, retaddr);
-
- qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmexit(%08x, %016" PRIx64 ", %016"
- PRIx64 ", " TARGET_FMT_lx ")!\n",
- exit_code, exit_info_1,
- x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
- control.exit_info_2)),
- env->eip);
-
- cs->exception_index = EXCP_VMEXIT;
- x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.exit_code),
- exit_code);
-
- x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
- control.exit_info_1), exit_info_1),
-
- /* remove any pending exception */
- env->old_exception = -1;
- cpu_loop_exit(cs);
-}
-
-void do_vmexit(CPUX86State *env)
-{
- CPUState *cs = env_cpu(env);
-
- if (env->hflags & HF_INHIBIT_IRQ_MASK) {
- x86_stl_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, control.int_state),
- SVM_INTERRUPT_SHADOW_MASK);
- env->hflags &= ~HF_INHIBIT_IRQ_MASK;
- } else {
- x86_stl_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, control.int_state), 0);
- }
- env->hflags2 &= ~HF2_NPT_MASK;
- tlb_flush_by_mmuidx(cs, 1 << MMU_NESTED_IDX);
-
- /* Save the VM state in the vmcb */
- svm_save_seg(env, MMU_PHYS_IDX,
- env->vm_vmcb + offsetof(struct vmcb, save.es),
- &env->segs[R_ES]);
- svm_save_seg(env, MMU_PHYS_IDX,
- env->vm_vmcb + offsetof(struct vmcb, save.cs),
- &env->segs[R_CS]);
- svm_save_seg(env, MMU_PHYS_IDX,
- env->vm_vmcb + offsetof(struct vmcb, save.ss),
- &env->segs[R_SS]);
- svm_save_seg(env, MMU_PHYS_IDX,
- env->vm_vmcb + offsetof(struct vmcb, save.ds),
- &env->segs[R_DS]);
-
- x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.gdtr.base),
- env->gdt.base);
- x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.gdtr.limit),
- env->gdt.limit);
-
- x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.idtr.base),
- env->idt.base);
- x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.idtr.limit),
- env->idt.limit);
-
- x86_stq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, save.efer), env->efer);
- x86_stq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, save.cr0), env->cr[0]);
- x86_stq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, save.cr2), env->cr[2]);
- x86_stq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, save.cr3), env->cr[3]);
- x86_stq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, save.cr4), env->cr[4]);
- x86_stl_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), env->int_ctl);
-
- x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.rflags),
- cpu_compute_eflags(env));
- x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.rip),
- env->eip);
- x86_stq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, save.rsp), env->regs[R_ESP]);
- x86_stq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, save.rax), env->regs[R_EAX]);
- x86_stq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, save.dr7), env->dr[7]);
- x86_stq_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, save.dr6), env->dr[6]);
- x86_stb_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.cpl),
- env->hflags & HF_CPL_MASK);
-
- /* Reload the host state from vm_hsave */
- env->hflags2 &= ~(HF2_HIF_MASK | HF2_VINTR_MASK);
- env->hflags &= ~HF_GUEST_MASK;
- env->intercept = 0;
- env->intercept_exceptions = 0;
-
- /* Clears the V_IRQ and V_INTR_MASKING bits inside the processor. */
- cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
- env->int_ctl = 0;
-
- /* Clears the TSC_OFFSET inside the processor. */
- env->tsc_offset = 0;
-
- env->gdt.base = x86_ldq_phys(cs, env->vm_hsave + offsetof(struct vmcb,
- save.gdtr.base));
- env->gdt.limit = x86_ldl_phys(cs, env->vm_hsave + offsetof(struct vmcb,
- save.gdtr.limit));
-
- env->idt.base = x86_ldq_phys(cs, env->vm_hsave + offsetof(struct vmcb,
- save.idtr.base));
- env->idt.limit = x86_ldl_phys(cs, env->vm_hsave + offsetof(struct vmcb,
- save.idtr.limit));
-
- cpu_x86_update_cr0(env, x86_ldq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb,
- save.cr0)) |
- CR0_PE_MASK);
- cpu_x86_update_cr4(env, x86_ldq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb,
- save.cr4)));
-
- /*
- * Resets the current ASID register to zero (host ASID; TLB flush).
- *
- * If the host is in PAE mode, the processor reloads the host's PDPEs
- * from the page table indicated the host's CR3. FIXME: If the PDPEs
- * contain illegal state, the processor causes a shutdown (QEMU does
- * not implement PDPTRs).
- */
- cpu_x86_update_cr3(env, x86_ldq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb,
- save.cr3)));
- /* we need to set the efer after the crs so the hidden flags get
- set properly */
- cpu_load_efer(env, x86_ldq_phys(cs, env->vm_hsave + offsetof(struct vmcb,
- save.efer)));
-
- /* Completion of the VMRUN instruction clears the host EFLAGS.RF bit. */
- env->eflags = 0;
- cpu_load_eflags(env, x86_ldq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb,
- save.rflags)),
- ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK |
- RF_MASK | VM_MASK));
-
- svm_load_seg_cache(env, MMU_PHYS_IDX,
- env->vm_hsave + offsetof(struct vmcb, save.es), R_ES);
- svm_load_seg_cache(env, MMU_PHYS_IDX,
- env->vm_hsave + offsetof(struct vmcb, save.cs), R_CS);
- svm_load_seg_cache(env, MMU_PHYS_IDX,
- env->vm_hsave + offsetof(struct vmcb, save.ss), R_SS);
- svm_load_seg_cache(env, MMU_PHYS_IDX,
- env->vm_hsave + offsetof(struct vmcb, save.ds), R_DS);
-
- env->eip = x86_ldq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb, save.rip));
- env->regs[R_ESP] = x86_ldq_phys(cs, env->vm_hsave +
- offsetof(struct vmcb, save.rsp));
- env->regs[R_EAX] = x86_ldq_phys(cs, env->vm_hsave +
- offsetof(struct vmcb, save.rax));
-
- env->dr[6] = x86_ldq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb, save.dr6));
-
- /* Disables all breakpoints in the host DR7 register. */
- cpu_x86_update_dr7(env,
- x86_ldq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb, save.dr7)) & ~0xff);
-
- /* other setups */
- x86_stl_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, control.exit_int_info),
- x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
- control.event_inj)));
- x86_stl_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, control.exit_int_info_err),
- x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
- control.event_inj_err)));
- x86_stl_phys(cs,
- env->vm_vmcb + offsetof(struct vmcb, control.event_inj), 0);
-
- env->hflags2 &= ~HF2_GIF_MASK;
- env->hflags2 &= ~HF2_VGIF_MASK;
-
-
- /* FIXME: Checks the reloaded host state for consistency. */
-
- /*
- * EFLAGS.TF causes a #DB trap after the VMRUN completes on the host
- * side (i.e., after the #VMEXIT from the guest). Since we're running
- * in the main loop, call do_interrupt_all directly.
- */
- if ((env->eflags & TF_MASK) != 0) {
- env->dr[6] |= DR6_BS;
- do_interrupt_all(X86_CPU(cs), EXCP01_DB, 0, 0, env->eip, 0);
- }
-}
+++ /dev/null
-/*
- * i386 TCG cpu class initialization functions specific to sysemu
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * 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 "tcg/helper-tcg.h"
-
-#include "sysemu/sysemu.h"
-#include "qemu/units.h"
-#include "exec/address-spaces.h"
-
-#include "tcg/tcg-cpu.h"
-
-static void tcg_cpu_machine_done(Notifier *n, void *unused)
-{
- X86CPU *cpu = container_of(n, X86CPU, machine_done);
- MemoryRegion *smram =
- (MemoryRegion *) object_resolve_path("/machine/smram", NULL);
-
- if (smram) {
- cpu->smram = g_new(MemoryRegion, 1);
- memory_region_init_alias(cpu->smram, OBJECT(cpu), "smram",
- smram, 0, 4 * GiB);
- memory_region_set_enabled(cpu->smram, true);
- memory_region_add_subregion_overlap(cpu->cpu_as_root, 0,
- cpu->smram, 1);
- }
-}
-
-bool tcg_cpu_realizefn(CPUState *cs, Error **errp)
-{
- X86CPU *cpu = X86_CPU(cs);
-
- /*
- * The realize order is important, since x86_cpu_realize() checks if
- * nothing else has been set by the user (or by accelerators) in
- * cpu->ucode_rev and cpu->phys_bits, and the memory regions
- * initialized here are needed for the vcpu initialization.
- *
- * realize order:
- * tcg_cpu -> host_cpu -> x86_cpu
- */
- cpu->cpu_as_mem = g_new(MemoryRegion, 1);
- cpu->cpu_as_root = g_new(MemoryRegion, 1);
-
- /* Outer container... */
- memory_region_init(cpu->cpu_as_root, OBJECT(cpu), "memory", ~0ull);
- memory_region_set_enabled(cpu->cpu_as_root, true);
-
- /*
- * ... with two regions inside: normal system memory with low
- * priority, and...
- */
- memory_region_init_alias(cpu->cpu_as_mem, OBJECT(cpu), "memory",
- get_system_memory(), 0, ~0ull);
- memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_mem, 0);
- memory_region_set_enabled(cpu->cpu_as_mem, true);
-
- cs->num_ases = 2;
- cpu_address_space_init(cs, 0, "cpu-memory", cs->memory);
- cpu_address_space_init(cs, 1, "cpu-smm", cpu->cpu_as_root);
-
- /* ... SMRAM with higher priority, linked from /machine/smram. */
- cpu->machine_done.notify = tcg_cpu_machine_done;
- qemu_add_machine_init_done_notifier(&cpu->machine_done);
- return true;
-}
--- /dev/null
+/*
+ * i386 breakpoint helpers - system code
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * 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.1 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/exec-all.h"
+#include "exec/helper-proto.h"
+#include "tcg/helper-tcg.h"
+
+
+static inline bool hw_local_breakpoint_enabled(unsigned long dr7, int index)
+{
+ return (dr7 >> (index * 2)) & 1;
+}
+
+static inline bool hw_global_breakpoint_enabled(unsigned long dr7, int index)
+{
+ return (dr7 >> (index * 2)) & 2;
+
+}
+static inline bool hw_breakpoint_enabled(unsigned long dr7, int index)
+{
+ return hw_global_breakpoint_enabled(dr7, index) ||
+ hw_local_breakpoint_enabled(dr7, index);
+}
+
+static inline int hw_breakpoint_type(unsigned long dr7, int index)
+{
+ return (dr7 >> (DR7_TYPE_SHIFT + (index * 4))) & 3;
+}
+
+static inline int hw_breakpoint_len(unsigned long dr7, int index)
+{
+ int len = ((dr7 >> (DR7_LEN_SHIFT + (index * 4))) & 3);
+ return (len == 2) ? 8 : len + 1;
+}
+
+static int hw_breakpoint_insert(CPUX86State *env, int index)
+{
+ CPUState *cs = env_cpu(env);
+ target_ulong dr7 = env->dr[7];
+ target_ulong drN = env->dr[index];
+ int err = 0;
+
+ switch (hw_breakpoint_type(dr7, index)) {
+ case DR7_TYPE_BP_INST:
+ if (hw_breakpoint_enabled(dr7, index)) {
+ err = cpu_breakpoint_insert(cs, drN, BP_CPU,
+ &env->cpu_breakpoint[index]);
+ }
+ break;
+
+ case DR7_TYPE_IO_RW:
+ /* Notice when we should enable calls to bpt_io. */
+ return hw_breakpoint_enabled(env->dr[7], index)
+ ? HF_IOBPT_MASK : 0;
+
+ case DR7_TYPE_DATA_WR:
+ if (hw_breakpoint_enabled(dr7, index)) {
+ err = cpu_watchpoint_insert(cs, drN,
+ hw_breakpoint_len(dr7, index),
+ BP_CPU | BP_MEM_WRITE,
+ &env->cpu_watchpoint[index]);
+ }
+ break;
+
+ case DR7_TYPE_DATA_RW:
+ if (hw_breakpoint_enabled(dr7, index)) {
+ err = cpu_watchpoint_insert(cs, drN,
+ hw_breakpoint_len(dr7, index),
+ BP_CPU | BP_MEM_ACCESS,
+ &env->cpu_watchpoint[index]);
+ }
+ break;
+ }
+ if (err) {
+ env->cpu_breakpoint[index] = NULL;
+ }
+ return 0;
+}
+
+static void hw_breakpoint_remove(CPUX86State *env, int index)
+{
+ CPUState *cs = env_cpu(env);
+
+ switch (hw_breakpoint_type(env->dr[7], index)) {
+ case DR7_TYPE_BP_INST:
+ if (env->cpu_breakpoint[index]) {
+ cpu_breakpoint_remove_by_ref(cs, env->cpu_breakpoint[index]);
+ env->cpu_breakpoint[index] = NULL;
+ }
+ break;
+
+ case DR7_TYPE_DATA_WR:
+ case DR7_TYPE_DATA_RW:
+ if (env->cpu_watchpoint[index]) {
+ cpu_watchpoint_remove_by_ref(cs, env->cpu_watchpoint[index]);
+ env->cpu_watchpoint[index] = NULL;
+ }
+ break;
+
+ case DR7_TYPE_IO_RW:
+ /* HF_IOBPT_MASK cleared elsewhere. */
+ break;
+ }
+}
+
+void cpu_x86_update_dr7(CPUX86State *env, uint32_t new_dr7)
+{
+ target_ulong old_dr7 = env->dr[7];
+ int iobpt = 0;
+ int i;
+
+ new_dr7 |= DR7_FIXED_1;
+
+ /* If nothing is changing except the global/local enable bits,
+ then we can make the change more efficient. */
+ if (((old_dr7 ^ new_dr7) & ~0xff) == 0) {
+ /* Fold the global and local enable bits together into the
+ global fields, then xor to show which registers have
+ changed collective enable state. */
+ int mod = ((old_dr7 | old_dr7 * 2) ^ (new_dr7 | new_dr7 * 2)) & 0xff;
+
+ for (i = 0; i < DR7_MAX_BP; i++) {
+ if ((mod & (2 << i * 2)) && !hw_breakpoint_enabled(new_dr7, i)) {
+ hw_breakpoint_remove(env, i);
+ }
+ }
+ env->dr[7] = new_dr7;
+ for (i = 0; i < DR7_MAX_BP; i++) {
+ if (mod & (2 << i * 2) && hw_breakpoint_enabled(new_dr7, i)) {
+ iobpt |= hw_breakpoint_insert(env, i);
+ } else if (hw_breakpoint_type(new_dr7, i) == DR7_TYPE_IO_RW
+ && hw_breakpoint_enabled(new_dr7, i)) {
+ iobpt |= HF_IOBPT_MASK;
+ }
+ }
+ } else {
+ for (i = 0; i < DR7_MAX_BP; i++) {
+ hw_breakpoint_remove(env, i);
+ }
+ env->dr[7] = new_dr7;
+ for (i = 0; i < DR7_MAX_BP; i++) {
+ iobpt |= hw_breakpoint_insert(env, i);
+ }
+ }
+
+ env->hflags = (env->hflags & ~HF_IOBPT_MASK) | iobpt;
+}
+
+bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update)
+{
+ target_ulong dr6;
+ int reg;
+ bool hit_enabled = false;
+
+ dr6 = env->dr[6] & ~0xf;
+ for (reg = 0; reg < DR7_MAX_BP; reg++) {
+ bool bp_match = false;
+ bool wp_match = false;
+
+ switch (hw_breakpoint_type(env->dr[7], reg)) {
+ case DR7_TYPE_BP_INST:
+ if (env->dr[reg] == env->eip) {
+ bp_match = true;
+ }
+ break;
+ case DR7_TYPE_DATA_WR:
+ case DR7_TYPE_DATA_RW:
+ if (env->cpu_watchpoint[reg] &&
+ env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT) {
+ wp_match = true;
+ }
+ break;
+ case DR7_TYPE_IO_RW:
+ break;
+ }
+ if (bp_match || wp_match) {
+ dr6 |= 1 << reg;
+ if (hw_breakpoint_enabled(env->dr[7], reg)) {
+ hit_enabled = true;
+ }
+ }
+ }
+
+ if (hit_enabled || force_dr6_update) {
+ env->dr[6] = dr6;
+ }
+
+ return hit_enabled;
+}
+
+void breakpoint_handler(CPUState *cs)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+
+ if (cs->watchpoint_hit) {
+ if (cs->watchpoint_hit->flags & BP_CPU) {
+ cs->watchpoint_hit = NULL;
+ if (check_hw_breakpoints(env, false)) {
+ /*
+ * FIXME: #DB should be delayed by one instruction if
+ * INHIBIT_IRQ is set (STI cannot trigger a watchpoint).
+ * The delayed #DB should also fuse with one generated
+ * by ICEBP (aka INT1).
+ */
+ raise_exception(env, EXCP01_DB);
+ } else {
+ cpu_loop_exit_noexc(cs);
+ }
+ }
+ } else {
+ if (cpu_breakpoint_test(cs, env->eip, BP_CPU)) {
+ check_hw_breakpoints(env, true);
+ raise_exception(env, EXCP01_DB);
+ }
+ }
+}
+
+target_ulong helper_get_dr(CPUX86State *env, int reg)
+{
+ if (reg >= 4 && reg < 6) {
+ if (env->cr[4] & CR4_DE_MASK) {
+ raise_exception_ra(env, EXCP06_ILLOP, GETPC());
+ } else {
+ reg += 2;
+ }
+ }
+
+ if (env->dr[7] & DR7_GD) {
+ env->dr[7] &= ~DR7_GD;
+ env->dr[6] |= DR6_BD;
+ raise_exception_ra(env, EXCP01_DB, GETPC());
+ }
+
+ return env->dr[reg];
+}
+
+void helper_set_dr(CPUX86State *env, int reg, target_ulong t0)
+{
+ if (reg >= 4 && reg < 6) {
+ if (env->cr[4] & CR4_DE_MASK) {
+ raise_exception_ra(env, EXCP06_ILLOP, GETPC());
+ } else {
+ reg += 2;
+ }
+ }
+
+ if (env->dr[7] & DR7_GD) {
+ env->dr[7] &= ~DR7_GD;
+ env->dr[6] |= DR6_BD;
+ raise_exception_ra(env, EXCP01_DB, GETPC());
+ }
+
+ if (reg < 4) {
+ if (hw_breakpoint_enabled(env->dr[7], reg)
+ && hw_breakpoint_type(env->dr[7], reg) != DR7_TYPE_IO_RW) {
+ hw_breakpoint_remove(env, reg);
+ env->dr[reg] = t0;
+ hw_breakpoint_insert(env, reg);
+ } else {
+ env->dr[reg] = t0;
+ }
+ } else {
+ if (t0 & DR_RESERVED_MASK) {
+ raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
+ }
+ if (reg == 6) {
+ env->dr[6] = t0 | DR6_FIXED_1;
+ } else {
+ cpu_x86_update_dr7(env, t0);
+ }
+ }
+}
+
+/* Check if Port I/O is trapped by a breakpoint. */
+void helper_bpt_io(CPUX86State *env, uint32_t port,
+ uint32_t size, target_ulong next_eip)
+{
+ target_ulong dr7 = env->dr[7];
+ int i, hit = 0;
+
+ for (i = 0; i < DR7_MAX_BP; ++i) {
+ if (hw_breakpoint_type(dr7, i) == DR7_TYPE_IO_RW
+ && hw_breakpoint_enabled(dr7, i)) {
+ int bpt_len = hw_breakpoint_len(dr7, i);
+ if (port + size - 1 >= env->dr[i]
+ && port <= env->dr[i] + bpt_len - 1) {
+ hit |= 1 << i;
+ }
+ }
+ }
+
+ if (hit) {
+ env->dr[6] = (env->dr[6] & ~0xf) | hit;
+ env->eip = next_eip;
+ raise_exception(env, EXCP01_DB);
+ }
+}
--- /dev/null
+/*
+ * x86 exception helpers - system code
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * 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.1 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/cpu_ldst.h"
+#include "exec/exec-all.h"
+#include "exec/page-protection.h"
+#include "tcg/helper-tcg.h"
+
+typedef struct TranslateParams {
+ target_ulong addr;
+ target_ulong cr3;
+ int pg_mode;
+ int mmu_idx;
+ int ptw_idx;
+ MMUAccessType access_type;
+} TranslateParams;
+
+typedef struct TranslateResult {
+ hwaddr paddr;
+ int prot;
+ int page_size;
+} TranslateResult;
+
+typedef enum TranslateFaultStage2 {
+ S2_NONE,
+ S2_GPA,
+ S2_GPT,
+} TranslateFaultStage2;
+
+typedef struct TranslateFault {
+ int exception_index;
+ int error_code;
+ target_ulong cr2;
+ TranslateFaultStage2 stage2;
+} TranslateFault;
+
+typedef struct PTETranslate {
+ CPUX86State *env;
+ TranslateFault *err;
+ int ptw_idx;
+ void *haddr;
+ hwaddr gaddr;
+} PTETranslate;
+
+static bool ptw_translate(PTETranslate *inout, hwaddr addr)
+{
+ int flags;
+
+ inout->gaddr = addr;
+ flags = probe_access_full_mmu(inout->env, addr, 0, MMU_DATA_STORE,
+ inout->ptw_idx, &inout->haddr, NULL);
+
+ if (unlikely(flags & TLB_INVALID_MASK)) {
+ TranslateFault *err = inout->err;
+
+ assert(inout->ptw_idx == MMU_NESTED_IDX);
+ *err = (TranslateFault){
+ .error_code = inout->env->error_code,
+ .cr2 = addr,
+ .stage2 = S2_GPT,
+ };
+ return false;
+ }
+ return true;
+}
+
+static inline uint32_t ptw_ldl(const PTETranslate *in, uint64_t ra)
+{
+ if (likely(in->haddr)) {
+ return ldl_p(in->haddr);
+ }
+ return cpu_ldl_mmuidx_ra(in->env, in->gaddr, in->ptw_idx, ra);
+}
+
+static inline uint64_t ptw_ldq(const PTETranslate *in, uint64_t ra)
+{
+ if (likely(in->haddr)) {
+ return ldq_p(in->haddr);
+ }
+ return cpu_ldq_mmuidx_ra(in->env, in->gaddr, in->ptw_idx, ra);
+}
+
+/*
+ * Note that we can use a 32-bit cmpxchg for all page table entries,
+ * even 64-bit ones, because PG_PRESENT_MASK, PG_ACCESSED_MASK and
+ * PG_DIRTY_MASK are all in the low 32 bits.
+ */
+static bool ptw_setl_slow(const PTETranslate *in, uint32_t old, uint32_t new)
+{
+ uint32_t cmp;
+
+ CPUState *cpu = env_cpu(in->env);
+ /* We are in cpu_exec, and start_exclusive can't be called directly.*/
+ g_assert(cpu->running);
+ cpu_exec_end(cpu);
+ /* Does x86 really perform a rmw cycle on mmio for ptw? */
+ start_exclusive();
+ cmp = cpu_ldl_mmuidx_ra(in->env, in->gaddr, in->ptw_idx, 0);
+ if (cmp == old) {
+ cpu_stl_mmuidx_ra(in->env, in->gaddr, new, in->ptw_idx, 0);
+ }
+ end_exclusive();
+ cpu_exec_start(cpu);
+ return cmp == old;
+}
+
+static inline bool ptw_setl(const PTETranslate *in, uint32_t old, uint32_t set)
+{
+ if (set & ~old) {
+ uint32_t new = old | set;
+ if (likely(in->haddr)) {
+ old = cpu_to_le32(old);
+ new = cpu_to_le32(new);
+ return qatomic_cmpxchg((uint32_t *)in->haddr, old, new) == old;
+ }
+ return ptw_setl_slow(in, old, new);
+ }
+ return true;
+}
+
+static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
+ TranslateResult *out, TranslateFault *err,
+ uint64_t ra)
+{
+ const target_ulong addr = in->addr;
+ const int pg_mode = in->pg_mode;
+ const bool is_user = is_mmu_index_user(in->mmu_idx);
+ const MMUAccessType access_type = in->access_type;
+ uint64_t ptep, pte, rsvd_mask;
+ PTETranslate pte_trans = {
+ .env = env,
+ .err = err,
+ .ptw_idx = in->ptw_idx,
+ };
+ hwaddr pte_addr, paddr;
+ uint32_t pkr;
+ int page_size;
+ int error_code;
+ int prot;
+
+ restart_all:
+ rsvd_mask = ~MAKE_64BIT_MASK(0, env_archcpu(env)->phys_bits);
+ rsvd_mask &= PG_ADDRESS_MASK;
+ if (!(pg_mode & PG_MODE_NXE)) {
+ rsvd_mask |= PG_NX_MASK;
+ }
+
+ if (pg_mode & PG_MODE_PAE) {
+#ifdef TARGET_X86_64
+ if (pg_mode & PG_MODE_LMA) {
+ if (pg_mode & PG_MODE_LA57) {
+ /*
+ * Page table level 5
+ */
+ pte_addr = (in->cr3 & ~0xfff) + (((addr >> 48) & 0x1ff) << 3);
+ if (!ptw_translate(&pte_trans, pte_addr)) {
+ return false;
+ }
+ restart_5:
+ pte = ptw_ldq(&pte_trans, ra);
+ if (!(pte & PG_PRESENT_MASK)) {
+ goto do_fault;
+ }
+ if (pte & (rsvd_mask | PG_PSE_MASK)) {
+ goto do_fault_rsvd;
+ }
+ if (!ptw_setl(&pte_trans, pte, PG_ACCESSED_MASK)) {
+ goto restart_5;
+ }
+ ptep = pte ^ PG_NX_MASK;
+ } else {
+ pte = in->cr3;
+ ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
+ }
+
+ /*
+ * Page table level 4
+ */
+ pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 39) & 0x1ff) << 3);
+ if (!ptw_translate(&pte_trans, pte_addr)) {
+ return false;
+ }
+ restart_4:
+ pte = ptw_ldq(&pte_trans, ra);
+ if (!(pte & PG_PRESENT_MASK)) {
+ goto do_fault;
+ }
+ if (pte & (rsvd_mask | PG_PSE_MASK)) {
+ goto do_fault_rsvd;
+ }
+ if (!ptw_setl(&pte_trans, pte, PG_ACCESSED_MASK)) {
+ goto restart_4;
+ }
+ ptep &= pte ^ PG_NX_MASK;
+
+ /*
+ * Page table level 3
+ */
+ pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 30) & 0x1ff) << 3);
+ if (!ptw_translate(&pte_trans, pte_addr)) {
+ return false;
+ }
+ restart_3_lma:
+ pte = ptw_ldq(&pte_trans, ra);
+ if (!(pte & PG_PRESENT_MASK)) {
+ goto do_fault;
+ }
+ if (pte & rsvd_mask) {
+ goto do_fault_rsvd;
+ }
+ if (!ptw_setl(&pte_trans, pte, PG_ACCESSED_MASK)) {
+ goto restart_3_lma;
+ }
+ ptep &= pte ^ PG_NX_MASK;
+ if (pte & PG_PSE_MASK) {
+ /* 1 GB page */
+ page_size = 1024 * 1024 * 1024;
+ goto do_check_protect;
+ }
+ } else
+#endif
+ {
+ /*
+ * Page table level 3
+ */
+ pte_addr = (in->cr3 & 0xffffffe0ULL) + ((addr >> 27) & 0x18);
+ if (!ptw_translate(&pte_trans, pte_addr)) {
+ return false;
+ }
+ rsvd_mask |= PG_HI_USER_MASK;
+ restart_3_nolma:
+ pte = ptw_ldq(&pte_trans, ra);
+ if (!(pte & PG_PRESENT_MASK)) {
+ goto do_fault;
+ }
+ if (pte & (rsvd_mask | PG_NX_MASK)) {
+ goto do_fault_rsvd;
+ }
+ if (!ptw_setl(&pte_trans, pte, PG_ACCESSED_MASK)) {
+ goto restart_3_nolma;
+ }
+ ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
+ }
+
+ /*
+ * Page table level 2
+ */
+ pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 21) & 0x1ff) << 3);
+ if (!ptw_translate(&pte_trans, pte_addr)) {
+ return false;
+ }
+ restart_2_pae:
+ pte = ptw_ldq(&pte_trans, ra);
+ if (!(pte & PG_PRESENT_MASK)) {
+ goto do_fault;
+ }
+ if (pte & rsvd_mask) {
+ goto do_fault_rsvd;
+ }
+ if (pte & PG_PSE_MASK) {
+ /* 2 MB page */
+ page_size = 2048 * 1024;
+ ptep &= pte ^ PG_NX_MASK;
+ goto do_check_protect;
+ }
+ if (!ptw_setl(&pte_trans, pte, PG_ACCESSED_MASK)) {
+ goto restart_2_pae;
+ }
+ ptep &= pte ^ PG_NX_MASK;
+
+ /*
+ * Page table level 1
+ */
+ pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 12) & 0x1ff) << 3);
+ if (!ptw_translate(&pte_trans, pte_addr)) {
+ return false;
+ }
+ pte = ptw_ldq(&pte_trans, ra);
+ if (!(pte & PG_PRESENT_MASK)) {
+ goto do_fault;
+ }
+ if (pte & rsvd_mask) {
+ goto do_fault_rsvd;
+ }
+ /* combine pde and pte nx, user and rw protections */
+ ptep &= pte ^ PG_NX_MASK;
+ page_size = 4096;
+ } else if (pg_mode & PG_MODE_PG) {
+ /*
+ * Page table level 2
+ */
+ pte_addr = (in->cr3 & 0xfffff000ULL) + ((addr >> 20) & 0xffc);
+ if (!ptw_translate(&pte_trans, pte_addr)) {
+ return false;
+ }
+ restart_2_nopae:
+ pte = ptw_ldl(&pte_trans, ra);
+ if (!(pte & PG_PRESENT_MASK)) {
+ goto do_fault;
+ }
+ ptep = pte | PG_NX_MASK;
+
+ /* if PSE bit is set, then we use a 4MB page */
+ if ((pte & PG_PSE_MASK) && (pg_mode & PG_MODE_PSE)) {
+ page_size = 4096 * 1024;
+ /*
+ * Bits 20-13 provide bits 39-32 of the address, bit 21 is reserved.
+ * Leave bits 20-13 in place for setting accessed/dirty bits below.
+ */
+ pte = (uint32_t)pte | ((pte & 0x1fe000LL) << (32 - 13));
+ rsvd_mask = 0x200000;
+ goto do_check_protect_pse36;
+ }
+ if (!ptw_setl(&pte_trans, pte, PG_ACCESSED_MASK)) {
+ goto restart_2_nopae;
+ }
+
+ /*
+ * Page table level 1
+ */
+ pte_addr = (pte & ~0xfffu) + ((addr >> 10) & 0xffc);
+ if (!ptw_translate(&pte_trans, pte_addr)) {
+ return false;
+ }
+ pte = ptw_ldl(&pte_trans, ra);
+ if (!(pte & PG_PRESENT_MASK)) {
+ goto do_fault;
+ }
+ /* combine pde and pte user and rw protections */
+ ptep &= pte | PG_NX_MASK;
+ page_size = 4096;
+ rsvd_mask = 0;
+ } else {
+ /*
+ * No paging (real mode), let's tentatively resolve the address as 1:1
+ * here, but conditionally still perform an NPT walk on it later.
+ */
+ page_size = 0x40000000;
+ paddr = in->addr;
+ prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ goto stage2;
+ }
+
+do_check_protect:
+ rsvd_mask |= (page_size - 1) & PG_ADDRESS_MASK & ~PG_PSE_PAT_MASK;
+do_check_protect_pse36:
+ if (pte & rsvd_mask) {
+ goto do_fault_rsvd;
+ }
+ ptep ^= PG_NX_MASK;
+
+ /* can the page can be put in the TLB? prot will tell us */
+ if (is_user && !(ptep & PG_USER_MASK)) {
+ goto do_fault_protect;
+ }
+
+ prot = 0;
+ if (!is_mmu_index_smap(in->mmu_idx) || !(ptep & PG_USER_MASK)) {
+ prot |= PAGE_READ;
+ if ((ptep & PG_RW_MASK) || !(is_user || (pg_mode & PG_MODE_WP))) {
+ prot |= PAGE_WRITE;
+ }
+ }
+ if (!(ptep & PG_NX_MASK) &&
+ (is_user ||
+ !((pg_mode & PG_MODE_SMEP) && (ptep & PG_USER_MASK)))) {
+ prot |= PAGE_EXEC;
+ }
+
+ if (ptep & PG_USER_MASK) {
+ pkr = pg_mode & PG_MODE_PKE ? env->pkru : 0;
+ } else {
+ pkr = pg_mode & PG_MODE_PKS ? env->pkrs : 0;
+ }
+ if (pkr) {
+ uint32_t pk = (pte & PG_PKRU_MASK) >> PG_PKRU_BIT;
+ uint32_t pkr_ad = (pkr >> pk * 2) & 1;
+ uint32_t pkr_wd = (pkr >> pk * 2) & 2;
+ uint32_t pkr_prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+
+ if (pkr_ad) {
+ pkr_prot &= ~(PAGE_READ | PAGE_WRITE);
+ } else if (pkr_wd && (is_user || (pg_mode & PG_MODE_WP))) {
+ pkr_prot &= ~PAGE_WRITE;
+ }
+ if ((pkr_prot & (1 << access_type)) == 0) {
+ goto do_fault_pk_protect;
+ }
+ prot &= pkr_prot;
+ }
+
+ if ((prot & (1 << access_type)) == 0) {
+ goto do_fault_protect;
+ }
+
+ /* yes, it can! */
+ {
+ uint32_t set = PG_ACCESSED_MASK;
+ if (access_type == MMU_DATA_STORE) {
+ set |= PG_DIRTY_MASK;
+ } else if (!(pte & PG_DIRTY_MASK)) {
+ /*
+ * Only set write access if already dirty...
+ * otherwise wait for dirty access.
+ */
+ prot &= ~PAGE_WRITE;
+ }
+ if (!ptw_setl(&pte_trans, pte, set)) {
+ /*
+ * We can arrive here from any of 3 levels and 2 formats.
+ * The only safe thing is to restart the entire lookup.
+ */
+ goto restart_all;
+ }
+ }
+
+ /* merge offset within page */
+ paddr = (pte & PG_ADDRESS_MASK & ~(page_size - 1)) | (addr & (page_size - 1));
+ stage2:
+
+ /*
+ * Note that NPT is walked (for both paging structures and final guest
+ * addresses) using the address with the A20 bit set.
+ */
+ if (in->ptw_idx == MMU_NESTED_IDX) {
+ CPUTLBEntryFull *full;
+ int flags, nested_page_size;
+
+ flags = probe_access_full_mmu(env, paddr, 0, access_type,
+ MMU_NESTED_IDX, &pte_trans.haddr, &full);
+ if (unlikely(flags & TLB_INVALID_MASK)) {
+ *err = (TranslateFault){
+ .error_code = env->error_code,
+ .cr2 = paddr,
+ .stage2 = S2_GPA,
+ };
+ return false;
+ }
+
+ /* Merge stage1 & stage2 protection bits. */
+ prot &= full->prot;
+
+ /* Re-verify resulting protection. */
+ if ((prot & (1 << access_type)) == 0) {
+ goto do_fault_protect;
+ }
+
+ /* Merge stage1 & stage2 addresses to final physical address. */
+ nested_page_size = 1 << full->lg_page_size;
+ paddr = (full->phys_addr & ~(nested_page_size - 1))
+ | (paddr & (nested_page_size - 1));
+
+ /*
+ * Use the larger of stage1 & stage2 page sizes, so that
+ * invalidation works.
+ */
+ if (nested_page_size > page_size) {
+ page_size = nested_page_size;
+ }
+ }
+
+ out->paddr = paddr & x86_get_a20_mask(env);
+ out->prot = prot;
+ out->page_size = page_size;
+ return true;
+
+ do_fault_rsvd:
+ error_code = PG_ERROR_RSVD_MASK;
+ goto do_fault_cont;
+ do_fault_protect:
+ error_code = PG_ERROR_P_MASK;
+ goto do_fault_cont;
+ do_fault_pk_protect:
+ assert(access_type != MMU_INST_FETCH);
+ error_code = PG_ERROR_PK_MASK | PG_ERROR_P_MASK;
+ goto do_fault_cont;
+ do_fault:
+ error_code = 0;
+ do_fault_cont:
+ if (is_user) {
+ error_code |= PG_ERROR_U_MASK;
+ }
+ switch (access_type) {
+ case MMU_DATA_LOAD:
+ break;
+ case MMU_DATA_STORE:
+ error_code |= PG_ERROR_W_MASK;
+ break;
+ case MMU_INST_FETCH:
+ if (pg_mode & (PG_MODE_NXE | PG_MODE_SMEP)) {
+ error_code |= PG_ERROR_I_D_MASK;
+ }
+ break;
+ }
+ *err = (TranslateFault){
+ .exception_index = EXCP0E_PAGE,
+ .error_code = error_code,
+ .cr2 = addr,
+ };
+ return false;
+}
+
+static G_NORETURN void raise_stage2(CPUX86State *env, TranslateFault *err,
+ uintptr_t retaddr)
+{
+ uint64_t exit_info_1 = err->error_code;
+
+ switch (err->stage2) {
+ case S2_GPT:
+ exit_info_1 |= SVM_NPTEXIT_GPT;
+ break;
+ case S2_GPA:
+ exit_info_1 |= SVM_NPTEXIT_GPA;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ x86_stq_phys(env_cpu(env),
+ env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
+ err->cr2);
+ cpu_vmexit(env, SVM_EXIT_NPF, exit_info_1, retaddr);
+}
+
+static bool get_physical_address(CPUX86State *env, vaddr addr,
+ MMUAccessType access_type, int mmu_idx,
+ TranslateResult *out, TranslateFault *err,
+ uint64_t ra)
+{
+ TranslateParams in;
+ bool use_stage2 = env->hflags2 & HF2_NPT_MASK;
+
+ in.addr = addr;
+ in.access_type = access_type;
+
+ switch (mmu_idx) {
+ case MMU_PHYS_IDX:
+ break;
+
+ case MMU_NESTED_IDX:
+ if (likely(use_stage2)) {
+ in.cr3 = env->nested_cr3;
+ in.pg_mode = env->nested_pg_mode;
+ in.mmu_idx =
+ env->nested_pg_mode & PG_MODE_LMA ? MMU_USER64_IDX : MMU_USER32_IDX;
+ in.ptw_idx = MMU_PHYS_IDX;
+
+ if (!mmu_translate(env, &in, out, err, ra)) {
+ err->stage2 = S2_GPA;
+ return false;
+ }
+ return true;
+ }
+ break;
+
+ default:
+ if (is_mmu_index_32(mmu_idx)) {
+ addr = (uint32_t)addr;
+ }
+
+ if (likely(env->cr[0] & CR0_PG_MASK || use_stage2)) {
+ in.cr3 = env->cr[3];
+ in.mmu_idx = mmu_idx;
+ in.ptw_idx = use_stage2 ? MMU_NESTED_IDX : MMU_PHYS_IDX;
+ in.pg_mode = get_pg_mode(env);
+
+ if (in.pg_mode & PG_MODE_LMA) {
+ /* test virtual address sign extension */
+ int shift = in.pg_mode & PG_MODE_LA57 ? 56 : 47;
+ int64_t sext = (int64_t)addr >> shift;
+ if (sext != 0 && sext != -1) {
+ *err = (TranslateFault){
+ .exception_index = EXCP0D_GPF,
+ .cr2 = addr,
+ };
+ return false;
+ }
+ }
+ return mmu_translate(env, &in, out, err, ra);
+ }
+ break;
+ }
+
+ /* No translation needed. */
+ out->paddr = addr & x86_get_a20_mask(env);
+ out->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ out->page_size = TARGET_PAGE_SIZE;
+ return true;
+}
+
+bool x86_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr)
+{
+ CPUX86State *env = cpu_env(cs);
+ TranslateResult out;
+ TranslateFault err;
+
+ if (get_physical_address(env, addr, access_type, mmu_idx, &out, &err,
+ retaddr)) {
+ /*
+ * Even if 4MB pages, we map only one 4KB page in the cache to
+ * avoid filling it too fast.
+ */
+ assert(out.prot & (1 << access_type));
+ tlb_set_page_with_attrs(cs, addr & TARGET_PAGE_MASK,
+ out.paddr & TARGET_PAGE_MASK,
+ cpu_get_mem_attrs(env),
+ out.prot, mmu_idx, out.page_size);
+ return true;
+ }
+
+ if (probe) {
+ /* This will be used if recursing for stage2 translation. */
+ env->error_code = err.error_code;
+ return false;
+ }
+
+ if (err.stage2 != S2_NONE) {
+ raise_stage2(env, &err, retaddr);
+ }
+
+ if (env->intercept_exceptions & (1 << err.exception_index)) {
+ /* cr2 is not modified in case of exceptions */
+ x86_stq_phys(cs, env->vm_vmcb +
+ offsetof(struct vmcb, control.exit_info_2),
+ err.cr2);
+ } else {
+ env->cr[2] = err.cr2;
+ }
+ raise_exception_err_ra(env, err.exception_index, err.error_code, retaddr);
+}
+
+G_NORETURN void x86_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
+ MMUAccessType access_type,
+ int mmu_idx, uintptr_t retaddr)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ handle_unaligned_access(&cpu->env, vaddr, access_type, retaddr);
+}
--- /dev/null
+/*
+ * x86 FPU, MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4/PNI helpers (system code)
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * 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.1 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 "qemu/main-loop.h"
+#include "cpu.h"
+#include "hw/irq.h"
+
+static qemu_irq ferr_irq;
+
+void x86_register_ferr_irq(qemu_irq irq)
+{
+ ferr_irq = irq;
+}
+
+void fpu_check_raise_ferr_irq(CPUX86State *env)
+{
+ if (ferr_irq && !(env->hflags2 & HF2_IGNNE_MASK)) {
+ bql_lock();
+ qemu_irq_raise(ferr_irq);
+ bql_unlock();
+ return;
+ }
+}
+
+void cpu_clear_ignne(void)
+{
+ CPUX86State *env = &X86_CPU(first_cpu)->env;
+ env->hflags2 &= ~HF2_IGNNE_MASK;
+}
+
+void cpu_set_ignne(void)
+{
+ CPUX86State *env = &X86_CPU(first_cpu)->env;
+
+ assert(bql_locked());
+
+ env->hflags2 |= HF2_IGNNE_MASK;
+ /*
+ * We get here in response to a write to port F0h. The chipset should
+ * deassert FP_IRQ and FERR# instead should stay signaled until FPSW_SE is
+ * cleared, because FERR# and FP_IRQ are two separate pins on real
+ * hardware. However, we don't model FERR# as a qemu_irq, so we just
+ * do directly what the chipset would do, i.e. deassert FP_IRQ.
+ */
+ qemu_irq_lower(ferr_irq);
+}
--- /dev/null
+i386_system_ss.add(when: ['CONFIG_TCG', 'CONFIG_SYSTEM_ONLY'], if_true: files(
+ 'tcg-cpu.c',
+ 'smm_helper.c',
+ 'excp_helper.c',
+ 'bpt_helper.c',
+ 'misc_helper.c',
+ 'fpu_helper.c',
+ 'svm_helper.c',
+ 'seg_helper.c',
+))
--- /dev/null
+/*
+ * x86 misc helpers - system code
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * 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.1 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 "qemu/main-loop.h"
+#include "cpu.h"
+#include "exec/helper-proto.h"
+#include "exec/cpu_ldst.h"
+#include "exec/address-spaces.h"
+#include "exec/exec-all.h"
+#include "tcg/helper-tcg.h"
+#include "hw/i386/apic.h"
+
+void helper_outb(CPUX86State *env, uint32_t port, uint32_t data)
+{
+ address_space_stb(&address_space_io, port, data,
+ cpu_get_mem_attrs(env), NULL);
+}
+
+target_ulong helper_inb(CPUX86State *env, uint32_t port)
+{
+ return address_space_ldub(&address_space_io, port,
+ cpu_get_mem_attrs(env), NULL);
+}
+
+void helper_outw(CPUX86State *env, uint32_t port, uint32_t data)
+{
+ address_space_stw(&address_space_io, port, data,
+ cpu_get_mem_attrs(env), NULL);
+}
+
+target_ulong helper_inw(CPUX86State *env, uint32_t port)
+{
+ return address_space_lduw(&address_space_io, port,
+ cpu_get_mem_attrs(env), NULL);
+}
+
+void helper_outl(CPUX86State *env, uint32_t port, uint32_t data)
+{
+ address_space_stl(&address_space_io, port, data,
+ cpu_get_mem_attrs(env), NULL);
+}
+
+target_ulong helper_inl(CPUX86State *env, uint32_t port)
+{
+ return address_space_ldl(&address_space_io, port,
+ cpu_get_mem_attrs(env), NULL);
+}
+
+target_ulong helper_read_cr8(CPUX86State *env)
+{
+ if (!(env->hflags2 & HF2_VINTR_MASK)) {
+ return cpu_get_apic_tpr(env_archcpu(env)->apic_state);
+ } else {
+ return env->int_ctl & V_TPR_MASK;
+ }
+}
+
+void helper_write_crN(CPUX86State *env, int reg, target_ulong t0)
+{
+ switch (reg) {
+ case 0:
+ /*
+ * If we reach this point, the CR0 write intercept is disabled.
+ * But we could still exit if the hypervisor has requested the selective
+ * intercept for bits other than TS and MP
+ */
+ if (cpu_svm_has_intercept(env, SVM_EXIT_CR0_SEL_WRITE) &&
+ ((env->cr[0] ^ t0) & ~(CR0_TS_MASK | CR0_MP_MASK))) {
+ cpu_vmexit(env, SVM_EXIT_CR0_SEL_WRITE, 0, GETPC());
+ }
+ cpu_x86_update_cr0(env, t0);
+ break;
+ case 3:
+ if ((env->efer & MSR_EFER_LMA) &&
+ (t0 & ((~0ULL) << env_archcpu(env)->phys_bits))) {
+ cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
+ }
+ if (!(env->efer & MSR_EFER_LMA)) {
+ t0 &= 0xffffffffUL;
+ }
+ cpu_x86_update_cr3(env, t0);
+ break;
+ case 4:
+ if (t0 & cr4_reserved_bits(env)) {
+ cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
+ }
+ if (((t0 ^ env->cr[4]) & CR4_LA57_MASK) &&
+ (env->hflags & HF_CS64_MASK)) {
+ raise_exception_ra(env, EXCP0D_GPF, GETPC());
+ }
+ cpu_x86_update_cr4(env, t0);
+ break;
+ case 8:
+ if (!(env->hflags2 & HF2_VINTR_MASK)) {
+ bql_lock();
+ cpu_set_apic_tpr(env_archcpu(env)->apic_state, t0);
+ bql_unlock();
+ }
+ env->int_ctl = (env->int_ctl & ~V_TPR_MASK) | (t0 & V_TPR_MASK);
+
+ CPUState *cs = env_cpu(env);
+ if (ctl_has_irq(env)) {
+ cpu_interrupt(cs, CPU_INTERRUPT_VIRQ);
+ } else {
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_VIRQ);
+ }
+ break;
+ default:
+ env->cr[reg] = t0;
+ break;
+ }
+}
+
+void helper_wrmsr(CPUX86State *env)
+{
+ uint64_t val;
+ CPUState *cs = env_cpu(env);
+
+ cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1, GETPC());
+
+ val = ((uint32_t)env->regs[R_EAX]) |
+ ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
+
+ switch ((uint32_t)env->regs[R_ECX]) {
+ case MSR_IA32_SYSENTER_CS:
+ env->sysenter_cs = val & 0xffff;
+ break;
+ case MSR_IA32_SYSENTER_ESP:
+ env->sysenter_esp = val;
+ break;
+ case MSR_IA32_SYSENTER_EIP:
+ env->sysenter_eip = val;
+ break;
+ case MSR_IA32_APICBASE: {
+ int ret;
+
+ if (val & MSR_IA32_APICBASE_RESERVED) {
+ goto error;
+ }
+
+ ret = cpu_set_apic_base(env_archcpu(env)->apic_state, val);
+ if (ret < 0) {
+ goto error;
+ }
+ break;
+ }
+ case MSR_EFER:
+ {
+ uint64_t update_mask;
+
+ update_mask = 0;
+ if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_SYSCALL) {
+ update_mask |= MSR_EFER_SCE;
+ }
+ if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
+ update_mask |= MSR_EFER_LME;
+ }
+ if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) {
+ update_mask |= MSR_EFER_FFXSR;
+ }
+ if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_NX) {
+ update_mask |= MSR_EFER_NXE;
+ }
+ if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
+ update_mask |= MSR_EFER_SVME;
+ }
+ if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) {
+ update_mask |= MSR_EFER_FFXSR;
+ }
+ cpu_load_efer(env, (env->efer & ~update_mask) |
+ (val & update_mask));
+ }
+ break;
+ case MSR_STAR:
+ env->star = val;
+ break;
+ case MSR_PAT:
+ env->pat = val;
+ break;
+ case MSR_IA32_PKRS:
+ if (val & 0xFFFFFFFF00000000ull) {
+ goto error;
+ }
+ env->pkrs = val;
+ tlb_flush(cs);
+ break;
+ case MSR_VM_HSAVE_PA:
+ if (val & (0xfff | ((~0ULL) << env_archcpu(env)->phys_bits))) {
+ goto error;
+ }
+ env->vm_hsave = val;
+ break;
+#ifdef TARGET_X86_64
+ case MSR_LSTAR:
+ env->lstar = val;
+ break;
+ case MSR_CSTAR:
+ env->cstar = val;
+ break;
+ case MSR_FMASK:
+ env->fmask = val;
+ break;
+ case MSR_FSBASE:
+ env->segs[R_FS].base = val;
+ break;
+ case MSR_GSBASE:
+ env->segs[R_GS].base = val;
+ break;
+ case MSR_KERNELGSBASE:
+ env->kernelgsbase = val;
+ break;
+#endif
+ case MSR_MTRRphysBase(0):
+ case MSR_MTRRphysBase(1):
+ case MSR_MTRRphysBase(2):
+ case MSR_MTRRphysBase(3):
+ case MSR_MTRRphysBase(4):
+ case MSR_MTRRphysBase(5):
+ case MSR_MTRRphysBase(6):
+ case MSR_MTRRphysBase(7):
+ env->mtrr_var[((uint32_t)env->regs[R_ECX] -
+ MSR_MTRRphysBase(0)) / 2].base = val;
+ break;
+ case MSR_MTRRphysMask(0):
+ case MSR_MTRRphysMask(1):
+ case MSR_MTRRphysMask(2):
+ case MSR_MTRRphysMask(3):
+ case MSR_MTRRphysMask(4):
+ case MSR_MTRRphysMask(5):
+ case MSR_MTRRphysMask(6):
+ case MSR_MTRRphysMask(7):
+ env->mtrr_var[((uint32_t)env->regs[R_ECX] -
+ MSR_MTRRphysMask(0)) / 2].mask = val;
+ break;
+ case MSR_MTRRfix64K_00000:
+ env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+ MSR_MTRRfix64K_00000] = val;
+ break;
+ case MSR_MTRRfix16K_80000:
+ case MSR_MTRRfix16K_A0000:
+ env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+ MSR_MTRRfix16K_80000 + 1] = val;
+ break;
+ case MSR_MTRRfix4K_C0000:
+ case MSR_MTRRfix4K_C8000:
+ case MSR_MTRRfix4K_D0000:
+ case MSR_MTRRfix4K_D8000:
+ case MSR_MTRRfix4K_E0000:
+ case MSR_MTRRfix4K_E8000:
+ case MSR_MTRRfix4K_F0000:
+ case MSR_MTRRfix4K_F8000:
+ env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+ MSR_MTRRfix4K_C0000 + 3] = val;
+ break;
+ case MSR_MTRRdefType:
+ env->mtrr_deftype = val;
+ break;
+ case MSR_MCG_STATUS:
+ env->mcg_status = val;
+ break;
+ case MSR_MCG_CTL:
+ if ((env->mcg_cap & MCG_CTL_P)
+ && (val == 0 || val == ~(uint64_t)0)) {
+ env->mcg_ctl = val;
+ }
+ break;
+ case MSR_TSC_AUX:
+ env->tsc_aux = val;
+ break;
+ case MSR_IA32_MISC_ENABLE:
+ env->msr_ia32_misc_enable = val;
+ break;
+ case MSR_IA32_BNDCFGS:
+ /* FIXME: #GP if reserved bits are set. */
+ /* FIXME: Extend highest implemented bit of linear address. */
+ env->msr_bndcfgs = val;
+ cpu_sync_bndcs_hflags(env);
+ break;
+ case MSR_APIC_START ... MSR_APIC_END: {
+ int ret;
+ int index = (uint32_t)env->regs[R_ECX] - MSR_APIC_START;
+
+ bql_lock();
+ ret = apic_msr_write(index, val);
+ bql_unlock();
+ if (ret < 0) {
+ goto error;
+ }
+
+ break;
+ }
+ default:
+ if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL
+ && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL +
+ (4 * env->mcg_cap & 0xff)) {
+ uint32_t offset = (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL;
+ if ((offset & 0x3) != 0
+ || (val == 0 || val == ~(uint64_t)0)) {
+ env->mce_banks[offset] = val;
+ }
+ break;
+ }
+ /* XXX: exception? */
+ break;
+ }
+ return;
+error:
+ raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
+}
+
+void helper_rdmsr(CPUX86State *env)
+{
+ X86CPU *x86_cpu = env_archcpu(env);
+ uint64_t val;
+
+ cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0, GETPC());
+
+ switch ((uint32_t)env->regs[R_ECX]) {
+ case MSR_IA32_SYSENTER_CS:
+ val = env->sysenter_cs;
+ break;
+ case MSR_IA32_SYSENTER_ESP:
+ val = env->sysenter_esp;
+ break;
+ case MSR_IA32_SYSENTER_EIP:
+ val = env->sysenter_eip;
+ break;
+ case MSR_IA32_APICBASE:
+ val = cpu_get_apic_base(env_archcpu(env)->apic_state);
+ break;
+ case MSR_EFER:
+ val = env->efer;
+ break;
+ case MSR_STAR:
+ val = env->star;
+ break;
+ case MSR_PAT:
+ val = env->pat;
+ break;
+ case MSR_IA32_PKRS:
+ val = env->pkrs;
+ break;
+ case MSR_VM_HSAVE_PA:
+ val = env->vm_hsave;
+ break;
+ case MSR_IA32_PERF_STATUS:
+ /* tsc_increment_by_tick */
+ val = 1000ULL;
+ /* CPU multiplier */
+ val |= (((uint64_t)4ULL) << 40);
+ break;
+#ifdef TARGET_X86_64
+ case MSR_LSTAR:
+ val = env->lstar;
+ break;
+ case MSR_CSTAR:
+ val = env->cstar;
+ break;
+ case MSR_FMASK:
+ val = env->fmask;
+ break;
+ case MSR_FSBASE:
+ val = env->segs[R_FS].base;
+ break;
+ case MSR_GSBASE:
+ val = env->segs[R_GS].base;
+ break;
+ case MSR_KERNELGSBASE:
+ val = env->kernelgsbase;
+ break;
+ case MSR_TSC_AUX:
+ val = env->tsc_aux;
+ break;
+#endif
+ case MSR_SMI_COUNT:
+ val = env->msr_smi_count;
+ break;
+ case MSR_MTRRphysBase(0):
+ case MSR_MTRRphysBase(1):
+ case MSR_MTRRphysBase(2):
+ case MSR_MTRRphysBase(3):
+ case MSR_MTRRphysBase(4):
+ case MSR_MTRRphysBase(5):
+ case MSR_MTRRphysBase(6):
+ case MSR_MTRRphysBase(7):
+ val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
+ MSR_MTRRphysBase(0)) / 2].base;
+ break;
+ case MSR_MTRRphysMask(0):
+ case MSR_MTRRphysMask(1):
+ case MSR_MTRRphysMask(2):
+ case MSR_MTRRphysMask(3):
+ case MSR_MTRRphysMask(4):
+ case MSR_MTRRphysMask(5):
+ case MSR_MTRRphysMask(6):
+ case MSR_MTRRphysMask(7):
+ val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
+ MSR_MTRRphysMask(0)) / 2].mask;
+ break;
+ case MSR_MTRRfix64K_00000:
+ val = env->mtrr_fixed[0];
+ break;
+ case MSR_MTRRfix16K_80000:
+ case MSR_MTRRfix16K_A0000:
+ val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+ MSR_MTRRfix16K_80000 + 1];
+ break;
+ case MSR_MTRRfix4K_C0000:
+ case MSR_MTRRfix4K_C8000:
+ case MSR_MTRRfix4K_D0000:
+ case MSR_MTRRfix4K_D8000:
+ case MSR_MTRRfix4K_E0000:
+ case MSR_MTRRfix4K_E8000:
+ case MSR_MTRRfix4K_F0000:
+ case MSR_MTRRfix4K_F8000:
+ val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+ MSR_MTRRfix4K_C0000 + 3];
+ break;
+ case MSR_MTRRdefType:
+ val = env->mtrr_deftype;
+ break;
+ case MSR_MTRRcap:
+ if (env->features[FEAT_1_EDX] & CPUID_MTRR) {
+ val = MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT |
+ MSR_MTRRcap_WC_SUPPORTED;
+ } else {
+ /* XXX: exception? */
+ val = 0;
+ }
+ break;
+ case MSR_MCG_CAP:
+ val = env->mcg_cap;
+ break;
+ case MSR_MCG_CTL:
+ if (env->mcg_cap & MCG_CTL_P) {
+ val = env->mcg_ctl;
+ } else {
+ val = 0;
+ }
+ break;
+ case MSR_MCG_STATUS:
+ val = env->mcg_status;
+ break;
+ case MSR_IA32_MISC_ENABLE:
+ val = env->msr_ia32_misc_enable;
+ break;
+ case MSR_IA32_BNDCFGS:
+ val = env->msr_bndcfgs;
+ break;
+ case MSR_IA32_UCODE_REV:
+ val = x86_cpu->ucode_rev;
+ break;
+ case MSR_CORE_THREAD_COUNT: {
+ CPUState *cs = CPU(x86_cpu);
+ val = (cs->nr_threads * cs->nr_cores) | (cs->nr_cores << 16);
+ break;
+ }
+ case MSR_APIC_START ... MSR_APIC_END: {
+ int ret;
+ int index = (uint32_t)env->regs[R_ECX] - MSR_APIC_START;
+
+ bql_lock();
+ ret = apic_msr_read(index, &val);
+ bql_unlock();
+ if (ret < 0) {
+ raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
+ }
+
+ break;
+ }
+ default:
+ if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL
+ && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL +
+ (4 * env->mcg_cap & 0xff)) {
+ uint32_t offset = (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL;
+ val = env->mce_banks[offset];
+ break;
+ }
+ /* XXX: exception? */
+ val = 0;
+ break;
+ }
+ env->regs[R_EAX] = (uint32_t)(val);
+ env->regs[R_EDX] = (uint32_t)(val >> 32);
+}
+
+void helper_flush_page(CPUX86State *env, target_ulong addr)
+{
+ tlb_flush_page(env_cpu(env), addr);
+}
+
+G_NORETURN void helper_hlt(CPUX86State *env)
+{
+ CPUState *cs = env_cpu(env);
+
+ do_end_instruction(env);
+ cs->halted = 1;
+ cs->exception_index = EXCP_HLT;
+ cpu_loop_exit(cs);
+}
+
+void helper_monitor(CPUX86State *env, target_ulong ptr)
+{
+ if ((uint32_t)env->regs[R_ECX] != 0) {
+ raise_exception_ra(env, EXCP0D_GPF, GETPC());
+ }
+ /* XXX: store address? */
+ cpu_svm_check_intercept_param(env, SVM_EXIT_MONITOR, 0, GETPC());
+}
+
+G_NORETURN void helper_mwait(CPUX86State *env, int next_eip_addend)
+{
+ CPUState *cs = env_cpu(env);
+
+ if ((uint32_t)env->regs[R_ECX] != 0) {
+ raise_exception_ra(env, EXCP0D_GPF, GETPC());
+ }
+ cpu_svm_check_intercept_param(env, SVM_EXIT_MWAIT, 0, GETPC());
+ env->eip += next_eip_addend;
+
+ /* XXX: not complete but not completely erroneous */
+ if (cs->cpu_index != 0 || CPU_NEXT(cs) != NULL) {
+ helper_pause(env);
+ } else {
+ helper_hlt(env);
+ }
+}
--- /dev/null
+/*
+ * x86 segmentation related helpers: (system-only code)
+ * TSS, interrupts, system calls, jumps and call/task gates, descriptors
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * 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.1 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 "qemu/log.h"
+#include "qemu/main-loop.h"
+#include "cpu.h"
+#include "exec/helper-proto.h"
+#include "exec/cpu_ldst.h"
+#include "tcg/helper-tcg.h"
+#include "../seg_helper.h"
+
+void helper_syscall(CPUX86State *env, int next_eip_addend)
+{
+ int selector;
+
+ if (!(env->efer & MSR_EFER_SCE)) {
+ raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC());
+ }
+ selector = (env->star >> 32) & 0xffff;
+#ifdef TARGET_X86_64
+ if (env->hflags & HF_LMA_MASK) {
+ int code64;
+
+ env->regs[R_ECX] = env->eip + next_eip_addend;
+ env->regs[11] = cpu_compute_eflags(env) & ~RF_MASK;
+
+ code64 = env->hflags & HF_CS64_MASK;
+
+ env->eflags &= ~(env->fmask | RF_MASK);
+ cpu_load_eflags(env, env->eflags, 0);
+ cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
+ 0, 0xffffffff,
+ DESC_G_MASK | DESC_P_MASK |
+ DESC_S_MASK |
+ DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK |
+ DESC_L_MASK);
+ cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
+ 0, 0xffffffff,
+ DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
+ DESC_S_MASK |
+ DESC_W_MASK | DESC_A_MASK);
+ if (code64) {
+ env->eip = env->lstar;
+ } else {
+ env->eip = env->cstar;
+ }
+ } else
+#endif
+ {
+ env->regs[R_ECX] = (uint32_t)(env->eip + next_eip_addend);
+
+ env->eflags &= ~(IF_MASK | RF_MASK | VM_MASK);
+ cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
+ 0, 0xffffffff,
+ DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
+ DESC_S_MASK |
+ DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
+ cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
+ 0, 0xffffffff,
+ DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
+ DESC_S_MASK |
+ DESC_W_MASK | DESC_A_MASK);
+ env->eip = (uint32_t)env->star;
+ }
+}
+
+void handle_even_inj(CPUX86State *env, int intno, int is_int,
+ int error_code, int is_hw, int rm)
+{
+ CPUState *cs = env_cpu(env);
+ uint32_t event_inj = x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
+ control.event_inj));
+
+ if (!(event_inj & SVM_EVTINJ_VALID)) {
+ int type;
+
+ if (is_int) {
+ type = SVM_EVTINJ_TYPE_SOFT;
+ } else {
+ type = SVM_EVTINJ_TYPE_EXEPT;
+ }
+ event_inj = intno | type | SVM_EVTINJ_VALID;
+ if (!rm && exception_has_error_code(intno)) {
+ event_inj |= SVM_EVTINJ_VALID_ERR;
+ x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
+ control.event_inj_err),
+ error_code);
+ }
+ x86_stl_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, control.event_inj),
+ event_inj);
+ }
+}
+
+void x86_cpu_do_interrupt(CPUState *cs)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+
+ if (cs->exception_index == EXCP_VMEXIT) {
+ assert(env->old_exception == -1);
+ do_vmexit(env);
+ } else {
+ do_interrupt_all(cpu, cs->exception_index,
+ env->exception_is_int,
+ env->error_code,
+ env->exception_next_eip, 0);
+ /* successfully delivered */
+ env->old_exception = -1;
+ }
+}
+
+bool x86_cpu_exec_halt(CPUState *cpu)
+{
+ X86CPU *x86_cpu = X86_CPU(cpu);
+ CPUX86State *env = &x86_cpu->env;
+
+ if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
+ bql_lock();
+ apic_poll_irq(x86_cpu->apic_state);
+ cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL);
+ bql_unlock();
+ }
+
+ if (!cpu_has_work(cpu)) {
+ return false;
+ }
+
+ /* Complete HLT instruction. */
+ if (env->eflags & TF_MASK) {
+ env->dr[6] |= DR6_BS;
+ do_interrupt_all(x86_cpu, EXCP01_DB, 0, 0, env->eip, 0);
+ }
+ return true;
+}
+
+bool x86_need_replay_interrupt(int interrupt_request)
+{
+ /*
+ * CPU_INTERRUPT_POLL is a virtual event which gets converted into a
+ * "real" interrupt event later. It does not need to be recorded for
+ * replay purposes.
+ */
+ return !(interrupt_request & CPU_INTERRUPT_POLL);
+}
+
+bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+ int intno;
+
+ interrupt_request = x86_cpu_pending_interrupt(cs, interrupt_request);
+ if (!interrupt_request) {
+ return false;
+ }
+
+ /* Don't process multiple interrupt requests in a single call.
+ * This is required to make icount-driven execution deterministic.
+ */
+ switch (interrupt_request) {
+ case CPU_INTERRUPT_POLL:
+ cs->interrupt_request &= ~CPU_INTERRUPT_POLL;
+ apic_poll_irq(cpu->apic_state);
+ break;
+ case CPU_INTERRUPT_SIPI:
+ do_cpu_sipi(cpu);
+ break;
+ case CPU_INTERRUPT_SMI:
+ cpu_svm_check_intercept_param(env, SVM_EXIT_SMI, 0, 0);
+ cs->interrupt_request &= ~CPU_INTERRUPT_SMI;
+ do_smm_enter(cpu);
+ break;
+ case CPU_INTERRUPT_NMI:
+ cpu_svm_check_intercept_param(env, SVM_EXIT_NMI, 0, 0);
+ cs->interrupt_request &= ~CPU_INTERRUPT_NMI;
+ env->hflags2 |= HF2_NMI_MASK;
+ do_interrupt_x86_hardirq(env, EXCP02_NMI, 1);
+ break;
+ case CPU_INTERRUPT_MCE:
+ cs->interrupt_request &= ~CPU_INTERRUPT_MCE;
+ do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0);
+ break;
+ case CPU_INTERRUPT_HARD:
+ cpu_svm_check_intercept_param(env, SVM_EXIT_INTR, 0, 0);
+ cs->interrupt_request &= ~(CPU_INTERRUPT_HARD |
+ CPU_INTERRUPT_VIRQ);
+ intno = cpu_get_pic_interrupt(env);
+ qemu_log_mask(CPU_LOG_INT,
+ "Servicing hardware INT=0x%02x\n", intno);
+ do_interrupt_x86_hardirq(env, intno, 1);
+ break;
+ case CPU_INTERRUPT_VIRQ:
+ cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR, 0, 0);
+ intno = x86_ldl_phys(cs, env->vm_vmcb
+ + offsetof(struct vmcb, control.int_vector));
+ qemu_log_mask(CPU_LOG_INT,
+ "Servicing virtual hardware INT=0x%02x\n", intno);
+ do_interrupt_x86_hardirq(env, intno, 1);
+ cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
+ env->int_ctl &= ~V_IRQ_MASK;
+ break;
+ }
+
+ /* Ensure that no TB jump will be modified as the program flow was changed. */
+ return true;
+}
+
+/* check if Port I/O is allowed in TSS */
+void helper_check_io(CPUX86State *env, uint32_t addr, uint32_t size)
+{
+ uintptr_t retaddr = GETPC();
+ uint32_t io_offset, val, mask;
+
+ /* TSS must be a valid 32 bit one */
+ if (!(env->tr.flags & DESC_P_MASK) ||
+ ((env->tr.flags >> DESC_TYPE_SHIFT) & 0xf) != 9 ||
+ env->tr.limit < 103) {
+ goto fail;
+ }
+ io_offset = cpu_lduw_kernel_ra(env, env->tr.base + 0x66, retaddr);
+ io_offset += (addr >> 3);
+ /* Note: the check needs two bytes */
+ if ((io_offset + 1) > env->tr.limit) {
+ goto fail;
+ }
+ val = cpu_lduw_kernel_ra(env, env->tr.base + io_offset, retaddr);
+ val >>= (addr & 7);
+ mask = (1 << size) - 1;
+ /* all bits must be zero to allow the I/O */
+ if ((val & mask) != 0) {
+ fail:
+ raise_exception_err_ra(env, EXCP0D_GPF, 0, retaddr);
+ }
+}
--- /dev/null
+/*
+ * x86 SMM helpers (system-only)
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * 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.1 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"
+#include "exec/log.h"
+#include "tcg/helper-tcg.h"
+
+
+/* SMM support */
+
+#ifdef TARGET_X86_64
+#define SMM_REVISION_ID 0x00020064
+#else
+#define SMM_REVISION_ID 0x00020000
+#endif
+
+void do_smm_enter(X86CPU *cpu)
+{
+ CPUX86State *env = &cpu->env;
+ CPUState *cs = CPU(cpu);
+ target_ulong sm_state;
+ SegmentCache *dt;
+ int i, offset;
+
+ qemu_log_mask(CPU_LOG_INT, "SMM: enter\n");
+ log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), CPU_DUMP_CCOP);
+
+ env->msr_smi_count++;
+ env->hflags |= HF_SMM_MASK;
+ if (env->hflags2 & HF2_NMI_MASK) {
+ env->hflags2 |= HF2_SMM_INSIDE_NMI_MASK;
+ } else {
+ env->hflags2 |= HF2_NMI_MASK;
+ }
+
+ sm_state = env->smbase + 0x8000;
+
+#ifdef TARGET_X86_64
+ for (i = 0; i < 6; i++) {
+ dt = &env->segs[i];
+ offset = 0x7e00 + i * 16;
+ x86_stw_phys(cs, sm_state + offset, dt->selector);
+ x86_stw_phys(cs, sm_state + offset + 2, (dt->flags >> 8) & 0xf0ff);
+ x86_stl_phys(cs, sm_state + offset + 4, dt->limit);
+ x86_stq_phys(cs, sm_state + offset + 8, dt->base);
+ }
+
+ x86_stq_phys(cs, sm_state + 0x7e68, env->gdt.base);
+ x86_stl_phys(cs, sm_state + 0x7e64, env->gdt.limit);
+
+ x86_stw_phys(cs, sm_state + 0x7e70, env->ldt.selector);
+ x86_stq_phys(cs, sm_state + 0x7e78, env->ldt.base);
+ x86_stl_phys(cs, sm_state + 0x7e74, env->ldt.limit);
+ x86_stw_phys(cs, sm_state + 0x7e72, (env->ldt.flags >> 8) & 0xf0ff);
+
+ x86_stq_phys(cs, sm_state + 0x7e88, env->idt.base);
+ x86_stl_phys(cs, sm_state + 0x7e84, env->idt.limit);
+
+ x86_stw_phys(cs, sm_state + 0x7e90, env->tr.selector);
+ x86_stq_phys(cs, sm_state + 0x7e98, env->tr.base);
+ x86_stl_phys(cs, sm_state + 0x7e94, env->tr.limit);
+ x86_stw_phys(cs, sm_state + 0x7e92, (env->tr.flags >> 8) & 0xf0ff);
+
+ /* ??? Vol 1, 16.5.6 Intel MPX and SMM says that IA32_BNDCFGS
+ is saved at offset 7ED0. Vol 3, 34.4.1.1, Table 32-2, has
+ 7EA0-7ED7 as "reserved". What's this, and what's really
+ supposed to happen? */
+ x86_stq_phys(cs, sm_state + 0x7ed0, env->efer);
+
+ x86_stq_phys(cs, sm_state + 0x7ff8, env->regs[R_EAX]);
+ x86_stq_phys(cs, sm_state + 0x7ff0, env->regs[R_ECX]);
+ x86_stq_phys(cs, sm_state + 0x7fe8, env->regs[R_EDX]);
+ x86_stq_phys(cs, sm_state + 0x7fe0, env->regs[R_EBX]);
+ x86_stq_phys(cs, sm_state + 0x7fd8, env->regs[R_ESP]);
+ x86_stq_phys(cs, sm_state + 0x7fd0, env->regs[R_EBP]);
+ x86_stq_phys(cs, sm_state + 0x7fc8, env->regs[R_ESI]);
+ x86_stq_phys(cs, sm_state + 0x7fc0, env->regs[R_EDI]);
+ for (i = 8; i < 16; i++) {
+ x86_stq_phys(cs, sm_state + 0x7ff8 - i * 8, env->regs[i]);
+ }
+ x86_stq_phys(cs, sm_state + 0x7f78, env->eip);
+ x86_stl_phys(cs, sm_state + 0x7f70, cpu_compute_eflags(env));
+ x86_stl_phys(cs, sm_state + 0x7f68, env->dr[6]);
+ x86_stl_phys(cs, sm_state + 0x7f60, env->dr[7]);
+
+ x86_stl_phys(cs, sm_state + 0x7f48, env->cr[4]);
+ x86_stq_phys(cs, sm_state + 0x7f50, env->cr[3]);
+ x86_stl_phys(cs, sm_state + 0x7f58, env->cr[0]);
+
+ x86_stl_phys(cs, sm_state + 0x7efc, SMM_REVISION_ID);
+ x86_stl_phys(cs, sm_state + 0x7f00, env->smbase);
+#else
+ x86_stl_phys(cs, sm_state + 0x7ffc, env->cr[0]);
+ x86_stl_phys(cs, sm_state + 0x7ff8, env->cr[3]);
+ x86_stl_phys(cs, sm_state + 0x7ff4, cpu_compute_eflags(env));
+ x86_stl_phys(cs, sm_state + 0x7ff0, env->eip);
+ x86_stl_phys(cs, sm_state + 0x7fec, env->regs[R_EDI]);
+ x86_stl_phys(cs, sm_state + 0x7fe8, env->regs[R_ESI]);
+ x86_stl_phys(cs, sm_state + 0x7fe4, env->regs[R_EBP]);
+ x86_stl_phys(cs, sm_state + 0x7fe0, env->regs[R_ESP]);
+ x86_stl_phys(cs, sm_state + 0x7fdc, env->regs[R_EBX]);
+ x86_stl_phys(cs, sm_state + 0x7fd8, env->regs[R_EDX]);
+ x86_stl_phys(cs, sm_state + 0x7fd4, env->regs[R_ECX]);
+ x86_stl_phys(cs, sm_state + 0x7fd0, env->regs[R_EAX]);
+ x86_stl_phys(cs, sm_state + 0x7fcc, env->dr[6]);
+ x86_stl_phys(cs, sm_state + 0x7fc8, env->dr[7]);
+
+ x86_stl_phys(cs, sm_state + 0x7fc4, env->tr.selector);
+ x86_stl_phys(cs, sm_state + 0x7f64, env->tr.base);
+ x86_stl_phys(cs, sm_state + 0x7f60, env->tr.limit);
+ x86_stl_phys(cs, sm_state + 0x7f5c, (env->tr.flags >> 8) & 0xf0ff);
+
+ x86_stl_phys(cs, sm_state + 0x7fc0, env->ldt.selector);
+ x86_stl_phys(cs, sm_state + 0x7f80, env->ldt.base);
+ x86_stl_phys(cs, sm_state + 0x7f7c, env->ldt.limit);
+ x86_stl_phys(cs, sm_state + 0x7f78, (env->ldt.flags >> 8) & 0xf0ff);
+
+ x86_stl_phys(cs, sm_state + 0x7f74, env->gdt.base);
+ x86_stl_phys(cs, sm_state + 0x7f70, env->gdt.limit);
+
+ x86_stl_phys(cs, sm_state + 0x7f58, env->idt.base);
+ x86_stl_phys(cs, sm_state + 0x7f54, env->idt.limit);
+
+ for (i = 0; i < 6; i++) {
+ dt = &env->segs[i];
+ if (i < 3) {
+ offset = 0x7f84 + i * 12;
+ } else {
+ offset = 0x7f2c + (i - 3) * 12;
+ }
+ x86_stl_phys(cs, sm_state + 0x7fa8 + i * 4, dt->selector);
+ x86_stl_phys(cs, sm_state + offset + 8, dt->base);
+ x86_stl_phys(cs, sm_state + offset + 4, dt->limit);
+ x86_stl_phys(cs, sm_state + offset, (dt->flags >> 8) & 0xf0ff);
+ }
+ x86_stl_phys(cs, sm_state + 0x7f14, env->cr[4]);
+
+ x86_stl_phys(cs, sm_state + 0x7efc, SMM_REVISION_ID);
+ x86_stl_phys(cs, sm_state + 0x7ef8, env->smbase);
+#endif
+ /* init SMM cpu state */
+
+#ifdef TARGET_X86_64
+ cpu_load_efer(env, 0);
+#endif
+ cpu_load_eflags(env, 0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C |
+ DF_MASK));
+ env->eip = 0x00008000;
+ cpu_x86_update_cr0(env,
+ env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK |
+ CR0_PG_MASK));
+ cpu_x86_update_cr4(env, 0);
+ env->dr[7] = 0x00000400;
+
+ cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase,
+ 0xffffffff,
+ DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+ DESC_G_MASK | DESC_A_MASK);
+ cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffffffff,
+ DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+ DESC_G_MASK | DESC_A_MASK);
+ cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffffffff,
+ DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+ DESC_G_MASK | DESC_A_MASK);
+ cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffffffff,
+ DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+ DESC_G_MASK | DESC_A_MASK);
+ cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffffffff,
+ DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+ DESC_G_MASK | DESC_A_MASK);
+ cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff,
+ DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+ DESC_G_MASK | DESC_A_MASK);
+}
+
+void helper_rsm(CPUX86State *env)
+{
+ X86CPU *cpu = env_archcpu(env);
+ CPUState *cs = env_cpu(env);
+ target_ulong sm_state;
+ int i, offset;
+ uint32_t val;
+
+ sm_state = env->smbase + 0x8000;
+#ifdef TARGET_X86_64
+ cpu_load_efer(env, x86_ldq_phys(cs, sm_state + 0x7ed0));
+
+ env->gdt.base = x86_ldq_phys(cs, sm_state + 0x7e68);
+ env->gdt.limit = x86_ldl_phys(cs, sm_state + 0x7e64);
+
+ env->ldt.selector = x86_lduw_phys(cs, sm_state + 0x7e70);
+ env->ldt.base = x86_ldq_phys(cs, sm_state + 0x7e78);
+ env->ldt.limit = x86_ldl_phys(cs, sm_state + 0x7e74);
+ env->ldt.flags = (x86_lduw_phys(cs, sm_state + 0x7e72) & 0xf0ff) << 8;
+
+ env->idt.base = x86_ldq_phys(cs, sm_state + 0x7e88);
+ env->idt.limit = x86_ldl_phys(cs, sm_state + 0x7e84);
+
+ env->tr.selector = x86_lduw_phys(cs, sm_state + 0x7e90);
+ env->tr.base = x86_ldq_phys(cs, sm_state + 0x7e98);
+ env->tr.limit = x86_ldl_phys(cs, sm_state + 0x7e94);
+ env->tr.flags = (x86_lduw_phys(cs, sm_state + 0x7e92) & 0xf0ff) << 8;
+
+ env->regs[R_EAX] = x86_ldq_phys(cs, sm_state + 0x7ff8);
+ env->regs[R_ECX] = x86_ldq_phys(cs, sm_state + 0x7ff0);
+ env->regs[R_EDX] = x86_ldq_phys(cs, sm_state + 0x7fe8);
+ env->regs[R_EBX] = x86_ldq_phys(cs, sm_state + 0x7fe0);
+ env->regs[R_ESP] = x86_ldq_phys(cs, sm_state + 0x7fd8);
+ env->regs[R_EBP] = x86_ldq_phys(cs, sm_state + 0x7fd0);
+ env->regs[R_ESI] = x86_ldq_phys(cs, sm_state + 0x7fc8);
+ env->regs[R_EDI] = x86_ldq_phys(cs, sm_state + 0x7fc0);
+ for (i = 8; i < 16; i++) {
+ env->regs[i] = x86_ldq_phys(cs, sm_state + 0x7ff8 - i * 8);
+ }
+ env->eip = x86_ldq_phys(cs, sm_state + 0x7f78);
+ cpu_load_eflags(env, x86_ldl_phys(cs, sm_state + 0x7f70),
+ ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
+ env->dr[6] = x86_ldl_phys(cs, sm_state + 0x7f68);
+ env->dr[7] = x86_ldl_phys(cs, sm_state + 0x7f60);
+
+ cpu_x86_update_cr4(env, x86_ldl_phys(cs, sm_state + 0x7f48));
+ cpu_x86_update_cr3(env, x86_ldq_phys(cs, sm_state + 0x7f50));
+ cpu_x86_update_cr0(env, x86_ldl_phys(cs, sm_state + 0x7f58));
+
+ for (i = 0; i < 6; i++) {
+ offset = 0x7e00 + i * 16;
+ cpu_x86_load_seg_cache(env, i,
+ x86_lduw_phys(cs, sm_state + offset),
+ x86_ldq_phys(cs, sm_state + offset + 8),
+ x86_ldl_phys(cs, sm_state + offset + 4),
+ (x86_lduw_phys(cs, sm_state + offset + 2) &
+ 0xf0ff) << 8);
+ }
+
+ val = x86_ldl_phys(cs, sm_state + 0x7efc); /* revision ID */
+ if (val & 0x20000) {
+ env->smbase = x86_ldl_phys(cs, sm_state + 0x7f00);
+ }
+#else
+ cpu_x86_update_cr0(env, x86_ldl_phys(cs, sm_state + 0x7ffc));
+ cpu_x86_update_cr3(env, x86_ldl_phys(cs, sm_state + 0x7ff8));
+ cpu_load_eflags(env, x86_ldl_phys(cs, sm_state + 0x7ff4),
+ ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
+ env->eip = x86_ldl_phys(cs, sm_state + 0x7ff0);
+ env->regs[R_EDI] = x86_ldl_phys(cs, sm_state + 0x7fec);
+ env->regs[R_ESI] = x86_ldl_phys(cs, sm_state + 0x7fe8);
+ env->regs[R_EBP] = x86_ldl_phys(cs, sm_state + 0x7fe4);
+ env->regs[R_ESP] = x86_ldl_phys(cs, sm_state + 0x7fe0);
+ env->regs[R_EBX] = x86_ldl_phys(cs, sm_state + 0x7fdc);
+ env->regs[R_EDX] = x86_ldl_phys(cs, sm_state + 0x7fd8);
+ env->regs[R_ECX] = x86_ldl_phys(cs, sm_state + 0x7fd4);
+ env->regs[R_EAX] = x86_ldl_phys(cs, sm_state + 0x7fd0);
+ env->dr[6] = x86_ldl_phys(cs, sm_state + 0x7fcc);
+ env->dr[7] = x86_ldl_phys(cs, sm_state + 0x7fc8);
+
+ env->tr.selector = x86_ldl_phys(cs, sm_state + 0x7fc4) & 0xffff;
+ env->tr.base = x86_ldl_phys(cs, sm_state + 0x7f64);
+ env->tr.limit = x86_ldl_phys(cs, sm_state + 0x7f60);
+ env->tr.flags = (x86_ldl_phys(cs, sm_state + 0x7f5c) & 0xf0ff) << 8;
+
+ env->ldt.selector = x86_ldl_phys(cs, sm_state + 0x7fc0) & 0xffff;
+ env->ldt.base = x86_ldl_phys(cs, sm_state + 0x7f80);
+ env->ldt.limit = x86_ldl_phys(cs, sm_state + 0x7f7c);
+ env->ldt.flags = (x86_ldl_phys(cs, sm_state + 0x7f78) & 0xf0ff) << 8;
+
+ env->gdt.base = x86_ldl_phys(cs, sm_state + 0x7f74);
+ env->gdt.limit = x86_ldl_phys(cs, sm_state + 0x7f70);
+
+ env->idt.base = x86_ldl_phys(cs, sm_state + 0x7f58);
+ env->idt.limit = x86_ldl_phys(cs, sm_state + 0x7f54);
+
+ for (i = 0; i < 6; i++) {
+ if (i < 3) {
+ offset = 0x7f84 + i * 12;
+ } else {
+ offset = 0x7f2c + (i - 3) * 12;
+ }
+ cpu_x86_load_seg_cache(env, i,
+ x86_ldl_phys(cs,
+ sm_state + 0x7fa8 + i * 4) & 0xffff,
+ x86_ldl_phys(cs, sm_state + offset + 8),
+ x86_ldl_phys(cs, sm_state + offset + 4),
+ (x86_ldl_phys(cs,
+ sm_state + offset) & 0xf0ff) << 8);
+ }
+ cpu_x86_update_cr4(env, x86_ldl_phys(cs, sm_state + 0x7f14));
+
+ val = x86_ldl_phys(cs, sm_state + 0x7efc); /* revision ID */
+ if (val & 0x20000) {
+ env->smbase = x86_ldl_phys(cs, sm_state + 0x7ef8);
+ }
+#endif
+ if ((env->hflags2 & HF2_SMM_INSIDE_NMI_MASK) == 0) {
+ env->hflags2 &= ~HF2_NMI_MASK;
+ }
+ env->hflags2 &= ~HF2_SMM_INSIDE_NMI_MASK;
+ env->hflags &= ~HF_SMM_MASK;
+
+ qemu_log_mask(CPU_LOG_INT, "SMM: after RSM\n");
+ log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), CPU_DUMP_CCOP);
+}
--- /dev/null
+/*
+ * x86 SVM helpers (system only)
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * 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.1 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 "qemu/log.h"
+#include "cpu.h"
+#include "exec/helper-proto.h"
+#include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
+#include "tcg/helper-tcg.h"
+
+/* Secure Virtual Machine helpers */
+
+static void svm_save_seg(CPUX86State *env, int mmu_idx, hwaddr addr,
+ const SegmentCache *sc)
+{
+ cpu_stw_mmuidx_ra(env, addr + offsetof(struct vmcb_seg, selector),
+ sc->selector, mmu_idx, 0);
+ cpu_stq_mmuidx_ra(env, addr + offsetof(struct vmcb_seg, base),
+ sc->base, mmu_idx, 0);
+ cpu_stl_mmuidx_ra(env, addr + offsetof(struct vmcb_seg, limit),
+ sc->limit, mmu_idx, 0);
+ cpu_stw_mmuidx_ra(env, addr + offsetof(struct vmcb_seg, attrib),
+ ((sc->flags >> 8) & 0xff)
+ | ((sc->flags >> 12) & 0x0f00),
+ mmu_idx, 0);
+}
+
+/*
+ * VMRUN and VMLOAD canonicalizes (i.e., sign-extend to bit 63) all base
+ * addresses in the segment registers that have been loaded.
+ */
+static inline void svm_canonicalization(CPUX86State *env, target_ulong *seg_base)
+{
+ uint16_t shift_amt = 64 - cpu_x86_virtual_addr_width(env);
+ *seg_base = ((((long) *seg_base) << shift_amt) >> shift_amt);
+}
+
+static void svm_load_seg(CPUX86State *env, int mmu_idx, hwaddr addr,
+ SegmentCache *sc)
+{
+ unsigned int flags;
+
+ sc->selector =
+ cpu_lduw_mmuidx_ra(env, addr + offsetof(struct vmcb_seg, selector),
+ mmu_idx, 0);
+ sc->base =
+ cpu_ldq_mmuidx_ra(env, addr + offsetof(struct vmcb_seg, base),
+ mmu_idx, 0);
+ sc->limit =
+ cpu_ldl_mmuidx_ra(env, addr + offsetof(struct vmcb_seg, limit),
+ mmu_idx, 0);
+ flags =
+ cpu_lduw_mmuidx_ra(env, addr + offsetof(struct vmcb_seg, attrib),
+ mmu_idx, 0);
+ sc->flags = ((flags & 0xff) << 8) | ((flags & 0x0f00) << 12);
+
+ svm_canonicalization(env, &sc->base);
+}
+
+static void svm_load_seg_cache(CPUX86State *env, int mmu_idx,
+ hwaddr addr, int seg_reg)
+{
+ SegmentCache sc;
+
+ svm_load_seg(env, mmu_idx, addr, &sc);
+ cpu_x86_load_seg_cache(env, seg_reg, sc.selector,
+ sc.base, sc.limit, sc.flags);
+}
+
+static inline bool is_efer_invalid_state (CPUX86State *env)
+{
+ if (!(env->efer & MSR_EFER_SVME)) {
+ return true;
+ }
+
+ if (env->efer & MSR_EFER_RESERVED) {
+ return true;
+ }
+
+ if ((env->efer & (MSR_EFER_LMA | MSR_EFER_LME)) &&
+ !(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM)) {
+ return true;
+ }
+
+ if ((env->efer & MSR_EFER_LME) && (env->cr[0] & CR0_PG_MASK)
+ && !(env->cr[4] & CR4_PAE_MASK)) {
+ return true;
+ }
+
+ if ((env->efer & MSR_EFER_LME) && (env->cr[0] & CR0_PG_MASK)
+ && !(env->cr[0] & CR0_PE_MASK)) {
+ return true;
+ }
+
+ if ((env->efer & MSR_EFER_LME) && (env->cr[0] & CR0_PG_MASK)
+ && (env->cr[4] & CR4_PAE_MASK)
+ && (env->segs[R_CS].flags & DESC_L_MASK)
+ && (env->segs[R_CS].flags & DESC_B_MASK)) {
+ return true;
+ }
+
+ return false;
+}
+
+static inline bool virtual_gif_enabled(CPUX86State *env)
+{
+ if (likely(env->hflags & HF_GUEST_MASK)) {
+ return (env->features[FEAT_SVM] & CPUID_SVM_VGIF)
+ && (env->int_ctl & V_GIF_ENABLED_MASK);
+ }
+ return false;
+}
+
+static inline bool virtual_vm_load_save_enabled(CPUX86State *env, uint32_t exit_code, uintptr_t retaddr)
+{
+ uint64_t lbr_ctl;
+
+ if (likely(env->hflags & HF_GUEST_MASK)) {
+ if (likely(!(env->hflags2 & HF2_NPT_MASK)) || !(env->efer & MSR_EFER_LMA)) {
+ cpu_vmexit(env, exit_code, 0, retaddr);
+ }
+
+ lbr_ctl = x86_ldl_phys(env_cpu(env), env->vm_vmcb + offsetof(struct vmcb,
+ control.lbr_ctl));
+ return (env->features[FEAT_SVM] & CPUID_SVM_V_VMSAVE_VMLOAD)
+ && (lbr_ctl & V_VMLOAD_VMSAVE_ENABLED_MASK);
+
+ }
+
+ return false;
+}
+
+static inline bool virtual_gif_set(CPUX86State *env)
+{
+ return !virtual_gif_enabled(env) || (env->int_ctl & V_GIF_MASK);
+}
+
+void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
+{
+ CPUState *cs = env_cpu(env);
+ X86CPU *cpu = env_archcpu(env);
+ target_ulong addr;
+ uint64_t nested_ctl;
+ uint32_t event_inj;
+ uint32_t asid;
+ uint64_t new_cr0;
+ uint64_t new_cr3;
+ uint64_t new_cr4;
+ uint64_t new_dr6;
+ uint64_t new_dr7;
+
+ if (aflag == 2) {
+ addr = env->regs[R_EAX];
+ } else {
+ addr = (uint32_t)env->regs[R_EAX];
+ }
+
+ /* Exceptions are checked before the intercept. */
+ if (addr & (0xfff | ((~0ULL) << env_archcpu(env)->phys_bits))) {
+ raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
+ }
+
+ cpu_svm_check_intercept_param(env, SVM_EXIT_VMRUN, 0, GETPC());
+
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmrun! " TARGET_FMT_lx "\n", addr);
+
+ env->vm_vmcb = addr;
+
+ /* save the current CPU state in the hsave page */
+ x86_stq_phys(cs, env->vm_hsave + offsetof(struct vmcb, save.gdtr.base),
+ env->gdt.base);
+ x86_stl_phys(cs, env->vm_hsave + offsetof(struct vmcb, save.gdtr.limit),
+ env->gdt.limit);
+
+ x86_stq_phys(cs, env->vm_hsave + offsetof(struct vmcb, save.idtr.base),
+ env->idt.base);
+ x86_stl_phys(cs, env->vm_hsave + offsetof(struct vmcb, save.idtr.limit),
+ env->idt.limit);
+
+ x86_stq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb, save.cr0), env->cr[0]);
+ x86_stq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb, save.cr2), env->cr[2]);
+ x86_stq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb, save.cr3), env->cr[3]);
+ x86_stq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb, save.cr4), env->cr[4]);
+ x86_stq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb, save.dr6), env->dr[6]);
+ x86_stq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb, save.dr7), env->dr[7]);
+
+ x86_stq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb, save.efer), env->efer);
+ x86_stq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb, save.rflags),
+ cpu_compute_eflags(env));
+
+ svm_save_seg(env, MMU_PHYS_IDX,
+ env->vm_hsave + offsetof(struct vmcb, save.es),
+ &env->segs[R_ES]);
+ svm_save_seg(env, MMU_PHYS_IDX,
+ env->vm_hsave + offsetof(struct vmcb, save.cs),
+ &env->segs[R_CS]);
+ svm_save_seg(env, MMU_PHYS_IDX,
+ env->vm_hsave + offsetof(struct vmcb, save.ss),
+ &env->segs[R_SS]);
+ svm_save_seg(env, MMU_PHYS_IDX,
+ env->vm_hsave + offsetof(struct vmcb, save.ds),
+ &env->segs[R_DS]);
+
+ x86_stq_phys(cs, env->vm_hsave + offsetof(struct vmcb, save.rip),
+ env->eip + next_eip_addend);
+ x86_stq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb, save.rsp), env->regs[R_ESP]);
+ x86_stq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb, save.rax), env->regs[R_EAX]);
+
+ /* load the interception bitmaps so we do not need to access the
+ vmcb in svm mode */
+ env->intercept = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
+ control.intercept));
+ env->intercept_cr_read = x86_lduw_phys(cs, env->vm_vmcb +
+ offsetof(struct vmcb,
+ control.intercept_cr_read));
+ env->intercept_cr_write = x86_lduw_phys(cs, env->vm_vmcb +
+ offsetof(struct vmcb,
+ control.intercept_cr_write));
+ env->intercept_dr_read = x86_lduw_phys(cs, env->vm_vmcb +
+ offsetof(struct vmcb,
+ control.intercept_dr_read));
+ env->intercept_dr_write = x86_lduw_phys(cs, env->vm_vmcb +
+ offsetof(struct vmcb,
+ control.intercept_dr_write));
+ env->intercept_exceptions = x86_ldl_phys(cs, env->vm_vmcb +
+ offsetof(struct vmcb,
+ control.intercept_exceptions
+ ));
+
+ env->hflags &= ~HF_INHIBIT_IRQ_MASK;
+ if (x86_ldl_phys(cs, env->vm_vmcb +
+ offsetof(struct vmcb, control.int_state)) &
+ SVM_INTERRUPT_SHADOW_MASK) {
+ env->hflags |= HF_INHIBIT_IRQ_MASK;
+ }
+
+ nested_ctl = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
+ control.nested_ctl));
+ asid = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
+ control.asid));
+
+ uint64_t msrpm_base_pa = x86_ldq_phys(cs, env->vm_vmcb +
+ offsetof(struct vmcb,
+ control.msrpm_base_pa));
+ uint64_t iopm_base_pa = x86_ldq_phys(cs, env->vm_vmcb +
+ offsetof(struct vmcb, control.iopm_base_pa));
+
+ if ((msrpm_base_pa & ~0xfff) >= (1ull << cpu->phys_bits) - SVM_MSRPM_SIZE) {
+ cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
+ }
+
+ if ((iopm_base_pa & ~0xfff) >= (1ull << cpu->phys_bits) - SVM_IOPM_SIZE) {
+ cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
+ }
+
+ env->nested_pg_mode = 0;
+
+ if (!cpu_svm_has_intercept(env, SVM_EXIT_VMRUN)) {
+ cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
+ }
+ if (asid == 0) {
+ cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
+ }
+
+ if (nested_ctl & SVM_NPT_ENABLED) {
+ env->nested_cr3 = x86_ldq_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb,
+ control.nested_cr3));
+ env->hflags2 |= HF2_NPT_MASK;
+
+ env->nested_pg_mode = get_pg_mode(env) & PG_MODE_SVM_MASK;
+
+ tlb_flush_by_mmuidx(cs, 1 << MMU_NESTED_IDX);
+ }
+
+ /* enable intercepts */
+ env->hflags |= HF_GUEST_MASK;
+
+ env->tsc_offset = x86_ldq_phys(cs, env->vm_vmcb +
+ offsetof(struct vmcb, control.tsc_offset));
+
+ new_cr0 = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.cr0));
+ if (new_cr0 & SVM_CR0_RESERVED_MASK) {
+ cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
+ }
+ if ((new_cr0 & CR0_NW_MASK) && !(new_cr0 & CR0_CD_MASK)) {
+ cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
+ }
+ new_cr3 = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.cr3));
+ if ((env->efer & MSR_EFER_LMA) &&
+ (new_cr3 & ((~0ULL) << cpu->phys_bits))) {
+ cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
+ }
+ new_cr4 = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.cr4));
+ if (new_cr4 & cr4_reserved_bits(env)) {
+ cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
+ }
+ /* clear exit_info_2 so we behave like the real hardware */
+ x86_stq_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 0);
+
+ cpu_x86_update_cr0(env, new_cr0);
+ cpu_x86_update_cr4(env, new_cr4);
+ cpu_x86_update_cr3(env, new_cr3);
+ env->cr[2] = x86_ldq_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, save.cr2));
+ env->int_ctl = x86_ldl_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
+ env->hflags2 &= ~(HF2_HIF_MASK | HF2_VINTR_MASK);
+ if (env->int_ctl & V_INTR_MASKING_MASK) {
+ env->hflags2 |= HF2_VINTR_MASK;
+ if (env->eflags & IF_MASK) {
+ env->hflags2 |= HF2_HIF_MASK;
+ }
+ }
+
+ cpu_load_efer(env,
+ x86_ldq_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, save.efer)));
+ env->eflags = 0;
+ cpu_load_eflags(env, x86_ldq_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb,
+ save.rflags)),
+ ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
+
+ svm_load_seg_cache(env, MMU_PHYS_IDX,
+ env->vm_vmcb + offsetof(struct vmcb, save.es), R_ES);
+ svm_load_seg_cache(env, MMU_PHYS_IDX,
+ env->vm_vmcb + offsetof(struct vmcb, save.cs), R_CS);
+ svm_load_seg_cache(env, MMU_PHYS_IDX,
+ env->vm_vmcb + offsetof(struct vmcb, save.ss), R_SS);
+ svm_load_seg_cache(env, MMU_PHYS_IDX,
+ env->vm_vmcb + offsetof(struct vmcb, save.ds), R_DS);
+ svm_load_seg(env, MMU_PHYS_IDX,
+ env->vm_vmcb + offsetof(struct vmcb, save.idtr), &env->idt);
+ svm_load_seg(env, MMU_PHYS_IDX,
+ env->vm_vmcb + offsetof(struct vmcb, save.gdtr), &env->gdt);
+
+ env->eip = x86_ldq_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, save.rip));
+
+ env->regs[R_ESP] = x86_ldq_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, save.rsp));
+ env->regs[R_EAX] = x86_ldq_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, save.rax));
+
+ new_dr7 = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.dr7));
+ new_dr6 = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.dr6));
+
+#ifdef TARGET_X86_64
+ if (new_dr7 & DR_RESERVED_MASK) {
+ cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
+ }
+ if (new_dr6 & DR_RESERVED_MASK) {
+ cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
+ }
+#endif
+
+ cpu_x86_update_dr7(env, new_dr7);
+ env->dr[6] = new_dr6;
+
+ if (is_efer_invalid_state(env)) {
+ cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
+ }
+
+ switch (x86_ldub_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, control.tlb_ctl))) {
+ case TLB_CONTROL_DO_NOTHING:
+ break;
+ case TLB_CONTROL_FLUSH_ALL_ASID:
+ /* FIXME: this is not 100% correct but should work for now */
+ tlb_flush(cs);
+ break;
+ }
+
+ env->hflags2 |= HF2_GIF_MASK;
+
+ if (ctl_has_irq(env)) {
+ cs->interrupt_request |= CPU_INTERRUPT_VIRQ;
+ }
+
+ if (virtual_gif_set(env)) {
+ env->hflags2 |= HF2_VGIF_MASK;
+ }
+
+ /* maybe we need to inject an event */
+ event_inj = x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
+ control.event_inj));
+ if (event_inj & SVM_EVTINJ_VALID) {
+ uint8_t vector = event_inj & SVM_EVTINJ_VEC_MASK;
+ uint16_t valid_err = event_inj & SVM_EVTINJ_VALID_ERR;
+ uint32_t event_inj_err = x86_ldl_phys(cs, env->vm_vmcb +
+ offsetof(struct vmcb,
+ control.event_inj_err));
+
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, "Injecting(%#hx): ", valid_err);
+ /* FIXME: need to implement valid_err */
+ switch (event_inj & SVM_EVTINJ_TYPE_MASK) {
+ case SVM_EVTINJ_TYPE_INTR:
+ cs->exception_index = vector;
+ env->error_code = event_inj_err;
+ env->exception_is_int = 0;
+ env->exception_next_eip = -1;
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, "INTR");
+ /* XXX: is it always correct? */
+ do_interrupt_x86_hardirq(env, vector, 1);
+ break;
+ case SVM_EVTINJ_TYPE_NMI:
+ cs->exception_index = EXCP02_NMI;
+ env->error_code = event_inj_err;
+ env->exception_is_int = 0;
+ env->exception_next_eip = env->eip;
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, "NMI");
+ cpu_loop_exit(cs);
+ break;
+ case SVM_EVTINJ_TYPE_EXEPT:
+ if (vector == EXCP02_NMI || vector >= 31) {
+ cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
+ }
+ cs->exception_index = vector;
+ env->error_code = event_inj_err;
+ env->exception_is_int = 0;
+ env->exception_next_eip = -1;
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, "EXEPT");
+ cpu_loop_exit(cs);
+ break;
+ case SVM_EVTINJ_TYPE_SOFT:
+ cs->exception_index = vector;
+ env->error_code = event_inj_err;
+ env->exception_is_int = 1;
+ env->exception_next_eip = env->eip;
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, "SOFT");
+ cpu_loop_exit(cs);
+ break;
+ default:
+ cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
+ break;
+ }
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, " %#x %#x\n", cs->exception_index,
+ env->error_code);
+ }
+}
+
+void helper_vmmcall(CPUX86State *env)
+{
+ cpu_svm_check_intercept_param(env, SVM_EXIT_VMMCALL, 0, GETPC());
+ raise_exception(env, EXCP06_ILLOP);
+}
+
+void helper_vmload(CPUX86State *env, int aflag)
+{
+ int mmu_idx = MMU_PHYS_IDX;
+ target_ulong addr;
+
+ if (aflag == 2) {
+ addr = env->regs[R_EAX];
+ } else {
+ addr = (uint32_t)env->regs[R_EAX];
+ }
+
+ /* Exceptions are checked before the intercept. */
+ if (addr & (0xfff | ((~0ULL) << env_archcpu(env)->phys_bits))) {
+ raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
+ }
+
+ cpu_svm_check_intercept_param(env, SVM_EXIT_VMLOAD, 0, GETPC());
+
+ if (virtual_vm_load_save_enabled(env, SVM_EXIT_VMLOAD, GETPC())) {
+ mmu_idx = MMU_NESTED_IDX;
+ }
+
+ svm_load_seg_cache(env, mmu_idx,
+ addr + offsetof(struct vmcb, save.fs), R_FS);
+ svm_load_seg_cache(env, mmu_idx,
+ addr + offsetof(struct vmcb, save.gs), R_GS);
+ svm_load_seg(env, mmu_idx,
+ addr + offsetof(struct vmcb, save.tr), &env->tr);
+ svm_load_seg(env, mmu_idx,
+ addr + offsetof(struct vmcb, save.ldtr), &env->ldt);
+
+#ifdef TARGET_X86_64
+ env->kernelgsbase =
+ cpu_ldq_mmuidx_ra(env,
+ addr + offsetof(struct vmcb, save.kernel_gs_base),
+ mmu_idx, 0);
+ env->lstar =
+ cpu_ldq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.lstar),
+ mmu_idx, 0);
+ env->cstar =
+ cpu_ldq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.cstar),
+ mmu_idx, 0);
+ env->fmask =
+ cpu_ldq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.sfmask),
+ mmu_idx, 0);
+ svm_canonicalization(env, &env->kernelgsbase);
+#endif
+ env->star =
+ cpu_ldq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.star),
+ mmu_idx, 0);
+ env->sysenter_cs =
+ cpu_ldq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.sysenter_cs),
+ mmu_idx, 0);
+ env->sysenter_esp =
+ cpu_ldq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.sysenter_esp),
+ mmu_idx, 0);
+ env->sysenter_eip =
+ cpu_ldq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.sysenter_eip),
+ mmu_idx, 0);
+}
+
+void helper_vmsave(CPUX86State *env, int aflag)
+{
+ int mmu_idx = MMU_PHYS_IDX;
+ target_ulong addr;
+
+ if (aflag == 2) {
+ addr = env->regs[R_EAX];
+ } else {
+ addr = (uint32_t)env->regs[R_EAX];
+ }
+
+ /* Exceptions are checked before the intercept. */
+ if (addr & (0xfff | ((~0ULL) << env_archcpu(env)->phys_bits))) {
+ raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
+ }
+
+ cpu_svm_check_intercept_param(env, SVM_EXIT_VMSAVE, 0, GETPC());
+
+ if (virtual_vm_load_save_enabled(env, SVM_EXIT_VMSAVE, GETPC())) {
+ mmu_idx = MMU_NESTED_IDX;
+ }
+
+ svm_save_seg(env, mmu_idx, addr + offsetof(struct vmcb, save.fs),
+ &env->segs[R_FS]);
+ svm_save_seg(env, mmu_idx, addr + offsetof(struct vmcb, save.gs),
+ &env->segs[R_GS]);
+ svm_save_seg(env, mmu_idx, addr + offsetof(struct vmcb, save.tr),
+ &env->tr);
+ svm_save_seg(env, mmu_idx, addr + offsetof(struct vmcb, save.ldtr),
+ &env->ldt);
+
+#ifdef TARGET_X86_64
+ cpu_stq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.kernel_gs_base),
+ env->kernelgsbase, mmu_idx, 0);
+ cpu_stq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.lstar),
+ env->lstar, mmu_idx, 0);
+ cpu_stq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.cstar),
+ env->cstar, mmu_idx, 0);
+ cpu_stq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.sfmask),
+ env->fmask, mmu_idx, 0);
+#endif
+ cpu_stq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.star),
+ env->star, mmu_idx, 0);
+ cpu_stq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.sysenter_cs),
+ env->sysenter_cs, mmu_idx, 0);
+ cpu_stq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.sysenter_esp),
+ env->sysenter_esp, mmu_idx, 0);
+ cpu_stq_mmuidx_ra(env, addr + offsetof(struct vmcb, save.sysenter_eip),
+ env->sysenter_eip, mmu_idx, 0);
+}
+
+void helper_stgi(CPUX86State *env)
+{
+ cpu_svm_check_intercept_param(env, SVM_EXIT_STGI, 0, GETPC());
+
+ if (virtual_gif_enabled(env)) {
+ env->int_ctl |= V_GIF_MASK;
+ env->hflags2 |= HF2_VGIF_MASK;
+ } else {
+ env->hflags2 |= HF2_GIF_MASK;
+ }
+}
+
+void helper_clgi(CPUX86State *env)
+{
+ cpu_svm_check_intercept_param(env, SVM_EXIT_CLGI, 0, GETPC());
+
+ if (virtual_gif_enabled(env)) {
+ env->int_ctl &= ~V_GIF_MASK;
+ env->hflags2 &= ~HF2_VGIF_MASK;
+ } else {
+ env->hflags2 &= ~HF2_GIF_MASK;
+ }
+}
+
+bool cpu_svm_has_intercept(CPUX86State *env, uint32_t type)
+{
+ switch (type) {
+ case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR0 + 8:
+ if (env->intercept_cr_read & (1 << (type - SVM_EXIT_READ_CR0))) {
+ return true;
+ }
+ break;
+ case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR0 + 8:
+ if (env->intercept_cr_write & (1 << (type - SVM_EXIT_WRITE_CR0))) {
+ return true;
+ }
+ break;
+ case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR0 + 7:
+ if (env->intercept_dr_read & (1 << (type - SVM_EXIT_READ_DR0))) {
+ return true;
+ }
+ break;
+ case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR0 + 7:
+ if (env->intercept_dr_write & (1 << (type - SVM_EXIT_WRITE_DR0))) {
+ return true;
+ }
+ break;
+ case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 31:
+ if (env->intercept_exceptions & (1 << (type - SVM_EXIT_EXCP_BASE))) {
+ return true;
+ }
+ break;
+ default:
+ if (env->intercept & (1ULL << (type - SVM_EXIT_INTR))) {
+ return true;
+ }
+ break;
+ }
+ return false;
+}
+
+void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type,
+ uint64_t param, uintptr_t retaddr)
+{
+ CPUState *cs = env_cpu(env);
+
+ if (likely(!(env->hflags & HF_GUEST_MASK))) {
+ return;
+ }
+
+ if (!cpu_svm_has_intercept(env, type)) {
+ return;
+ }
+
+ if (type == SVM_EXIT_MSR) {
+ /* FIXME: this should be read in at vmrun (faster this way?) */
+ uint64_t addr = x86_ldq_phys(cs, env->vm_vmcb +
+ offsetof(struct vmcb,
+ control.msrpm_base_pa));
+ uint32_t t0, t1;
+
+ switch ((uint32_t)env->regs[R_ECX]) {
+ case 0 ... 0x1fff:
+ t0 = (env->regs[R_ECX] * 2) % 8;
+ t1 = (env->regs[R_ECX] * 2) / 8;
+ break;
+ case 0xc0000000 ... 0xc0001fff:
+ t0 = (8192 + env->regs[R_ECX] - 0xc0000000) * 2;
+ t1 = (t0 / 8);
+ t0 %= 8;
+ break;
+ case 0xc0010000 ... 0xc0011fff:
+ t0 = (16384 + env->regs[R_ECX] - 0xc0010000) * 2;
+ t1 = (t0 / 8);
+ t0 %= 8;
+ break;
+ default:
+ cpu_vmexit(env, type, param, retaddr);
+ t0 = 0;
+ t1 = 0;
+ break;
+ }
+ if (x86_ldub_phys(cs, addr + t1) & ((1 << param) << t0)) {
+ cpu_vmexit(env, type, param, retaddr);
+ }
+ return;
+ }
+
+ cpu_vmexit(env, type, param, retaddr);
+}
+
+void helper_svm_check_intercept(CPUX86State *env, uint32_t type)
+{
+ cpu_svm_check_intercept_param(env, type, 0, GETPC());
+}
+
+void helper_svm_check_io(CPUX86State *env, uint32_t port, uint32_t param,
+ uint32_t next_eip_addend)
+{
+ CPUState *cs = env_cpu(env);
+
+ if (env->intercept & (1ULL << (SVM_EXIT_IOIO - SVM_EXIT_INTR))) {
+ /* FIXME: this should be read in at vmrun (faster this way?) */
+ uint64_t addr = x86_ldq_phys(cs, env->vm_vmcb +
+ offsetof(struct vmcb, control.iopm_base_pa));
+ uint16_t mask = (1 << ((param >> 4) & 7)) - 1;
+
+ if (x86_lduw_phys(cs, addr + port / 8) & (mask << (port & 7))) {
+ /* next env->eip */
+ x86_stq_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
+ env->eip + next_eip_addend);
+ cpu_vmexit(env, SVM_EXIT_IOIO, param | (port << 16), GETPC());
+ }
+ }
+}
+
+void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1,
+ uintptr_t retaddr)
+{
+ CPUState *cs = env_cpu(env);
+
+ cpu_restore_state(cs, retaddr);
+
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmexit(%08x, %016" PRIx64 ", %016"
+ PRIx64 ", " TARGET_FMT_lx ")!\n",
+ exit_code, exit_info_1,
+ x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
+ control.exit_info_2)),
+ env->eip);
+
+ cs->exception_index = EXCP_VMEXIT;
+ x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.exit_code),
+ exit_code);
+
+ x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
+ control.exit_info_1), exit_info_1),
+
+ /* remove any pending exception */
+ env->old_exception = -1;
+ cpu_loop_exit(cs);
+}
+
+void do_vmexit(CPUX86State *env)
+{
+ CPUState *cs = env_cpu(env);
+
+ if (env->hflags & HF_INHIBIT_IRQ_MASK) {
+ x86_stl_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, control.int_state),
+ SVM_INTERRUPT_SHADOW_MASK);
+ env->hflags &= ~HF_INHIBIT_IRQ_MASK;
+ } else {
+ x86_stl_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, control.int_state), 0);
+ }
+ env->hflags2 &= ~HF2_NPT_MASK;
+ tlb_flush_by_mmuidx(cs, 1 << MMU_NESTED_IDX);
+
+ /* Save the VM state in the vmcb */
+ svm_save_seg(env, MMU_PHYS_IDX,
+ env->vm_vmcb + offsetof(struct vmcb, save.es),
+ &env->segs[R_ES]);
+ svm_save_seg(env, MMU_PHYS_IDX,
+ env->vm_vmcb + offsetof(struct vmcb, save.cs),
+ &env->segs[R_CS]);
+ svm_save_seg(env, MMU_PHYS_IDX,
+ env->vm_vmcb + offsetof(struct vmcb, save.ss),
+ &env->segs[R_SS]);
+ svm_save_seg(env, MMU_PHYS_IDX,
+ env->vm_vmcb + offsetof(struct vmcb, save.ds),
+ &env->segs[R_DS]);
+
+ x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.gdtr.base),
+ env->gdt.base);
+ x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.gdtr.limit),
+ env->gdt.limit);
+
+ x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.idtr.base),
+ env->idt.base);
+ x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.idtr.limit),
+ env->idt.limit);
+
+ x86_stq_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, save.efer), env->efer);
+ x86_stq_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, save.cr0), env->cr[0]);
+ x86_stq_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, save.cr2), env->cr[2]);
+ x86_stq_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, save.cr3), env->cr[3]);
+ x86_stq_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, save.cr4), env->cr[4]);
+ x86_stl_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), env->int_ctl);
+
+ x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.rflags),
+ cpu_compute_eflags(env));
+ x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.rip),
+ env->eip);
+ x86_stq_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, save.rsp), env->regs[R_ESP]);
+ x86_stq_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, save.rax), env->regs[R_EAX]);
+ x86_stq_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, save.dr7), env->dr[7]);
+ x86_stq_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, save.dr6), env->dr[6]);
+ x86_stb_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.cpl),
+ env->hflags & HF_CPL_MASK);
+
+ /* Reload the host state from vm_hsave */
+ env->hflags2 &= ~(HF2_HIF_MASK | HF2_VINTR_MASK);
+ env->hflags &= ~HF_GUEST_MASK;
+ env->intercept = 0;
+ env->intercept_exceptions = 0;
+
+ /* Clears the V_IRQ and V_INTR_MASKING bits inside the processor. */
+ cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
+ env->int_ctl = 0;
+
+ /* Clears the TSC_OFFSET inside the processor. */
+ env->tsc_offset = 0;
+
+ env->gdt.base = x86_ldq_phys(cs, env->vm_hsave + offsetof(struct vmcb,
+ save.gdtr.base));
+ env->gdt.limit = x86_ldl_phys(cs, env->vm_hsave + offsetof(struct vmcb,
+ save.gdtr.limit));
+
+ env->idt.base = x86_ldq_phys(cs, env->vm_hsave + offsetof(struct vmcb,
+ save.idtr.base));
+ env->idt.limit = x86_ldl_phys(cs, env->vm_hsave + offsetof(struct vmcb,
+ save.idtr.limit));
+
+ cpu_x86_update_cr0(env, x86_ldq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb,
+ save.cr0)) |
+ CR0_PE_MASK);
+ cpu_x86_update_cr4(env, x86_ldq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb,
+ save.cr4)));
+
+ /*
+ * Resets the current ASID register to zero (host ASID; TLB flush).
+ *
+ * If the host is in PAE mode, the processor reloads the host's PDPEs
+ * from the page table indicated the host's CR3. FIXME: If the PDPEs
+ * contain illegal state, the processor causes a shutdown (QEMU does
+ * not implement PDPTRs).
+ */
+ cpu_x86_update_cr3(env, x86_ldq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb,
+ save.cr3)));
+ /* we need to set the efer after the crs so the hidden flags get
+ set properly */
+ cpu_load_efer(env, x86_ldq_phys(cs, env->vm_hsave + offsetof(struct vmcb,
+ save.efer)));
+
+ /* Completion of the VMRUN instruction clears the host EFLAGS.RF bit. */
+ env->eflags = 0;
+ cpu_load_eflags(env, x86_ldq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb,
+ save.rflags)),
+ ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK |
+ RF_MASK | VM_MASK));
+
+ svm_load_seg_cache(env, MMU_PHYS_IDX,
+ env->vm_hsave + offsetof(struct vmcb, save.es), R_ES);
+ svm_load_seg_cache(env, MMU_PHYS_IDX,
+ env->vm_hsave + offsetof(struct vmcb, save.cs), R_CS);
+ svm_load_seg_cache(env, MMU_PHYS_IDX,
+ env->vm_hsave + offsetof(struct vmcb, save.ss), R_SS);
+ svm_load_seg_cache(env, MMU_PHYS_IDX,
+ env->vm_hsave + offsetof(struct vmcb, save.ds), R_DS);
+
+ env->eip = x86_ldq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb, save.rip));
+ env->regs[R_ESP] = x86_ldq_phys(cs, env->vm_hsave +
+ offsetof(struct vmcb, save.rsp));
+ env->regs[R_EAX] = x86_ldq_phys(cs, env->vm_hsave +
+ offsetof(struct vmcb, save.rax));
+
+ env->dr[6] = x86_ldq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb, save.dr6));
+
+ /* Disables all breakpoints in the host DR7 register. */
+ cpu_x86_update_dr7(env,
+ x86_ldq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb, save.dr7)) & ~0xff);
+
+ /* other setups */
+ x86_stl_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, control.exit_int_info),
+ x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
+ control.event_inj)));
+ x86_stl_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, control.exit_int_info_err),
+ x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
+ control.event_inj_err)));
+ x86_stl_phys(cs,
+ env->vm_vmcb + offsetof(struct vmcb, control.event_inj), 0);
+
+ env->hflags2 &= ~HF2_GIF_MASK;
+ env->hflags2 &= ~HF2_VGIF_MASK;
+
+
+ /* FIXME: Checks the reloaded host state for consistency. */
+
+ /*
+ * EFLAGS.TF causes a #DB trap after the VMRUN completes on the host
+ * side (i.e., after the #VMEXIT from the guest). Since we're running
+ * in the main loop, call do_interrupt_all directly.
+ */
+ if ((env->eflags & TF_MASK) != 0) {
+ env->dr[6] |= DR6_BS;
+ do_interrupt_all(X86_CPU(cs), EXCP01_DB, 0, 0, env->eip, 0);
+ }
+}
--- /dev/null
+/*
+ * i386 TCG cpu class initialization functions specific to system emulation
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * 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 "tcg/helper-tcg.h"
+
+#include "system/system.h"
+#include "qemu/units.h"
+#include "exec/address-spaces.h"
+
+#include "tcg/tcg-cpu.h"
+
+static void tcg_cpu_machine_done(Notifier *n, void *unused)
+{
+ X86CPU *cpu = container_of(n, X86CPU, machine_done);
+ MemoryRegion *smram =
+ (MemoryRegion *) object_resolve_path("/machine/smram", NULL);
+
+ if (smram) {
+ cpu->smram = g_new(MemoryRegion, 1);
+ memory_region_init_alias(cpu->smram, OBJECT(cpu), "smram",
+ smram, 0, 4 * GiB);
+ memory_region_set_enabled(cpu->smram, true);
+ memory_region_add_subregion_overlap(cpu->cpu_as_root, 0,
+ cpu->smram, 1);
+ }
+}
+
+bool tcg_cpu_realizefn(CPUState *cs, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(cs);
+
+ /*
+ * The realize order is important, since x86_cpu_realize() checks if
+ * nothing else has been set by the user (or by accelerators) in
+ * cpu->ucode_rev and cpu->phys_bits, and the memory regions
+ * initialized here are needed for the vcpu initialization.
+ *
+ * realize order:
+ * tcg_cpu -> host_cpu -> x86_cpu
+ */
+ cpu->cpu_as_mem = g_new(MemoryRegion, 1);
+ cpu->cpu_as_root = g_new(MemoryRegion, 1);
+
+ /* Outer container... */
+ memory_region_init(cpu->cpu_as_root, OBJECT(cpu), "memory", ~0ull);
+ memory_region_set_enabled(cpu->cpu_as_root, true);
+
+ /*
+ * ... with two regions inside: normal system memory with low
+ * priority, and...
+ */
+ memory_region_init_alias(cpu->cpu_as_mem, OBJECT(cpu), "memory",
+ get_system_memory(), 0, ~0ull);
+ memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_mem, 0);
+ memory_region_set_enabled(cpu->cpu_as_mem, true);
+
+ cs->num_ases = 2;
+ cpu_address_space_init(cs, 0, "cpu-memory", cs->memory);
+ cpu_address_space_init(cs, 1, "cpu-smm", cpu->cpu_as_root);
+
+ /* ... SMRAM with higher priority, linked from /machine/smram. */
+ cpu->machine_done.notify = tcg_cpu_machine_done;
+ qemu_add_machine_init_done_notifier(&cpu->machine_done);
+ return true;
+}
#endif
/*
- * Many sysemu-only helpers are not reachable for user-only.
+ * Many system-only helpers are not reachable for user-only.
* Define stub generators here, so that we need not either sprinkle
* ifdefs through the translator, nor provide the helper function.
*/
*/
#include "qemu/osdep.h"
-#include "sysemu/kvm_int.h"
+#include "system/kvm_int.h"
#include "qemu/main-loop.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
#include "qemu/guest-random.h"
-#include "sysemu/whpx.h"
+#include "system/whpx.h"
#include "whpx-internal.h"
#include "whpx-accel-ops.h"
#ifndef TARGET_I386_WHPX_ACCEL_OPS_H
#define TARGET_I386_WHPX_ACCEL_OPS_H
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
int whpx_init_vcpu(CPUState *cpu);
int whpx_vcpu_exec(CPUState *cpu);
#include "exec/ioport.h"
#include "gdbstub/helpers.h"
#include "qemu/accel.h"
-#include "sysemu/whpx.h"
-#include "sysemu/cpus.h"
-#include "sysemu/runstate.h"
+#include "system/whpx.h"
+#include "system/cpus.h"
+#include "system/runstate.h"
#include "qemu/main-loop.h"
#include "hw/boards.h"
#include "hw/intc/ioapic.h"
#include "hw/i386/apic_internal.h"
#include "hw/i386/apic-msidef.h"
#include "hw/pci/msi.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/whpx.h"
+#include "system/hw_accel.h"
+#include "system/whpx.h"
#include "whpx-internal.h"
struct whpx_lapic_state {
#include "qemu/osdep.h"
#include "cpu.h"
#include "elf.h"
-#include "sysemu/dump.h"
+#include "system/dump.h"
#include "internals.h"
/* struct user_pt_regs from arch/loongarch/include/uapi/asm/ptrace.h */
#include "qemu/qemu-print.h"
#include "qapi/error.h"
#include "qemu/module.h"
-#include "sysemu/qtest.h"
-#include "sysemu/tcg.h"
-#include "sysemu/kvm.h"
+#include "system/qtest.h"
+#include "system/tcg.h"
+#include "system/kvm.h"
#include "kvm/kvm_loongarch.h"
#include "exec/exec-all.h"
#include "cpu.h"
#include "fpu/softfloat-helpers.h"
#include "cpu-csr.h"
#ifndef CONFIG_USER_ONLY
-#include "sysemu/reset.h"
+#include "system/reset.h"
#endif
#include "vec.h"
#ifdef CONFIG_KVM
#include "qemu/timer.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/kvm.h"
-#include "sysemu/kvm_int.h"
+#include "system/system.h"
+#include "system/kvm.h"
+#include "system/kvm_int.h"
#include "hw/pci/pci.h"
#include "exec/memattrs.h"
#include "exec/address-spaces.h"
#include "hw/irq.h"
#include "qemu/log.h"
#include "hw/loader.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "cpu-csr.h"
#include "kvm_loongarch.h"
#include "trace.h"
#include "qemu/osdep.h"
#include "cpu.h"
#include "migration/cpu.h"
-#include "sysemu/tcg.h"
+#include "system/tcg.h"
#include "vec.h"
static const VMStateDescription vmstate_fpu_reg = {
#include "internal.h"
#include "kvm_mips.h"
#include "qemu/module.h"
-#include "sysemu/kvm.h"
-#include "sysemu/qtest.h"
+#include "system/kvm.h"
+#include "system/qtest.h"
#include "exec/exec-all.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-clock.h"
DEF_HELPER_FLAGS_2(rddsp, 0, tl, tl, env)
#ifndef CONFIG_USER_ONLY
-#include "tcg/sysemu_helper.h.inc"
+#include "tcg/system_helper.h.inc"
#endif /* !CONFIG_USER_ONLY */
#include "tcg/msa_helper.h.inc"
#include "internal.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
-#include "sysemu/kvm.h"
-#include "sysemu/kvm_int.h"
-#include "sysemu/runstate.h"
+#include "system/kvm.h"
+#include "system/kvm_int.h"
+#include "system/runstate.h"
#include "kvm_mips.h"
#include "hw/boards.h"
#include "fpu_helper.h"
))
if have_system
- subdir('sysemu')
+ subdir('system')
endif
if 'CONFIG_TCG' in config_all_accel
+++ /dev/null
-/*
- * QEMU MIPS address translation support
- *
- * 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 "cpu.h"
-
-uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr)
-{
- return addr & 0x1fffffffll;
-}
-
-uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr)
-{
- return addr | ~0x7fffffffll;
-}
-
-uint64_t cpu_mips_kseg1_to_phys(void *opaque, uint64_t addr)
-{
- return addr & 0x1fffffffll;
-}
-
-uint64_t cpu_mips_phys_to_kseg1(void *opaque, uint64_t addr)
-{
- return (addr & 0x1fffffffll) | 0xffffffffa0000000ll;
-}
+++ /dev/null
-/*
- * QEMU MIPS CPU
- *
- * Copyright (c) 2012 SUSE LINUX Products GmbH
- *
- * 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.1 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/lgpl-2.1.html>
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "internal.h"
-#include "exec/exec-all.h"
-
-/* Called for updates to CP0_Status. */
-void sync_c0_status(CPUMIPSState *env, CPUMIPSState *cpu, int tc)
-{
- int32_t tcstatus, *tcst;
- uint32_t v = cpu->CP0_Status;
- uint32_t cu, mx, asid, ksu;
- uint32_t mask = ((1 << CP0TCSt_TCU3)
- | (1 << CP0TCSt_TCU2)
- | (1 << CP0TCSt_TCU1)
- | (1 << CP0TCSt_TCU0)
- | (1 << CP0TCSt_TMX)
- | (3 << CP0TCSt_TKSU)
- | (0xff << CP0TCSt_TASID));
-
- cu = (v >> CP0St_CU0) & 0xf;
- mx = (v >> CP0St_MX) & 0x1;
- ksu = (v >> CP0St_KSU) & 0x3;
- asid = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
-
- tcstatus = cu << CP0TCSt_TCU0;
- tcstatus |= mx << CP0TCSt_TMX;
- tcstatus |= ksu << CP0TCSt_TKSU;
- tcstatus |= asid;
-
- if (tc == cpu->current_tc) {
- tcst = &cpu->active_tc.CP0_TCStatus;
- } else {
- tcst = &cpu->tcs[tc].CP0_TCStatus;
- }
-
- *tcst &= ~mask;
- *tcst |= tcstatus;
- compute_hflags(cpu);
-}
-
-void cpu_mips_store_status(CPUMIPSState *env, target_ulong val)
-{
- uint32_t mask = env->CP0_Status_rw_bitmask;
- target_ulong old = env->CP0_Status;
-
- if (env->insn_flags & ISA_MIPS_R6) {
- bool has_supervisor = extract32(mask, CP0St_KSU, 2) == 0x3;
-#if defined(TARGET_MIPS64)
- uint32_t ksux = (1 << CP0St_KX) & val;
- ksux |= (ksux >> 1) & val; /* KX = 0 forces SX to be 0 */
- ksux |= (ksux >> 1) & val; /* SX = 0 forces UX to be 0 */
- val = (val & ~(7 << CP0St_UX)) | ksux;
-#endif
- if (has_supervisor && extract32(val, CP0St_KSU, 2) == 0x3) {
- mask &= ~(3 << CP0St_KSU);
- }
- mask &= ~(((1 << CP0St_SR) | (1 << CP0St_NMI)) & val);
- }
-
- env->CP0_Status = (old & ~mask) | (val & mask);
-#if defined(TARGET_MIPS64)
- if ((env->CP0_Status ^ old) & (old & (7 << CP0St_UX))) {
- /* Access to at least one of the 64-bit segments has been disabled */
- tlb_flush(env_cpu(env));
- }
-#endif
- if (ase_mt_available(env)) {
- sync_c0_status(env, env, env->current_tc);
- } else {
- compute_hflags(env);
- }
-}
-
-void cpu_mips_store_cause(CPUMIPSState *env, target_ulong val)
-{
- uint32_t mask = 0x00C00300;
- uint32_t old = env->CP0_Cause;
- int i;
-
- if (env->insn_flags & ISA_MIPS_R2) {
- mask |= 1 << CP0Ca_DC;
- }
- if (env->insn_flags & ISA_MIPS_R6) {
- mask &= ~((1 << CP0Ca_WP) & val);
- }
-
- env->CP0_Cause = (env->CP0_Cause & ~mask) | (val & mask);
-
- if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
- if (env->CP0_Cause & (1 << CP0Ca_DC)) {
- cpu_mips_stop_count(env);
- } else {
- cpu_mips_start_count(env);
- }
- }
-
- /* Set/reset software interrupts */
- for (i = 0 ; i < 2 ; i++) {
- if ((old ^ env->CP0_Cause) & (1 << (CP0Ca_IP + i))) {
- cpu_mips_soft_irq(env, i, env->CP0_Cause & (1 << (CP0Ca_IP + i)));
- }
- }
-}
+++ /dev/null
-/*
- * QEMU MIPS timer support
- *
- * 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 "hw/irq.h"
-#include "qemu/timer.h"
-#include "sysemu/kvm.h"
-#include "internal.h"
-
-/* MIPS R4K timer */
-static uint32_t cpu_mips_get_count_val(CPUMIPSState *env)
-{
- int64_t now_ns;
- now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- return env->CP0_Count +
- (uint32_t)clock_ns_to_ticks(env->count_clock, now_ns);
-}
-
-static void cpu_mips_timer_update(CPUMIPSState *env)
-{
- uint64_t now_ns, next_ns;
- uint32_t wait;
-
- now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- wait = env->CP0_Compare - cpu_mips_get_count_val(env);
- /* Clamp interval to overflow if virtual time had not progressed */
- if (!wait) {
- wait = UINT32_MAX;
- }
- next_ns = now_ns + clock_ticks_to_ns(env->count_clock, wait);
- timer_mod(env->timer, next_ns);
-}
-
-/* Expire the timer. */
-static void cpu_mips_timer_expire(CPUMIPSState *env)
-{
- cpu_mips_timer_update(env);
- if (env->insn_flags & ISA_MIPS_R2) {
- env->CP0_Cause |= 1 << CP0Ca_TI;
- }
- qemu_irq_raise(env->irq[(env->CP0_IntCtl >> CP0IntCtl_IPTI) & 0x7]);
-}
-
-uint32_t cpu_mips_get_count(CPUMIPSState *env)
-{
- if (env->CP0_Cause & (1 << CP0Ca_DC)) {
- return env->CP0_Count;
- } else {
- uint64_t now_ns;
-
- now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- if (timer_pending(env->timer)
- && timer_expired(env->timer, now_ns)) {
- /* The timer has already expired. */
- cpu_mips_timer_expire(env);
- }
-
- return cpu_mips_get_count_val(env);
- }
-}
-
-void cpu_mips_store_count(CPUMIPSState *env, uint32_t count)
-{
- /*
- * This gets called from cpu_state_reset(), potentially before timer init.
- * So env->timer may be NULL, which is also the case with KVM enabled so
- * treat timer as disabled in that case.
- */
- if (env->CP0_Cause & (1 << CP0Ca_DC) || !env->timer) {
- env->CP0_Count = count;
- } else {
- /* Store new count register */
- env->CP0_Count = count - (uint32_t)clock_ns_to_ticks(env->count_clock,
- qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
- /* Update timer timer */
- cpu_mips_timer_update(env);
- }
-}
-
-void cpu_mips_store_compare(CPUMIPSState *env, uint32_t value)
-{
- env->CP0_Compare = value;
- if (!(env->CP0_Cause & (1 << CP0Ca_DC))) {
- cpu_mips_timer_update(env);
- }
- if (env->insn_flags & ISA_MIPS_R2) {
- env->CP0_Cause &= ~(1 << CP0Ca_TI);
- }
- qemu_irq_lower(env->irq[(env->CP0_IntCtl >> CP0IntCtl_IPTI) & 0x7]);
-}
-
-void cpu_mips_start_count(CPUMIPSState *env)
-{
- cpu_mips_store_count(env, env->CP0_Count);
-}
-
-void cpu_mips_stop_count(CPUMIPSState *env)
-{
- /* Store the current value */
- env->CP0_Count += (uint32_t)clock_ns_to_ticks(env->count_clock,
- qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
-}
-
-static void mips_timer_cb(void *opaque)
-{
- CPUMIPSState *env;
-
- env = opaque;
-
- if (env->CP0_Cause & (1 << CP0Ca_DC)) {
- return;
- }
-
- cpu_mips_timer_expire(env);
-}
-
-void cpu_mips_clock_init(MIPSCPU *cpu)
-{
- CPUMIPSState *env = &cpu->env;
-
- /*
- * If we're in KVM mode, don't create the periodic timer, that is handled in
- * kernel.
- */
- if (!kvm_enabled()) {
- env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &mips_timer_cb, env);
- }
-}
+++ /dev/null
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "internal.h"
-#include "migration/cpu.h"
-#include "fpu_helper.h"
-
-static int cpu_post_load(void *opaque, int version_id)
-{
- MIPSCPU *cpu = opaque;
- CPUMIPSState *env = &cpu->env;
-
- restore_fp_status(env);
- restore_msa_fp_status(env);
- compute_hflags(env);
- restore_pamask(env);
-
- return 0;
-}
-
-/* FPU state */
-
-static int get_fpr(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field)
-{
- int i;
- fpr_t *v = pv;
- /* Restore entire MSA vector register */
- for (i = 0; i < MSA_WRLEN / 64; i++) {
- qemu_get_sbe64s(f, &v->wr.d[i]);
- }
- return 0;
-}
-
-static int put_fpr(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, JSONWriter *vmdesc)
-{
- int i;
- fpr_t *v = pv;
- /* Save entire MSA vector register */
- for (i = 0; i < MSA_WRLEN / 64; i++) {
- qemu_put_sbe64s(f, &v->wr.d[i]);
- }
-
- return 0;
-}
-
-static const VMStateInfo vmstate_info_fpr = {
- .name = "fpr",
- .get = get_fpr,
- .put = put_fpr,
-};
-
-#define VMSTATE_FPR_ARRAY_V(_f, _s, _n, _v) \
- VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_fpr, fpr_t)
-
-#define VMSTATE_FPR_ARRAY(_f, _s, _n) \
- VMSTATE_FPR_ARRAY_V(_f, _s, _n, 0)
-
-static const VMStateField vmstate_fpu_fields[] = {
- VMSTATE_FPR_ARRAY(fpr, CPUMIPSFPUContext, 32),
- VMSTATE_UINT32(fcr0, CPUMIPSFPUContext),
- VMSTATE_UINT32(fcr31, CPUMIPSFPUContext),
- VMSTATE_END_OF_LIST()
-};
-
-static const VMStateDescription vmstate_fpu = {
- .name = "cpu/fpu",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = vmstate_fpu_fields
-};
-
-static const VMStateDescription vmstate_inactive_fpu = {
- .name = "cpu/inactive_fpu",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = vmstate_fpu_fields
-};
-
-/* TC state */
-
-static const VMStateField vmstate_tc_fields[] = {
- VMSTATE_UINTTL_ARRAY(gpr, TCState, 32),
-#if defined(TARGET_MIPS64)
- VMSTATE_UINT64_ARRAY(gpr_hi, TCState, 32),
-#endif /* TARGET_MIPS64 */
- VMSTATE_UINTTL(PC, TCState),
- VMSTATE_UINTTL_ARRAY(HI, TCState, MIPS_DSP_ACC),
- VMSTATE_UINTTL_ARRAY(LO, TCState, MIPS_DSP_ACC),
- VMSTATE_UINTTL_ARRAY(ACX, TCState, MIPS_DSP_ACC),
- VMSTATE_UINTTL(DSPControl, TCState),
- VMSTATE_INT32(CP0_TCStatus, TCState),
- VMSTATE_INT32(CP0_TCBind, TCState),
- VMSTATE_UINTTL(CP0_TCHalt, TCState),
- VMSTATE_UINTTL(CP0_TCContext, TCState),
- VMSTATE_UINTTL(CP0_TCSchedule, TCState),
- VMSTATE_UINTTL(CP0_TCScheFBack, TCState),
- VMSTATE_INT32(CP0_Debug_tcstatus, TCState),
- VMSTATE_UINTTL(CP0_UserLocal, TCState),
- VMSTATE_INT32(msacsr, TCState),
- VMSTATE_UINTTL_ARRAY(mxu_gpr, TCState, NUMBER_OF_MXU_REGISTERS - 1),
- VMSTATE_UINTTL(mxu_cr, TCState),
- VMSTATE_END_OF_LIST()
-};
-
-static const VMStateDescription vmstate_tc = {
- .name = "cpu/tc",
- .version_id = 2,
- .minimum_version_id = 2,
- .fields = vmstate_tc_fields
-};
-
-static const VMStateDescription vmstate_inactive_tc = {
- .name = "cpu/inactive_tc",
- .version_id = 2,
- .minimum_version_id = 2,
- .fields = vmstate_tc_fields
-};
-
-/* MVP state */
-
-static const VMStateDescription vmstate_mvp = {
- .name = "cpu/mvp",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (const VMStateField[]) {
- VMSTATE_INT32(CP0_MVPControl, CPUMIPSMVPContext),
- VMSTATE_INT32(CP0_MVPConf0, CPUMIPSMVPContext),
- VMSTATE_INT32(CP0_MVPConf1, CPUMIPSMVPContext),
- VMSTATE_END_OF_LIST()
- }
-};
-
-/* TLB state */
-
-static int get_tlb(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field)
-{
- r4k_tlb_t *v = pv;
- uint16_t flags;
-
- qemu_get_betls(f, &v->VPN);
- qemu_get_be32s(f, &v->PageMask);
- qemu_get_be16s(f, &v->ASID);
- qemu_get_be32s(f, &v->MMID);
- qemu_get_be16s(f, &flags);
- v->G = (flags >> 10) & 1;
- v->C0 = (flags >> 7) & 3;
- v->C1 = (flags >> 4) & 3;
- v->V0 = (flags >> 3) & 1;
- v->V1 = (flags >> 2) & 1;
- v->D0 = (flags >> 1) & 1;
- v->D1 = (flags >> 0) & 1;
- v->EHINV = (flags >> 15) & 1;
- v->RI1 = (flags >> 14) & 1;
- v->RI0 = (flags >> 13) & 1;
- v->XI1 = (flags >> 12) & 1;
- v->XI0 = (flags >> 11) & 1;
- qemu_get_be64s(f, &v->PFN[0]);
- qemu_get_be64s(f, &v->PFN[1]);
-
- return 0;
-}
-
-static int put_tlb(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, JSONWriter *vmdesc)
-{
- r4k_tlb_t *v = pv;
-
- uint16_t asid = v->ASID;
- uint32_t mmid = v->MMID;
- uint16_t flags = ((v->EHINV << 15) |
- (v->RI1 << 14) |
- (v->RI0 << 13) |
- (v->XI1 << 12) |
- (v->XI0 << 11) |
- (v->G << 10) |
- (v->C0 << 7) |
- (v->C1 << 4) |
- (v->V0 << 3) |
- (v->V1 << 2) |
- (v->D0 << 1) |
- (v->D1 << 0));
-
- qemu_put_betls(f, &v->VPN);
- qemu_put_be32s(f, &v->PageMask);
- qemu_put_be16s(f, &asid);
- qemu_put_be32s(f, &mmid);
- qemu_put_be16s(f, &flags);
- qemu_put_be64s(f, &v->PFN[0]);
- qemu_put_be64s(f, &v->PFN[1]);
-
- return 0;
-}
-
-static const VMStateInfo vmstate_info_tlb = {
- .name = "tlb_entry",
- .get = get_tlb,
- .put = put_tlb,
-};
-
-#define VMSTATE_TLB_ARRAY_V(_f, _s, _n, _v) \
- VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_tlb, r4k_tlb_t)
-
-#define VMSTATE_TLB_ARRAY(_f, _s, _n) \
- VMSTATE_TLB_ARRAY_V(_f, _s, _n, 0)
-
-static const VMStateDescription vmstate_tlb = {
- .name = "cpu/tlb",
- .version_id = 3,
- .minimum_version_id = 3,
- .fields = (const VMStateField[]) {
- VMSTATE_UINT32(nb_tlb, CPUMIPSTLBContext),
- VMSTATE_UINT32(tlb_in_use, CPUMIPSTLBContext),
- VMSTATE_TLB_ARRAY(mmu.r4k.tlb, CPUMIPSTLBContext, MIPS_TLB_MAX),
- VMSTATE_END_OF_LIST()
- }
-};
-
-/* MIPS CPU state */
-
-const VMStateDescription vmstate_mips_cpu = {
- .name = "cpu",
- .version_id = 21,
- .minimum_version_id = 21,
- .post_load = cpu_post_load,
- .fields = (const VMStateField[]) {
- /* Active TC */
- VMSTATE_STRUCT(env.active_tc, MIPSCPU, 1, vmstate_tc, TCState),
-
- /* Active FPU */
- VMSTATE_STRUCT(env.active_fpu, MIPSCPU, 1, vmstate_fpu,
- CPUMIPSFPUContext),
-
- /* MVP */
- VMSTATE_STRUCT_POINTER(env.mvp, MIPSCPU, vmstate_mvp,
- CPUMIPSMVPContext),
-
- /* TLB */
- VMSTATE_STRUCT_POINTER(env.tlb, MIPSCPU, vmstate_tlb,
- CPUMIPSTLBContext),
-
- /* CPU metastate */
- VMSTATE_UINT32(env.current_tc, MIPSCPU),
- VMSTATE_UNUSED(sizeof(uint32_t)), /* was current_fpu */
- VMSTATE_INT32(env.error_code, MIPSCPU),
- VMSTATE_UINTTL(env.btarget, MIPSCPU),
- VMSTATE_UINTTL(env.bcond, MIPSCPU),
-
- /* Remaining CP0 registers */
- VMSTATE_INT32(env.CP0_Index, MIPSCPU),
- VMSTATE_INT32(env.CP0_VPControl, MIPSCPU),
- VMSTATE_INT32(env.CP0_Random, MIPSCPU),
- VMSTATE_INT32(env.CP0_VPEControl, MIPSCPU),
- VMSTATE_INT32(env.CP0_VPEConf0, MIPSCPU),
- VMSTATE_INT32(env.CP0_VPEConf1, MIPSCPU),
- VMSTATE_UINTTL(env.CP0_YQMask, MIPSCPU),
- VMSTATE_UINTTL(env.CP0_VPESchedule, MIPSCPU),
- VMSTATE_UINTTL(env.CP0_VPEScheFBack, MIPSCPU),
- VMSTATE_INT32(env.CP0_VPEOpt, MIPSCPU),
- VMSTATE_UINT64(env.CP0_EntryLo0, MIPSCPU),
- VMSTATE_UINT64(env.CP0_EntryLo1, MIPSCPU),
- VMSTATE_INT32(env.CP0_GlobalNumber, MIPSCPU),
- VMSTATE_UINTTL(env.CP0_Context, MIPSCPU),
- VMSTATE_INT32(env.CP0_MemoryMapID, MIPSCPU),
- VMSTATE_INT32(env.CP0_PageMask, MIPSCPU),
- VMSTATE_INT32(env.CP0_PageGrain, MIPSCPU),
- VMSTATE_UINTTL(env.CP0_SegCtl0, MIPSCPU),
- VMSTATE_UINTTL(env.CP0_SegCtl1, MIPSCPU),
- VMSTATE_UINTTL(env.CP0_SegCtl2, MIPSCPU),
- VMSTATE_UINTTL(env.CP0_PWBase, MIPSCPU),
- VMSTATE_UINTTL(env.CP0_PWField, MIPSCPU),
- VMSTATE_UINTTL(env.CP0_PWSize, MIPSCPU),
- VMSTATE_INT32(env.CP0_Wired, MIPSCPU),
- VMSTATE_INT32(env.CP0_PWCtl, MIPSCPU),
- VMSTATE_INT32(env.CP0_SRSConf0, MIPSCPU),
- VMSTATE_INT32(env.CP0_SRSConf1, MIPSCPU),
- VMSTATE_INT32(env.CP0_SRSConf2, MIPSCPU),
- VMSTATE_INT32(env.CP0_SRSConf3, MIPSCPU),
- VMSTATE_INT32(env.CP0_SRSConf4, MIPSCPU),
- VMSTATE_INT32(env.CP0_HWREna, MIPSCPU),
- VMSTATE_UINTTL(env.CP0_BadVAddr, MIPSCPU),
- VMSTATE_UINT32(env.CP0_BadInstr, MIPSCPU),
- VMSTATE_UINT32(env.CP0_BadInstrP, MIPSCPU),
- VMSTATE_UINT32(env.CP0_BadInstrX, MIPSCPU),
- VMSTATE_INT32(env.CP0_Count, MIPSCPU),
- VMSTATE_UNUSED(sizeof(uint32_t)), /* was CP0_SAARI */
- VMSTATE_UNUSED(2 * sizeof(uint64_t)), /* was CP0_SAAR[2] */
- VMSTATE_UINTTL(env.CP0_EntryHi, MIPSCPU),
- VMSTATE_INT32(env.CP0_Compare, MIPSCPU),
- VMSTATE_INT32(env.CP0_Status, MIPSCPU),
- VMSTATE_INT32(env.CP0_IntCtl, MIPSCPU),
- VMSTATE_INT32(env.CP0_SRSCtl, MIPSCPU),
- VMSTATE_INT32(env.CP0_SRSMap, MIPSCPU),
- VMSTATE_INT32(env.CP0_Cause, MIPSCPU),
- VMSTATE_UINTTL(env.CP0_EPC, MIPSCPU),
- VMSTATE_INT32(env.CP0_PRid, MIPSCPU),
- VMSTATE_UINTTL(env.CP0_EBase, MIPSCPU),
- VMSTATE_UINTTL(env.CP0_CMGCRBase, MIPSCPU),
- VMSTATE_INT32(env.CP0_Config0, MIPSCPU),
- VMSTATE_INT32(env.CP0_Config1, MIPSCPU),
- VMSTATE_INT32(env.CP0_Config2, MIPSCPU),
- VMSTATE_INT32(env.CP0_Config3, MIPSCPU),
- VMSTATE_INT32(env.CP0_Config4, MIPSCPU),
- VMSTATE_INT32(env.CP0_Config5, MIPSCPU),
- VMSTATE_INT32(env.CP0_Config6, MIPSCPU),
- VMSTATE_INT32(env.CP0_Config7, MIPSCPU),
- VMSTATE_UINT64(env.CP0_LLAddr, MIPSCPU),
- VMSTATE_UINT64_ARRAY(env.CP0_MAAR, MIPSCPU, MIPS_MAAR_MAX),
- VMSTATE_INT32(env.CP0_MAARI, MIPSCPU),
- VMSTATE_UINTTL(env.lladdr, MIPSCPU),
- VMSTATE_UINTTL_ARRAY(env.CP0_WatchLo, MIPSCPU, 8),
- VMSTATE_UINT64_ARRAY(env.CP0_WatchHi, MIPSCPU, 8),
- VMSTATE_UINTTL(env.CP0_XContext, MIPSCPU),
- VMSTATE_INT32(env.CP0_Framemask, MIPSCPU),
- VMSTATE_INT32(env.CP0_Debug, MIPSCPU),
- VMSTATE_UINTTL(env.CP0_DEPC, MIPSCPU),
- VMSTATE_INT32(env.CP0_Performance0, MIPSCPU),
- VMSTATE_INT32(env.CP0_ErrCtl, MIPSCPU),
- VMSTATE_UINT64(env.CP0_TagLo, MIPSCPU),
- VMSTATE_INT32(env.CP0_DataLo, MIPSCPU),
- VMSTATE_INT32(env.CP0_TagHi, MIPSCPU),
- VMSTATE_INT32(env.CP0_DataHi, MIPSCPU),
- VMSTATE_UINTTL(env.CP0_ErrorEPC, MIPSCPU),
- VMSTATE_INT32(env.CP0_DESAVE, MIPSCPU),
- VMSTATE_UINTTL_ARRAY(env.CP0_KScratch, MIPSCPU, MIPS_KSCRATCH_NUM),
-
- /* Inactive TC */
- VMSTATE_STRUCT_ARRAY(env.tcs, MIPSCPU, MIPS_SHADOW_SET_MAX, 1,
- vmstate_inactive_tc, TCState),
- VMSTATE_STRUCT_ARRAY(env.fpus, MIPSCPU, MIPS_FPU_MAX, 1,
- vmstate_inactive_fpu, CPUMIPSFPUContext),
-
- VMSTATE_END_OF_LIST()
- },
-};
+++ /dev/null
-mips_system_ss.add(files(
- 'addr.c',
- 'cp0.c',
- 'cp0_timer.c',
- 'machine.c',
- 'mips-qmp-cmds.c',
- 'physaddr.c',
-))
+++ /dev/null
-/*
- * QEMU MIPS CPU (monitor definitions)
- *
- * SPDX-FileCopyrightText: 2012 SUSE LINUX Products GmbH
- *
- * SPDX-License-Identifier: LGPL-2.1-or-later
- */
-
-#include "qemu/osdep.h"
-#include "qapi/qapi-commands-machine-target.h"
-#include "cpu.h"
-
-static void mips_cpu_add_definition(gpointer data, gpointer user_data)
-{
- ObjectClass *oc = data;
- CpuDefinitionInfoList **cpu_list = user_data;
- CpuDefinitionInfo *info;
- const char *typename;
-
- typename = object_class_get_name(oc);
- info = g_malloc0(sizeof(*info));
- info->name = cpu_model_from_type(typename);
- info->q_typename = g_strdup(typename);
-
- QAPI_LIST_PREPEND(*cpu_list, info);
-}
-
-CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
-{
- CpuDefinitionInfoList *cpu_list = NULL;
- GSList *list;
-
- list = object_class_get_list(TYPE_MIPS_CPU, false);
- g_slist_foreach(list, mips_cpu_add_definition, &cpu_list);
- g_slist_free(list);
-
- return cpu_list;
-}
+++ /dev/null
-/*
- * MIPS TLB (Translation lookaside buffer) helpers.
- *
- * Copyright (c) 2004-2005 Jocelyn Mayer
- *
- * 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.1 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/exec-all.h"
-#include "exec/page-protection.h"
-#include "../internal.h"
-
-static int is_seg_am_mapped(unsigned int am, bool eu, int mmu_idx)
-{
- /*
- * Interpret access control mode and mmu_idx.
- * AdE? TLB?
- * AM K S U E K S U E
- * UK 0 0 1 1 0 0 - - 0
- * MK 1 0 1 1 0 1 - - !eu
- * MSK 2 0 0 1 0 1 1 - !eu
- * MUSK 3 0 0 0 0 1 1 1 !eu
- * MUSUK 4 0 0 0 0 0 1 1 0
- * USK 5 0 0 1 0 0 0 - 0
- * - 6 - - - - - - - -
- * UUSK 7 0 0 0 0 0 0 0 0
- */
- int32_t adetlb_mask;
-
- switch (mmu_idx) {
- case 3: /* ERL */
- /* If EU is set, always unmapped */
- if (eu) {
- return 0;
- }
- /* fall through */
- case MIPS_HFLAG_KM:
- /* Never AdE, TLB mapped if AM={1,2,3} */
- adetlb_mask = 0x70000000;
- goto check_tlb;
-
- case MIPS_HFLAG_SM:
- /* AdE if AM={0,1}, TLB mapped if AM={2,3,4} */
- adetlb_mask = 0xc0380000;
- goto check_ade;
-
- case MIPS_HFLAG_UM:
- /* AdE if AM={0,1,2,5}, TLB mapped if AM={3,4} */
- adetlb_mask = 0xe4180000;
- /* fall through */
- check_ade:
- /* does this AM cause AdE in current execution mode */
- if ((adetlb_mask << am) < 0) {
- return TLBRET_BADADDR;
- }
- adetlb_mask <<= 8;
- /* fall through */
- check_tlb:
- /* is this AM mapped in current execution mode */
- return ((adetlb_mask << am) < 0);
- default:
- g_assert_not_reached();
- };
-}
-
-static int get_seg_physical_address(CPUMIPSState *env, hwaddr *physical,
- int *prot, target_ulong real_address,
- MMUAccessType access_type, int mmu_idx,
- unsigned int am, bool eu,
- target_ulong segmask,
- hwaddr physical_base)
-{
- int mapped = is_seg_am_mapped(am, eu, mmu_idx);
-
- if (mapped < 0) {
- /* is_seg_am_mapped can report TLBRET_BADADDR */
- return mapped;
- } else if (mapped) {
- /* The segment is TLB mapped */
- return env->tlb->map_address(env, physical, prot, real_address,
- access_type);
- } else {
- /* The segment is unmapped */
- *physical = physical_base | (real_address & segmask);
- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- return TLBRET_MATCH;
- }
-}
-
-static int get_segctl_physical_address(CPUMIPSState *env, hwaddr *physical,
- int *prot, target_ulong real_address,
- MMUAccessType access_type, int mmu_idx,
- uint16_t segctl, target_ulong segmask)
-{
- unsigned int am = (segctl & CP0SC_AM_MASK) >> CP0SC_AM;
- bool eu = (segctl >> CP0SC_EU) & 1;
- hwaddr pa = ((hwaddr)segctl & CP0SC_PA_MASK) << 20;
-
- return get_seg_physical_address(env, physical, prot, real_address,
- access_type, mmu_idx, am, eu, segmask,
- pa & ~(hwaddr)segmask);
-}
-
-int get_physical_address(CPUMIPSState *env, hwaddr *physical,
- int *prot, target_ulong real_address,
- MMUAccessType access_type, int mmu_idx)
-{
- /* User mode can only access useg/xuseg */
-#if defined(TARGET_MIPS64)
- int user_mode = mmu_idx == MIPS_HFLAG_UM;
- int supervisor_mode = mmu_idx == MIPS_HFLAG_SM;
- int kernel_mode = !user_mode && !supervisor_mode;
- int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
- int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;
- int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
-#endif
- int ret = TLBRET_MATCH;
- /* effective address (modified for KVM T&E kernel segments) */
- target_ulong address = real_address;
-
- if (address <= USEG_LIMIT) {
- /* useg */
- uint16_t segctl;
-
- if (address >= 0x40000000UL) {
- segctl = env->CP0_SegCtl2;
- } else {
- segctl = env->CP0_SegCtl2 >> 16;
- }
- ret = get_segctl_physical_address(env, physical, prot,
- real_address, access_type,
- mmu_idx, segctl, 0x3FFFFFFF);
-#if defined(TARGET_MIPS64)
- } else if (address < 0x4000000000000000ULL) {
- /* xuseg */
- if (UX && address <= (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) {
- ret = env->tlb->map_address(env, physical, prot,
- real_address, access_type);
- } else {
- ret = TLBRET_BADADDR;
- }
- } else if (address < 0x8000000000000000ULL) {
- /* xsseg */
- if ((supervisor_mode || kernel_mode) &&
- SX && address <= (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) {
- ret = env->tlb->map_address(env, physical, prot,
- real_address, access_type);
- } else {
- ret = TLBRET_BADADDR;
- }
- } else if (address < 0xC000000000000000ULL) {
- /* xkphys */
- if ((address & 0x07FFFFFFFFFFFFFFULL) <= env->PAMask) {
- /* KX/SX/UX bit to check for each xkphys EVA access mode */
- static const uint8_t am_ksux[8] = {
- [CP0SC_AM_UK] = (1u << CP0St_KX),
- [CP0SC_AM_MK] = (1u << CP0St_KX),
- [CP0SC_AM_MSK] = (1u << CP0St_SX),
- [CP0SC_AM_MUSK] = (1u << CP0St_UX),
- [CP0SC_AM_MUSUK] = (1u << CP0St_UX),
- [CP0SC_AM_USK] = (1u << CP0St_SX),
- [6] = (1u << CP0St_KX),
- [CP0SC_AM_UUSK] = (1u << CP0St_UX),
- };
- unsigned int am = CP0SC_AM_UK;
- unsigned int xr = (env->CP0_SegCtl2 & CP0SC2_XR_MASK) >> CP0SC2_XR;
-
- if (xr & (1 << ((address >> 59) & 0x7))) {
- am = (env->CP0_SegCtl1 & CP0SC1_XAM_MASK) >> CP0SC1_XAM;
- }
- /* Does CP0_Status.KX/SX/UX permit the access mode (am) */
- if (env->CP0_Status & am_ksux[am]) {
- ret = get_seg_physical_address(env, physical, prot,
- real_address, access_type,
- mmu_idx, am, false, env->PAMask,
- 0);
- } else {
- ret = TLBRET_BADADDR;
- }
- } else {
- ret = TLBRET_BADADDR;
- }
- } else if (address < 0xFFFFFFFF80000000ULL) {
- /* xkseg */
- if (kernel_mode && KX &&
- address <= (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) {
- ret = env->tlb->map_address(env, physical, prot,
- real_address, access_type);
- } else {
- ret = TLBRET_BADADDR;
- }
-#endif
- } else if (address < KSEG1_BASE) {
- /* kseg0 */
- ret = get_segctl_physical_address(env, physical, prot, real_address,
- access_type, mmu_idx,
- env->CP0_SegCtl1 >> 16, 0x1FFFFFFF);
- } else if (address < KSEG2_BASE) {
- /* kseg1 */
- ret = get_segctl_physical_address(env, physical, prot, real_address,
- access_type, mmu_idx,
- env->CP0_SegCtl1, 0x1FFFFFFF);
- } else if (address < KSEG3_BASE) {
- /* sseg (kseg2) */
- ret = get_segctl_physical_address(env, physical, prot, real_address,
- access_type, mmu_idx,
- env->CP0_SegCtl0 >> 16, 0x1FFFFFFF);
- } else {
- /*
- * kseg3
- * XXX: debug segment is not emulated
- */
- ret = get_segctl_physical_address(env, physical, prot, real_address,
- access_type, mmu_idx,
- env->CP0_SegCtl0, 0x1FFFFFFF);
- }
- return ret;
-}
-
-hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
-{
- CPUMIPSState *env = cpu_env(cs);
- hwaddr phys_addr;
- int prot;
-
- if (get_physical_address(env, &phys_addr, &prot, addr, MMU_DATA_LOAD,
- mips_env_mmu_index(env)) != 0) {
- return -1;
- }
- return phys_addr;
-}
--- /dev/null
+/*
+ * QEMU MIPS address translation support
+ *
+ * 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 "cpu.h"
+
+uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr)
+{
+ return addr & 0x1fffffffll;
+}
+
+uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr)
+{
+ return addr | ~0x7fffffffll;
+}
+
+uint64_t cpu_mips_kseg1_to_phys(void *opaque, uint64_t addr)
+{
+ return addr & 0x1fffffffll;
+}
+
+uint64_t cpu_mips_phys_to_kseg1(void *opaque, uint64_t addr)
+{
+ return (addr & 0x1fffffffll) | 0xffffffffa0000000ll;
+}
--- /dev/null
+/*
+ * QEMU MIPS CPU
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * 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.1 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/lgpl-2.1.html>
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "internal.h"
+#include "exec/exec-all.h"
+
+/* Called for updates to CP0_Status. */
+void sync_c0_status(CPUMIPSState *env, CPUMIPSState *cpu, int tc)
+{
+ int32_t tcstatus, *tcst;
+ uint32_t v = cpu->CP0_Status;
+ uint32_t cu, mx, asid, ksu;
+ uint32_t mask = ((1 << CP0TCSt_TCU3)
+ | (1 << CP0TCSt_TCU2)
+ | (1 << CP0TCSt_TCU1)
+ | (1 << CP0TCSt_TCU0)
+ | (1 << CP0TCSt_TMX)
+ | (3 << CP0TCSt_TKSU)
+ | (0xff << CP0TCSt_TASID));
+
+ cu = (v >> CP0St_CU0) & 0xf;
+ mx = (v >> CP0St_MX) & 0x1;
+ ksu = (v >> CP0St_KSU) & 0x3;
+ asid = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
+
+ tcstatus = cu << CP0TCSt_TCU0;
+ tcstatus |= mx << CP0TCSt_TMX;
+ tcstatus |= ksu << CP0TCSt_TKSU;
+ tcstatus |= asid;
+
+ if (tc == cpu->current_tc) {
+ tcst = &cpu->active_tc.CP0_TCStatus;
+ } else {
+ tcst = &cpu->tcs[tc].CP0_TCStatus;
+ }
+
+ *tcst &= ~mask;
+ *tcst |= tcstatus;
+ compute_hflags(cpu);
+}
+
+void cpu_mips_store_status(CPUMIPSState *env, target_ulong val)
+{
+ uint32_t mask = env->CP0_Status_rw_bitmask;
+ target_ulong old = env->CP0_Status;
+
+ if (env->insn_flags & ISA_MIPS_R6) {
+ bool has_supervisor = extract32(mask, CP0St_KSU, 2) == 0x3;
+#if defined(TARGET_MIPS64)
+ uint32_t ksux = (1 << CP0St_KX) & val;
+ ksux |= (ksux >> 1) & val; /* KX = 0 forces SX to be 0 */
+ ksux |= (ksux >> 1) & val; /* SX = 0 forces UX to be 0 */
+ val = (val & ~(7 << CP0St_UX)) | ksux;
+#endif
+ if (has_supervisor && extract32(val, CP0St_KSU, 2) == 0x3) {
+ mask &= ~(3 << CP0St_KSU);
+ }
+ mask &= ~(((1 << CP0St_SR) | (1 << CP0St_NMI)) & val);
+ }
+
+ env->CP0_Status = (old & ~mask) | (val & mask);
+#if defined(TARGET_MIPS64)
+ if ((env->CP0_Status ^ old) & (old & (7 << CP0St_UX))) {
+ /* Access to at least one of the 64-bit segments has been disabled */
+ tlb_flush(env_cpu(env));
+ }
+#endif
+ if (ase_mt_available(env)) {
+ sync_c0_status(env, env, env->current_tc);
+ } else {
+ compute_hflags(env);
+ }
+}
+
+void cpu_mips_store_cause(CPUMIPSState *env, target_ulong val)
+{
+ uint32_t mask = 0x00C00300;
+ uint32_t old = env->CP0_Cause;
+ int i;
+
+ if (env->insn_flags & ISA_MIPS_R2) {
+ mask |= 1 << CP0Ca_DC;
+ }
+ if (env->insn_flags & ISA_MIPS_R6) {
+ mask &= ~((1 << CP0Ca_WP) & val);
+ }
+
+ env->CP0_Cause = (env->CP0_Cause & ~mask) | (val & mask);
+
+ if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
+ if (env->CP0_Cause & (1 << CP0Ca_DC)) {
+ cpu_mips_stop_count(env);
+ } else {
+ cpu_mips_start_count(env);
+ }
+ }
+
+ /* Set/reset software interrupts */
+ for (i = 0 ; i < 2 ; i++) {
+ if ((old ^ env->CP0_Cause) & (1 << (CP0Ca_IP + i))) {
+ cpu_mips_soft_irq(env, i, env->CP0_Cause & (1 << (CP0Ca_IP + i)));
+ }
+ }
+}
--- /dev/null
+/*
+ * QEMU MIPS timer support
+ *
+ * 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 "hw/irq.h"
+#include "qemu/timer.h"
+#include "system/kvm.h"
+#include "internal.h"
+
+/* MIPS R4K timer */
+static uint32_t cpu_mips_get_count_val(CPUMIPSState *env)
+{
+ int64_t now_ns;
+ now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ return env->CP0_Count +
+ (uint32_t)clock_ns_to_ticks(env->count_clock, now_ns);
+}
+
+static void cpu_mips_timer_update(CPUMIPSState *env)
+{
+ uint64_t now_ns, next_ns;
+ uint32_t wait;
+
+ now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ wait = env->CP0_Compare - cpu_mips_get_count_val(env);
+ /* Clamp interval to overflow if virtual time had not progressed */
+ if (!wait) {
+ wait = UINT32_MAX;
+ }
+ next_ns = now_ns + clock_ticks_to_ns(env->count_clock, wait);
+ timer_mod(env->timer, next_ns);
+}
+
+/* Expire the timer. */
+static void cpu_mips_timer_expire(CPUMIPSState *env)
+{
+ cpu_mips_timer_update(env);
+ if (env->insn_flags & ISA_MIPS_R2) {
+ env->CP0_Cause |= 1 << CP0Ca_TI;
+ }
+ qemu_irq_raise(env->irq[(env->CP0_IntCtl >> CP0IntCtl_IPTI) & 0x7]);
+}
+
+uint32_t cpu_mips_get_count(CPUMIPSState *env)
+{
+ if (env->CP0_Cause & (1 << CP0Ca_DC)) {
+ return env->CP0_Count;
+ } else {
+ uint64_t now_ns;
+
+ now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ if (timer_pending(env->timer)
+ && timer_expired(env->timer, now_ns)) {
+ /* The timer has already expired. */
+ cpu_mips_timer_expire(env);
+ }
+
+ return cpu_mips_get_count_val(env);
+ }
+}
+
+void cpu_mips_store_count(CPUMIPSState *env, uint32_t count)
+{
+ /*
+ * This gets called from cpu_state_reset(), potentially before timer init.
+ * So env->timer may be NULL, which is also the case with KVM enabled so
+ * treat timer as disabled in that case.
+ */
+ if (env->CP0_Cause & (1 << CP0Ca_DC) || !env->timer) {
+ env->CP0_Count = count;
+ } else {
+ /* Store new count register */
+ env->CP0_Count = count - (uint32_t)clock_ns_to_ticks(env->count_clock,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
+ /* Update timer timer */
+ cpu_mips_timer_update(env);
+ }
+}
+
+void cpu_mips_store_compare(CPUMIPSState *env, uint32_t value)
+{
+ env->CP0_Compare = value;
+ if (!(env->CP0_Cause & (1 << CP0Ca_DC))) {
+ cpu_mips_timer_update(env);
+ }
+ if (env->insn_flags & ISA_MIPS_R2) {
+ env->CP0_Cause &= ~(1 << CP0Ca_TI);
+ }
+ qemu_irq_lower(env->irq[(env->CP0_IntCtl >> CP0IntCtl_IPTI) & 0x7]);
+}
+
+void cpu_mips_start_count(CPUMIPSState *env)
+{
+ cpu_mips_store_count(env, env->CP0_Count);
+}
+
+void cpu_mips_stop_count(CPUMIPSState *env)
+{
+ /* Store the current value */
+ env->CP0_Count += (uint32_t)clock_ns_to_ticks(env->count_clock,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
+}
+
+static void mips_timer_cb(void *opaque)
+{
+ CPUMIPSState *env;
+
+ env = opaque;
+
+ if (env->CP0_Cause & (1 << CP0Ca_DC)) {
+ return;
+ }
+
+ cpu_mips_timer_expire(env);
+}
+
+void cpu_mips_clock_init(MIPSCPU *cpu)
+{
+ CPUMIPSState *env = &cpu->env;
+
+ /*
+ * If we're in KVM mode, don't create the periodic timer, that is handled in
+ * kernel.
+ */
+ if (!kvm_enabled()) {
+ env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &mips_timer_cb, env);
+ }
+}
--- /dev/null
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "internal.h"
+#include "migration/cpu.h"
+#include "fpu_helper.h"
+
+static int cpu_post_load(void *opaque, int version_id)
+{
+ MIPSCPU *cpu = opaque;
+ CPUMIPSState *env = &cpu->env;
+
+ restore_fp_status(env);
+ restore_msa_fp_status(env);
+ compute_hflags(env);
+ restore_pamask(env);
+
+ return 0;
+}
+
+/* FPU state */
+
+static int get_fpr(QEMUFile *f, void *pv, size_t size,
+ const VMStateField *field)
+{
+ int i;
+ fpr_t *v = pv;
+ /* Restore entire MSA vector register */
+ for (i = 0; i < MSA_WRLEN / 64; i++) {
+ qemu_get_sbe64s(f, &v->wr.d[i]);
+ }
+ return 0;
+}
+
+static int put_fpr(QEMUFile *f, void *pv, size_t size,
+ const VMStateField *field, JSONWriter *vmdesc)
+{
+ int i;
+ fpr_t *v = pv;
+ /* Save entire MSA vector register */
+ for (i = 0; i < MSA_WRLEN / 64; i++) {
+ qemu_put_sbe64s(f, &v->wr.d[i]);
+ }
+
+ return 0;
+}
+
+static const VMStateInfo vmstate_info_fpr = {
+ .name = "fpr",
+ .get = get_fpr,
+ .put = put_fpr,
+};
+
+#define VMSTATE_FPR_ARRAY_V(_f, _s, _n, _v) \
+ VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_fpr, fpr_t)
+
+#define VMSTATE_FPR_ARRAY(_f, _s, _n) \
+ VMSTATE_FPR_ARRAY_V(_f, _s, _n, 0)
+
+static const VMStateField vmstate_fpu_fields[] = {
+ VMSTATE_FPR_ARRAY(fpr, CPUMIPSFPUContext, 32),
+ VMSTATE_UINT32(fcr0, CPUMIPSFPUContext),
+ VMSTATE_UINT32(fcr31, CPUMIPSFPUContext),
+ VMSTATE_END_OF_LIST()
+};
+
+static const VMStateDescription vmstate_fpu = {
+ .name = "cpu/fpu",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = vmstate_fpu_fields
+};
+
+static const VMStateDescription vmstate_inactive_fpu = {
+ .name = "cpu/inactive_fpu",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = vmstate_fpu_fields
+};
+
+/* TC state */
+
+static const VMStateField vmstate_tc_fields[] = {
+ VMSTATE_UINTTL_ARRAY(gpr, TCState, 32),
+#if defined(TARGET_MIPS64)
+ VMSTATE_UINT64_ARRAY(gpr_hi, TCState, 32),
+#endif /* TARGET_MIPS64 */
+ VMSTATE_UINTTL(PC, TCState),
+ VMSTATE_UINTTL_ARRAY(HI, TCState, MIPS_DSP_ACC),
+ VMSTATE_UINTTL_ARRAY(LO, TCState, MIPS_DSP_ACC),
+ VMSTATE_UINTTL_ARRAY(ACX, TCState, MIPS_DSP_ACC),
+ VMSTATE_UINTTL(DSPControl, TCState),
+ VMSTATE_INT32(CP0_TCStatus, TCState),
+ VMSTATE_INT32(CP0_TCBind, TCState),
+ VMSTATE_UINTTL(CP0_TCHalt, TCState),
+ VMSTATE_UINTTL(CP0_TCContext, TCState),
+ VMSTATE_UINTTL(CP0_TCSchedule, TCState),
+ VMSTATE_UINTTL(CP0_TCScheFBack, TCState),
+ VMSTATE_INT32(CP0_Debug_tcstatus, TCState),
+ VMSTATE_UINTTL(CP0_UserLocal, TCState),
+ VMSTATE_INT32(msacsr, TCState),
+ VMSTATE_UINTTL_ARRAY(mxu_gpr, TCState, NUMBER_OF_MXU_REGISTERS - 1),
+ VMSTATE_UINTTL(mxu_cr, TCState),
+ VMSTATE_END_OF_LIST()
+};
+
+static const VMStateDescription vmstate_tc = {
+ .name = "cpu/tc",
+ .version_id = 2,
+ .minimum_version_id = 2,
+ .fields = vmstate_tc_fields
+};
+
+static const VMStateDescription vmstate_inactive_tc = {
+ .name = "cpu/inactive_tc",
+ .version_id = 2,
+ .minimum_version_id = 2,
+ .fields = vmstate_tc_fields
+};
+
+/* MVP state */
+
+static const VMStateDescription vmstate_mvp = {
+ .name = "cpu/mvp",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (const VMStateField[]) {
+ VMSTATE_INT32(CP0_MVPControl, CPUMIPSMVPContext),
+ VMSTATE_INT32(CP0_MVPConf0, CPUMIPSMVPContext),
+ VMSTATE_INT32(CP0_MVPConf1, CPUMIPSMVPContext),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+/* TLB state */
+
+static int get_tlb(QEMUFile *f, void *pv, size_t size,
+ const VMStateField *field)
+{
+ r4k_tlb_t *v = pv;
+ uint16_t flags;
+
+ qemu_get_betls(f, &v->VPN);
+ qemu_get_be32s(f, &v->PageMask);
+ qemu_get_be16s(f, &v->ASID);
+ qemu_get_be32s(f, &v->MMID);
+ qemu_get_be16s(f, &flags);
+ v->G = (flags >> 10) & 1;
+ v->C0 = (flags >> 7) & 3;
+ v->C1 = (flags >> 4) & 3;
+ v->V0 = (flags >> 3) & 1;
+ v->V1 = (flags >> 2) & 1;
+ v->D0 = (flags >> 1) & 1;
+ v->D1 = (flags >> 0) & 1;
+ v->EHINV = (flags >> 15) & 1;
+ v->RI1 = (flags >> 14) & 1;
+ v->RI0 = (flags >> 13) & 1;
+ v->XI1 = (flags >> 12) & 1;
+ v->XI0 = (flags >> 11) & 1;
+ qemu_get_be64s(f, &v->PFN[0]);
+ qemu_get_be64s(f, &v->PFN[1]);
+
+ return 0;
+}
+
+static int put_tlb(QEMUFile *f, void *pv, size_t size,
+ const VMStateField *field, JSONWriter *vmdesc)
+{
+ r4k_tlb_t *v = pv;
+
+ uint16_t asid = v->ASID;
+ uint32_t mmid = v->MMID;
+ uint16_t flags = ((v->EHINV << 15) |
+ (v->RI1 << 14) |
+ (v->RI0 << 13) |
+ (v->XI1 << 12) |
+ (v->XI0 << 11) |
+ (v->G << 10) |
+ (v->C0 << 7) |
+ (v->C1 << 4) |
+ (v->V0 << 3) |
+ (v->V1 << 2) |
+ (v->D0 << 1) |
+ (v->D1 << 0));
+
+ qemu_put_betls(f, &v->VPN);
+ qemu_put_be32s(f, &v->PageMask);
+ qemu_put_be16s(f, &asid);
+ qemu_put_be32s(f, &mmid);
+ qemu_put_be16s(f, &flags);
+ qemu_put_be64s(f, &v->PFN[0]);
+ qemu_put_be64s(f, &v->PFN[1]);
+
+ return 0;
+}
+
+static const VMStateInfo vmstate_info_tlb = {
+ .name = "tlb_entry",
+ .get = get_tlb,
+ .put = put_tlb,
+};
+
+#define VMSTATE_TLB_ARRAY_V(_f, _s, _n, _v) \
+ VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_tlb, r4k_tlb_t)
+
+#define VMSTATE_TLB_ARRAY(_f, _s, _n) \
+ VMSTATE_TLB_ARRAY_V(_f, _s, _n, 0)
+
+static const VMStateDescription vmstate_tlb = {
+ .name = "cpu/tlb",
+ .version_id = 3,
+ .minimum_version_id = 3,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT32(nb_tlb, CPUMIPSTLBContext),
+ VMSTATE_UINT32(tlb_in_use, CPUMIPSTLBContext),
+ VMSTATE_TLB_ARRAY(mmu.r4k.tlb, CPUMIPSTLBContext, MIPS_TLB_MAX),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+/* MIPS CPU state */
+
+const VMStateDescription vmstate_mips_cpu = {
+ .name = "cpu",
+ .version_id = 21,
+ .minimum_version_id = 21,
+ .post_load = cpu_post_load,
+ .fields = (const VMStateField[]) {
+ /* Active TC */
+ VMSTATE_STRUCT(env.active_tc, MIPSCPU, 1, vmstate_tc, TCState),
+
+ /* Active FPU */
+ VMSTATE_STRUCT(env.active_fpu, MIPSCPU, 1, vmstate_fpu,
+ CPUMIPSFPUContext),
+
+ /* MVP */
+ VMSTATE_STRUCT_POINTER(env.mvp, MIPSCPU, vmstate_mvp,
+ CPUMIPSMVPContext),
+
+ /* TLB */
+ VMSTATE_STRUCT_POINTER(env.tlb, MIPSCPU, vmstate_tlb,
+ CPUMIPSTLBContext),
+
+ /* CPU metastate */
+ VMSTATE_UINT32(env.current_tc, MIPSCPU),
+ VMSTATE_UNUSED(sizeof(uint32_t)), /* was current_fpu */
+ VMSTATE_INT32(env.error_code, MIPSCPU),
+ VMSTATE_UINTTL(env.btarget, MIPSCPU),
+ VMSTATE_UINTTL(env.bcond, MIPSCPU),
+
+ /* Remaining CP0 registers */
+ VMSTATE_INT32(env.CP0_Index, MIPSCPU),
+ VMSTATE_INT32(env.CP0_VPControl, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Random, MIPSCPU),
+ VMSTATE_INT32(env.CP0_VPEControl, MIPSCPU),
+ VMSTATE_INT32(env.CP0_VPEConf0, MIPSCPU),
+ VMSTATE_INT32(env.CP0_VPEConf1, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_YQMask, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_VPESchedule, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_VPEScheFBack, MIPSCPU),
+ VMSTATE_INT32(env.CP0_VPEOpt, MIPSCPU),
+ VMSTATE_UINT64(env.CP0_EntryLo0, MIPSCPU),
+ VMSTATE_UINT64(env.CP0_EntryLo1, MIPSCPU),
+ VMSTATE_INT32(env.CP0_GlobalNumber, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_Context, MIPSCPU),
+ VMSTATE_INT32(env.CP0_MemoryMapID, MIPSCPU),
+ VMSTATE_INT32(env.CP0_PageMask, MIPSCPU),
+ VMSTATE_INT32(env.CP0_PageGrain, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_SegCtl0, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_SegCtl1, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_SegCtl2, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_PWBase, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_PWField, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_PWSize, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Wired, MIPSCPU),
+ VMSTATE_INT32(env.CP0_PWCtl, MIPSCPU),
+ VMSTATE_INT32(env.CP0_SRSConf0, MIPSCPU),
+ VMSTATE_INT32(env.CP0_SRSConf1, MIPSCPU),
+ VMSTATE_INT32(env.CP0_SRSConf2, MIPSCPU),
+ VMSTATE_INT32(env.CP0_SRSConf3, MIPSCPU),
+ VMSTATE_INT32(env.CP0_SRSConf4, MIPSCPU),
+ VMSTATE_INT32(env.CP0_HWREna, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_BadVAddr, MIPSCPU),
+ VMSTATE_UINT32(env.CP0_BadInstr, MIPSCPU),
+ VMSTATE_UINT32(env.CP0_BadInstrP, MIPSCPU),
+ VMSTATE_UINT32(env.CP0_BadInstrX, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Count, MIPSCPU),
+ VMSTATE_UNUSED(sizeof(uint32_t)), /* was CP0_SAARI */
+ VMSTATE_UNUSED(2 * sizeof(uint64_t)), /* was CP0_SAAR[2] */
+ VMSTATE_UINTTL(env.CP0_EntryHi, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Compare, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Status, MIPSCPU),
+ VMSTATE_INT32(env.CP0_IntCtl, MIPSCPU),
+ VMSTATE_INT32(env.CP0_SRSCtl, MIPSCPU),
+ VMSTATE_INT32(env.CP0_SRSMap, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Cause, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_EPC, MIPSCPU),
+ VMSTATE_INT32(env.CP0_PRid, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_EBase, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_CMGCRBase, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Config0, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Config1, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Config2, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Config3, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Config4, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Config5, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Config6, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Config7, MIPSCPU),
+ VMSTATE_UINT64(env.CP0_LLAddr, MIPSCPU),
+ VMSTATE_UINT64_ARRAY(env.CP0_MAAR, MIPSCPU, MIPS_MAAR_MAX),
+ VMSTATE_INT32(env.CP0_MAARI, MIPSCPU),
+ VMSTATE_UINTTL(env.lladdr, MIPSCPU),
+ VMSTATE_UINTTL_ARRAY(env.CP0_WatchLo, MIPSCPU, 8),
+ VMSTATE_UINT64_ARRAY(env.CP0_WatchHi, MIPSCPU, 8),
+ VMSTATE_UINTTL(env.CP0_XContext, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Framemask, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Debug, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_DEPC, MIPSCPU),
+ VMSTATE_INT32(env.CP0_Performance0, MIPSCPU),
+ VMSTATE_INT32(env.CP0_ErrCtl, MIPSCPU),
+ VMSTATE_UINT64(env.CP0_TagLo, MIPSCPU),
+ VMSTATE_INT32(env.CP0_DataLo, MIPSCPU),
+ VMSTATE_INT32(env.CP0_TagHi, MIPSCPU),
+ VMSTATE_INT32(env.CP0_DataHi, MIPSCPU),
+ VMSTATE_UINTTL(env.CP0_ErrorEPC, MIPSCPU),
+ VMSTATE_INT32(env.CP0_DESAVE, MIPSCPU),
+ VMSTATE_UINTTL_ARRAY(env.CP0_KScratch, MIPSCPU, MIPS_KSCRATCH_NUM),
+
+ /* Inactive TC */
+ VMSTATE_STRUCT_ARRAY(env.tcs, MIPSCPU, MIPS_SHADOW_SET_MAX, 1,
+ vmstate_inactive_tc, TCState),
+ VMSTATE_STRUCT_ARRAY(env.fpus, MIPSCPU, MIPS_FPU_MAX, 1,
+ vmstate_inactive_fpu, CPUMIPSFPUContext),
+
+ VMSTATE_END_OF_LIST()
+ },
+};
--- /dev/null
+mips_system_ss.add(files(
+ 'addr.c',
+ 'cp0.c',
+ 'cp0_timer.c',
+ 'machine.c',
+ 'mips-qmp-cmds.c',
+ 'physaddr.c',
+))
--- /dev/null
+/*
+ * QEMU MIPS CPU (monitor definitions)
+ *
+ * SPDX-FileCopyrightText: 2012 SUSE LINUX Products GmbH
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/qapi-commands-machine-target.h"
+#include "cpu.h"
+
+static void mips_cpu_add_definition(gpointer data, gpointer user_data)
+{
+ ObjectClass *oc = data;
+ CpuDefinitionInfoList **cpu_list = user_data;
+ CpuDefinitionInfo *info;
+ const char *typename;
+
+ typename = object_class_get_name(oc);
+ info = g_malloc0(sizeof(*info));
+ info->name = cpu_model_from_type(typename);
+ info->q_typename = g_strdup(typename);
+
+ QAPI_LIST_PREPEND(*cpu_list, info);
+}
+
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+{
+ CpuDefinitionInfoList *cpu_list = NULL;
+ GSList *list;
+
+ list = object_class_get_list(TYPE_MIPS_CPU, false);
+ g_slist_foreach(list, mips_cpu_add_definition, &cpu_list);
+ g_slist_free(list);
+
+ return cpu_list;
+}
--- /dev/null
+/*
+ * MIPS TLB (Translation lookaside buffer) helpers.
+ *
+ * Copyright (c) 2004-2005 Jocelyn Mayer
+ *
+ * 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.1 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/exec-all.h"
+#include "exec/page-protection.h"
+#include "../internal.h"
+
+static int is_seg_am_mapped(unsigned int am, bool eu, int mmu_idx)
+{
+ /*
+ * Interpret access control mode and mmu_idx.
+ * AdE? TLB?
+ * AM K S U E K S U E
+ * UK 0 0 1 1 0 0 - - 0
+ * MK 1 0 1 1 0 1 - - !eu
+ * MSK 2 0 0 1 0 1 1 - !eu
+ * MUSK 3 0 0 0 0 1 1 1 !eu
+ * MUSUK 4 0 0 0 0 0 1 1 0
+ * USK 5 0 0 1 0 0 0 - 0
+ * - 6 - - - - - - - -
+ * UUSK 7 0 0 0 0 0 0 0 0
+ */
+ int32_t adetlb_mask;
+
+ switch (mmu_idx) {
+ case 3: /* ERL */
+ /* If EU is set, always unmapped */
+ if (eu) {
+ return 0;
+ }
+ /* fall through */
+ case MIPS_HFLAG_KM:
+ /* Never AdE, TLB mapped if AM={1,2,3} */
+ adetlb_mask = 0x70000000;
+ goto check_tlb;
+
+ case MIPS_HFLAG_SM:
+ /* AdE if AM={0,1}, TLB mapped if AM={2,3,4} */
+ adetlb_mask = 0xc0380000;
+ goto check_ade;
+
+ case MIPS_HFLAG_UM:
+ /* AdE if AM={0,1,2,5}, TLB mapped if AM={3,4} */
+ adetlb_mask = 0xe4180000;
+ /* fall through */
+ check_ade:
+ /* does this AM cause AdE in current execution mode */
+ if ((adetlb_mask << am) < 0) {
+ return TLBRET_BADADDR;
+ }
+ adetlb_mask <<= 8;
+ /* fall through */
+ check_tlb:
+ /* is this AM mapped in current execution mode */
+ return ((adetlb_mask << am) < 0);
+ default:
+ g_assert_not_reached();
+ };
+}
+
+static int get_seg_physical_address(CPUMIPSState *env, hwaddr *physical,
+ int *prot, target_ulong real_address,
+ MMUAccessType access_type, int mmu_idx,
+ unsigned int am, bool eu,
+ target_ulong segmask,
+ hwaddr physical_base)
+{
+ int mapped = is_seg_am_mapped(am, eu, mmu_idx);
+
+ if (mapped < 0) {
+ /* is_seg_am_mapped can report TLBRET_BADADDR */
+ return mapped;
+ } else if (mapped) {
+ /* The segment is TLB mapped */
+ return env->tlb->map_address(env, physical, prot, real_address,
+ access_type);
+ } else {
+ /* The segment is unmapped */
+ *physical = physical_base | (real_address & segmask);
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ return TLBRET_MATCH;
+ }
+}
+
+static int get_segctl_physical_address(CPUMIPSState *env, hwaddr *physical,
+ int *prot, target_ulong real_address,
+ MMUAccessType access_type, int mmu_idx,
+ uint16_t segctl, target_ulong segmask)
+{
+ unsigned int am = (segctl & CP0SC_AM_MASK) >> CP0SC_AM;
+ bool eu = (segctl >> CP0SC_EU) & 1;
+ hwaddr pa = ((hwaddr)segctl & CP0SC_PA_MASK) << 20;
+
+ return get_seg_physical_address(env, physical, prot, real_address,
+ access_type, mmu_idx, am, eu, segmask,
+ pa & ~(hwaddr)segmask);
+}
+
+int get_physical_address(CPUMIPSState *env, hwaddr *physical,
+ int *prot, target_ulong real_address,
+ MMUAccessType access_type, int mmu_idx)
+{
+ /* User mode can only access useg/xuseg */
+#if defined(TARGET_MIPS64)
+ int user_mode = mmu_idx == MIPS_HFLAG_UM;
+ int supervisor_mode = mmu_idx == MIPS_HFLAG_SM;
+ int kernel_mode = !user_mode && !supervisor_mode;
+ int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
+ int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;
+ int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
+#endif
+ int ret = TLBRET_MATCH;
+ /* effective address (modified for KVM T&E kernel segments) */
+ target_ulong address = real_address;
+
+ if (address <= USEG_LIMIT) {
+ /* useg */
+ uint16_t segctl;
+
+ if (address >= 0x40000000UL) {
+ segctl = env->CP0_SegCtl2;
+ } else {
+ segctl = env->CP0_SegCtl2 >> 16;
+ }
+ ret = get_segctl_physical_address(env, physical, prot,
+ real_address, access_type,
+ mmu_idx, segctl, 0x3FFFFFFF);
+#if defined(TARGET_MIPS64)
+ } else if (address < 0x4000000000000000ULL) {
+ /* xuseg */
+ if (UX && address <= (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) {
+ ret = env->tlb->map_address(env, physical, prot,
+ real_address, access_type);
+ } else {
+ ret = TLBRET_BADADDR;
+ }
+ } else if (address < 0x8000000000000000ULL) {
+ /* xsseg */
+ if ((supervisor_mode || kernel_mode) &&
+ SX && address <= (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) {
+ ret = env->tlb->map_address(env, physical, prot,
+ real_address, access_type);
+ } else {
+ ret = TLBRET_BADADDR;
+ }
+ } else if (address < 0xC000000000000000ULL) {
+ /* xkphys */
+ if ((address & 0x07FFFFFFFFFFFFFFULL) <= env->PAMask) {
+ /* KX/SX/UX bit to check for each xkphys EVA access mode */
+ static const uint8_t am_ksux[8] = {
+ [CP0SC_AM_UK] = (1u << CP0St_KX),
+ [CP0SC_AM_MK] = (1u << CP0St_KX),
+ [CP0SC_AM_MSK] = (1u << CP0St_SX),
+ [CP0SC_AM_MUSK] = (1u << CP0St_UX),
+ [CP0SC_AM_MUSUK] = (1u << CP0St_UX),
+ [CP0SC_AM_USK] = (1u << CP0St_SX),
+ [6] = (1u << CP0St_KX),
+ [CP0SC_AM_UUSK] = (1u << CP0St_UX),
+ };
+ unsigned int am = CP0SC_AM_UK;
+ unsigned int xr = (env->CP0_SegCtl2 & CP0SC2_XR_MASK) >> CP0SC2_XR;
+
+ if (xr & (1 << ((address >> 59) & 0x7))) {
+ am = (env->CP0_SegCtl1 & CP0SC1_XAM_MASK) >> CP0SC1_XAM;
+ }
+ /* Does CP0_Status.KX/SX/UX permit the access mode (am) */
+ if (env->CP0_Status & am_ksux[am]) {
+ ret = get_seg_physical_address(env, physical, prot,
+ real_address, access_type,
+ mmu_idx, am, false, env->PAMask,
+ 0);
+ } else {
+ ret = TLBRET_BADADDR;
+ }
+ } else {
+ ret = TLBRET_BADADDR;
+ }
+ } else if (address < 0xFFFFFFFF80000000ULL) {
+ /* xkseg */
+ if (kernel_mode && KX &&
+ address <= (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) {
+ ret = env->tlb->map_address(env, physical, prot,
+ real_address, access_type);
+ } else {
+ ret = TLBRET_BADADDR;
+ }
+#endif
+ } else if (address < KSEG1_BASE) {
+ /* kseg0 */
+ ret = get_segctl_physical_address(env, physical, prot, real_address,
+ access_type, mmu_idx,
+ env->CP0_SegCtl1 >> 16, 0x1FFFFFFF);
+ } else if (address < KSEG2_BASE) {
+ /* kseg1 */
+ ret = get_segctl_physical_address(env, physical, prot, real_address,
+ access_type, mmu_idx,
+ env->CP0_SegCtl1, 0x1FFFFFFF);
+ } else if (address < KSEG3_BASE) {
+ /* sseg (kseg2) */
+ ret = get_segctl_physical_address(env, physical, prot, real_address,
+ access_type, mmu_idx,
+ env->CP0_SegCtl0 >> 16, 0x1FFFFFFF);
+ } else {
+ /*
+ * kseg3
+ * XXX: debug segment is not emulated
+ */
+ ret = get_segctl_physical_address(env, physical, prot, real_address,
+ access_type, mmu_idx,
+ env->CP0_SegCtl0, 0x1FFFFFFF);
+ }
+ return ret;
+}
+
+hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
+{
+ CPUMIPSState *env = cpu_env(cs);
+ hwaddr phys_addr;
+ int prot;
+
+ if (get_physical_address(env, &phys_addr, &prot, addr, MMU_DATA_LOAD,
+ mips_env_mmu_index(env)) != 0) {
+ return -1;
+ }
+ return phys_addr;
+}
))
if have_system
- subdir('sysemu')
+ subdir('system')
endif
+++ /dev/null
-/*
- * Helpers for emulation of CP0-related MIPS instructions.
- *
- * Copyright (C) 2004-2005 Jocelyn Mayer
- * Copyright (C) 2020 Wave Computing, Inc.
- * Copyright (C) 2020 Aleksandar Markovic <amarkovic@wavecomp.com>
- *
- * 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.1 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 "qemu/log.h"
-#include "qemu/main-loop.h"
-#include "cpu.h"
-#include "internal.h"
-#include "qemu/host-utils.h"
-#include "exec/helper-proto.h"
-#include "exec/exec-all.h"
-
-
-/* SMP helpers. */
-static bool mips_vpe_is_wfi(MIPSCPU *c)
-{
- CPUState *cpu = CPU(c);
- CPUMIPSState *env = &c->env;
-
- /*
- * If the VPE is halted but otherwise active, it means it's waiting for
- * an interrupt.\
- */
- return cpu->halted && mips_vpe_active(env);
-}
-
-static bool mips_vp_is_wfi(MIPSCPU *c)
-{
- CPUState *cpu = CPU(c);
- CPUMIPSState *env = &c->env;
-
- return cpu->halted && mips_vp_active(env);
-}
-
-static inline void mips_vpe_wake(MIPSCPU *c)
-{
- /*
- * Don't set ->halted = 0 directly, let it be done via cpu_has_work
- * because there might be other conditions that state that c should
- * be sleeping.
- */
- bql_lock();
- cpu_interrupt(CPU(c), CPU_INTERRUPT_WAKE);
- bql_unlock();
-}
-
-static inline void mips_vpe_sleep(MIPSCPU *cpu)
-{
- CPUState *cs = CPU(cpu);
-
- /*
- * The VPE was shut off, really go to bed.
- * Reset any old _WAKE requests.
- */
- cs->halted = 1;
- cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE);
-}
-
-static inline void mips_tc_wake(MIPSCPU *cpu, int tc)
-{
- CPUMIPSState *c = &cpu->env;
-
- /* FIXME: TC reschedule. */
- if (mips_vpe_active(c) && !mips_vpe_is_wfi(cpu)) {
- mips_vpe_wake(cpu);
- }
-}
-
-static inline void mips_tc_sleep(MIPSCPU *cpu, int tc)
-{
- CPUMIPSState *c = &cpu->env;
-
- /* FIXME: TC reschedule. */
- if (!mips_vpe_active(c)) {
- mips_vpe_sleep(cpu);
- }
-}
-
-/**
- * mips_cpu_map_tc:
- * @env: CPU from which mapping is performed.
- * @tc: Should point to an int with the value of the global TC index.
- *
- * This function will transform @tc into a local index within the
- * returned #CPUMIPSState.
- */
-
-/*
- * FIXME: This code assumes that all VPEs have the same number of TCs,
- * which depends on runtime setup. Can probably be fixed by
- * walking the list of CPUMIPSStates.
- */
-static CPUMIPSState *mips_cpu_map_tc(CPUMIPSState *env, int *tc)
-{
- MIPSCPU *cpu;
- CPUState *cs;
- CPUState *other_cs;
- int vpe_idx;
- int tc_idx = *tc;
-
- if (!(env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))) {
- /* Not allowed to address other CPUs. */
- *tc = env->current_tc;
- return env;
- }
-
- cs = env_cpu(env);
- vpe_idx = tc_idx / cs->nr_threads;
- *tc = tc_idx % cs->nr_threads;
- other_cs = qemu_get_cpu(vpe_idx);
- if (other_cs == NULL) {
- return env;
- }
- cpu = MIPS_CPU(other_cs);
- return &cpu->env;
-}
-
-/*
- * The per VPE CP0_Status register shares some fields with the per TC
- * CP0_TCStatus registers. These fields are wired to the same registers,
- * so changes to either of them should be reflected on both registers.
- *
- * Also, EntryHi shares the bottom 8 bit ASID with TCStauts.
- *
- * These helper call synchronizes the regs for a given cpu.
- */
-
-/*
- * Called for updates to CP0_Status. Defined in "cpu.h" for gdbstub.c.
- * static inline void sync_c0_status(CPUMIPSState *env, CPUMIPSState *cpu,
- * int tc);
- */
-
-/* Called for updates to CP0_TCStatus. */
-static void sync_c0_tcstatus(CPUMIPSState *cpu, int tc,
- target_ulong v)
-{
- uint32_t status;
- uint32_t tcu, tmx, tasid, tksu;
- uint32_t mask = ((1U << CP0St_CU3)
- | (1 << CP0St_CU2)
- | (1 << CP0St_CU1)
- | (1 << CP0St_CU0)
- | (1 << CP0St_MX)
- | (3 << CP0St_KSU));
-
- tcu = (v >> CP0TCSt_TCU0) & 0xf;
- tmx = (v >> CP0TCSt_TMX) & 0x1;
- tasid = v & cpu->CP0_EntryHi_ASID_mask;
- tksu = (v >> CP0TCSt_TKSU) & 0x3;
-
- status = tcu << CP0St_CU0;
- status |= tmx << CP0St_MX;
- status |= tksu << CP0St_KSU;
-
- cpu->CP0_Status &= ~mask;
- cpu->CP0_Status |= status;
-
- /* Sync the TASID with EntryHi. */
- cpu->CP0_EntryHi &= ~cpu->CP0_EntryHi_ASID_mask;
- cpu->CP0_EntryHi |= tasid;
-
- compute_hflags(cpu);
-}
-
-/* Called for updates to CP0_EntryHi. */
-static void sync_c0_entryhi(CPUMIPSState *cpu, int tc)
-{
- int32_t *tcst;
- uint32_t asid, v = cpu->CP0_EntryHi;
-
- asid = v & cpu->CP0_EntryHi_ASID_mask;
-
- if (tc == cpu->current_tc) {
- tcst = &cpu->active_tc.CP0_TCStatus;
- } else {
- tcst = &cpu->tcs[tc].CP0_TCStatus;
- }
-
- *tcst &= ~cpu->CP0_EntryHi_ASID_mask;
- *tcst |= asid;
-}
-
-/* XXX: do not use a global */
-uint32_t cpu_mips_get_random(CPUMIPSState *env)
-{
- static uint32_t seed = 1;
- static uint32_t prev_idx;
- uint32_t idx;
- uint32_t nb_rand_tlb = env->tlb->nb_tlb - env->CP0_Wired;
-
- if (nb_rand_tlb == 1) {
- return env->tlb->nb_tlb - 1;
- }
-
- /* Don't return same value twice, so get another value */
- do {
- /*
- * Use a simple algorithm of Linear Congruential Generator
- * from ISO/IEC 9899 standard.
- */
- seed = 1103515245 * seed + 12345;
- idx = (seed >> 16) % nb_rand_tlb + env->CP0_Wired;
- } while (idx == prev_idx);
- prev_idx = idx;
- return idx;
-}
-
-/* CP0 helpers */
-target_ulong helper_mfc0_mvpcontrol(CPUMIPSState *env)
-{
- return env->mvp->CP0_MVPControl;
-}
-
-target_ulong helper_mfc0_mvpconf0(CPUMIPSState *env)
-{
- return env->mvp->CP0_MVPConf0;
-}
-
-target_ulong helper_mfc0_mvpconf1(CPUMIPSState *env)
-{
- return env->mvp->CP0_MVPConf1;
-}
-
-target_ulong helper_mfc0_random(CPUMIPSState *env)
-{
- return (int32_t)cpu_mips_get_random(env);
-}
-
-target_ulong helper_mfc0_tcstatus(CPUMIPSState *env)
-{
- return env->active_tc.CP0_TCStatus;
-}
-
-target_ulong helper_mftc0_tcstatus(CPUMIPSState *env)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- return other->active_tc.CP0_TCStatus;
- } else {
- return other->tcs[other_tc].CP0_TCStatus;
- }
-}
-
-target_ulong helper_mfc0_tcbind(CPUMIPSState *env)
-{
- return env->active_tc.CP0_TCBind;
-}
-
-target_ulong helper_mftc0_tcbind(CPUMIPSState *env)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- return other->active_tc.CP0_TCBind;
- } else {
- return other->tcs[other_tc].CP0_TCBind;
- }
-}
-
-target_ulong helper_mfc0_tcrestart(CPUMIPSState *env)
-{
- return env->active_tc.PC;
-}
-
-target_ulong helper_mftc0_tcrestart(CPUMIPSState *env)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- return other->active_tc.PC;
- } else {
- return other->tcs[other_tc].PC;
- }
-}
-
-target_ulong helper_mfc0_tchalt(CPUMIPSState *env)
-{
- return env->active_tc.CP0_TCHalt;
-}
-
-target_ulong helper_mftc0_tchalt(CPUMIPSState *env)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- return other->active_tc.CP0_TCHalt;
- } else {
- return other->tcs[other_tc].CP0_TCHalt;
- }
-}
-
-target_ulong helper_mfc0_tccontext(CPUMIPSState *env)
-{
- return env->active_tc.CP0_TCContext;
-}
-
-target_ulong helper_mftc0_tccontext(CPUMIPSState *env)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- return other->active_tc.CP0_TCContext;
- } else {
- return other->tcs[other_tc].CP0_TCContext;
- }
-}
-
-target_ulong helper_mfc0_tcschedule(CPUMIPSState *env)
-{
- return env->active_tc.CP0_TCSchedule;
-}
-
-target_ulong helper_mftc0_tcschedule(CPUMIPSState *env)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- return other->active_tc.CP0_TCSchedule;
- } else {
- return other->tcs[other_tc].CP0_TCSchedule;
- }
-}
-
-target_ulong helper_mfc0_tcschefback(CPUMIPSState *env)
-{
- return env->active_tc.CP0_TCScheFBack;
-}
-
-target_ulong helper_mftc0_tcschefback(CPUMIPSState *env)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- return other->active_tc.CP0_TCScheFBack;
- } else {
- return other->tcs[other_tc].CP0_TCScheFBack;
- }
-}
-
-target_ulong helper_mfc0_count(CPUMIPSState *env)
-{
- return (int32_t)cpu_mips_get_count(env);
-}
-
-target_ulong helper_mftc0_entryhi(CPUMIPSState *env)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- return other->CP0_EntryHi;
-}
-
-target_ulong helper_mftc0_cause(CPUMIPSState *env)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- return other->CP0_Cause;
-}
-
-target_ulong helper_mftc0_status(CPUMIPSState *env)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- return other->CP0_Status;
-}
-
-target_ulong helper_mfc0_lladdr(CPUMIPSState *env)
-{
- return (int32_t)(env->CP0_LLAddr >> env->CP0_LLAddr_shift);
-}
-
-target_ulong helper_mfc0_maar(CPUMIPSState *env)
-{
- return (int32_t) env->CP0_MAAR[env->CP0_MAARI];
-}
-
-target_ulong helper_mfhc0_maar(CPUMIPSState *env)
-{
- return env->CP0_MAAR[env->CP0_MAARI] >> 32;
-}
-
-target_ulong helper_mfc0_watchlo(CPUMIPSState *env, uint32_t sel)
-{
- return (int32_t)env->CP0_WatchLo[sel];
-}
-
-target_ulong helper_mfc0_watchhi(CPUMIPSState *env, uint32_t sel)
-{
- return (int32_t) env->CP0_WatchHi[sel];
-}
-
-target_ulong helper_mfhc0_watchhi(CPUMIPSState *env, uint32_t sel)
-{
- return env->CP0_WatchHi[sel] >> 32;
-}
-
-target_ulong helper_mfc0_debug(CPUMIPSState *env)
-{
- target_ulong t0 = env->CP0_Debug;
- if (env->hflags & MIPS_HFLAG_DM) {
- t0 |= 1 << CP0DB_DM;
- }
-
- return t0;
-}
-
-target_ulong helper_mftc0_debug(CPUMIPSState *env)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- int32_t tcstatus;
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- tcstatus = other->active_tc.CP0_Debug_tcstatus;
- } else {
- tcstatus = other->tcs[other_tc].CP0_Debug_tcstatus;
- }
-
- /* XXX: Might be wrong, check with EJTAG spec. */
- return (other->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
- (tcstatus & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
-}
-
-#if defined(TARGET_MIPS64)
-target_ulong helper_dmfc0_tcrestart(CPUMIPSState *env)
-{
- return env->active_tc.PC;
-}
-
-target_ulong helper_dmfc0_tchalt(CPUMIPSState *env)
-{
- return env->active_tc.CP0_TCHalt;
-}
-
-target_ulong helper_dmfc0_tccontext(CPUMIPSState *env)
-{
- return env->active_tc.CP0_TCContext;
-}
-
-target_ulong helper_dmfc0_tcschedule(CPUMIPSState *env)
-{
- return env->active_tc.CP0_TCSchedule;
-}
-
-target_ulong helper_dmfc0_tcschefback(CPUMIPSState *env)
-{
- return env->active_tc.CP0_TCScheFBack;
-}
-
-target_ulong helper_dmfc0_lladdr(CPUMIPSState *env)
-{
- return env->CP0_LLAddr >> env->CP0_LLAddr_shift;
-}
-
-target_ulong helper_dmfc0_maar(CPUMIPSState *env)
-{
- return env->CP0_MAAR[env->CP0_MAARI];
-}
-
-target_ulong helper_dmfc0_watchlo(CPUMIPSState *env, uint32_t sel)
-{
- return env->CP0_WatchLo[sel];
-}
-
-target_ulong helper_dmfc0_watchhi(CPUMIPSState *env, uint32_t sel)
-{
- return env->CP0_WatchHi[sel];
-}
-
-#endif /* TARGET_MIPS64 */
-
-void helper_mtc0_index(CPUMIPSState *env, target_ulong arg1)
-{
- uint32_t index_p = env->CP0_Index & 0x80000000;
- uint32_t tlb_index = arg1 & 0x7fffffff;
- if (tlb_index < env->tlb->nb_tlb) {
- if (env->insn_flags & ISA_MIPS_R6) {
- index_p |= arg1 & 0x80000000;
- }
- env->CP0_Index = index_p | tlb_index;
- }
-}
-
-void helper_mtc0_mvpcontrol(CPUMIPSState *env, target_ulong arg1)
-{
- uint32_t mask = 0;
- uint32_t newval;
-
- if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
- mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) |
- (1 << CP0MVPCo_EVP);
- }
- if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) {
- mask |= (1 << CP0MVPCo_STLB);
- }
- newval = (env->mvp->CP0_MVPControl & ~mask) | (arg1 & mask);
-
- /* TODO: Enable/disable shared TLB, enable/disable VPEs. */
-
- env->mvp->CP0_MVPControl = newval;
-}
-
-void helper_mtc0_vpecontrol(CPUMIPSState *env, target_ulong arg1)
-{
- uint32_t mask;
- uint32_t newval;
-
- mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
- (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
- newval = (env->CP0_VPEControl & ~mask) | (arg1 & mask);
-
- /*
- * Yield scheduler intercept not implemented.
- * Gating storage scheduler intercept not implemented.
- */
-
- /* TODO: Enable/disable TCs. */
-
- env->CP0_VPEControl = newval;
-}
-
-void helper_mttc0_vpecontrol(CPUMIPSState *env, target_ulong arg1)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
- uint32_t mask;
- uint32_t newval;
-
- mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
- (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
- newval = (other->CP0_VPEControl & ~mask) | (arg1 & mask);
-
- /* TODO: Enable/disable TCs. */
-
- other->CP0_VPEControl = newval;
-}
-
-target_ulong helper_mftc0_vpecontrol(CPUMIPSState *env)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
- /* FIXME: Mask away return zero on read bits. */
- return other->CP0_VPEControl;
-}
-
-target_ulong helper_mftc0_vpeconf0(CPUMIPSState *env)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- return other->CP0_VPEConf0;
-}
-
-void helper_mtc0_vpeconf0(CPUMIPSState *env, target_ulong arg1)
-{
- uint32_t mask = 0;
- uint32_t newval;
-
- if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
- if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA)) {
- mask |= (0xff << CP0VPEC0_XTC);
- }
- mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
- }
- newval = (env->CP0_VPEConf0 & ~mask) | (arg1 & mask);
-
- /* TODO: TC exclusive handling due to ERL/EXL. */
-
- env->CP0_VPEConf0 = newval;
-}
-
-void helper_mttc0_vpeconf0(CPUMIPSState *env, target_ulong arg1)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
- uint32_t mask = 0;
- uint32_t newval;
-
- mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
- newval = (other->CP0_VPEConf0 & ~mask) | (arg1 & mask);
-
- /* TODO: TC exclusive handling due to ERL/EXL. */
- other->CP0_VPEConf0 = newval;
-}
-
-void helper_mtc0_vpeconf1(CPUMIPSState *env, target_ulong arg1)
-{
- uint32_t mask = 0;
- uint32_t newval;
-
- if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
- mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) |
- (0xff << CP0VPEC1_NCP1);
- newval = (env->CP0_VPEConf1 & ~mask) | (arg1 & mask);
-
- /* UDI not implemented. */
- /* CP2 not implemented. */
-
- /* TODO: Handle FPU (CP1) binding. */
-
- env->CP0_VPEConf1 = newval;
-}
-
-void helper_mtc0_yqmask(CPUMIPSState *env, target_ulong arg1)
-{
- /* Yield qualifier inputs not implemented. */
- env->CP0_YQMask = 0x00000000;
-}
-
-void helper_mtc0_vpeopt(CPUMIPSState *env, target_ulong arg1)
-{
- env->CP0_VPEOpt = arg1 & 0x0000ffff;
-}
-
-#define MTC0_ENTRYLO_MASK(env) ((env->PAMask >> 6) & 0x3FFFFFFF)
-
-void helper_mtc0_entrylo0(CPUMIPSState *env, target_ulong arg1)
-{
- /* 1k pages not implemented */
- target_ulong rxi = arg1 & (env->CP0_PageGrain & (3u << CP0PG_XIE));
- env->CP0_EntryLo0 = (arg1 & MTC0_ENTRYLO_MASK(env))
- | (rxi << (CP0EnLo_XI - 30));
-}
-
-#if defined(TARGET_MIPS64)
-#define DMTC0_ENTRYLO_MASK(env) (env->PAMask >> 6)
-
-void helper_dmtc0_entrylo0(CPUMIPSState *env, uint64_t arg1)
-{
- uint64_t rxi = arg1 & ((env->CP0_PageGrain & (3ull << CP0PG_XIE)) << 32);
- env->CP0_EntryLo0 = (arg1 & DMTC0_ENTRYLO_MASK(env)) | rxi;
-}
-#endif
-
-void helper_mtc0_tcstatus(CPUMIPSState *env, target_ulong arg1)
-{
- uint32_t mask = env->CP0_TCStatus_rw_bitmask;
- uint32_t newval;
-
- newval = (env->active_tc.CP0_TCStatus & ~mask) | (arg1 & mask);
-
- env->active_tc.CP0_TCStatus = newval;
- sync_c0_tcstatus(env, env->current_tc, newval);
-}
-
-void helper_mttc0_tcstatus(CPUMIPSState *env, target_ulong arg1)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- other->active_tc.CP0_TCStatus = arg1;
- } else {
- other->tcs[other_tc].CP0_TCStatus = arg1;
- }
- sync_c0_tcstatus(other, other_tc, arg1);
-}
-
-void helper_mtc0_tcbind(CPUMIPSState *env, target_ulong arg1)
-{
- uint32_t mask = (1 << CP0TCBd_TBE);
- uint32_t newval;
-
- if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) {
- mask |= (1 << CP0TCBd_CurVPE);
- }
- newval = (env->active_tc.CP0_TCBind & ~mask) | (arg1 & mask);
- env->active_tc.CP0_TCBind = newval;
-}
-
-void helper_mttc0_tcbind(CPUMIPSState *env, target_ulong arg1)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- uint32_t mask = (1 << CP0TCBd_TBE);
- uint32_t newval;
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) {
- mask |= (1 << CP0TCBd_CurVPE);
- }
- if (other_tc == other->current_tc) {
- newval = (other->active_tc.CP0_TCBind & ~mask) | (arg1 & mask);
- other->active_tc.CP0_TCBind = newval;
- } else {
- newval = (other->tcs[other_tc].CP0_TCBind & ~mask) | (arg1 & mask);
- other->tcs[other_tc].CP0_TCBind = newval;
- }
-}
-
-void helper_mtc0_tcrestart(CPUMIPSState *env, target_ulong arg1)
-{
- env->active_tc.PC = arg1;
- env->active_tc.CP0_TCStatus &= ~(1 << CP0TCSt_TDS);
- env->CP0_LLAddr = 0;
- env->lladdr = 0;
- /* MIPS16 not implemented. */
-}
-
-void helper_mttc0_tcrestart(CPUMIPSState *env, target_ulong arg1)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- other->active_tc.PC = arg1;
- other->active_tc.CP0_TCStatus &= ~(1 << CP0TCSt_TDS);
- other->CP0_LLAddr = 0;
- other->lladdr = 0;
- /* MIPS16 not implemented. */
- } else {
- other->tcs[other_tc].PC = arg1;
- other->tcs[other_tc].CP0_TCStatus &= ~(1 << CP0TCSt_TDS);
- other->CP0_LLAddr = 0;
- other->lladdr = 0;
- /* MIPS16 not implemented. */
- }
-}
-
-void helper_mtc0_tchalt(CPUMIPSState *env, target_ulong arg1)
-{
- MIPSCPU *cpu = env_archcpu(env);
-
- env->active_tc.CP0_TCHalt = arg1 & 0x1;
-
- /* TODO: Halt TC / Restart (if allocated+active) TC. */
- if (env->active_tc.CP0_TCHalt & 1) {
- mips_tc_sleep(cpu, env->current_tc);
- } else {
- mips_tc_wake(cpu, env->current_tc);
- }
-}
-
-void helper_mttc0_tchalt(CPUMIPSState *env, target_ulong arg1)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
- MIPSCPU *other_cpu = env_archcpu(other);
-
- /* TODO: Halt TC / Restart (if allocated+active) TC. */
-
- if (other_tc == other->current_tc) {
- other->active_tc.CP0_TCHalt = arg1;
- } else {
- other->tcs[other_tc].CP0_TCHalt = arg1;
- }
-
- if (arg1 & 1) {
- mips_tc_sleep(other_cpu, other_tc);
- } else {
- mips_tc_wake(other_cpu, other_tc);
- }
-}
-
-void helper_mtc0_tccontext(CPUMIPSState *env, target_ulong arg1)
-{
- env->active_tc.CP0_TCContext = arg1;
-}
-
-void helper_mttc0_tccontext(CPUMIPSState *env, target_ulong arg1)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- other->active_tc.CP0_TCContext = arg1;
- } else {
- other->tcs[other_tc].CP0_TCContext = arg1;
- }
-}
-
-void helper_mtc0_tcschedule(CPUMIPSState *env, target_ulong arg1)
-{
- env->active_tc.CP0_TCSchedule = arg1;
-}
-
-void helper_mttc0_tcschedule(CPUMIPSState *env, target_ulong arg1)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- other->active_tc.CP0_TCSchedule = arg1;
- } else {
- other->tcs[other_tc].CP0_TCSchedule = arg1;
- }
-}
-
-void helper_mtc0_tcschefback(CPUMIPSState *env, target_ulong arg1)
-{
- env->active_tc.CP0_TCScheFBack = arg1;
-}
-
-void helper_mttc0_tcschefback(CPUMIPSState *env, target_ulong arg1)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- other->active_tc.CP0_TCScheFBack = arg1;
- } else {
- other->tcs[other_tc].CP0_TCScheFBack = arg1;
- }
-}
-
-void helper_mtc0_entrylo1(CPUMIPSState *env, target_ulong arg1)
-{
- /* 1k pages not implemented */
- target_ulong rxi = arg1 & (env->CP0_PageGrain & (3u << CP0PG_XIE));
- env->CP0_EntryLo1 = (arg1 & MTC0_ENTRYLO_MASK(env))
- | (rxi << (CP0EnLo_XI - 30));
-}
-
-#if defined(TARGET_MIPS64)
-void helper_dmtc0_entrylo1(CPUMIPSState *env, uint64_t arg1)
-{
- uint64_t rxi = arg1 & ((env->CP0_PageGrain & (3ull << CP0PG_XIE)) << 32);
- env->CP0_EntryLo1 = (arg1 & DMTC0_ENTRYLO_MASK(env)) | rxi;
-}
-#endif
-
-void helper_mtc0_context(CPUMIPSState *env, target_ulong arg1)
-{
- env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (arg1 & ~0x007FFFFF);
-}
-
-void helper_mtc0_memorymapid(CPUMIPSState *env, target_ulong arg1)
-{
- int32_t old;
- old = env->CP0_MemoryMapID;
- env->CP0_MemoryMapID = (int32_t) arg1;
- /* If the MemoryMapID changes, flush qemu's TLB. */
- if (old != env->CP0_MemoryMapID) {
- cpu_mips_tlb_flush(env);
- }
-}
-
-void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t *pagemask)
-{
- uint32_t mask;
- int maskbits;
-
- /* Don't care MASKX as we don't support 1KB page */
- mask = extract32((uint32_t)arg1, CP0PM_MASK, 16);
- maskbits = cto32(mask);
-
- /* Ensure no more set bit after first zero */
- if ((mask >> maskbits) != 0) {
- goto invalid;
- }
- /* We don't support VTLB entry smaller than target page */
- if ((maskbits + TARGET_PAGE_BITS_MIN) < TARGET_PAGE_BITS) {
- goto invalid;
- }
- env->CP0_PageMask = mask << CP0PM_MASK;
-
- return;
-
-invalid:
- /* When invalid, set to default target page size. */
- mask = (~TARGET_PAGE_MASK >> TARGET_PAGE_BITS_MIN);
- env->CP0_PageMask = mask << CP0PM_MASK;
-}
-
-void helper_mtc0_pagemask(CPUMIPSState *env, target_ulong arg1)
-{
- update_pagemask(env, arg1, &env->CP0_PageMask);
-}
-
-void helper_mtc0_pagegrain(CPUMIPSState *env, target_ulong arg1)
-{
- /* SmartMIPS not implemented */
- /* 1k pages not implemented */
- env->CP0_PageGrain = (arg1 & env->CP0_PageGrain_rw_bitmask) |
- (env->CP0_PageGrain & ~env->CP0_PageGrain_rw_bitmask);
- compute_hflags(env);
- restore_pamask(env);
-}
-
-void helper_mtc0_segctl0(CPUMIPSState *env, target_ulong arg1)
-{
- CPUState *cs = env_cpu(env);
-
- env->CP0_SegCtl0 = arg1 & CP0SC0_MASK;
- tlb_flush(cs);
-}
-
-void helper_mtc0_segctl1(CPUMIPSState *env, target_ulong arg1)
-{
- CPUState *cs = env_cpu(env);
-
- env->CP0_SegCtl1 = arg1 & CP0SC1_MASK;
- tlb_flush(cs);
-}
-
-void helper_mtc0_segctl2(CPUMIPSState *env, target_ulong arg1)
-{
- CPUState *cs = env_cpu(env);
-
- env->CP0_SegCtl2 = arg1 & CP0SC2_MASK;
- tlb_flush(cs);
-}
-
-void helper_mtc0_pwfield(CPUMIPSState *env, target_ulong arg1)
-{
-#if defined(TARGET_MIPS64)
- uint64_t mask = 0x3F3FFFFFFFULL;
- uint32_t old_ptei = (env->CP0_PWField >> CP0PF_PTEI) & 0x3FULL;
- uint32_t new_ptei = (arg1 >> CP0PF_PTEI) & 0x3FULL;
-
- if ((env->insn_flags & ISA_MIPS_R6)) {
- if (((arg1 >> CP0PF_BDI) & 0x3FULL) < 12) {
- mask &= ~(0x3FULL << CP0PF_BDI);
- }
- if (((arg1 >> CP0PF_GDI) & 0x3FULL) < 12) {
- mask &= ~(0x3FULL << CP0PF_GDI);
- }
- if (((arg1 >> CP0PF_UDI) & 0x3FULL) < 12) {
- mask &= ~(0x3FULL << CP0PF_UDI);
- }
- if (((arg1 >> CP0PF_MDI) & 0x3FULL) < 12) {
- mask &= ~(0x3FULL << CP0PF_MDI);
- }
- if (((arg1 >> CP0PF_PTI) & 0x3FULL) < 12) {
- mask &= ~(0x3FULL << CP0PF_PTI);
- }
- }
- env->CP0_PWField = arg1 & mask;
-
- if ((new_ptei >= 32) ||
- ((env->insn_flags & ISA_MIPS_R6) &&
- (new_ptei == 0 || new_ptei == 1))) {
- env->CP0_PWField = (env->CP0_PWField & ~0x3FULL) |
- (old_ptei << CP0PF_PTEI);
- }
-#else
- uint32_t mask = 0x3FFFFFFF;
- uint32_t old_ptew = (env->CP0_PWField >> CP0PF_PTEW) & 0x3F;
- uint32_t new_ptew = (arg1 >> CP0PF_PTEW) & 0x3F;
-
- if ((env->insn_flags & ISA_MIPS_R6)) {
- if (((arg1 >> CP0PF_GDW) & 0x3F) < 12) {
- mask &= ~(0x3F << CP0PF_GDW);
- }
- if (((arg1 >> CP0PF_UDW) & 0x3F) < 12) {
- mask &= ~(0x3F << CP0PF_UDW);
- }
- if (((arg1 >> CP0PF_MDW) & 0x3F) < 12) {
- mask &= ~(0x3F << CP0PF_MDW);
- }
- if (((arg1 >> CP0PF_PTW) & 0x3F) < 12) {
- mask &= ~(0x3F << CP0PF_PTW);
- }
- }
- env->CP0_PWField = arg1 & mask;
-
- if ((new_ptew >= 32) ||
- ((env->insn_flags & ISA_MIPS_R6) &&
- (new_ptew == 0 || new_ptew == 1))) {
- env->CP0_PWField = (env->CP0_PWField & ~0x3F) |
- (old_ptew << CP0PF_PTEW);
- }
-#endif
-}
-
-void helper_mtc0_pwsize(CPUMIPSState *env, target_ulong arg1)
-{
-#if defined(TARGET_MIPS64)
- env->CP0_PWSize = arg1 & 0x3F7FFFFFFFULL;
-#else
- env->CP0_PWSize = arg1 & 0x3FFFFFFF;
-#endif
-}
-
-void helper_mtc0_wired(CPUMIPSState *env, target_ulong arg1)
-{
- if (env->insn_flags & ISA_MIPS_R6) {
- if (arg1 < env->tlb->nb_tlb) {
- env->CP0_Wired = arg1;
- }
- } else {
- env->CP0_Wired = arg1 % env->tlb->nb_tlb;
- }
-}
-
-void helper_mtc0_pwctl(CPUMIPSState *env, target_ulong arg1)
-{
-#if defined(TARGET_MIPS64)
- /* PWEn = 0. Hardware page table walking is not implemented. */
- env->CP0_PWCtl = (env->CP0_PWCtl & 0x000000C0) | (arg1 & 0x5C00003F);
-#else
- env->CP0_PWCtl = (arg1 & 0x800000FF);
-#endif
-}
-
-void helper_mtc0_srsconf0(CPUMIPSState *env, target_ulong arg1)
-{
- env->CP0_SRSConf0 |= arg1 & env->CP0_SRSConf0_rw_bitmask;
-}
-
-void helper_mtc0_srsconf1(CPUMIPSState *env, target_ulong arg1)
-{
- env->CP0_SRSConf1 |= arg1 & env->CP0_SRSConf1_rw_bitmask;
-}
-
-void helper_mtc0_srsconf2(CPUMIPSState *env, target_ulong arg1)
-{
- env->CP0_SRSConf2 |= arg1 & env->CP0_SRSConf2_rw_bitmask;
-}
-
-void helper_mtc0_srsconf3(CPUMIPSState *env, target_ulong arg1)
-{
- env->CP0_SRSConf3 |= arg1 & env->CP0_SRSConf3_rw_bitmask;
-}
-
-void helper_mtc0_srsconf4(CPUMIPSState *env, target_ulong arg1)
-{
- env->CP0_SRSConf4 |= arg1 & env->CP0_SRSConf4_rw_bitmask;
-}
-
-void helper_mtc0_hwrena(CPUMIPSState *env, target_ulong arg1)
-{
- uint32_t mask = 0x0000000F;
-
- if ((env->CP0_Config1 & (1 << CP0C1_PC)) &&
- (env->insn_flags & ISA_MIPS_R6)) {
- mask |= (1 << 4);
- }
- if (env->insn_flags & ISA_MIPS_R6) {
- mask |= (1 << 5);
- }
- if (env->CP0_Config3 & (1 << CP0C3_ULRI)) {
- mask |= (1 << 29);
-
- if (arg1 & (1 << 29)) {
- env->hflags |= MIPS_HFLAG_HWRENA_ULR;
- } else {
- env->hflags &= ~MIPS_HFLAG_HWRENA_ULR;
- }
- }
-
- env->CP0_HWREna = arg1 & mask;
-}
-
-void helper_mtc0_count(CPUMIPSState *env, target_ulong arg1)
-{
- cpu_mips_store_count(env, arg1);
-}
-
-void helper_mtc0_entryhi(CPUMIPSState *env, target_ulong arg1)
-{
- target_ulong old, val, mask;
- mask = (TARGET_PAGE_MASK << 1) | env->CP0_EntryHi_ASID_mask;
- if (((env->CP0_Config4 >> CP0C4_IE) & 0x3) >= 2) {
- mask |= 1 << CP0EnHi_EHINV;
- }
-
- /* 1k pages not implemented */
-#if defined(TARGET_MIPS64)
- if (env->insn_flags & ISA_MIPS_R6) {
- int entryhi_r = extract64(arg1, 62, 2);
- int config0_at = extract32(env->CP0_Config0, 13, 2);
- bool no_supervisor = (env->CP0_Status_rw_bitmask & 0x8) == 0;
- if ((entryhi_r == 2) ||
- (entryhi_r == 1 && (no_supervisor || config0_at == 1))) {
- /* skip EntryHi.R field if new value is reserved */
- mask &= ~(0x3ull << 62);
- }
- }
- mask &= env->SEGMask;
-#endif
- old = env->CP0_EntryHi;
- val = (arg1 & mask) | (old & ~mask);
- env->CP0_EntryHi = val;
- if (ase_mt_available(env)) {
- sync_c0_entryhi(env, env->current_tc);
- }
- /* If the ASID changes, flush qemu's TLB. */
- if ((old & env->CP0_EntryHi_ASID_mask) !=
- (val & env->CP0_EntryHi_ASID_mask)) {
- tlb_flush(env_cpu(env));
- }
-}
-
-void helper_mttc0_entryhi(CPUMIPSState *env, target_ulong arg1)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- other->CP0_EntryHi = arg1;
- sync_c0_entryhi(other, other_tc);
-}
-
-void helper_mtc0_compare(CPUMIPSState *env, target_ulong arg1)
-{
- cpu_mips_store_compare(env, arg1);
-}
-
-void helper_mtc0_status(CPUMIPSState *env, target_ulong arg1)
-{
- uint32_t val, old;
-
- old = env->CP0_Status;
- cpu_mips_store_status(env, arg1);
- val = env->CP0_Status;
-
- if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
- qemu_log("Status %08x (%08x) => %08x (%08x) Cause %08x",
- old, old & env->CP0_Cause & CP0Ca_IP_mask,
- val, val & env->CP0_Cause & CP0Ca_IP_mask,
- env->CP0_Cause);
- switch (mips_env_mmu_index(env)) {
- case 3:
- qemu_log(", ERL\n");
- break;
- case MIPS_HFLAG_UM:
- qemu_log(", UM\n");
- break;
- case MIPS_HFLAG_SM:
- qemu_log(", SM\n");
- break;
- case MIPS_HFLAG_KM:
- qemu_log("\n");
- break;
- default:
- cpu_abort(env_cpu(env), "Invalid MMU mode!\n");
- break;
- }
- }
-}
-
-void helper_mttc0_status(CPUMIPSState *env, target_ulong arg1)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- uint32_t mask = env->CP0_Status_rw_bitmask & ~0xf1000018;
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- other->CP0_Status = (other->CP0_Status & ~mask) | (arg1 & mask);
- sync_c0_status(env, other, other_tc);
-}
-
-void helper_mtc0_intctl(CPUMIPSState *env, target_ulong arg1)
-{
- env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000003e0) | (arg1 & 0x000003e0);
-}
-
-void helper_mtc0_srsctl(CPUMIPSState *env, target_ulong arg1)
-{
- uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS);
- env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (arg1 & mask);
-}
-
-void helper_mtc0_cause(CPUMIPSState *env, target_ulong arg1)
-{
- cpu_mips_store_cause(env, arg1);
-}
-
-void helper_mttc0_cause(CPUMIPSState *env, target_ulong arg1)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- cpu_mips_store_cause(other, arg1);
-}
-
-target_ulong helper_mftc0_epc(CPUMIPSState *env)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- return other->CP0_EPC;
-}
-
-target_ulong helper_mftc0_ebase(CPUMIPSState *env)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- return other->CP0_EBase;
-}
-
-void helper_mtc0_ebase(CPUMIPSState *env, target_ulong arg1)
-{
- target_ulong mask = 0x3FFFF000 | env->CP0_EBaseWG_rw_bitmask;
- if (arg1 & env->CP0_EBaseWG_rw_bitmask) {
- mask |= ~0x3FFFFFFF;
- }
- env->CP0_EBase = (env->CP0_EBase & ~mask) | (arg1 & mask);
-}
-
-void helper_mttc0_ebase(CPUMIPSState *env, target_ulong arg1)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
- target_ulong mask = 0x3FFFF000 | env->CP0_EBaseWG_rw_bitmask;
- if (arg1 & env->CP0_EBaseWG_rw_bitmask) {
- mask |= ~0x3FFFFFFF;
- }
- other->CP0_EBase = (other->CP0_EBase & ~mask) | (arg1 & mask);
-}
-
-target_ulong helper_mftc0_configx(CPUMIPSState *env, target_ulong idx)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- switch (idx) {
- case 0: return other->CP0_Config0;
- case 1: return other->CP0_Config1;
- case 2: return other->CP0_Config2;
- case 3: return other->CP0_Config3;
- /* 4 and 5 are reserved. */
- case 6: return other->CP0_Config6;
- case 7: return other->CP0_Config7;
- default:
- break;
- }
- return 0;
-}
-
-void helper_mtc0_config0(CPUMIPSState *env, target_ulong arg1)
-{
- env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (arg1 & 0x00000007);
-}
-
-void helper_mtc0_config2(CPUMIPSState *env, target_ulong arg1)
-{
- /* tertiary/secondary caches not implemented */
- env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
-}
-
-void helper_mtc0_config3(CPUMIPSState *env, target_ulong arg1)
-{
- if (env->insn_flags & ASE_MICROMIPS) {
- env->CP0_Config3 = (env->CP0_Config3 & ~(1 << CP0C3_ISA_ON_EXC)) |
- (arg1 & (1 << CP0C3_ISA_ON_EXC));
- }
-}
-
-void helper_mtc0_config4(CPUMIPSState *env, target_ulong arg1)
-{
- env->CP0_Config4 = (env->CP0_Config4 & (~env->CP0_Config4_rw_bitmask)) |
- (arg1 & env->CP0_Config4_rw_bitmask);
-}
-
-void helper_mtc0_config5(CPUMIPSState *env, target_ulong arg1)
-{
- env->CP0_Config5 = (env->CP0_Config5 & (~env->CP0_Config5_rw_bitmask)) |
- (arg1 & env->CP0_Config5_rw_bitmask);
- env->CP0_EntryHi_ASID_mask = (env->CP0_Config5 & (1 << CP0C5_MI)) ?
- 0x0 : (env->CP0_Config4 & (1 << CP0C4_AE)) ? 0x3ff : 0xff;
- compute_hflags(env);
-}
-
-void helper_mtc0_lladdr(CPUMIPSState *env, target_ulong arg1)
-{
- target_long mask = env->CP0_LLAddr_rw_bitmask;
- arg1 = arg1 << env->CP0_LLAddr_shift;
- env->CP0_LLAddr = (env->CP0_LLAddr & ~mask) | (arg1 & mask);
-}
-
-#define MTC0_MAAR_MASK(env) \
- ((0x1ULL << 63) | ((env->PAMask >> 4) & ~0xFFFull) | 0x3)
-
-void helper_mtc0_maar(CPUMIPSState *env, target_ulong arg1)
-{
- env->CP0_MAAR[env->CP0_MAARI] = arg1 & MTC0_MAAR_MASK(env);
-}
-
-void helper_mthc0_maar(CPUMIPSState *env, target_ulong arg1)
-{
- env->CP0_MAAR[env->CP0_MAARI] =
- (((uint64_t) arg1 << 32) & MTC0_MAAR_MASK(env)) |
- (env->CP0_MAAR[env->CP0_MAARI] & 0x00000000ffffffffULL);
-}
-
-void helper_mtc0_maari(CPUMIPSState *env, target_ulong arg1)
-{
- int index = arg1 & 0x3f;
- if (index == 0x3f) {
- /*
- * Software may write all ones to INDEX to determine the
- * maximum value supported.
- */
- env->CP0_MAARI = MIPS_MAAR_MAX - 1;
- } else if (index < MIPS_MAAR_MAX) {
- env->CP0_MAARI = index;
- }
- /*
- * Other than the all ones, if the value written is not supported,
- * then INDEX is unchanged from its previous value.
- */
-}
-
-void helper_mtc0_watchlo(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
-{
- /*
- * Watch exceptions for instructions, data loads, data stores
- * not implemented.
- */
- env->CP0_WatchLo[sel] = (arg1 & ~0x7);
-}
-
-void helper_mtc0_watchhi(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
-{
- uint64_t mask = 0x40000FF8 | (env->CP0_EntryHi_ASID_mask << CP0WH_ASID);
- uint64_t m_bit = env->CP0_WatchHi[sel] & (1 << CP0WH_M); /* read-only */
- if ((env->CP0_Config5 >> CP0C5_MI) & 1) {
- mask |= 0xFFFFFFFF00000000ULL; /* MMID */
- }
- env->CP0_WatchHi[sel] = m_bit | (arg1 & mask);
- env->CP0_WatchHi[sel] &= ~(env->CP0_WatchHi[sel] & arg1 & 0x7);
-}
-
-void helper_mthc0_watchhi(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
-{
- env->CP0_WatchHi[sel] = ((uint64_t) (arg1) << 32) |
- (env->CP0_WatchHi[sel] & 0x00000000ffffffffULL);
-}
-
-void helper_mtc0_xcontext(CPUMIPSState *env, target_ulong arg1)
-{
- target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
- env->CP0_XContext = (env->CP0_XContext & mask) | (arg1 & ~mask);
-}
-
-void helper_mtc0_framemask(CPUMIPSState *env, target_ulong arg1)
-{
- env->CP0_Framemask = arg1; /* XXX */
-}
-
-void helper_mtc0_debug(CPUMIPSState *env, target_ulong arg1)
-{
- env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (arg1 & 0x13300120);
- if (arg1 & (1 << CP0DB_DM)) {
- env->hflags |= MIPS_HFLAG_DM;
- } else {
- env->hflags &= ~MIPS_HFLAG_DM;
- }
-}
-
-void helper_mttc0_debug(CPUMIPSState *env, target_ulong arg1)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- uint32_t val = arg1 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- /* XXX: Might be wrong, check with EJTAG spec. */
- if (other_tc == other->current_tc) {
- other->active_tc.CP0_Debug_tcstatus = val;
- } else {
- other->tcs[other_tc].CP0_Debug_tcstatus = val;
- }
- other->CP0_Debug = (other->CP0_Debug &
- ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
- (arg1 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
-}
-
-void helper_mtc0_performance0(CPUMIPSState *env, target_ulong arg1)
-{
- env->CP0_Performance0 = arg1 & 0x000007ff;
-}
-
-void helper_mtc0_errctl(CPUMIPSState *env, target_ulong arg1)
-{
- int32_t wst = arg1 & (1 << CP0EC_WST);
- int32_t spr = arg1 & (1 << CP0EC_SPR);
- int32_t itc = env->itc_tag ? (arg1 & (1 << CP0EC_ITC)) : 0;
-
- env->CP0_ErrCtl = wst | spr | itc;
-
- if (itc && !wst && !spr) {
- env->hflags |= MIPS_HFLAG_ITC_CACHE;
- } else {
- env->hflags &= ~MIPS_HFLAG_ITC_CACHE;
- }
-}
-
-void helper_mtc0_taglo(CPUMIPSState *env, target_ulong arg1)
-{
- if (env->hflags & MIPS_HFLAG_ITC_CACHE) {
- /*
- * If CACHE instruction is configured for ITC tags then make all
- * CP0.TagLo bits writable. The actual write to ITC Configuration
- * Tag will take care of the read-only bits.
- */
- env->CP0_TagLo = arg1;
- } else {
- env->CP0_TagLo = arg1 & 0xFFFFFCF6;
- }
-}
-
-void helper_mtc0_datalo(CPUMIPSState *env, target_ulong arg1)
-{
- env->CP0_DataLo = arg1; /* XXX */
-}
-
-void helper_mtc0_taghi(CPUMIPSState *env, target_ulong arg1)
-{
- env->CP0_TagHi = arg1; /* XXX */
-}
-
-void helper_mtc0_datahi(CPUMIPSState *env, target_ulong arg1)
-{
- env->CP0_DataHi = arg1; /* XXX */
-}
-
-/* MIPS MT functions */
-target_ulong helper_mftgpr(CPUMIPSState *env, uint32_t sel)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- return other->active_tc.gpr[sel];
- } else {
- return other->tcs[other_tc].gpr[sel];
- }
-}
-
-target_ulong helper_mftlo(CPUMIPSState *env, uint32_t sel)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- return other->active_tc.LO[sel];
- } else {
- return other->tcs[other_tc].LO[sel];
- }
-}
-
-target_ulong helper_mfthi(CPUMIPSState *env, uint32_t sel)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- return other->active_tc.HI[sel];
- } else {
- return other->tcs[other_tc].HI[sel];
- }
-}
-
-target_ulong helper_mftacx(CPUMIPSState *env, uint32_t sel)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- return other->active_tc.ACX[sel];
- } else {
- return other->tcs[other_tc].ACX[sel];
- }
-}
-
-target_ulong helper_mftdsp(CPUMIPSState *env)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- return other->active_tc.DSPControl;
- } else {
- return other->tcs[other_tc].DSPControl;
- }
-}
-
-void helper_mttgpr(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- other->active_tc.gpr[sel] = arg1;
- } else {
- other->tcs[other_tc].gpr[sel] = arg1;
- }
-}
-
-void helper_mttlo(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- other->active_tc.LO[sel] = arg1;
- } else {
- other->tcs[other_tc].LO[sel] = arg1;
- }
-}
-
-void helper_mtthi(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- other->active_tc.HI[sel] = arg1;
- } else {
- other->tcs[other_tc].HI[sel] = arg1;
- }
-}
-
-void helper_mttacx(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- other->active_tc.ACX[sel] = arg1;
- } else {
- other->tcs[other_tc].ACX[sel] = arg1;
- }
-}
-
-void helper_mttdsp(CPUMIPSState *env, target_ulong arg1)
-{
- int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
- CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-
- if (other_tc == other->current_tc) {
- other->active_tc.DSPControl = arg1;
- } else {
- other->tcs[other_tc].DSPControl = arg1;
- }
-}
-
-/* MIPS MT functions */
-target_ulong helper_dmt(void)
-{
- /* TODO */
- return 0;
-}
-
-target_ulong helper_emt(void)
-{
- /* TODO */
- return 0;
-}
-
-target_ulong helper_dvpe(CPUMIPSState *env)
-{
- CPUState *other_cs = first_cpu;
- target_ulong prev = env->mvp->CP0_MVPControl;
-
- CPU_FOREACH(other_cs) {
- MIPSCPU *other_cpu = MIPS_CPU(other_cs);
- /* Turn off all VPEs except the one executing the dvpe. */
- if (&other_cpu->env != env) {
- other_cpu->env.mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP);
- mips_vpe_sleep(other_cpu);
- }
- }
- return prev;
-}
-
-target_ulong helper_evpe(CPUMIPSState *env)
-{
- CPUState *other_cs = first_cpu;
- target_ulong prev = env->mvp->CP0_MVPControl;
-
- CPU_FOREACH(other_cs) {
- MIPSCPU *other_cpu = MIPS_CPU(other_cs);
-
- if (&other_cpu->env != env
- /* If the VPE is WFI, don't disturb its sleep. */
- && !mips_vpe_is_wfi(other_cpu)) {
- /* Enable the VPE. */
- other_cpu->env.mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
- mips_vpe_wake(other_cpu); /* And wake it up. */
- }
- }
- return prev;
-}
-
-/* R6 Multi-threading */
-target_ulong helper_dvp(CPUMIPSState *env)
-{
- CPUState *other_cs = first_cpu;
- target_ulong prev = env->CP0_VPControl;
-
- if (!((env->CP0_VPControl >> CP0VPCtl_DIS) & 1)) {
- CPU_FOREACH(other_cs) {
- MIPSCPU *other_cpu = MIPS_CPU(other_cs);
- /* Turn off all VPs except the one executing the dvp. */
- if (&other_cpu->env != env) {
- mips_vpe_sleep(other_cpu);
- }
- }
- env->CP0_VPControl |= (1 << CP0VPCtl_DIS);
- }
- return prev;
-}
-
-target_ulong helper_evp(CPUMIPSState *env)
-{
- CPUState *other_cs = first_cpu;
- target_ulong prev = env->CP0_VPControl;
-
- if ((env->CP0_VPControl >> CP0VPCtl_DIS) & 1) {
- CPU_FOREACH(other_cs) {
- MIPSCPU *other_cpu = MIPS_CPU(other_cs);
- if ((&other_cpu->env != env) && !mips_vp_is_wfi(other_cpu)) {
- /*
- * If the VP is WFI, don't disturb its sleep.
- * Otherwise, wake it up.
- */
- mips_vpe_wake(other_cpu);
- }
- }
- env->CP0_VPControl &= ~(1 << CP0VPCtl_DIS);
- }
- return prev;
-}
+++ /dev/null
-/*
- * Loongson CSR instructions translation routines
- *
- * Copyright (c) 2023 Jiaxun Yang <jiaxun.yang@flygoat.com>
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-
-#define GET_MEMTXATTRS(cas) \
- ((MemTxAttrs){.requester_id = env_cpu(cas)->cpu_index})
-
-uint64_t helper_lcsr_rdcsr(CPUMIPSState *env, target_ulong r_addr)
-{
- return address_space_ldl(&env->iocsr.as, r_addr,
- GET_MEMTXATTRS(env), NULL);
-}
-
-uint64_t helper_lcsr_drdcsr(CPUMIPSState *env, target_ulong r_addr)
-{
- return address_space_ldq(&env->iocsr.as, r_addr,
- GET_MEMTXATTRS(env), NULL);
-}
-
-void helper_lcsr_wrcsr(CPUMIPSState *env, target_ulong w_addr,
- target_ulong val)
-{
- address_space_stl(&env->iocsr.as, w_addr,
- val, GET_MEMTXATTRS(env), NULL);
-}
-
-void helper_lcsr_dwrcsr(CPUMIPSState *env, target_ulong w_addr,
- target_ulong val)
-{
- address_space_stq(&env->iocsr.as, w_addr,
- val, GET_MEMTXATTRS(env), NULL);
-}
+++ /dev/null
-mips_system_ss.add(files(
- 'cp0_helper.c',
- 'special_helper.c',
- 'tlb_helper.c',
-))
-mips_system_ss.add(when: ['CONFIG_SEMIHOSTING'],
- if_true: files('mips-semi.c'),
- if_false: files('semihosting-stub.c')
-)
-mips_system_ss.add(when: 'TARGET_MIPS64', if_true: files(
- 'lcsr_helper.c',
-))
+++ /dev/null
-/*
- * Unified Hosting Interface syscalls.
- *
- * Copyright (c) 2015 Imagination Technologies
- *
- * 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.1 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 "qemu/log.h"
-#include "gdbstub/syscalls.h"
-#include "gdbstub/helpers.h"
-#include "semihosting/uaccess.h"
-#include "semihosting/semihost.h"
-#include "semihosting/console.h"
-#include "semihosting/syscalls.h"
-#include "internal.h"
-
-typedef enum UHIOp {
- UHI_exit = 1,
- UHI_open = 2,
- UHI_close = 3,
- UHI_read = 4,
- UHI_write = 5,
- UHI_lseek = 6,
- UHI_unlink = 7,
- UHI_fstat = 8,
- UHI_argc = 9,
- UHI_argnlen = 10,
- UHI_argn = 11,
- UHI_plog = 13,
- UHI_assert = 14,
- UHI_pread = 19,
- UHI_pwrite = 20,
- UHI_link = 22
-} UHIOp;
-
-typedef struct UHIStat {
- int16_t uhi_st_dev;
- uint16_t uhi_st_ino;
- uint32_t uhi_st_mode;
- uint16_t uhi_st_nlink;
- uint16_t uhi_st_uid;
- uint16_t uhi_st_gid;
- int16_t uhi_st_rdev;
- uint64_t uhi_st_size;
- uint64_t uhi_st_atime;
- uint64_t uhi_st_spare1;
- uint64_t uhi_st_mtime;
- uint64_t uhi_st_spare2;
- uint64_t uhi_st_ctime;
- uint64_t uhi_st_spare3;
- uint64_t uhi_st_blksize;
- uint64_t uhi_st_blocks;
- uint64_t uhi_st_spare4[2];
-} UHIStat;
-
-enum UHIOpenFlags {
- UHIOpen_RDONLY = 0x0,
- UHIOpen_WRONLY = 0x1,
- UHIOpen_RDWR = 0x2,
- UHIOpen_APPEND = 0x8,
- UHIOpen_CREAT = 0x200,
- UHIOpen_TRUNC = 0x400,
- UHIOpen_EXCL = 0x800
-};
-
-enum UHIErrno {
- UHI_EACCESS = 13,
- UHI_EAGAIN = 11,
- UHI_EBADF = 9,
- UHI_EBADMSG = 77,
- UHI_EBUSY = 16,
- UHI_ECONNRESET = 104,
- UHI_EEXIST = 17,
- UHI_EFBIG = 27,
- UHI_EINTR = 4,
- UHI_EINVAL = 22,
- UHI_EIO = 5,
- UHI_EISDIR = 21,
- UHI_ELOOP = 92,
- UHI_EMFILE = 24,
- UHI_EMLINK = 31,
- UHI_ENAMETOOLONG = 91,
- UHI_ENETDOWN = 115,
- UHI_ENETUNREACH = 114,
- UHI_ENFILE = 23,
- UHI_ENOBUFS = 105,
- UHI_ENOENT = 2,
- UHI_ENOMEM = 12,
- UHI_ENOSPC = 28,
- UHI_ENOSR = 63,
- UHI_ENOTCONN = 128,
- UHI_ENOTDIR = 20,
- UHI_ENXIO = 6,
- UHI_EOVERFLOW = 139,
- UHI_EPERM = 1,
- UHI_EPIPE = 32,
- UHI_ERANGE = 34,
- UHI_EROFS = 30,
- UHI_ESPIPE = 29,
- UHI_ETIMEDOUT = 116,
- UHI_ETXTBSY = 26,
- UHI_EWOULDBLOCK = 11,
- UHI_EXDEV = 18,
-};
-
-static void report_fault(CPUMIPSState *env)
-{
- int op = env->active_tc.gpr[25];
- error_report("Fault during UHI operation %d", op);
- abort();
-}
-
-static void uhi_cb(CPUState *cs, uint64_t ret, int err)
-{
- CPUMIPSState *env = cpu_env(cs);
-
-#define E(N) case E##N: err = UHI_E##N; break
-
- switch (err) {
- case 0:
- break;
- E(PERM);
- E(NOENT);
- E(INTR);
- E(BADF);
- E(BUSY);
- E(EXIST);
- E(NOTDIR);
- E(ISDIR);
- E(INVAL);
- E(NFILE);
- E(MFILE);
- E(FBIG);
- E(NOSPC);
- E(SPIPE);
- E(ROFS);
- E(NAMETOOLONG);
- default:
- err = UHI_EINVAL;
- break;
- case EFAULT:
- report_fault(env);
- }
-
-#undef E
-
- env->active_tc.gpr[2] = ret;
- env->active_tc.gpr[3] = err;
-}
-
-static void uhi_fstat_cb(CPUState *cs, uint64_t ret, int err)
-{
- QEMU_BUILD_BUG_ON(sizeof(UHIStat) < sizeof(struct gdb_stat));
-
- if (!err) {
- CPUMIPSState *env = cpu_env(cs);
- target_ulong addr = env->active_tc.gpr[5];
- UHIStat *dst = lock_user(VERIFY_WRITE, addr, sizeof(UHIStat), 1);
- struct gdb_stat s;
-
- if (!dst) {
- report_fault(env);
- }
-
- memcpy(&s, dst, sizeof(struct gdb_stat));
- memset(dst, 0, sizeof(UHIStat));
-
- dst->uhi_st_dev = tswap16(be32_to_cpu(s.gdb_st_dev));
- dst->uhi_st_ino = tswap16(be32_to_cpu(s.gdb_st_ino));
- dst->uhi_st_mode = tswap32(be32_to_cpu(s.gdb_st_mode));
- dst->uhi_st_nlink = tswap16(be32_to_cpu(s.gdb_st_nlink));
- dst->uhi_st_uid = tswap16(be32_to_cpu(s.gdb_st_uid));
- dst->uhi_st_gid = tswap16(be32_to_cpu(s.gdb_st_gid));
- dst->uhi_st_rdev = tswap16(be32_to_cpu(s.gdb_st_rdev));
- dst->uhi_st_size = tswap64(be64_to_cpu(s.gdb_st_size));
- dst->uhi_st_atime = tswap64(be32_to_cpu(s.gdb_st_atime));
- dst->uhi_st_mtime = tswap64(be32_to_cpu(s.gdb_st_mtime));
- dst->uhi_st_ctime = tswap64(be32_to_cpu(s.gdb_st_ctime));
- dst->uhi_st_blksize = tswap64(be64_to_cpu(s.gdb_st_blksize));
- dst->uhi_st_blocks = tswap64(be64_to_cpu(s.gdb_st_blocks));
-
- unlock_user(dst, addr, sizeof(UHIStat));
- }
-
- uhi_cb(cs, ret, err);
-}
-
-void mips_semihosting(CPUMIPSState *env)
-{
- CPUState *cs = env_cpu(env);
- target_ulong *gpr = env->active_tc.gpr;
- const UHIOp op = gpr[25];
- char *p;
-
- switch (op) {
- case UHI_exit:
- gdb_exit(gpr[4]);
- exit(gpr[4]);
-
- case UHI_open:
- {
- target_ulong fname = gpr[4];
- int ret = -1;
-
- p = lock_user_string(fname);
- if (!p) {
- report_fault(env);
- }
- if (!strcmp("/dev/stdin", p)) {
- ret = 0;
- } else if (!strcmp("/dev/stdout", p)) {
- ret = 1;
- } else if (!strcmp("/dev/stderr", p)) {
- ret = 2;
- }
- unlock_user(p, fname, 0);
-
- /* FIXME: reusing a guest fd doesn't seem correct. */
- if (ret >= 0) {
- gpr[2] = ret;
- break;
- }
-
- semihost_sys_open(cs, uhi_cb, fname, 0, gpr[5], gpr[6]);
- }
- break;
-
- case UHI_close:
- semihost_sys_close(cs, uhi_cb, gpr[4]);
- break;
- case UHI_read:
- semihost_sys_read(cs, uhi_cb, gpr[4], gpr[5], gpr[6]);
- break;
- case UHI_write:
- semihost_sys_write(cs, uhi_cb, gpr[4], gpr[5], gpr[6]);
- break;
- case UHI_lseek:
- semihost_sys_lseek(cs, uhi_cb, gpr[4], gpr[5], gpr[6]);
- break;
- case UHI_unlink:
- semihost_sys_remove(cs, uhi_cb, gpr[4], 0);
- break;
- case UHI_fstat:
- semihost_sys_fstat(cs, uhi_fstat_cb, gpr[4], gpr[5]);
- break;
-
- case UHI_argc:
- gpr[2] = semihosting_get_argc();
- break;
- case UHI_argnlen:
- {
- const char *s = semihosting_get_arg(gpr[4]);
- gpr[2] = s ? strlen(s) : -1;
- }
- break;
- case UHI_argn:
- {
- const char *s = semihosting_get_arg(gpr[4]);
- target_ulong addr;
- size_t len;
-
- if (!s) {
- gpr[2] = -1;
- break;
- }
- len = strlen(s) + 1;
- addr = gpr[5];
- p = lock_user(VERIFY_WRITE, addr, len, 0);
- if (!p) {
- report_fault(env);
- }
- memcpy(p, s, len);
- unlock_user(p, addr, len);
- gpr[2] = 0;
- }
- break;
-
- case UHI_plog:
- {
- target_ulong addr = gpr[4];
- ssize_t len = target_strlen(addr);
- GString *str;
- char *pct_d;
-
- if (len < 0) {
- report_fault(env);
- }
- p = lock_user(VERIFY_READ, addr, len, 1);
- if (!p) {
- report_fault(env);
- }
-
- pct_d = strstr(p, "%d");
- if (!pct_d) {
- unlock_user(p, addr, 0);
- semihost_sys_write(cs, uhi_cb, 2, addr, len);
- break;
- }
-
- str = g_string_new_len(p, pct_d - p);
- g_string_append_printf(str, "%d%s", (int)gpr[5], pct_d + 2);
- unlock_user(p, addr, 0);
-
- /*
- * When we're using gdb, we need a guest address, so
- * drop the string onto the stack below the stack pointer.
- */
- if (use_gdb_syscalls()) {
- addr = gpr[29] - str->len;
- p = lock_user(VERIFY_WRITE, addr, str->len, 0);
- if (!p) {
- report_fault(env);
- }
- memcpy(p, str->str, str->len);
- unlock_user(p, addr, str->len);
- semihost_sys_write(cs, uhi_cb, 2, addr, str->len);
- } else {
- gpr[2] = qemu_semihosting_console_write(str->str, str->len);
- }
- g_string_free(str, true);
- }
- break;
-
- case UHI_assert:
- {
- const char *msg, *file;
-
- msg = lock_user_string(gpr[4]);
- if (!msg) {
- msg = "<EFAULT>";
- }
- file = lock_user_string(gpr[5]);
- if (!file) {
- file = "<EFAULT>";
- }
-
- error_report("UHI assertion \"%s\": file \"%s\", line %d",
- msg, file, (int)gpr[6]);
- abort();
- }
-
- default:
- error_report("Unknown UHI operation %d", op);
- abort();
- }
- return;
-}
+++ /dev/null
-/*
- * MIPS semihosting stub
- *
- * SPDX-FileContributor: Philippe Mathieu-Daudé <philmd@linaro.org>
- * SPDX-FileCopyrightText: 2024 Linaro Ltd.
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-
-#include "qemu/osdep.h"
-#include "internal.h"
-
-void mips_semihosting(CPUMIPSState *env)
-{
- g_assert_not_reached();
-}
+++ /dev/null
-/*
- * QEMU MIPS emulation: Special opcode helpers
- *
- * Copyright (c) 2004-2005 Jocelyn Mayer
- *
- * 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.1 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 "qemu/log.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-#include "exec/exec-all.h"
-#include "internal.h"
-
-/* Specials */
-target_ulong helper_di(CPUMIPSState *env)
-{
- target_ulong t0 = env->CP0_Status;
-
- env->CP0_Status = t0 & ~(1 << CP0St_IE);
- return t0;
-}
-
-target_ulong helper_ei(CPUMIPSState *env)
-{
- target_ulong t0 = env->CP0_Status;
-
- env->CP0_Status = t0 | (1 << CP0St_IE);
- return t0;
-}
-
-static void debug_pre_eret(CPUMIPSState *env)
-{
- if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
- qemu_log("ERET: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx,
- env->active_tc.PC, env->CP0_EPC);
- if (env->CP0_Status & (1 << CP0St_ERL)) {
- qemu_log(" ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC);
- }
- if (env->hflags & MIPS_HFLAG_DM) {
- qemu_log(" DEPC " TARGET_FMT_lx, env->CP0_DEPC);
- }
- qemu_log("\n");
- }
-}
-
-static void debug_post_eret(CPUMIPSState *env)
-{
- if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
- qemu_log(" => PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx,
- env->active_tc.PC, env->CP0_EPC);
- if (env->CP0_Status & (1 << CP0St_ERL)) {
- qemu_log(" ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC);
- }
- if (env->hflags & MIPS_HFLAG_DM) {
- qemu_log(" DEPC " TARGET_FMT_lx, env->CP0_DEPC);
- }
- switch (mips_env_mmu_index(env)) {
- case 3:
- qemu_log(", ERL\n");
- break;
- case MIPS_HFLAG_UM:
- qemu_log(", UM\n");
- break;
- case MIPS_HFLAG_SM:
- qemu_log(", SM\n");
- break;
- case MIPS_HFLAG_KM:
- qemu_log("\n");
- break;
- default:
- cpu_abort(env_cpu(env), "Invalid MMU mode!\n");
- break;
- }
- }
-}
-
-bool mips_io_recompile_replay_branch(CPUState *cs, const TranslationBlock *tb)
-{
- CPUMIPSState *env = cpu_env(cs);
-
- if ((env->hflags & MIPS_HFLAG_BMASK) != 0
- && !tcg_cflags_has(cs, CF_PCREL) && env->active_tc.PC != tb->pc) {
- env->active_tc.PC -= (env->hflags & MIPS_HFLAG_B16 ? 2 : 4);
- env->hflags &= ~MIPS_HFLAG_BMASK;
- return true;
- }
- return false;
-}
-
-static inline void exception_return(CPUMIPSState *env)
-{
- debug_pre_eret(env);
- if (env->CP0_Status & (1 << CP0St_ERL)) {
- mips_env_set_pc(env, env->CP0_ErrorEPC);
- env->CP0_Status &= ~(1 << CP0St_ERL);
- } else {
- mips_env_set_pc(env, env->CP0_EPC);
- env->CP0_Status &= ~(1 << CP0St_EXL);
- }
- compute_hflags(env);
- debug_post_eret(env);
-}
-
-void helper_eret(CPUMIPSState *env)
-{
- exception_return(env);
- env->CP0_LLAddr = 1;
- env->lladdr = 1;
-}
-
-void helper_eretnc(CPUMIPSState *env)
-{
- exception_return(env);
-}
-
-void helper_deret(CPUMIPSState *env)
-{
- debug_pre_eret(env);
-
- env->hflags &= ~MIPS_HFLAG_DM;
- compute_hflags(env);
-
- mips_env_set_pc(env, env->CP0_DEPC);
-
- debug_post_eret(env);
-}
-
-void helper_cache(CPUMIPSState *env, target_ulong addr, uint32_t op)
-{
- static const char *const type_name[] = {
- "Primary Instruction",
- "Primary Data or Unified Primary",
- "Tertiary",
- "Secondary"
- };
- uint32_t cache_type = extract32(op, 0, 2);
- uint32_t cache_operation = extract32(op, 2, 3);
- target_ulong index = addr & 0x1fffffff;
-
- switch (cache_operation) {
- case 0b010: /* Index Store Tag */
- memory_region_dispatch_write(env->itc_tag, index, env->CP0_TagLo,
- MO_64, MEMTXATTRS_UNSPECIFIED);
- break;
- case 0b001: /* Index Load Tag */
- memory_region_dispatch_read(env->itc_tag, index, &env->CP0_TagLo,
- MO_64, MEMTXATTRS_UNSPECIFIED);
- break;
- case 0b000: /* Index Invalidate */
- case 0b100: /* Hit Invalidate */
- case 0b110: /* Hit Writeback */
- /* no-op */
- break;
- default:
- qemu_log_mask(LOG_UNIMP, "cache operation:%u (type: %s cache)\n",
- cache_operation, type_name[cache_type]);
- break;
- }
-}
+++ /dev/null
-/*
- * MIPS TLB (Translation lookaside buffer) helpers.
- *
- * Copyright (c) 2004-2005 Jocelyn Mayer
- *
- * 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.1 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 "qemu/bitops.h"
-
-#include "cpu.h"
-#include "internal.h"
-#include "exec/exec-all.h"
-#include "exec/page-protection.h"
-#include "exec/cpu_ldst.h"
-#include "exec/log.h"
-#include "exec/helper-proto.h"
-
-/* TLB management */
-static void r4k_mips_tlb_flush_extra(CPUMIPSState *env, int first)
-{
- /* Discard entries from env->tlb[first] onwards. */
- while (env->tlb->tlb_in_use > first) {
- r4k_invalidate_tlb(env, --env->tlb->tlb_in_use, 0);
- }
-}
-
-static inline uint64_t get_tlb_pfn_from_entrylo(uint64_t entrylo)
-{
-#if defined(TARGET_MIPS64)
- return extract64(entrylo, 6, 54);
-#else
- return extract64(entrylo, 6, 24) | /* PFN */
- (extract64(entrylo, 32, 32) << 24); /* PFNX */
-#endif
-}
-
-static void r4k_fill_tlb(CPUMIPSState *env, int idx)
-{
- r4k_tlb_t *tlb;
- uint64_t mask = env->CP0_PageMask >> (TARGET_PAGE_BITS + 1);
-
- /* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */
- tlb = &env->tlb->mmu.r4k.tlb[idx];
- if (env->CP0_EntryHi & (1 << CP0EnHi_EHINV)) {
- tlb->EHINV = 1;
- return;
- }
- tlb->EHINV = 0;
- tlb->VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1);
-#if defined(TARGET_MIPS64)
- tlb->VPN &= env->SEGMask;
-#endif
- tlb->ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
- tlb->MMID = env->CP0_MemoryMapID;
- tlb->PageMask = env->CP0_PageMask;
- tlb->G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1;
- tlb->V0 = (env->CP0_EntryLo0 & 2) != 0;
- tlb->D0 = (env->CP0_EntryLo0 & 4) != 0;
- tlb->C0 = (env->CP0_EntryLo0 >> 3) & 0x7;
- tlb->XI0 = (env->CP0_EntryLo0 >> CP0EnLo_XI) & 1;
- tlb->RI0 = (env->CP0_EntryLo0 >> CP0EnLo_RI) & 1;
- tlb->PFN[0] = (get_tlb_pfn_from_entrylo(env->CP0_EntryLo0) & ~mask) << 12;
- tlb->V1 = (env->CP0_EntryLo1 & 2) != 0;
- tlb->D1 = (env->CP0_EntryLo1 & 4) != 0;
- tlb->C1 = (env->CP0_EntryLo1 >> 3) & 0x7;
- tlb->XI1 = (env->CP0_EntryLo1 >> CP0EnLo_XI) & 1;
- tlb->RI1 = (env->CP0_EntryLo1 >> CP0EnLo_RI) & 1;
- tlb->PFN[1] = (get_tlb_pfn_from_entrylo(env->CP0_EntryLo1) & ~mask) << 12;
-}
-
-static void r4k_helper_tlbinv(CPUMIPSState *env)
-{
- bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1);
- uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
- uint32_t MMID = env->CP0_MemoryMapID;
- uint32_t tlb_mmid;
- r4k_tlb_t *tlb;
- int idx;
-
- MMID = mi ? MMID : (uint32_t) ASID;
- for (idx = 0; idx < env->tlb->nb_tlb; idx++) {
- tlb = &env->tlb->mmu.r4k.tlb[idx];
- tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID;
- if (!tlb->G && tlb_mmid == MMID) {
- tlb->EHINV = 1;
- }
- }
- cpu_mips_tlb_flush(env);
-}
-
-static void r4k_helper_tlbinvf(CPUMIPSState *env)
-{
- int idx;
-
- for (idx = 0; idx < env->tlb->nb_tlb; idx++) {
- env->tlb->mmu.r4k.tlb[idx].EHINV = 1;
- }
- cpu_mips_tlb_flush(env);
-}
-
-static void r4k_helper_tlbwi(CPUMIPSState *env)
-{
- bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1);
- target_ulong VPN;
- uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
- uint32_t MMID = env->CP0_MemoryMapID;
- uint32_t tlb_mmid;
- bool EHINV, G, V0, D0, V1, D1, XI0, XI1, RI0, RI1;
- r4k_tlb_t *tlb;
- int idx;
-
- MMID = mi ? MMID : (uint32_t) ASID;
-
- idx = (env->CP0_Index & ~0x80000000) % env->tlb->nb_tlb;
- tlb = &env->tlb->mmu.r4k.tlb[idx];
- VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1);
-#if defined(TARGET_MIPS64)
- VPN &= env->SEGMask;
-#endif
- EHINV = (env->CP0_EntryHi & (1 << CP0EnHi_EHINV)) != 0;
- G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1;
- V0 = (env->CP0_EntryLo0 & 2) != 0;
- D0 = (env->CP0_EntryLo0 & 4) != 0;
- XI0 = (env->CP0_EntryLo0 >> CP0EnLo_XI) &1;
- RI0 = (env->CP0_EntryLo0 >> CP0EnLo_RI) &1;
- V1 = (env->CP0_EntryLo1 & 2) != 0;
- D1 = (env->CP0_EntryLo1 & 4) != 0;
- XI1 = (env->CP0_EntryLo1 >> CP0EnLo_XI) &1;
- RI1 = (env->CP0_EntryLo1 >> CP0EnLo_RI) &1;
-
- tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID;
- /*
- * Discard cached TLB entries, unless tlbwi is just upgrading access
- * permissions on the current entry.
- */
- if (tlb->VPN != VPN || tlb_mmid != MMID || tlb->G != G ||
- (!tlb->EHINV && EHINV) ||
- (tlb->V0 && !V0) || (tlb->D0 && !D0) ||
- (!tlb->XI0 && XI0) || (!tlb->RI0 && RI0) ||
- (tlb->V1 && !V1) || (tlb->D1 && !D1) ||
- (!tlb->XI1 && XI1) || (!tlb->RI1 && RI1)) {
- r4k_mips_tlb_flush_extra(env, env->tlb->nb_tlb);
- }
-
- r4k_invalidate_tlb(env, idx, 0);
- r4k_fill_tlb(env, idx);
-}
-
-static void r4k_helper_tlbwr(CPUMIPSState *env)
-{
- int r = cpu_mips_get_random(env);
-
- r4k_invalidate_tlb(env, r, 1);
- r4k_fill_tlb(env, r);
-}
-
-static void r4k_helper_tlbp(CPUMIPSState *env)
-{
- bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1);
- r4k_tlb_t *tlb;
- target_ulong mask;
- target_ulong tag;
- target_ulong VPN;
- uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
- uint32_t MMID = env->CP0_MemoryMapID;
- uint32_t tlb_mmid;
- int i;
-
- MMID = mi ? MMID : (uint32_t) ASID;
- for (i = 0; i < env->tlb->nb_tlb; i++) {
- tlb = &env->tlb->mmu.r4k.tlb[i];
- /* 1k pages are not supported. */
- mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
- tag = env->CP0_EntryHi & ~mask;
- VPN = tlb->VPN & ~mask;
-#if defined(TARGET_MIPS64)
- tag &= env->SEGMask;
-#endif
- tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID;
- /* Check ASID/MMID, virtual page number & size */
- if ((tlb->G == 1 || tlb_mmid == MMID) && VPN == tag && !tlb->EHINV) {
- /* TLB match */
- env->CP0_Index = i;
- break;
- }
- }
- if (i == env->tlb->nb_tlb) {
- /* No match. Discard any shadow entries, if any of them match. */
- for (i = env->tlb->nb_tlb; i < env->tlb->tlb_in_use; i++) {
- tlb = &env->tlb->mmu.r4k.tlb[i];
- /* 1k pages are not supported. */
- mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
- tag = env->CP0_EntryHi & ~mask;
- VPN = tlb->VPN & ~mask;
-#if defined(TARGET_MIPS64)
- tag &= env->SEGMask;
-#endif
- tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID;
- /* Check ASID/MMID, virtual page number & size */
- if ((tlb->G == 1 || tlb_mmid == MMID) && VPN == tag) {
- r4k_mips_tlb_flush_extra(env, i);
- break;
- }
- }
-
- env->CP0_Index |= 0x80000000;
- }
-}
-
-static inline uint64_t get_entrylo_pfn_from_tlb(uint64_t tlb_pfn)
-{
-#if defined(TARGET_MIPS64)
- return tlb_pfn << 6;
-#else
- return (extract64(tlb_pfn, 0, 24) << 6) | /* PFN */
- (extract64(tlb_pfn, 24, 32) << 32); /* PFNX */
-#endif
-}
-
-static void r4k_helper_tlbr(CPUMIPSState *env)
-{
- bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1);
- uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
- uint32_t MMID = env->CP0_MemoryMapID;
- uint32_t tlb_mmid;
- r4k_tlb_t *tlb;
- int idx;
-
- MMID = mi ? MMID : (uint32_t) ASID;
- idx = (env->CP0_Index & ~0x80000000) % env->tlb->nb_tlb;
- tlb = &env->tlb->mmu.r4k.tlb[idx];
-
- tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID;
- /* If this will change the current ASID/MMID, flush qemu's TLB. */
- if (MMID != tlb_mmid) {
- cpu_mips_tlb_flush(env);
- }
-
- r4k_mips_tlb_flush_extra(env, env->tlb->nb_tlb);
-
- if (tlb->EHINV) {
- env->CP0_EntryHi = 1 << CP0EnHi_EHINV;
- env->CP0_PageMask = 0;
- env->CP0_EntryLo0 = 0;
- env->CP0_EntryLo1 = 0;
- } else {
- env->CP0_EntryHi = mi ? tlb->VPN : tlb->VPN | tlb->ASID;
- env->CP0_MemoryMapID = tlb->MMID;
- env->CP0_PageMask = tlb->PageMask;
- env->CP0_EntryLo0 = tlb->G | (tlb->V0 << 1) | (tlb->D0 << 2) |
- ((uint64_t)tlb->RI0 << CP0EnLo_RI) |
- ((uint64_t)tlb->XI0 << CP0EnLo_XI) | (tlb->C0 << 3) |
- get_entrylo_pfn_from_tlb(tlb->PFN[0] >> 12);
- env->CP0_EntryLo1 = tlb->G | (tlb->V1 << 1) | (tlb->D1 << 2) |
- ((uint64_t)tlb->RI1 << CP0EnLo_RI) |
- ((uint64_t)tlb->XI1 << CP0EnLo_XI) | (tlb->C1 << 3) |
- get_entrylo_pfn_from_tlb(tlb->PFN[1] >> 12);
- }
-}
-
-void helper_tlbwi(CPUMIPSState *env)
-{
- env->tlb->helper_tlbwi(env);
-}
-
-void helper_tlbwr(CPUMIPSState *env)
-{
- env->tlb->helper_tlbwr(env);
-}
-
-void helper_tlbp(CPUMIPSState *env)
-{
- env->tlb->helper_tlbp(env);
-}
-
-void helper_tlbr(CPUMIPSState *env)
-{
- env->tlb->helper_tlbr(env);
-}
-
-void helper_tlbinv(CPUMIPSState *env)
-{
- env->tlb->helper_tlbinv(env);
-}
-
-void helper_tlbinvf(CPUMIPSState *env)
-{
- env->tlb->helper_tlbinvf(env);
-}
-
-static void global_invalidate_tlb(CPUMIPSState *env,
- uint32_t invMsgVPN2,
- uint8_t invMsgR,
- uint32_t invMsgMMid,
- bool invAll,
- bool invVAMMid,
- bool invMMid,
- bool invVA)
-{
-
- int idx;
- r4k_tlb_t *tlb;
- bool VAMatch;
- bool MMidMatch;
-
- for (idx = 0; idx < env->tlb->nb_tlb; idx++) {
- tlb = &env->tlb->mmu.r4k.tlb[idx];
- VAMatch =
- (((tlb->VPN & ~tlb->PageMask) == (invMsgVPN2 & ~tlb->PageMask))
-#ifdef TARGET_MIPS64
- &&
- (extract64(env->CP0_EntryHi, 62, 2) == invMsgR)
-#endif
- );
- MMidMatch = tlb->MMID == invMsgMMid;
- if ((invAll && (idx > env->CP0_Wired)) ||
- (VAMatch && invVAMMid && (tlb->G || MMidMatch)) ||
- (VAMatch && invVA) ||
- (MMidMatch && !(tlb->G) && invMMid)) {
- tlb->EHINV = 1;
- }
- }
- cpu_mips_tlb_flush(env);
-}
-
-void helper_ginvt(CPUMIPSState *env, target_ulong arg, uint32_t type)
-{
- bool invAll = type == 0;
- bool invVA = type == 1;
- bool invMMid = type == 2;
- bool invVAMMid = type == 3;
- uint32_t invMsgVPN2 = arg & (TARGET_PAGE_MASK << 1);
- uint8_t invMsgR = 0;
- uint32_t invMsgMMid = env->CP0_MemoryMapID;
- CPUState *other_cs = first_cpu;
-
-#ifdef TARGET_MIPS64
- invMsgR = extract64(arg, 62, 2);
-#endif
-
- CPU_FOREACH(other_cs) {
- MIPSCPU *other_cpu = MIPS_CPU(other_cs);
- global_invalidate_tlb(&other_cpu->env, invMsgVPN2, invMsgR, invMsgMMid,
- invAll, invVAMMid, invMMid, invVA);
- }
-}
-
-/* no MMU emulation */
-static int no_mmu_map_address(CPUMIPSState *env, hwaddr *physical, int *prot,
- target_ulong address, MMUAccessType access_type)
-{
- *physical = address;
- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- return TLBRET_MATCH;
-}
-
-/* fixed mapping MMU emulation */
-static int fixed_mmu_map_address(CPUMIPSState *env, hwaddr *physical,
- int *prot, target_ulong address,
- MMUAccessType access_type)
-{
- if (address <= (int32_t)0x7FFFFFFFUL) {
- if (!(env->CP0_Status & (1 << CP0St_ERL))) {
- *physical = address + 0x40000000UL;
- } else {
- *physical = address;
- }
- } else if (address <= (int32_t)0xBFFFFFFFUL) {
- *physical = address & 0x1FFFFFFF;
- } else {
- *physical = address;
- }
-
- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- return TLBRET_MATCH;
-}
-
-/* MIPS32/MIPS64 R4000-style MMU emulation */
-static int r4k_map_address(CPUMIPSState *env, hwaddr *physical, int *prot,
- target_ulong address, MMUAccessType access_type)
-{
- uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
- uint32_t MMID = env->CP0_MemoryMapID;
- bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1);
- uint32_t tlb_mmid;
- int i;
-
- MMID = mi ? MMID : (uint32_t) ASID;
-
- for (i = 0; i < env->tlb->tlb_in_use; i++) {
- r4k_tlb_t *tlb = &env->tlb->mmu.r4k.tlb[i];
- /* 1k pages are not supported. */
- target_ulong mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
- target_ulong tag = address & ~mask;
- target_ulong VPN = tlb->VPN & ~mask;
-#if defined(TARGET_MIPS64)
- tag &= env->SEGMask;
-#endif
-
- /* Check ASID/MMID, virtual page number & size */
- tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID;
- if ((tlb->G == 1 || tlb_mmid == MMID) && VPN == tag && !tlb->EHINV) {
- /* TLB match */
- int n = !!(address & mask & ~(mask >> 1));
- /* Check access rights */
- if (!(n ? tlb->V1 : tlb->V0)) {
- return TLBRET_INVALID;
- }
- if (access_type == MMU_INST_FETCH && (n ? tlb->XI1 : tlb->XI0)) {
- return TLBRET_XI;
- }
- if (access_type == MMU_DATA_LOAD && (n ? tlb->RI1 : tlb->RI0)) {
- return TLBRET_RI;
- }
- if (access_type != MMU_DATA_STORE || (n ? tlb->D1 : tlb->D0)) {
- *physical = tlb->PFN[n] | (address & (mask >> 1));
- *prot = PAGE_READ;
- if (n ? tlb->D1 : tlb->D0) {
- *prot |= PAGE_WRITE;
- }
- if (!(n ? tlb->XI1 : tlb->XI0)) {
- *prot |= PAGE_EXEC;
- }
- return TLBRET_MATCH;
- }
- return TLBRET_DIRTY;
- }
- }
- return TLBRET_NOMATCH;
-}
-
-static void no_mmu_init(CPUMIPSState *env, const mips_def_t *def)
-{
- env->tlb->nb_tlb = 1;
- env->tlb->map_address = &no_mmu_map_address;
-}
-
-static void fixed_mmu_init(CPUMIPSState *env, const mips_def_t *def)
-{
- env->tlb->nb_tlb = 1;
- env->tlb->map_address = &fixed_mmu_map_address;
-}
-
-static void r4k_mmu_init(CPUMIPSState *env, const mips_def_t *def)
-{
- env->tlb->nb_tlb = 1 + ((def->CP0_Config1 >> CP0C1_MMU) & 63);
- env->tlb->map_address = &r4k_map_address;
- env->tlb->helper_tlbwi = r4k_helper_tlbwi;
- env->tlb->helper_tlbwr = r4k_helper_tlbwr;
- env->tlb->helper_tlbp = r4k_helper_tlbp;
- env->tlb->helper_tlbr = r4k_helper_tlbr;
- env->tlb->helper_tlbinv = r4k_helper_tlbinv;
- env->tlb->helper_tlbinvf = r4k_helper_tlbinvf;
-}
-
-void mmu_init(CPUMIPSState *env, const mips_def_t *def)
-{
- env->tlb = g_malloc0(sizeof(CPUMIPSTLBContext));
-
- switch (def->mmu_type) {
- case MMU_TYPE_NONE:
- no_mmu_init(env, def);
- break;
- case MMU_TYPE_R4000:
- r4k_mmu_init(env, def);
- break;
- case MMU_TYPE_FMT:
- fixed_mmu_init(env, def);
- break;
- case MMU_TYPE_R3000:
- case MMU_TYPE_R6000:
- case MMU_TYPE_R8000:
- default:
- cpu_abort(env_cpu(env), "MMU type not supported\n");
- }
-}
-
-void cpu_mips_tlb_flush(CPUMIPSState *env)
-{
- /* Flush qemu's TLB and discard all shadowed entries. */
- tlb_flush(env_cpu(env));
- env->tlb->tlb_in_use = env->tlb->nb_tlb;
-}
-
-static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
- MMUAccessType access_type, int tlb_error)
-{
- CPUState *cs = env_cpu(env);
- int exception = 0, error_code = 0;
-
- if (access_type == MMU_INST_FETCH) {
- error_code |= EXCP_INST_NOTAVAIL;
- }
-
- switch (tlb_error) {
- default:
- case TLBRET_BADADDR:
- /* Reference to kernel address from user mode or supervisor mode */
- /* Reference to supervisor address from user mode */
- if (access_type == MMU_DATA_STORE) {
- exception = EXCP_AdES;
- } else {
- exception = EXCP_AdEL;
- }
- break;
- case TLBRET_NOMATCH:
- /* No TLB match for a mapped address */
- if (access_type == MMU_DATA_STORE) {
- exception = EXCP_TLBS;
- } else {
- exception = EXCP_TLBL;
- }
- error_code |= EXCP_TLB_NOMATCH;
- break;
- case TLBRET_INVALID:
- /* TLB match with no valid bit */
- if (access_type == MMU_DATA_STORE) {
- exception = EXCP_TLBS;
- } else {
- exception = EXCP_TLBL;
- }
- break;
- case TLBRET_DIRTY:
- /* TLB match but 'D' bit is cleared */
- exception = EXCP_LTLBL;
- break;
- case TLBRET_XI:
- /* Execute-Inhibit Exception */
- if (env->CP0_PageGrain & (1 << CP0PG_IEC)) {
- exception = EXCP_TLBXI;
- } else {
- exception = EXCP_TLBL;
- }
- break;
- case TLBRET_RI:
- /* Read-Inhibit Exception */
- if (env->CP0_PageGrain & (1 << CP0PG_IEC)) {
- exception = EXCP_TLBRI;
- } else {
- exception = EXCP_TLBL;
- }
- break;
- }
- /* Raise exception */
- if (!(env->hflags & MIPS_HFLAG_DM)) {
- env->CP0_BadVAddr = address;
- }
- env->CP0_Context = (env->CP0_Context & ~0x007fffff) |
- ((address >> 9) & 0x007ffff0);
- env->CP0_EntryHi = (env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask) |
- (env->CP0_EntryHi & (1 << CP0EnHi_EHINV)) |
- (address & (TARGET_PAGE_MASK << 1));
-#if defined(TARGET_MIPS64)
- env->CP0_EntryHi &= env->SEGMask;
- env->CP0_XContext =
- (env->CP0_XContext & ((~0ULL) << (env->SEGBITS - 7))) | /* PTEBase */
- (extract64(address, 62, 2) << (env->SEGBITS - 9)) | /* R */
- (extract64(address, 13, env->SEGBITS - 13) << 4); /* BadVPN2 */
-#endif
- cs->exception_index = exception;
- env->error_code = error_code;
-}
-
-#if !defined(TARGET_MIPS64)
-
-/*
- * Perform hardware page table walk
- *
- * Memory accesses are performed using the KERNEL privilege level.
- * Synchronous exceptions detected on memory accesses cause a silent exit
- * from page table walking, resulting in a TLB or XTLB Refill exception.
- *
- * Implementations are not required to support page table walk memory
- * accesses from mapped memory regions. When an unsupported access is
- * attempted, a silent exit is taken, resulting in a TLB or XTLB Refill
- * exception.
- *
- * Note that if an exception is caused by AddressTranslation or LoadMemory
- * functions, the exception is not taken, a silent exit is taken,
- * resulting in a TLB or XTLB Refill exception.
- */
-
-static bool get_pte(CPUMIPSState *env, uint64_t vaddr, MemOp op,
- uint64_t *pte, unsigned ptw_mmu_idx)
-{
- MemOpIdx oi;
-
- if ((vaddr & (memop_size(op) - 1)) != 0) {
- return false;
- }
-
- oi = make_memop_idx(op | mo_endian_env(env), ptw_mmu_idx);
- if (op == MO_64) {
- *pte = cpu_ldq_mmu(env, vaddr, oi, 0);
- } else {
- *pte = cpu_ldl_mmu(env, vaddr, oi, 0);
- }
-
- return true;
-}
-
-static uint64_t get_tlb_entry_layout(CPUMIPSState *env, uint64_t entry,
- MemOp op, int ptei)
-{
- unsigned entry_size = memop_size(op) << 3;
- uint64_t result = entry;
- uint64_t rixi;
- if (ptei > entry_size) {
- ptei -= 32;
- }
- result >>= (ptei - 2);
- rixi = result & 3;
- result >>= 2;
- result |= rixi << CP0EnLo_XI;
- return result;
-}
-
-static int walk_directory(CPUMIPSState *env, uint64_t *vaddr,
- int directory_index, bool *huge_page, bool *hgpg_directory_hit,
- uint64_t *pw_entrylo0, uint64_t *pw_entrylo1,
- MemOp directory_mop, MemOp leaf_mop, int ptw_mmu_idx)
-{
- int dph = (env->CP0_PWCtl >> CP0PC_DPH) & 0x1;
- int psn = (env->CP0_PWCtl >> CP0PC_PSN) & 0x3F;
- int hugepg = (env->CP0_PWCtl >> CP0PC_HUGEPG) & 0x1;
- int pf_ptew = (env->CP0_PWField >> CP0PF_PTEW) & 0x3F;
- uint64_t entry;
- uint64_t paddr;
- int prot;
- uint64_t lsb = 0;
- uint64_t w = 0;
-
- if (get_physical_address(env, &paddr, &prot, *vaddr, MMU_DATA_LOAD,
- ptw_mmu_idx) != TLBRET_MATCH) {
- /* wrong base address */
- return 0;
- }
- if (!get_pte(env, *vaddr, directory_mop, &entry, ptw_mmu_idx)) {
- return 0;
- }
-
- if ((entry & (1 << psn)) && hugepg) {
- *huge_page = true;
- *hgpg_directory_hit = true;
- entry = get_tlb_entry_layout(env, entry, leaf_mop, pf_ptew);
- w = directory_index - 1;
- if (directory_index & 0x1) {
- /* Generate adjacent page from same PTE for odd TLB page */
- lsb = BIT_ULL(w) >> 6;
- *pw_entrylo0 = entry & ~lsb; /* even page */
- *pw_entrylo1 = entry | lsb; /* odd page */
- } else if (dph) {
- int oddpagebit = 1 << leaf_mop;
- uint64_t vaddr2 = *vaddr ^ oddpagebit;
- if (*vaddr & oddpagebit) {
- *pw_entrylo1 = entry;
- } else {
- *pw_entrylo0 = entry;
- }
- if (get_physical_address(env, &paddr, &prot, vaddr2, MMU_DATA_LOAD,
- ptw_mmu_idx) != TLBRET_MATCH) {
- return 0;
- }
- if (!get_pte(env, vaddr2, leaf_mop, &entry, ptw_mmu_idx)) {
- return 0;
- }
- entry = get_tlb_entry_layout(env, entry, leaf_mop, pf_ptew);
- if (*vaddr & oddpagebit) {
- *pw_entrylo0 = entry;
- } else {
- *pw_entrylo1 = entry;
- }
- } else {
- return 0;
- }
- return 1;
- } else {
- *vaddr = entry;
- return 2;
- }
-}
-
-static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
- int ptw_mmu_idx)
-{
- int gdw = (env->CP0_PWSize >> CP0PS_GDW) & 0x3F;
- int udw = (env->CP0_PWSize >> CP0PS_UDW) & 0x3F;
- int mdw = (env->CP0_PWSize >> CP0PS_MDW) & 0x3F;
- int ptw = (env->CP0_PWSize >> CP0PS_PTW) & 0x3F;
- int ptew = (env->CP0_PWSize >> CP0PS_PTEW) & 0x3F;
-
- /* Initial values */
- bool huge_page = false;
- bool hgpg_bdhit = false;
- bool hgpg_gdhit = false;
- bool hgpg_udhit = false;
- bool hgpg_mdhit = false;
-
- int32_t pw_pagemask = 0;
- target_ulong pw_entryhi = 0;
- uint64_t pw_entrylo0 = 0;
- uint64_t pw_entrylo1 = 0;
-
- /* Native pointer size */
- /*For the 32-bit architectures, this bit is fixed to 0.*/
- MemOp native_op = (((env->CP0_PWSize >> CP0PS_PS) & 1) == 0) ? MO_32 : MO_64;
-
- /* Indices from PWField */
- int pf_gdw = (env->CP0_PWField >> CP0PF_GDW) & 0x3F;
- int pf_udw = (env->CP0_PWField >> CP0PF_UDW) & 0x3F;
- int pf_mdw = (env->CP0_PWField >> CP0PF_MDW) & 0x3F;
- int pf_ptw = (env->CP0_PWField >> CP0PF_PTW) & 0x3F;
- int pf_ptew = (env->CP0_PWField >> CP0PF_PTEW) & 0x3F;
-
- /* Indices computed from faulting address */
- int gindex = (address >> pf_gdw) & ((1 << gdw) - 1);
- int uindex = (address >> pf_udw) & ((1 << udw) - 1);
- int mindex = (address >> pf_mdw) & ((1 << mdw) - 1);
- int ptindex = (address >> pf_ptw) & ((1 << ptw) - 1);
-
- /* Other HTW configs */
- int hugepg = (env->CP0_PWCtl >> CP0PC_HUGEPG) & 0x1;
- MemOp directory_mop, leaf_mop;
-
- /* Offsets into tables */
- unsigned goffset, uoffset, moffset, ptoffset0, ptoffset1;
-
- /* Starting address - Page Table Base */
- uint64_t vaddr = env->CP0_PWBase;
-
- uint64_t dir_entry;
- uint64_t paddr;
- int prot;
- int m;
-
- if (!(env->CP0_Config3 & (1 << CP0C3_PW))) {
- /* walker is unimplemented */
- return false;
- }
- if (!(env->CP0_PWCtl & (1 << CP0PC_PWEN))) {
- /* walker is disabled */
- return false;
- }
- if (!(gdw > 0 || udw > 0 || mdw > 0)) {
- /* no structure to walk */
- return false;
- }
- if (ptew > 1) {
- return false;
- }
-
- /* HTW Shift values (depend on entry size) */
- directory_mop = (hugepg && (ptew == 1)) ? native_op + 1 : native_op;
- leaf_mop = (ptew == 1) ? native_op + 1 : native_op;
-
- goffset = gindex << directory_mop;
- uoffset = uindex << directory_mop;
- moffset = mindex << directory_mop;
- ptoffset0 = (ptindex >> 1) << (leaf_mop + 1);
- ptoffset1 = ptoffset0 | (1 << (leaf_mop));
-
- /* Global Directory */
- if (gdw > 0) {
- vaddr |= goffset;
- switch (walk_directory(env, &vaddr, pf_gdw, &huge_page, &hgpg_gdhit,
- &pw_entrylo0, &pw_entrylo1,
- directory_mop, leaf_mop, ptw_mmu_idx))
- {
- case 0:
- return false;
- case 1:
- goto refill;
- case 2:
- default:
- break;
- }
- }
-
- /* Upper directory */
- if (udw > 0) {
- vaddr |= uoffset;
- switch (walk_directory(env, &vaddr, pf_udw, &huge_page, &hgpg_udhit,
- &pw_entrylo0, &pw_entrylo1,
- directory_mop, leaf_mop, ptw_mmu_idx))
- {
- case 0:
- return false;
- case 1:
- goto refill;
- case 2:
- default:
- break;
- }
- }
-
- /* Middle directory */
- if (mdw > 0) {
- vaddr |= moffset;
- switch (walk_directory(env, &vaddr, pf_mdw, &huge_page, &hgpg_mdhit,
- &pw_entrylo0, &pw_entrylo1,
- directory_mop, leaf_mop, ptw_mmu_idx))
- {
- case 0:
- return false;
- case 1:
- goto refill;
- case 2:
- default:
- break;
- }
- }
-
- /* Leaf Level Page Table - First half of PTE pair */
- vaddr |= ptoffset0;
- if (get_physical_address(env, &paddr, &prot, vaddr, MMU_DATA_LOAD,
- ptw_mmu_idx) != TLBRET_MATCH) {
- return false;
- }
- if (!get_pte(env, vaddr, leaf_mop, &dir_entry, ptw_mmu_idx)) {
- return false;
- }
- dir_entry = get_tlb_entry_layout(env, dir_entry, leaf_mop, pf_ptew);
- pw_entrylo0 = dir_entry;
-
- /* Leaf Level Page Table - Second half of PTE pair */
- vaddr |= ptoffset1;
- if (get_physical_address(env, &paddr, &prot, vaddr, MMU_DATA_LOAD,
- ptw_mmu_idx) != TLBRET_MATCH) {
- return false;
- }
- if (!get_pte(env, vaddr, leaf_mop, &dir_entry, ptw_mmu_idx)) {
- return false;
- }
- dir_entry = get_tlb_entry_layout(env, dir_entry, leaf_mop, pf_ptew);
- pw_entrylo1 = dir_entry;
-
-refill:
-
- m = (1 << pf_ptw) - 1;
-
- if (huge_page) {
- switch (hgpg_bdhit << 3 | hgpg_gdhit << 2 | hgpg_udhit << 1 |
- hgpg_mdhit)
- {
- case 4:
- m = (1 << pf_gdw) - 1;
- if (pf_gdw & 1) {
- m >>= 1;
- }
- break;
- case 2:
- m = (1 << pf_udw) - 1;
- if (pf_udw & 1) {
- m >>= 1;
- }
- break;
- case 1:
- m = (1 << pf_mdw) - 1;
- if (pf_mdw & 1) {
- m >>= 1;
- }
- break;
- }
- }
- pw_pagemask = m >> TARGET_PAGE_BITS_MIN;
- update_pagemask(env, pw_pagemask << CP0PM_MASK, &pw_pagemask);
- pw_entryhi = (address & ~0x1fff) | (env->CP0_EntryHi & 0xFF);
- {
- target_ulong tmp_entryhi = env->CP0_EntryHi;
- int32_t tmp_pagemask = env->CP0_PageMask;
- uint64_t tmp_entrylo0 = env->CP0_EntryLo0;
- uint64_t tmp_entrylo1 = env->CP0_EntryLo1;
-
- env->CP0_EntryHi = pw_entryhi;
- env->CP0_PageMask = pw_pagemask;
- env->CP0_EntryLo0 = pw_entrylo0;
- env->CP0_EntryLo1 = pw_entrylo1;
-
- /*
- * The hardware page walker inserts a page into the TLB in a manner
- * identical to a TLBWR instruction as executed by the software refill
- * handler.
- */
- r4k_helper_tlbwr(env);
-
- env->CP0_EntryHi = tmp_entryhi;
- env->CP0_PageMask = tmp_pagemask;
- env->CP0_EntryLo0 = tmp_entrylo0;
- env->CP0_EntryLo1 = tmp_entrylo1;
- }
- return true;
-}
-#endif
-
-bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr)
-{
- CPUMIPSState *env = cpu_env(cs);
- hwaddr physical;
- int prot;
- int ret = TLBRET_BADADDR;
-
- /* data access */
- /* XXX: put correct access by using cpu_restore_state() correctly */
- ret = get_physical_address(env, &physical, &prot, address,
- access_type, mmu_idx);
- switch (ret) {
- case TLBRET_MATCH:
- qemu_log_mask(CPU_LOG_MMU,
- "%s address=%" VADDR_PRIx " physical " HWADDR_FMT_plx
- " prot %d\n", __func__, address, physical, prot);
- break;
- default:
- qemu_log_mask(CPU_LOG_MMU,
- "%s address=%" VADDR_PRIx " ret %d\n", __func__, address,
- ret);
- break;
- }
- if (ret == TLBRET_MATCH) {
- tlb_set_page(cs, address & TARGET_PAGE_MASK,
- physical & TARGET_PAGE_MASK, prot,
- mmu_idx, TARGET_PAGE_SIZE);
- return true;
- }
-#if !defined(TARGET_MIPS64)
- if ((ret == TLBRET_NOMATCH) && (env->tlb->nb_tlb > 1)) {
- /*
- * Memory reads during hardware page table walking are performed
- * as if they were kernel-mode load instructions.
- */
- int ptw_mmu_idx = (env->hflags & MIPS_HFLAG_ERL ?
- MMU_ERL_IDX : MMU_KERNEL_IDX);
-
- if (page_table_walk_refill(env, address, ptw_mmu_idx)) {
- ret = get_physical_address(env, &physical, &prot, address,
- access_type, mmu_idx);
- if (ret == TLBRET_MATCH) {
- tlb_set_page(cs, address & TARGET_PAGE_MASK,
- physical & TARGET_PAGE_MASK, prot,
- mmu_idx, TARGET_PAGE_SIZE);
- return true;
- }
- }
- }
-#endif
- if (probe) {
- return false;
- }
-
- raise_mmu_exception(env, address, access_type, ret);
- do_raise_exception_err(env, cs->exception_index, env->error_code, retaddr);
-}
-
-hwaddr cpu_mips_translate_address(CPUMIPSState *env, target_ulong address,
- MMUAccessType access_type, uintptr_t retaddr)
-{
- hwaddr physical;
- int prot;
- int ret = 0;
- CPUState *cs = env_cpu(env);
-
- /* data access */
- ret = get_physical_address(env, &physical, &prot, address, access_type,
- mips_env_mmu_index(env));
- if (ret == TLBRET_MATCH) {
- return physical;
- }
-
- raise_mmu_exception(env, address, access_type, ret);
- cpu_loop_exit_restore(cs, retaddr);
-}
-
-static void set_hflags_for_handler(CPUMIPSState *env)
-{
- /* Exception handlers are entered in 32-bit mode. */
- env->hflags &= ~(MIPS_HFLAG_M16);
- /* ...except that microMIPS lets you choose. */
- if (env->insn_flags & ASE_MICROMIPS) {
- env->hflags |= (!!(env->CP0_Config3 &
- (1 << CP0C3_ISA_ON_EXC))
- << MIPS_HFLAG_M16_SHIFT);
- }
-}
-
-static inline void set_badinstr_registers(CPUMIPSState *env)
-{
- if (env->insn_flags & ISA_NANOMIPS32) {
- if (env->CP0_Config3 & (1 << CP0C3_BI)) {
- uint32_t instr = (cpu_lduw_code(env, env->active_tc.PC)) << 16;
- if ((instr & 0x10000000) == 0) {
- instr |= cpu_lduw_code(env, env->active_tc.PC + 2);
- }
- env->CP0_BadInstr = instr;
-
- if ((instr & 0xFC000000) == 0x60000000) {
- instr = cpu_lduw_code(env, env->active_tc.PC + 4) << 16;
- env->CP0_BadInstrX = instr;
- }
- }
- return;
- }
-
- if (env->hflags & MIPS_HFLAG_M16) {
- /* TODO: add BadInstr support for microMIPS */
- return;
- }
- if (env->CP0_Config3 & (1 << CP0C3_BI)) {
- env->CP0_BadInstr = cpu_ldl_code(env, env->active_tc.PC);
- }
- if ((env->CP0_Config3 & (1 << CP0C3_BP)) &&
- (env->hflags & MIPS_HFLAG_BMASK)) {
- env->CP0_BadInstrP = cpu_ldl_code(env, env->active_tc.PC - 4);
- }
-}
-
-void mips_cpu_do_interrupt(CPUState *cs)
-{
- MIPSCPU *cpu = MIPS_CPU(cs);
- CPUMIPSState *env = &cpu->env;
- bool update_badinstr = 0;
- target_ulong offset;
- int cause = -1;
-
- if (qemu_loglevel_mask(CPU_LOG_INT)
- && cs->exception_index != EXCP_EXT_INTERRUPT) {
- qemu_log("%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx
- " %s exception\n",
- __func__, env->active_tc.PC, env->CP0_EPC,
- mips_exception_name(cs->exception_index));
- }
- if (cs->exception_index == EXCP_EXT_INTERRUPT &&
- (env->hflags & MIPS_HFLAG_DM)) {
- cs->exception_index = EXCP_DINT;
- }
- offset = 0x180;
- switch (cs->exception_index) {
- case EXCP_SEMIHOST:
- cs->exception_index = EXCP_NONE;
- mips_semihosting(env);
- env->active_tc.PC += env->error_code;
- return;
- case EXCP_DSS:
- env->CP0_Debug |= 1 << CP0DB_DSS;
- /*
- * Debug single step cannot be raised inside a delay slot and
- * resume will always occur on the next instruction
- * (but we assume the pc has always been updated during
- * code translation).
- */
- env->CP0_DEPC = env->active_tc.PC | !!(env->hflags & MIPS_HFLAG_M16);
- goto enter_debug_mode;
- case EXCP_DINT:
- env->CP0_Debug |= 1 << CP0DB_DINT;
- goto set_DEPC;
- case EXCP_DIB:
- env->CP0_Debug |= 1 << CP0DB_DIB;
- goto set_DEPC;
- case EXCP_DBp:
- env->CP0_Debug |= 1 << CP0DB_DBp;
- /* Setup DExcCode - SDBBP instruction */
- env->CP0_Debug = (env->CP0_Debug & ~(0x1fULL << CP0DB_DEC)) |
- (9 << CP0DB_DEC);
- goto set_DEPC;
- case EXCP_DDBS:
- env->CP0_Debug |= 1 << CP0DB_DDBS;
- goto set_DEPC;
- case EXCP_DDBL:
- env->CP0_Debug |= 1 << CP0DB_DDBL;
- set_DEPC:
- env->CP0_DEPC = exception_resume_pc(env);
- env->hflags &= ~MIPS_HFLAG_BMASK;
- enter_debug_mode:
- if (env->insn_flags & ISA_MIPS3) {
- env->hflags |= MIPS_HFLAG_64;
- if (!(env->insn_flags & ISA_MIPS_R6) ||
- env->CP0_Status & (1 << CP0St_KX)) {
- env->hflags &= ~MIPS_HFLAG_AWRAP;
- }
- }
- env->hflags |= MIPS_HFLAG_DM | MIPS_HFLAG_CP0;
- env->hflags &= ~(MIPS_HFLAG_KSU);
- /* EJTAG probe trap enable is not implemented... */
- if (!(env->CP0_Status & (1 << CP0St_EXL))) {
- env->CP0_Cause &= ~(1U << CP0Ca_BD);
- }
- env->active_tc.PC = env->exception_base + 0x480;
- set_hflags_for_handler(env);
- break;
- case EXCP_RESET:
- cpu_reset(CPU(cpu));
- break;
- case EXCP_SRESET:
- env->CP0_Status |= (1 << CP0St_SR);
- memset(env->CP0_WatchLo, 0, sizeof(env->CP0_WatchLo));
- goto set_error_EPC;
- case EXCP_NMI:
- env->CP0_Status |= (1 << CP0St_NMI);
- set_error_EPC:
- env->CP0_ErrorEPC = exception_resume_pc(env);
- env->hflags &= ~MIPS_HFLAG_BMASK;
- env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
- if (env->insn_flags & ISA_MIPS3) {
- env->hflags |= MIPS_HFLAG_64;
- if (!(env->insn_flags & ISA_MIPS_R6) ||
- env->CP0_Status & (1 << CP0St_KX)) {
- env->hflags &= ~MIPS_HFLAG_AWRAP;
- }
- }
- env->hflags |= MIPS_HFLAG_CP0;
- env->hflags &= ~(MIPS_HFLAG_KSU);
- if (!(env->CP0_Status & (1 << CP0St_EXL))) {
- env->CP0_Cause &= ~(1U << CP0Ca_BD);
- }
- env->active_tc.PC = env->exception_base;
- set_hflags_for_handler(env);
- break;
- case EXCP_EXT_INTERRUPT:
- cause = 0;
- if (env->CP0_Cause & (1 << CP0Ca_IV)) {
- uint32_t spacing = (env->CP0_IntCtl >> CP0IntCtl_VS) & 0x1f;
-
- if ((env->CP0_Status & (1 << CP0St_BEV)) || spacing == 0) {
- offset = 0x200;
- } else {
- uint32_t vector = 0;
- uint32_t pending = (env->CP0_Cause & CP0Ca_IP_mask) >> CP0Ca_IP;
-
- if (env->CP0_Config3 & (1 << CP0C3_VEIC)) {
- /*
- * For VEIC mode, the external interrupt controller feeds
- * the vector through the CP0Cause IP lines.
- */
- vector = pending;
- } else {
- /*
- * Vectored Interrupts
- * Mask with Status.IM7-IM0 to get enabled interrupts.
- */
- pending &= (env->CP0_Status >> CP0St_IM) & 0xff;
- /* Find the highest-priority interrupt. */
- while (pending >>= 1) {
- vector++;
- }
- }
- offset = 0x200 + (vector * (spacing << 5));
- }
- }
- goto set_EPC;
- case EXCP_LTLBL:
- cause = 1;
- update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL);
- goto set_EPC;
- case EXCP_TLBL:
- cause = 2;
- update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL);
- if ((env->error_code & EXCP_TLB_NOMATCH) &&
- !(env->CP0_Status & (1 << CP0St_EXL))) {
-#if defined(TARGET_MIPS64)
- int R = env->CP0_BadVAddr >> 62;
- int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
- int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
-
- if ((R != 0 || UX) && (R != 3 || KX) &&
- (!(env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)))) {
- offset = 0x080;
- } else {
-#endif
- offset = 0x000;
-#if defined(TARGET_MIPS64)
- }
-#endif
- }
- goto set_EPC;
- case EXCP_TLBS:
- cause = 3;
- update_badinstr = 1;
- if ((env->error_code & EXCP_TLB_NOMATCH) &&
- !(env->CP0_Status & (1 << CP0St_EXL))) {
-#if defined(TARGET_MIPS64)
- int R = env->CP0_BadVAddr >> 62;
- int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
- int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
-
- if ((R != 0 || UX) && (R != 3 || KX) &&
- (!(env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)))) {
- offset = 0x080;
- } else {
-#endif
- offset = 0x000;
-#if defined(TARGET_MIPS64)
- }
-#endif
- }
- goto set_EPC;
- case EXCP_AdEL:
- cause = 4;
- update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL);
- goto set_EPC;
- case EXCP_AdES:
- cause = 5;
- update_badinstr = 1;
- goto set_EPC;
- case EXCP_IBE:
- cause = 6;
- goto set_EPC;
- case EXCP_DBE:
- cause = 7;
- goto set_EPC;
- case EXCP_SYSCALL:
- cause = 8;
- update_badinstr = 1;
- goto set_EPC;
- case EXCP_BREAK:
- cause = 9;
- update_badinstr = 1;
- goto set_EPC;
- case EXCP_RI:
- cause = 10;
- update_badinstr = 1;
- goto set_EPC;
- case EXCP_CpU:
- cause = 11;
- update_badinstr = 1;
- env->CP0_Cause = (env->CP0_Cause & ~(0x3 << CP0Ca_CE)) |
- (env->error_code << CP0Ca_CE);
- goto set_EPC;
- case EXCP_OVERFLOW:
- cause = 12;
- update_badinstr = 1;
- goto set_EPC;
- case EXCP_TRAP:
- cause = 13;
- update_badinstr = 1;
- goto set_EPC;
- case EXCP_MSAFPE:
- cause = 14;
- update_badinstr = 1;
- goto set_EPC;
- case EXCP_FPE:
- cause = 15;
- update_badinstr = 1;
- goto set_EPC;
- case EXCP_C2E:
- cause = 18;
- goto set_EPC;
- case EXCP_TLBRI:
- cause = 19;
- update_badinstr = 1;
- goto set_EPC;
- case EXCP_TLBXI:
- cause = 20;
- goto set_EPC;
- case EXCP_MSADIS:
- cause = 21;
- update_badinstr = 1;
- goto set_EPC;
- case EXCP_MDMX:
- cause = 22;
- goto set_EPC;
- case EXCP_DWATCH:
- cause = 23;
- /* XXX: TODO: manage deferred watch exceptions */
- goto set_EPC;
- case EXCP_MCHECK:
- cause = 24;
- goto set_EPC;
- case EXCP_THREAD:
- cause = 25;
- goto set_EPC;
- case EXCP_DSPDIS:
- cause = 26;
- goto set_EPC;
- case EXCP_CACHE:
- cause = 30;
- offset = 0x100;
- set_EPC:
- if (!(env->CP0_Status & (1 << CP0St_EXL))) {
- env->CP0_EPC = exception_resume_pc(env);
- if (update_badinstr) {
- set_badinstr_registers(env);
- }
- if (env->hflags & MIPS_HFLAG_BMASK) {
- env->CP0_Cause |= (1U << CP0Ca_BD);
- } else {
- env->CP0_Cause &= ~(1U << CP0Ca_BD);
- }
- env->CP0_Status |= (1 << CP0St_EXL);
- if (env->insn_flags & ISA_MIPS3) {
- env->hflags |= MIPS_HFLAG_64;
- if (!(env->insn_flags & ISA_MIPS_R6) ||
- env->CP0_Status & (1 << CP0St_KX)) {
- env->hflags &= ~MIPS_HFLAG_AWRAP;
- }
- }
- env->hflags |= MIPS_HFLAG_CP0;
- env->hflags &= ~(MIPS_HFLAG_KSU);
- }
- env->hflags &= ~MIPS_HFLAG_BMASK;
- if (env->CP0_Status & (1 << CP0St_BEV)) {
- env->active_tc.PC = env->exception_base + 0x200;
- } else if (cause == 30 && !(env->CP0_Config3 & (1 << CP0C3_SC) &&
- env->CP0_Config5 & (1 << CP0C5_CV))) {
- /* Force KSeg1 for cache errors */
- env->active_tc.PC = KSEG1_BASE | (env->CP0_EBase & 0x1FFFF000);
- } else {
- env->active_tc.PC = env->CP0_EBase & ~0xfff;
- }
-
- env->active_tc.PC += offset;
- set_hflags_for_handler(env);
- env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) |
- (cause << CP0Ca_EC);
- break;
- default:
- abort();
- }
- if (qemu_loglevel_mask(CPU_LOG_INT)
- && cs->exception_index != EXCP_EXT_INTERRUPT) {
- qemu_log("%s: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d\n"
- " S %08x C %08x A " TARGET_FMT_lx " D " TARGET_FMT_lx "\n",
- __func__, env->active_tc.PC, env->CP0_EPC, cause,
- env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr,
- env->CP0_DEPC);
- }
- cs->exception_index = EXCP_NONE;
-}
-
-bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
-{
- if (interrupt_request & CPU_INTERRUPT_HARD) {
- CPUMIPSState *env = cpu_env(cs);
-
- if (cpu_mips_hw_interrupts_enabled(env) &&
- cpu_mips_hw_interrupts_pending(env)) {
- /* Raise it */
- cs->exception_index = EXCP_EXT_INTERRUPT;
- env->error_code = 0;
- mips_cpu_do_interrupt(cs);
- return true;
- }
- }
- return false;
-}
-
-void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra)
-{
- CPUState *cs = env_cpu(env);
- r4k_tlb_t *tlb;
- target_ulong addr;
- target_ulong end;
- uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
- uint32_t MMID = env->CP0_MemoryMapID;
- bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1);
- uint32_t tlb_mmid;
- target_ulong mask;
-
- MMID = mi ? MMID : (uint32_t) ASID;
-
- tlb = &env->tlb->mmu.r4k.tlb[idx];
- /*
- * The qemu TLB is flushed when the ASID/MMID changes, so no need to
- * flush these entries again.
- */
- tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID;
- if (tlb->G == 0 && tlb_mmid != MMID) {
- return;
- }
-
- if (use_extra && env->tlb->tlb_in_use < MIPS_TLB_MAX) {
- /*
- * For tlbwr, we can shadow the discarded entry into
- * a new (fake) TLB entry, as long as the guest can not
- * tell that it's there.
- */
- env->tlb->mmu.r4k.tlb[env->tlb->tlb_in_use] = *tlb;
- env->tlb->tlb_in_use++;
- return;
- }
-
- /* 1k pages are not supported. */
- mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
- if (tlb->V0) {
- addr = tlb->VPN & ~mask;
-#if defined(TARGET_MIPS64)
- if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) {
- addr |= 0x3FFFFF0000000000ULL;
- }
-#endif
- end = addr | (mask >> 1);
- while (addr < end) {
- tlb_flush_page(cs, addr);
- addr += TARGET_PAGE_SIZE;
- }
- }
- if (tlb->V1) {
- addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1);
-#if defined(TARGET_MIPS64)
- if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) {
- addr |= 0x3FFFFF0000000000ULL;
- }
-#endif
- end = addr | mask;
- while (addr - 1 < end) {
- tlb_flush_page(cs, addr);
- addr += TARGET_PAGE_SIZE;
- }
- }
-}
+++ /dev/null
-/*
- * QEMU MIPS sysemu helpers
- *
- * Copyright (c) 2004-2005 Jocelyn Mayer
- * Copyright (c) 2006 Marius Groeger (FPU operations)
- * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
- * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
- *
- * SPDX-License-Identifier: LGPL-2.1-or-later
- */
-
-/* CP0 helpers */
-DEF_HELPER_1(mfc0_mvpcontrol, tl, env)
-DEF_HELPER_1(mfc0_mvpconf0, tl, env)
-DEF_HELPER_1(mfc0_mvpconf1, tl, env)
-DEF_HELPER_1(mftc0_vpecontrol, tl, env)
-DEF_HELPER_1(mftc0_vpeconf0, tl, env)
-DEF_HELPER_1(mfc0_random, tl, env)
-DEF_HELPER_1(mfc0_tcstatus, tl, env)
-DEF_HELPER_1(mftc0_tcstatus, tl, env)
-DEF_HELPER_1(mfc0_tcbind, tl, env)
-DEF_HELPER_1(mftc0_tcbind, tl, env)
-DEF_HELPER_1(mfc0_tcrestart, tl, env)
-DEF_HELPER_1(mftc0_tcrestart, tl, env)
-DEF_HELPER_1(mfc0_tchalt, tl, env)
-DEF_HELPER_1(mftc0_tchalt, tl, env)
-DEF_HELPER_1(mfc0_tccontext, tl, env)
-DEF_HELPER_1(mftc0_tccontext, tl, env)
-DEF_HELPER_1(mfc0_tcschedule, tl, env)
-DEF_HELPER_1(mftc0_tcschedule, tl, env)
-DEF_HELPER_1(mfc0_tcschefback, tl, env)
-DEF_HELPER_1(mftc0_tcschefback, tl, env)
-DEF_HELPER_1(mfc0_count, tl, env)
-DEF_HELPER_1(mftc0_entryhi, tl, env)
-DEF_HELPER_1(mftc0_status, tl, env)
-DEF_HELPER_1(mftc0_cause, tl, env)
-DEF_HELPER_1(mftc0_epc, tl, env)
-DEF_HELPER_1(mftc0_ebase, tl, env)
-DEF_HELPER_2(mftc0_configx, tl, env, tl)
-DEF_HELPER_1(mfc0_lladdr, tl, env)
-DEF_HELPER_1(mfc0_maar, tl, env)
-DEF_HELPER_1(mfhc0_maar, tl, env)
-DEF_HELPER_2(mfc0_watchlo, tl, env, i32)
-DEF_HELPER_2(mfc0_watchhi, tl, env, i32)
-DEF_HELPER_2(mfhc0_watchhi, tl, env, i32)
-DEF_HELPER_1(mfc0_debug, tl, env)
-DEF_HELPER_1(mftc0_debug, tl, env)
-#ifdef TARGET_MIPS64
-DEF_HELPER_1(dmfc0_tcrestart, tl, env)
-DEF_HELPER_1(dmfc0_tchalt, tl, env)
-DEF_HELPER_1(dmfc0_tccontext, tl, env)
-DEF_HELPER_1(dmfc0_tcschedule, tl, env)
-DEF_HELPER_1(dmfc0_tcschefback, tl, env)
-DEF_HELPER_1(dmfc0_lladdr, tl, env)
-DEF_HELPER_1(dmfc0_maar, tl, env)
-DEF_HELPER_2(dmfc0_watchlo, tl, env, i32)
-DEF_HELPER_2(dmfc0_watchhi, tl, env, i32)
-#endif /* TARGET_MIPS64 */
-
-DEF_HELPER_2(mtc0_index, void, env, tl)
-DEF_HELPER_2(mtc0_mvpcontrol, void, env, tl)
-DEF_HELPER_2(mtc0_vpecontrol, void, env, tl)
-DEF_HELPER_2(mttc0_vpecontrol, void, env, tl)
-DEF_HELPER_2(mtc0_vpeconf0, void, env, tl)
-DEF_HELPER_2(mttc0_vpeconf0, void, env, tl)
-DEF_HELPER_2(mtc0_vpeconf1, void, env, tl)
-DEF_HELPER_2(mtc0_yqmask, void, env, tl)
-DEF_HELPER_2(mtc0_vpeopt, void, env, tl)
-DEF_HELPER_2(mtc0_entrylo0, void, env, tl)
-DEF_HELPER_2(mtc0_tcstatus, void, env, tl)
-DEF_HELPER_2(mttc0_tcstatus, void, env, tl)
-DEF_HELPER_2(mtc0_tcbind, void, env, tl)
-DEF_HELPER_2(mttc0_tcbind, void, env, tl)
-DEF_HELPER_2(mtc0_tcrestart, void, env, tl)
-DEF_HELPER_2(mttc0_tcrestart, void, env, tl)
-DEF_HELPER_2(mtc0_tchalt, void, env, tl)
-DEF_HELPER_2(mttc0_tchalt, void, env, tl)
-DEF_HELPER_2(mtc0_tccontext, void, env, tl)
-DEF_HELPER_2(mttc0_tccontext, void, env, tl)
-DEF_HELPER_2(mtc0_tcschedule, void, env, tl)
-DEF_HELPER_2(mttc0_tcschedule, void, env, tl)
-DEF_HELPER_2(mtc0_tcschefback, void, env, tl)
-DEF_HELPER_2(mttc0_tcschefback, void, env, tl)
-DEF_HELPER_2(mtc0_entrylo1, void, env, tl)
-DEF_HELPER_2(mtc0_context, void, env, tl)
-DEF_HELPER_2(mtc0_memorymapid, void, env, tl)
-DEF_HELPER_2(mtc0_pagemask, void, env, tl)
-DEF_HELPER_2(mtc0_pagegrain, void, env, tl)
-DEF_HELPER_2(mtc0_segctl0, void, env, tl)
-DEF_HELPER_2(mtc0_segctl1, void, env, tl)
-DEF_HELPER_2(mtc0_segctl2, void, env, tl)
-DEF_HELPER_2(mtc0_pwfield, void, env, tl)
-DEF_HELPER_2(mtc0_pwsize, void, env, tl)
-DEF_HELPER_2(mtc0_wired, void, env, tl)
-DEF_HELPER_2(mtc0_srsconf0, void, env, tl)
-DEF_HELPER_2(mtc0_srsconf1, void, env, tl)
-DEF_HELPER_2(mtc0_srsconf2, void, env, tl)
-DEF_HELPER_2(mtc0_srsconf3, void, env, tl)
-DEF_HELPER_2(mtc0_srsconf4, void, env, tl)
-DEF_HELPER_2(mtc0_hwrena, void, env, tl)
-DEF_HELPER_2(mtc0_pwctl, void, env, tl)
-DEF_HELPER_2(mtc0_count, void, env, tl)
-DEF_HELPER_2(mtc0_entryhi, void, env, tl)
-DEF_HELPER_2(mttc0_entryhi, void, env, tl)
-DEF_HELPER_2(mtc0_compare, void, env, tl)
-DEF_HELPER_2(mtc0_status, void, env, tl)
-DEF_HELPER_2(mttc0_status, void, env, tl)
-DEF_HELPER_2(mtc0_intctl, void, env, tl)
-DEF_HELPER_2(mtc0_srsctl, void, env, tl)
-DEF_HELPER_2(mtc0_cause, void, env, tl)
-DEF_HELPER_2(mttc0_cause, void, env, tl)
-DEF_HELPER_2(mtc0_ebase, void, env, tl)
-DEF_HELPER_2(mttc0_ebase, void, env, tl)
-DEF_HELPER_2(mtc0_config0, void, env, tl)
-DEF_HELPER_2(mtc0_config2, void, env, tl)
-DEF_HELPER_2(mtc0_config3, void, env, tl)
-DEF_HELPER_2(mtc0_config4, void, env, tl)
-DEF_HELPER_2(mtc0_config5, void, env, tl)
-DEF_HELPER_2(mtc0_lladdr, void, env, tl)
-DEF_HELPER_2(mtc0_maar, void, env, tl)
-DEF_HELPER_2(mthc0_maar, void, env, tl)
-DEF_HELPER_2(mtc0_maari, void, env, tl)
-DEF_HELPER_3(mtc0_watchlo, void, env, tl, i32)
-DEF_HELPER_3(mtc0_watchhi, void, env, tl, i32)
-DEF_HELPER_3(mthc0_watchhi, void, env, tl, i32)
-DEF_HELPER_2(mtc0_xcontext, void, env, tl)
-DEF_HELPER_2(mtc0_framemask, void, env, tl)
-DEF_HELPER_2(mtc0_debug, void, env, tl)
-DEF_HELPER_2(mttc0_debug, void, env, tl)
-DEF_HELPER_2(mtc0_performance0, void, env, tl)
-DEF_HELPER_2(mtc0_errctl, void, env, tl)
-DEF_HELPER_2(mtc0_taglo, void, env, tl)
-DEF_HELPER_2(mtc0_datalo, void, env, tl)
-DEF_HELPER_2(mtc0_taghi, void, env, tl)
-DEF_HELPER_2(mtc0_datahi, void, env, tl)
-
-#if defined(TARGET_MIPS64)
-DEF_HELPER_2(dmtc0_entrylo0, void, env, i64)
-DEF_HELPER_2(dmtc0_entrylo1, void, env, i64)
-#endif
-
-/* MIPS MT functions */
-DEF_HELPER_2(mftgpr, tl, env, i32)
-DEF_HELPER_2(mftlo, tl, env, i32)
-DEF_HELPER_2(mfthi, tl, env, i32)
-DEF_HELPER_2(mftacx, tl, env, i32)
-DEF_HELPER_1(mftdsp, tl, env)
-DEF_HELPER_3(mttgpr, void, env, tl, i32)
-DEF_HELPER_3(mttlo, void, env, tl, i32)
-DEF_HELPER_3(mtthi, void, env, tl, i32)
-DEF_HELPER_3(mttacx, void, env, tl, i32)
-DEF_HELPER_2(mttdsp, void, env, tl)
-DEF_HELPER_0(dmt, tl)
-DEF_HELPER_0(emt, tl)
-DEF_HELPER_1(dvpe, tl, env)
-DEF_HELPER_1(evpe, tl, env)
-
-/* R6 Multi-threading */
-DEF_HELPER_1(dvp, tl, env)
-DEF_HELPER_1(evp, tl, env)
-
-/* TLB */
-DEF_HELPER_1(tlbwi, void, env)
-DEF_HELPER_1(tlbwr, void, env)
-DEF_HELPER_1(tlbp, void, env)
-DEF_HELPER_1(tlbr, void, env)
-DEF_HELPER_1(tlbinv, void, env)
-DEF_HELPER_1(tlbinvf, void, env)
-DEF_HELPER_3(ginvt, void, env, tl, i32)
-
-/* Special */
-DEF_HELPER_1(di, tl, env)
-DEF_HELPER_1(ei, tl, env)
-DEF_HELPER_1(eret, void, env)
-DEF_HELPER_1(eretnc, void, env)
-DEF_HELPER_1(deret, void, env)
-DEF_HELPER_3(cache, void, env, tl, i32)
-
-#ifdef TARGET_MIPS64
-/* Longson CSR */
-DEF_HELPER_2(lcsr_rdcsr, i64, env, tl)
-DEF_HELPER_2(lcsr_drdcsr, i64, env, tl)
-DEF_HELPER_3(lcsr_wrcsr, void, env, tl, tl)
-DEF_HELPER_3(lcsr_dwrcsr, void, env, tl, tl)
-#endif
--- /dev/null
+/*
+ * Helpers for emulation of CP0-related MIPS instructions.
+ *
+ * Copyright (C) 2004-2005 Jocelyn Mayer
+ * Copyright (C) 2020 Wave Computing, Inc.
+ * Copyright (C) 2020 Aleksandar Markovic <amarkovic@wavecomp.com>
+ *
+ * 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.1 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 "qemu/log.h"
+#include "qemu/main-loop.h"
+#include "cpu.h"
+#include "internal.h"
+#include "qemu/host-utils.h"
+#include "exec/helper-proto.h"
+#include "exec/exec-all.h"
+
+
+/* SMP helpers. */
+static bool mips_vpe_is_wfi(MIPSCPU *c)
+{
+ CPUState *cpu = CPU(c);
+ CPUMIPSState *env = &c->env;
+
+ /*
+ * If the VPE is halted but otherwise active, it means it's waiting for
+ * an interrupt.\
+ */
+ return cpu->halted && mips_vpe_active(env);
+}
+
+static bool mips_vp_is_wfi(MIPSCPU *c)
+{
+ CPUState *cpu = CPU(c);
+ CPUMIPSState *env = &c->env;
+
+ return cpu->halted && mips_vp_active(env);
+}
+
+static inline void mips_vpe_wake(MIPSCPU *c)
+{
+ /*
+ * Don't set ->halted = 0 directly, let it be done via cpu_has_work
+ * because there might be other conditions that state that c should
+ * be sleeping.
+ */
+ bql_lock();
+ cpu_interrupt(CPU(c), CPU_INTERRUPT_WAKE);
+ bql_unlock();
+}
+
+static inline void mips_vpe_sleep(MIPSCPU *cpu)
+{
+ CPUState *cs = CPU(cpu);
+
+ /*
+ * The VPE was shut off, really go to bed.
+ * Reset any old _WAKE requests.
+ */
+ cs->halted = 1;
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE);
+}
+
+static inline void mips_tc_wake(MIPSCPU *cpu, int tc)
+{
+ CPUMIPSState *c = &cpu->env;
+
+ /* FIXME: TC reschedule. */
+ if (mips_vpe_active(c) && !mips_vpe_is_wfi(cpu)) {
+ mips_vpe_wake(cpu);
+ }
+}
+
+static inline void mips_tc_sleep(MIPSCPU *cpu, int tc)
+{
+ CPUMIPSState *c = &cpu->env;
+
+ /* FIXME: TC reschedule. */
+ if (!mips_vpe_active(c)) {
+ mips_vpe_sleep(cpu);
+ }
+}
+
+/**
+ * mips_cpu_map_tc:
+ * @env: CPU from which mapping is performed.
+ * @tc: Should point to an int with the value of the global TC index.
+ *
+ * This function will transform @tc into a local index within the
+ * returned #CPUMIPSState.
+ */
+
+/*
+ * FIXME: This code assumes that all VPEs have the same number of TCs,
+ * which depends on runtime setup. Can probably be fixed by
+ * walking the list of CPUMIPSStates.
+ */
+static CPUMIPSState *mips_cpu_map_tc(CPUMIPSState *env, int *tc)
+{
+ MIPSCPU *cpu;
+ CPUState *cs;
+ CPUState *other_cs;
+ int vpe_idx;
+ int tc_idx = *tc;
+
+ if (!(env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))) {
+ /* Not allowed to address other CPUs. */
+ *tc = env->current_tc;
+ return env;
+ }
+
+ cs = env_cpu(env);
+ vpe_idx = tc_idx / cs->nr_threads;
+ *tc = tc_idx % cs->nr_threads;
+ other_cs = qemu_get_cpu(vpe_idx);
+ if (other_cs == NULL) {
+ return env;
+ }
+ cpu = MIPS_CPU(other_cs);
+ return &cpu->env;
+}
+
+/*
+ * The per VPE CP0_Status register shares some fields with the per TC
+ * CP0_TCStatus registers. These fields are wired to the same registers,
+ * so changes to either of them should be reflected on both registers.
+ *
+ * Also, EntryHi shares the bottom 8 bit ASID with TCStauts.
+ *
+ * These helper call synchronizes the regs for a given cpu.
+ */
+
+/*
+ * Called for updates to CP0_Status. Defined in "cpu.h" for gdbstub.c.
+ * static inline void sync_c0_status(CPUMIPSState *env, CPUMIPSState *cpu,
+ * int tc);
+ */
+
+/* Called for updates to CP0_TCStatus. */
+static void sync_c0_tcstatus(CPUMIPSState *cpu, int tc,
+ target_ulong v)
+{
+ uint32_t status;
+ uint32_t tcu, tmx, tasid, tksu;
+ uint32_t mask = ((1U << CP0St_CU3)
+ | (1 << CP0St_CU2)
+ | (1 << CP0St_CU1)
+ | (1 << CP0St_CU0)
+ | (1 << CP0St_MX)
+ | (3 << CP0St_KSU));
+
+ tcu = (v >> CP0TCSt_TCU0) & 0xf;
+ tmx = (v >> CP0TCSt_TMX) & 0x1;
+ tasid = v & cpu->CP0_EntryHi_ASID_mask;
+ tksu = (v >> CP0TCSt_TKSU) & 0x3;
+
+ status = tcu << CP0St_CU0;
+ status |= tmx << CP0St_MX;
+ status |= tksu << CP0St_KSU;
+
+ cpu->CP0_Status &= ~mask;
+ cpu->CP0_Status |= status;
+
+ /* Sync the TASID with EntryHi. */
+ cpu->CP0_EntryHi &= ~cpu->CP0_EntryHi_ASID_mask;
+ cpu->CP0_EntryHi |= tasid;
+
+ compute_hflags(cpu);
+}
+
+/* Called for updates to CP0_EntryHi. */
+static void sync_c0_entryhi(CPUMIPSState *cpu, int tc)
+{
+ int32_t *tcst;
+ uint32_t asid, v = cpu->CP0_EntryHi;
+
+ asid = v & cpu->CP0_EntryHi_ASID_mask;
+
+ if (tc == cpu->current_tc) {
+ tcst = &cpu->active_tc.CP0_TCStatus;
+ } else {
+ tcst = &cpu->tcs[tc].CP0_TCStatus;
+ }
+
+ *tcst &= ~cpu->CP0_EntryHi_ASID_mask;
+ *tcst |= asid;
+}
+
+/* XXX: do not use a global */
+uint32_t cpu_mips_get_random(CPUMIPSState *env)
+{
+ static uint32_t seed = 1;
+ static uint32_t prev_idx;
+ uint32_t idx;
+ uint32_t nb_rand_tlb = env->tlb->nb_tlb - env->CP0_Wired;
+
+ if (nb_rand_tlb == 1) {
+ return env->tlb->nb_tlb - 1;
+ }
+
+ /* Don't return same value twice, so get another value */
+ do {
+ /*
+ * Use a simple algorithm of Linear Congruential Generator
+ * from ISO/IEC 9899 standard.
+ */
+ seed = 1103515245 * seed + 12345;
+ idx = (seed >> 16) % nb_rand_tlb + env->CP0_Wired;
+ } while (idx == prev_idx);
+ prev_idx = idx;
+ return idx;
+}
+
+/* CP0 helpers */
+target_ulong helper_mfc0_mvpcontrol(CPUMIPSState *env)
+{
+ return env->mvp->CP0_MVPControl;
+}
+
+target_ulong helper_mfc0_mvpconf0(CPUMIPSState *env)
+{
+ return env->mvp->CP0_MVPConf0;
+}
+
+target_ulong helper_mfc0_mvpconf1(CPUMIPSState *env)
+{
+ return env->mvp->CP0_MVPConf1;
+}
+
+target_ulong helper_mfc0_random(CPUMIPSState *env)
+{
+ return (int32_t)cpu_mips_get_random(env);
+}
+
+target_ulong helper_mfc0_tcstatus(CPUMIPSState *env)
+{
+ return env->active_tc.CP0_TCStatus;
+}
+
+target_ulong helper_mftc0_tcstatus(CPUMIPSState *env)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ return other->active_tc.CP0_TCStatus;
+ } else {
+ return other->tcs[other_tc].CP0_TCStatus;
+ }
+}
+
+target_ulong helper_mfc0_tcbind(CPUMIPSState *env)
+{
+ return env->active_tc.CP0_TCBind;
+}
+
+target_ulong helper_mftc0_tcbind(CPUMIPSState *env)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ return other->active_tc.CP0_TCBind;
+ } else {
+ return other->tcs[other_tc].CP0_TCBind;
+ }
+}
+
+target_ulong helper_mfc0_tcrestart(CPUMIPSState *env)
+{
+ return env->active_tc.PC;
+}
+
+target_ulong helper_mftc0_tcrestart(CPUMIPSState *env)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ return other->active_tc.PC;
+ } else {
+ return other->tcs[other_tc].PC;
+ }
+}
+
+target_ulong helper_mfc0_tchalt(CPUMIPSState *env)
+{
+ return env->active_tc.CP0_TCHalt;
+}
+
+target_ulong helper_mftc0_tchalt(CPUMIPSState *env)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ return other->active_tc.CP0_TCHalt;
+ } else {
+ return other->tcs[other_tc].CP0_TCHalt;
+ }
+}
+
+target_ulong helper_mfc0_tccontext(CPUMIPSState *env)
+{
+ return env->active_tc.CP0_TCContext;
+}
+
+target_ulong helper_mftc0_tccontext(CPUMIPSState *env)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ return other->active_tc.CP0_TCContext;
+ } else {
+ return other->tcs[other_tc].CP0_TCContext;
+ }
+}
+
+target_ulong helper_mfc0_tcschedule(CPUMIPSState *env)
+{
+ return env->active_tc.CP0_TCSchedule;
+}
+
+target_ulong helper_mftc0_tcschedule(CPUMIPSState *env)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ return other->active_tc.CP0_TCSchedule;
+ } else {
+ return other->tcs[other_tc].CP0_TCSchedule;
+ }
+}
+
+target_ulong helper_mfc0_tcschefback(CPUMIPSState *env)
+{
+ return env->active_tc.CP0_TCScheFBack;
+}
+
+target_ulong helper_mftc0_tcschefback(CPUMIPSState *env)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ return other->active_tc.CP0_TCScheFBack;
+ } else {
+ return other->tcs[other_tc].CP0_TCScheFBack;
+ }
+}
+
+target_ulong helper_mfc0_count(CPUMIPSState *env)
+{
+ return (int32_t)cpu_mips_get_count(env);
+}
+
+target_ulong helper_mftc0_entryhi(CPUMIPSState *env)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ return other->CP0_EntryHi;
+}
+
+target_ulong helper_mftc0_cause(CPUMIPSState *env)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ return other->CP0_Cause;
+}
+
+target_ulong helper_mftc0_status(CPUMIPSState *env)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ return other->CP0_Status;
+}
+
+target_ulong helper_mfc0_lladdr(CPUMIPSState *env)
+{
+ return (int32_t)(env->CP0_LLAddr >> env->CP0_LLAddr_shift);
+}
+
+target_ulong helper_mfc0_maar(CPUMIPSState *env)
+{
+ return (int32_t) env->CP0_MAAR[env->CP0_MAARI];
+}
+
+target_ulong helper_mfhc0_maar(CPUMIPSState *env)
+{
+ return env->CP0_MAAR[env->CP0_MAARI] >> 32;
+}
+
+target_ulong helper_mfc0_watchlo(CPUMIPSState *env, uint32_t sel)
+{
+ return (int32_t)env->CP0_WatchLo[sel];
+}
+
+target_ulong helper_mfc0_watchhi(CPUMIPSState *env, uint32_t sel)
+{
+ return (int32_t) env->CP0_WatchHi[sel];
+}
+
+target_ulong helper_mfhc0_watchhi(CPUMIPSState *env, uint32_t sel)
+{
+ return env->CP0_WatchHi[sel] >> 32;
+}
+
+target_ulong helper_mfc0_debug(CPUMIPSState *env)
+{
+ target_ulong t0 = env->CP0_Debug;
+ if (env->hflags & MIPS_HFLAG_DM) {
+ t0 |= 1 << CP0DB_DM;
+ }
+
+ return t0;
+}
+
+target_ulong helper_mftc0_debug(CPUMIPSState *env)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ int32_t tcstatus;
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ tcstatus = other->active_tc.CP0_Debug_tcstatus;
+ } else {
+ tcstatus = other->tcs[other_tc].CP0_Debug_tcstatus;
+ }
+
+ /* XXX: Might be wrong, check with EJTAG spec. */
+ return (other->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
+ (tcstatus & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
+}
+
+#if defined(TARGET_MIPS64)
+target_ulong helper_dmfc0_tcrestart(CPUMIPSState *env)
+{
+ return env->active_tc.PC;
+}
+
+target_ulong helper_dmfc0_tchalt(CPUMIPSState *env)
+{
+ return env->active_tc.CP0_TCHalt;
+}
+
+target_ulong helper_dmfc0_tccontext(CPUMIPSState *env)
+{
+ return env->active_tc.CP0_TCContext;
+}
+
+target_ulong helper_dmfc0_tcschedule(CPUMIPSState *env)
+{
+ return env->active_tc.CP0_TCSchedule;
+}
+
+target_ulong helper_dmfc0_tcschefback(CPUMIPSState *env)
+{
+ return env->active_tc.CP0_TCScheFBack;
+}
+
+target_ulong helper_dmfc0_lladdr(CPUMIPSState *env)
+{
+ return env->CP0_LLAddr >> env->CP0_LLAddr_shift;
+}
+
+target_ulong helper_dmfc0_maar(CPUMIPSState *env)
+{
+ return env->CP0_MAAR[env->CP0_MAARI];
+}
+
+target_ulong helper_dmfc0_watchlo(CPUMIPSState *env, uint32_t sel)
+{
+ return env->CP0_WatchLo[sel];
+}
+
+target_ulong helper_dmfc0_watchhi(CPUMIPSState *env, uint32_t sel)
+{
+ return env->CP0_WatchHi[sel];
+}
+
+#endif /* TARGET_MIPS64 */
+
+void helper_mtc0_index(CPUMIPSState *env, target_ulong arg1)
+{
+ uint32_t index_p = env->CP0_Index & 0x80000000;
+ uint32_t tlb_index = arg1 & 0x7fffffff;
+ if (tlb_index < env->tlb->nb_tlb) {
+ if (env->insn_flags & ISA_MIPS_R6) {
+ index_p |= arg1 & 0x80000000;
+ }
+ env->CP0_Index = index_p | tlb_index;
+ }
+}
+
+void helper_mtc0_mvpcontrol(CPUMIPSState *env, target_ulong arg1)
+{
+ uint32_t mask = 0;
+ uint32_t newval;
+
+ if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
+ mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) |
+ (1 << CP0MVPCo_EVP);
+ }
+ if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) {
+ mask |= (1 << CP0MVPCo_STLB);
+ }
+ newval = (env->mvp->CP0_MVPControl & ~mask) | (arg1 & mask);
+
+ /* TODO: Enable/disable shared TLB, enable/disable VPEs. */
+
+ env->mvp->CP0_MVPControl = newval;
+}
+
+void helper_mtc0_vpecontrol(CPUMIPSState *env, target_ulong arg1)
+{
+ uint32_t mask;
+ uint32_t newval;
+
+ mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
+ (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
+ newval = (env->CP0_VPEControl & ~mask) | (arg1 & mask);
+
+ /*
+ * Yield scheduler intercept not implemented.
+ * Gating storage scheduler intercept not implemented.
+ */
+
+ /* TODO: Enable/disable TCs. */
+
+ env->CP0_VPEControl = newval;
+}
+
+void helper_mttc0_vpecontrol(CPUMIPSState *env, target_ulong arg1)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ uint32_t mask;
+ uint32_t newval;
+
+ mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
+ (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
+ newval = (other->CP0_VPEControl & ~mask) | (arg1 & mask);
+
+ /* TODO: Enable/disable TCs. */
+
+ other->CP0_VPEControl = newval;
+}
+
+target_ulong helper_mftc0_vpecontrol(CPUMIPSState *env)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ /* FIXME: Mask away return zero on read bits. */
+ return other->CP0_VPEControl;
+}
+
+target_ulong helper_mftc0_vpeconf0(CPUMIPSState *env)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ return other->CP0_VPEConf0;
+}
+
+void helper_mtc0_vpeconf0(CPUMIPSState *env, target_ulong arg1)
+{
+ uint32_t mask = 0;
+ uint32_t newval;
+
+ if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
+ if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA)) {
+ mask |= (0xff << CP0VPEC0_XTC);
+ }
+ mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
+ }
+ newval = (env->CP0_VPEConf0 & ~mask) | (arg1 & mask);
+
+ /* TODO: TC exclusive handling due to ERL/EXL. */
+
+ env->CP0_VPEConf0 = newval;
+}
+
+void helper_mttc0_vpeconf0(CPUMIPSState *env, target_ulong arg1)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ uint32_t mask = 0;
+ uint32_t newval;
+
+ mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
+ newval = (other->CP0_VPEConf0 & ~mask) | (arg1 & mask);
+
+ /* TODO: TC exclusive handling due to ERL/EXL. */
+ other->CP0_VPEConf0 = newval;
+}
+
+void helper_mtc0_vpeconf1(CPUMIPSState *env, target_ulong arg1)
+{
+ uint32_t mask = 0;
+ uint32_t newval;
+
+ if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
+ mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) |
+ (0xff << CP0VPEC1_NCP1);
+ newval = (env->CP0_VPEConf1 & ~mask) | (arg1 & mask);
+
+ /* UDI not implemented. */
+ /* CP2 not implemented. */
+
+ /* TODO: Handle FPU (CP1) binding. */
+
+ env->CP0_VPEConf1 = newval;
+}
+
+void helper_mtc0_yqmask(CPUMIPSState *env, target_ulong arg1)
+{
+ /* Yield qualifier inputs not implemented. */
+ env->CP0_YQMask = 0x00000000;
+}
+
+void helper_mtc0_vpeopt(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_VPEOpt = arg1 & 0x0000ffff;
+}
+
+#define MTC0_ENTRYLO_MASK(env) ((env->PAMask >> 6) & 0x3FFFFFFF)
+
+void helper_mtc0_entrylo0(CPUMIPSState *env, target_ulong arg1)
+{
+ /* 1k pages not implemented */
+ target_ulong rxi = arg1 & (env->CP0_PageGrain & (3u << CP0PG_XIE));
+ env->CP0_EntryLo0 = (arg1 & MTC0_ENTRYLO_MASK(env))
+ | (rxi << (CP0EnLo_XI - 30));
+}
+
+#if defined(TARGET_MIPS64)
+#define DMTC0_ENTRYLO_MASK(env) (env->PAMask >> 6)
+
+void helper_dmtc0_entrylo0(CPUMIPSState *env, uint64_t arg1)
+{
+ uint64_t rxi = arg1 & ((env->CP0_PageGrain & (3ull << CP0PG_XIE)) << 32);
+ env->CP0_EntryLo0 = (arg1 & DMTC0_ENTRYLO_MASK(env)) | rxi;
+}
+#endif
+
+void helper_mtc0_tcstatus(CPUMIPSState *env, target_ulong arg1)
+{
+ uint32_t mask = env->CP0_TCStatus_rw_bitmask;
+ uint32_t newval;
+
+ newval = (env->active_tc.CP0_TCStatus & ~mask) | (arg1 & mask);
+
+ env->active_tc.CP0_TCStatus = newval;
+ sync_c0_tcstatus(env, env->current_tc, newval);
+}
+
+void helper_mttc0_tcstatus(CPUMIPSState *env, target_ulong arg1)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ other->active_tc.CP0_TCStatus = arg1;
+ } else {
+ other->tcs[other_tc].CP0_TCStatus = arg1;
+ }
+ sync_c0_tcstatus(other, other_tc, arg1);
+}
+
+void helper_mtc0_tcbind(CPUMIPSState *env, target_ulong arg1)
+{
+ uint32_t mask = (1 << CP0TCBd_TBE);
+ uint32_t newval;
+
+ if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) {
+ mask |= (1 << CP0TCBd_CurVPE);
+ }
+ newval = (env->active_tc.CP0_TCBind & ~mask) | (arg1 & mask);
+ env->active_tc.CP0_TCBind = newval;
+}
+
+void helper_mttc0_tcbind(CPUMIPSState *env, target_ulong arg1)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ uint32_t mask = (1 << CP0TCBd_TBE);
+ uint32_t newval;
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) {
+ mask |= (1 << CP0TCBd_CurVPE);
+ }
+ if (other_tc == other->current_tc) {
+ newval = (other->active_tc.CP0_TCBind & ~mask) | (arg1 & mask);
+ other->active_tc.CP0_TCBind = newval;
+ } else {
+ newval = (other->tcs[other_tc].CP0_TCBind & ~mask) | (arg1 & mask);
+ other->tcs[other_tc].CP0_TCBind = newval;
+ }
+}
+
+void helper_mtc0_tcrestart(CPUMIPSState *env, target_ulong arg1)
+{
+ env->active_tc.PC = arg1;
+ env->active_tc.CP0_TCStatus &= ~(1 << CP0TCSt_TDS);
+ env->CP0_LLAddr = 0;
+ env->lladdr = 0;
+ /* MIPS16 not implemented. */
+}
+
+void helper_mttc0_tcrestart(CPUMIPSState *env, target_ulong arg1)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ other->active_tc.PC = arg1;
+ other->active_tc.CP0_TCStatus &= ~(1 << CP0TCSt_TDS);
+ other->CP0_LLAddr = 0;
+ other->lladdr = 0;
+ /* MIPS16 not implemented. */
+ } else {
+ other->tcs[other_tc].PC = arg1;
+ other->tcs[other_tc].CP0_TCStatus &= ~(1 << CP0TCSt_TDS);
+ other->CP0_LLAddr = 0;
+ other->lladdr = 0;
+ /* MIPS16 not implemented. */
+ }
+}
+
+void helper_mtc0_tchalt(CPUMIPSState *env, target_ulong arg1)
+{
+ MIPSCPU *cpu = env_archcpu(env);
+
+ env->active_tc.CP0_TCHalt = arg1 & 0x1;
+
+ /* TODO: Halt TC / Restart (if allocated+active) TC. */
+ if (env->active_tc.CP0_TCHalt & 1) {
+ mips_tc_sleep(cpu, env->current_tc);
+ } else {
+ mips_tc_wake(cpu, env->current_tc);
+ }
+}
+
+void helper_mttc0_tchalt(CPUMIPSState *env, target_ulong arg1)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ MIPSCPU *other_cpu = env_archcpu(other);
+
+ /* TODO: Halt TC / Restart (if allocated+active) TC. */
+
+ if (other_tc == other->current_tc) {
+ other->active_tc.CP0_TCHalt = arg1;
+ } else {
+ other->tcs[other_tc].CP0_TCHalt = arg1;
+ }
+
+ if (arg1 & 1) {
+ mips_tc_sleep(other_cpu, other_tc);
+ } else {
+ mips_tc_wake(other_cpu, other_tc);
+ }
+}
+
+void helper_mtc0_tccontext(CPUMIPSState *env, target_ulong arg1)
+{
+ env->active_tc.CP0_TCContext = arg1;
+}
+
+void helper_mttc0_tccontext(CPUMIPSState *env, target_ulong arg1)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ other->active_tc.CP0_TCContext = arg1;
+ } else {
+ other->tcs[other_tc].CP0_TCContext = arg1;
+ }
+}
+
+void helper_mtc0_tcschedule(CPUMIPSState *env, target_ulong arg1)
+{
+ env->active_tc.CP0_TCSchedule = arg1;
+}
+
+void helper_mttc0_tcschedule(CPUMIPSState *env, target_ulong arg1)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ other->active_tc.CP0_TCSchedule = arg1;
+ } else {
+ other->tcs[other_tc].CP0_TCSchedule = arg1;
+ }
+}
+
+void helper_mtc0_tcschefback(CPUMIPSState *env, target_ulong arg1)
+{
+ env->active_tc.CP0_TCScheFBack = arg1;
+}
+
+void helper_mttc0_tcschefback(CPUMIPSState *env, target_ulong arg1)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ other->active_tc.CP0_TCScheFBack = arg1;
+ } else {
+ other->tcs[other_tc].CP0_TCScheFBack = arg1;
+ }
+}
+
+void helper_mtc0_entrylo1(CPUMIPSState *env, target_ulong arg1)
+{
+ /* 1k pages not implemented */
+ target_ulong rxi = arg1 & (env->CP0_PageGrain & (3u << CP0PG_XIE));
+ env->CP0_EntryLo1 = (arg1 & MTC0_ENTRYLO_MASK(env))
+ | (rxi << (CP0EnLo_XI - 30));
+}
+
+#if defined(TARGET_MIPS64)
+void helper_dmtc0_entrylo1(CPUMIPSState *env, uint64_t arg1)
+{
+ uint64_t rxi = arg1 & ((env->CP0_PageGrain & (3ull << CP0PG_XIE)) << 32);
+ env->CP0_EntryLo1 = (arg1 & DMTC0_ENTRYLO_MASK(env)) | rxi;
+}
+#endif
+
+void helper_mtc0_context(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (arg1 & ~0x007FFFFF);
+}
+
+void helper_mtc0_memorymapid(CPUMIPSState *env, target_ulong arg1)
+{
+ int32_t old;
+ old = env->CP0_MemoryMapID;
+ env->CP0_MemoryMapID = (int32_t) arg1;
+ /* If the MemoryMapID changes, flush qemu's TLB. */
+ if (old != env->CP0_MemoryMapID) {
+ cpu_mips_tlb_flush(env);
+ }
+}
+
+void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t *pagemask)
+{
+ uint32_t mask;
+ int maskbits;
+
+ /* Don't care MASKX as we don't support 1KB page */
+ mask = extract32((uint32_t)arg1, CP0PM_MASK, 16);
+ maskbits = cto32(mask);
+
+ /* Ensure no more set bit after first zero */
+ if ((mask >> maskbits) != 0) {
+ goto invalid;
+ }
+ /* We don't support VTLB entry smaller than target page */
+ if ((maskbits + TARGET_PAGE_BITS_MIN) < TARGET_PAGE_BITS) {
+ goto invalid;
+ }
+ env->CP0_PageMask = mask << CP0PM_MASK;
+
+ return;
+
+invalid:
+ /* When invalid, set to default target page size. */
+ mask = (~TARGET_PAGE_MASK >> TARGET_PAGE_BITS_MIN);
+ env->CP0_PageMask = mask << CP0PM_MASK;
+}
+
+void helper_mtc0_pagemask(CPUMIPSState *env, target_ulong arg1)
+{
+ update_pagemask(env, arg1, &env->CP0_PageMask);
+}
+
+void helper_mtc0_pagegrain(CPUMIPSState *env, target_ulong arg1)
+{
+ /* SmartMIPS not implemented */
+ /* 1k pages not implemented */
+ env->CP0_PageGrain = (arg1 & env->CP0_PageGrain_rw_bitmask) |
+ (env->CP0_PageGrain & ~env->CP0_PageGrain_rw_bitmask);
+ compute_hflags(env);
+ restore_pamask(env);
+}
+
+void helper_mtc0_segctl0(CPUMIPSState *env, target_ulong arg1)
+{
+ CPUState *cs = env_cpu(env);
+
+ env->CP0_SegCtl0 = arg1 & CP0SC0_MASK;
+ tlb_flush(cs);
+}
+
+void helper_mtc0_segctl1(CPUMIPSState *env, target_ulong arg1)
+{
+ CPUState *cs = env_cpu(env);
+
+ env->CP0_SegCtl1 = arg1 & CP0SC1_MASK;
+ tlb_flush(cs);
+}
+
+void helper_mtc0_segctl2(CPUMIPSState *env, target_ulong arg1)
+{
+ CPUState *cs = env_cpu(env);
+
+ env->CP0_SegCtl2 = arg1 & CP0SC2_MASK;
+ tlb_flush(cs);
+}
+
+void helper_mtc0_pwfield(CPUMIPSState *env, target_ulong arg1)
+{
+#if defined(TARGET_MIPS64)
+ uint64_t mask = 0x3F3FFFFFFFULL;
+ uint32_t old_ptei = (env->CP0_PWField >> CP0PF_PTEI) & 0x3FULL;
+ uint32_t new_ptei = (arg1 >> CP0PF_PTEI) & 0x3FULL;
+
+ if ((env->insn_flags & ISA_MIPS_R6)) {
+ if (((arg1 >> CP0PF_BDI) & 0x3FULL) < 12) {
+ mask &= ~(0x3FULL << CP0PF_BDI);
+ }
+ if (((arg1 >> CP0PF_GDI) & 0x3FULL) < 12) {
+ mask &= ~(0x3FULL << CP0PF_GDI);
+ }
+ if (((arg1 >> CP0PF_UDI) & 0x3FULL) < 12) {
+ mask &= ~(0x3FULL << CP0PF_UDI);
+ }
+ if (((arg1 >> CP0PF_MDI) & 0x3FULL) < 12) {
+ mask &= ~(0x3FULL << CP0PF_MDI);
+ }
+ if (((arg1 >> CP0PF_PTI) & 0x3FULL) < 12) {
+ mask &= ~(0x3FULL << CP0PF_PTI);
+ }
+ }
+ env->CP0_PWField = arg1 & mask;
+
+ if ((new_ptei >= 32) ||
+ ((env->insn_flags & ISA_MIPS_R6) &&
+ (new_ptei == 0 || new_ptei == 1))) {
+ env->CP0_PWField = (env->CP0_PWField & ~0x3FULL) |
+ (old_ptei << CP0PF_PTEI);
+ }
+#else
+ uint32_t mask = 0x3FFFFFFF;
+ uint32_t old_ptew = (env->CP0_PWField >> CP0PF_PTEW) & 0x3F;
+ uint32_t new_ptew = (arg1 >> CP0PF_PTEW) & 0x3F;
+
+ if ((env->insn_flags & ISA_MIPS_R6)) {
+ if (((arg1 >> CP0PF_GDW) & 0x3F) < 12) {
+ mask &= ~(0x3F << CP0PF_GDW);
+ }
+ if (((arg1 >> CP0PF_UDW) & 0x3F) < 12) {
+ mask &= ~(0x3F << CP0PF_UDW);
+ }
+ if (((arg1 >> CP0PF_MDW) & 0x3F) < 12) {
+ mask &= ~(0x3F << CP0PF_MDW);
+ }
+ if (((arg1 >> CP0PF_PTW) & 0x3F) < 12) {
+ mask &= ~(0x3F << CP0PF_PTW);
+ }
+ }
+ env->CP0_PWField = arg1 & mask;
+
+ if ((new_ptew >= 32) ||
+ ((env->insn_flags & ISA_MIPS_R6) &&
+ (new_ptew == 0 || new_ptew == 1))) {
+ env->CP0_PWField = (env->CP0_PWField & ~0x3F) |
+ (old_ptew << CP0PF_PTEW);
+ }
+#endif
+}
+
+void helper_mtc0_pwsize(CPUMIPSState *env, target_ulong arg1)
+{
+#if defined(TARGET_MIPS64)
+ env->CP0_PWSize = arg1 & 0x3F7FFFFFFFULL;
+#else
+ env->CP0_PWSize = arg1 & 0x3FFFFFFF;
+#endif
+}
+
+void helper_mtc0_wired(CPUMIPSState *env, target_ulong arg1)
+{
+ if (env->insn_flags & ISA_MIPS_R6) {
+ if (arg1 < env->tlb->nb_tlb) {
+ env->CP0_Wired = arg1;
+ }
+ } else {
+ env->CP0_Wired = arg1 % env->tlb->nb_tlb;
+ }
+}
+
+void helper_mtc0_pwctl(CPUMIPSState *env, target_ulong arg1)
+{
+#if defined(TARGET_MIPS64)
+ /* PWEn = 0. Hardware page table walking is not implemented. */
+ env->CP0_PWCtl = (env->CP0_PWCtl & 0x000000C0) | (arg1 & 0x5C00003F);
+#else
+ env->CP0_PWCtl = (arg1 & 0x800000FF);
+#endif
+}
+
+void helper_mtc0_srsconf0(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_SRSConf0 |= arg1 & env->CP0_SRSConf0_rw_bitmask;
+}
+
+void helper_mtc0_srsconf1(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_SRSConf1 |= arg1 & env->CP0_SRSConf1_rw_bitmask;
+}
+
+void helper_mtc0_srsconf2(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_SRSConf2 |= arg1 & env->CP0_SRSConf2_rw_bitmask;
+}
+
+void helper_mtc0_srsconf3(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_SRSConf3 |= arg1 & env->CP0_SRSConf3_rw_bitmask;
+}
+
+void helper_mtc0_srsconf4(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_SRSConf4 |= arg1 & env->CP0_SRSConf4_rw_bitmask;
+}
+
+void helper_mtc0_hwrena(CPUMIPSState *env, target_ulong arg1)
+{
+ uint32_t mask = 0x0000000F;
+
+ if ((env->CP0_Config1 & (1 << CP0C1_PC)) &&
+ (env->insn_flags & ISA_MIPS_R6)) {
+ mask |= (1 << 4);
+ }
+ if (env->insn_flags & ISA_MIPS_R6) {
+ mask |= (1 << 5);
+ }
+ if (env->CP0_Config3 & (1 << CP0C3_ULRI)) {
+ mask |= (1 << 29);
+
+ if (arg1 & (1 << 29)) {
+ env->hflags |= MIPS_HFLAG_HWRENA_ULR;
+ } else {
+ env->hflags &= ~MIPS_HFLAG_HWRENA_ULR;
+ }
+ }
+
+ env->CP0_HWREna = arg1 & mask;
+}
+
+void helper_mtc0_count(CPUMIPSState *env, target_ulong arg1)
+{
+ cpu_mips_store_count(env, arg1);
+}
+
+void helper_mtc0_entryhi(CPUMIPSState *env, target_ulong arg1)
+{
+ target_ulong old, val, mask;
+ mask = (TARGET_PAGE_MASK << 1) | env->CP0_EntryHi_ASID_mask;
+ if (((env->CP0_Config4 >> CP0C4_IE) & 0x3) >= 2) {
+ mask |= 1 << CP0EnHi_EHINV;
+ }
+
+ /* 1k pages not implemented */
+#if defined(TARGET_MIPS64)
+ if (env->insn_flags & ISA_MIPS_R6) {
+ int entryhi_r = extract64(arg1, 62, 2);
+ int config0_at = extract32(env->CP0_Config0, 13, 2);
+ bool no_supervisor = (env->CP0_Status_rw_bitmask & 0x8) == 0;
+ if ((entryhi_r == 2) ||
+ (entryhi_r == 1 && (no_supervisor || config0_at == 1))) {
+ /* skip EntryHi.R field if new value is reserved */
+ mask &= ~(0x3ull << 62);
+ }
+ }
+ mask &= env->SEGMask;
+#endif
+ old = env->CP0_EntryHi;
+ val = (arg1 & mask) | (old & ~mask);
+ env->CP0_EntryHi = val;
+ if (ase_mt_available(env)) {
+ sync_c0_entryhi(env, env->current_tc);
+ }
+ /* If the ASID changes, flush qemu's TLB. */
+ if ((old & env->CP0_EntryHi_ASID_mask) !=
+ (val & env->CP0_EntryHi_ASID_mask)) {
+ tlb_flush(env_cpu(env));
+ }
+}
+
+void helper_mttc0_entryhi(CPUMIPSState *env, target_ulong arg1)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ other->CP0_EntryHi = arg1;
+ sync_c0_entryhi(other, other_tc);
+}
+
+void helper_mtc0_compare(CPUMIPSState *env, target_ulong arg1)
+{
+ cpu_mips_store_compare(env, arg1);
+}
+
+void helper_mtc0_status(CPUMIPSState *env, target_ulong arg1)
+{
+ uint32_t val, old;
+
+ old = env->CP0_Status;
+ cpu_mips_store_status(env, arg1);
+ val = env->CP0_Status;
+
+ if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
+ qemu_log("Status %08x (%08x) => %08x (%08x) Cause %08x",
+ old, old & env->CP0_Cause & CP0Ca_IP_mask,
+ val, val & env->CP0_Cause & CP0Ca_IP_mask,
+ env->CP0_Cause);
+ switch (mips_env_mmu_index(env)) {
+ case 3:
+ qemu_log(", ERL\n");
+ break;
+ case MIPS_HFLAG_UM:
+ qemu_log(", UM\n");
+ break;
+ case MIPS_HFLAG_SM:
+ qemu_log(", SM\n");
+ break;
+ case MIPS_HFLAG_KM:
+ qemu_log("\n");
+ break;
+ default:
+ cpu_abort(env_cpu(env), "Invalid MMU mode!\n");
+ break;
+ }
+ }
+}
+
+void helper_mttc0_status(CPUMIPSState *env, target_ulong arg1)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ uint32_t mask = env->CP0_Status_rw_bitmask & ~0xf1000018;
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ other->CP0_Status = (other->CP0_Status & ~mask) | (arg1 & mask);
+ sync_c0_status(env, other, other_tc);
+}
+
+void helper_mtc0_intctl(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000003e0) | (arg1 & 0x000003e0);
+}
+
+void helper_mtc0_srsctl(CPUMIPSState *env, target_ulong arg1)
+{
+ uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS);
+ env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (arg1 & mask);
+}
+
+void helper_mtc0_cause(CPUMIPSState *env, target_ulong arg1)
+{
+ cpu_mips_store_cause(env, arg1);
+}
+
+void helper_mttc0_cause(CPUMIPSState *env, target_ulong arg1)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ cpu_mips_store_cause(other, arg1);
+}
+
+target_ulong helper_mftc0_epc(CPUMIPSState *env)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ return other->CP0_EPC;
+}
+
+target_ulong helper_mftc0_ebase(CPUMIPSState *env)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ return other->CP0_EBase;
+}
+
+void helper_mtc0_ebase(CPUMIPSState *env, target_ulong arg1)
+{
+ target_ulong mask = 0x3FFFF000 | env->CP0_EBaseWG_rw_bitmask;
+ if (arg1 & env->CP0_EBaseWG_rw_bitmask) {
+ mask |= ~0x3FFFFFFF;
+ }
+ env->CP0_EBase = (env->CP0_EBase & ~mask) | (arg1 & mask);
+}
+
+void helper_mttc0_ebase(CPUMIPSState *env, target_ulong arg1)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ target_ulong mask = 0x3FFFF000 | env->CP0_EBaseWG_rw_bitmask;
+ if (arg1 & env->CP0_EBaseWG_rw_bitmask) {
+ mask |= ~0x3FFFFFFF;
+ }
+ other->CP0_EBase = (other->CP0_EBase & ~mask) | (arg1 & mask);
+}
+
+target_ulong helper_mftc0_configx(CPUMIPSState *env, target_ulong idx)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ switch (idx) {
+ case 0: return other->CP0_Config0;
+ case 1: return other->CP0_Config1;
+ case 2: return other->CP0_Config2;
+ case 3: return other->CP0_Config3;
+ /* 4 and 5 are reserved. */
+ case 6: return other->CP0_Config6;
+ case 7: return other->CP0_Config7;
+ default:
+ break;
+ }
+ return 0;
+}
+
+void helper_mtc0_config0(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (arg1 & 0x00000007);
+}
+
+void helper_mtc0_config2(CPUMIPSState *env, target_ulong arg1)
+{
+ /* tertiary/secondary caches not implemented */
+ env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
+}
+
+void helper_mtc0_config3(CPUMIPSState *env, target_ulong arg1)
+{
+ if (env->insn_flags & ASE_MICROMIPS) {
+ env->CP0_Config3 = (env->CP0_Config3 & ~(1 << CP0C3_ISA_ON_EXC)) |
+ (arg1 & (1 << CP0C3_ISA_ON_EXC));
+ }
+}
+
+void helper_mtc0_config4(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_Config4 = (env->CP0_Config4 & (~env->CP0_Config4_rw_bitmask)) |
+ (arg1 & env->CP0_Config4_rw_bitmask);
+}
+
+void helper_mtc0_config5(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_Config5 = (env->CP0_Config5 & (~env->CP0_Config5_rw_bitmask)) |
+ (arg1 & env->CP0_Config5_rw_bitmask);
+ env->CP0_EntryHi_ASID_mask = (env->CP0_Config5 & (1 << CP0C5_MI)) ?
+ 0x0 : (env->CP0_Config4 & (1 << CP0C4_AE)) ? 0x3ff : 0xff;
+ compute_hflags(env);
+}
+
+void helper_mtc0_lladdr(CPUMIPSState *env, target_ulong arg1)
+{
+ target_long mask = env->CP0_LLAddr_rw_bitmask;
+ arg1 = arg1 << env->CP0_LLAddr_shift;
+ env->CP0_LLAddr = (env->CP0_LLAddr & ~mask) | (arg1 & mask);
+}
+
+#define MTC0_MAAR_MASK(env) \
+ ((0x1ULL << 63) | ((env->PAMask >> 4) & ~0xFFFull) | 0x3)
+
+void helper_mtc0_maar(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_MAAR[env->CP0_MAARI] = arg1 & MTC0_MAAR_MASK(env);
+}
+
+void helper_mthc0_maar(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_MAAR[env->CP0_MAARI] =
+ (((uint64_t) arg1 << 32) & MTC0_MAAR_MASK(env)) |
+ (env->CP0_MAAR[env->CP0_MAARI] & 0x00000000ffffffffULL);
+}
+
+void helper_mtc0_maari(CPUMIPSState *env, target_ulong arg1)
+{
+ int index = arg1 & 0x3f;
+ if (index == 0x3f) {
+ /*
+ * Software may write all ones to INDEX to determine the
+ * maximum value supported.
+ */
+ env->CP0_MAARI = MIPS_MAAR_MAX - 1;
+ } else if (index < MIPS_MAAR_MAX) {
+ env->CP0_MAARI = index;
+ }
+ /*
+ * Other than the all ones, if the value written is not supported,
+ * then INDEX is unchanged from its previous value.
+ */
+}
+
+void helper_mtc0_watchlo(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
+{
+ /*
+ * Watch exceptions for instructions, data loads, data stores
+ * not implemented.
+ */
+ env->CP0_WatchLo[sel] = (arg1 & ~0x7);
+}
+
+void helper_mtc0_watchhi(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
+{
+ uint64_t mask = 0x40000FF8 | (env->CP0_EntryHi_ASID_mask << CP0WH_ASID);
+ uint64_t m_bit = env->CP0_WatchHi[sel] & (1 << CP0WH_M); /* read-only */
+ if ((env->CP0_Config5 >> CP0C5_MI) & 1) {
+ mask |= 0xFFFFFFFF00000000ULL; /* MMID */
+ }
+ env->CP0_WatchHi[sel] = m_bit | (arg1 & mask);
+ env->CP0_WatchHi[sel] &= ~(env->CP0_WatchHi[sel] & arg1 & 0x7);
+}
+
+void helper_mthc0_watchhi(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
+{
+ env->CP0_WatchHi[sel] = ((uint64_t) (arg1) << 32) |
+ (env->CP0_WatchHi[sel] & 0x00000000ffffffffULL);
+}
+
+void helper_mtc0_xcontext(CPUMIPSState *env, target_ulong arg1)
+{
+ target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
+ env->CP0_XContext = (env->CP0_XContext & mask) | (arg1 & ~mask);
+}
+
+void helper_mtc0_framemask(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_Framemask = arg1; /* XXX */
+}
+
+void helper_mtc0_debug(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (arg1 & 0x13300120);
+ if (arg1 & (1 << CP0DB_DM)) {
+ env->hflags |= MIPS_HFLAG_DM;
+ } else {
+ env->hflags &= ~MIPS_HFLAG_DM;
+ }
+}
+
+void helper_mttc0_debug(CPUMIPSState *env, target_ulong arg1)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ uint32_t val = arg1 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ /* XXX: Might be wrong, check with EJTAG spec. */
+ if (other_tc == other->current_tc) {
+ other->active_tc.CP0_Debug_tcstatus = val;
+ } else {
+ other->tcs[other_tc].CP0_Debug_tcstatus = val;
+ }
+ other->CP0_Debug = (other->CP0_Debug &
+ ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
+ (arg1 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
+}
+
+void helper_mtc0_performance0(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_Performance0 = arg1 & 0x000007ff;
+}
+
+void helper_mtc0_errctl(CPUMIPSState *env, target_ulong arg1)
+{
+ int32_t wst = arg1 & (1 << CP0EC_WST);
+ int32_t spr = arg1 & (1 << CP0EC_SPR);
+ int32_t itc = env->itc_tag ? (arg1 & (1 << CP0EC_ITC)) : 0;
+
+ env->CP0_ErrCtl = wst | spr | itc;
+
+ if (itc && !wst && !spr) {
+ env->hflags |= MIPS_HFLAG_ITC_CACHE;
+ } else {
+ env->hflags &= ~MIPS_HFLAG_ITC_CACHE;
+ }
+}
+
+void helper_mtc0_taglo(CPUMIPSState *env, target_ulong arg1)
+{
+ if (env->hflags & MIPS_HFLAG_ITC_CACHE) {
+ /*
+ * If CACHE instruction is configured for ITC tags then make all
+ * CP0.TagLo bits writable. The actual write to ITC Configuration
+ * Tag will take care of the read-only bits.
+ */
+ env->CP0_TagLo = arg1;
+ } else {
+ env->CP0_TagLo = arg1 & 0xFFFFFCF6;
+ }
+}
+
+void helper_mtc0_datalo(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_DataLo = arg1; /* XXX */
+}
+
+void helper_mtc0_taghi(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_TagHi = arg1; /* XXX */
+}
+
+void helper_mtc0_datahi(CPUMIPSState *env, target_ulong arg1)
+{
+ env->CP0_DataHi = arg1; /* XXX */
+}
+
+/* MIPS MT functions */
+target_ulong helper_mftgpr(CPUMIPSState *env, uint32_t sel)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ return other->active_tc.gpr[sel];
+ } else {
+ return other->tcs[other_tc].gpr[sel];
+ }
+}
+
+target_ulong helper_mftlo(CPUMIPSState *env, uint32_t sel)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ return other->active_tc.LO[sel];
+ } else {
+ return other->tcs[other_tc].LO[sel];
+ }
+}
+
+target_ulong helper_mfthi(CPUMIPSState *env, uint32_t sel)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ return other->active_tc.HI[sel];
+ } else {
+ return other->tcs[other_tc].HI[sel];
+ }
+}
+
+target_ulong helper_mftacx(CPUMIPSState *env, uint32_t sel)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ return other->active_tc.ACX[sel];
+ } else {
+ return other->tcs[other_tc].ACX[sel];
+ }
+}
+
+target_ulong helper_mftdsp(CPUMIPSState *env)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ return other->active_tc.DSPControl;
+ } else {
+ return other->tcs[other_tc].DSPControl;
+ }
+}
+
+void helper_mttgpr(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ other->active_tc.gpr[sel] = arg1;
+ } else {
+ other->tcs[other_tc].gpr[sel] = arg1;
+ }
+}
+
+void helper_mttlo(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ other->active_tc.LO[sel] = arg1;
+ } else {
+ other->tcs[other_tc].LO[sel] = arg1;
+ }
+}
+
+void helper_mtthi(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ other->active_tc.HI[sel] = arg1;
+ } else {
+ other->tcs[other_tc].HI[sel] = arg1;
+ }
+}
+
+void helper_mttacx(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ other->active_tc.ACX[sel] = arg1;
+ } else {
+ other->tcs[other_tc].ACX[sel] = arg1;
+ }
+}
+
+void helper_mttdsp(CPUMIPSState *env, target_ulong arg1)
+{
+ int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+ CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+
+ if (other_tc == other->current_tc) {
+ other->active_tc.DSPControl = arg1;
+ } else {
+ other->tcs[other_tc].DSPControl = arg1;
+ }
+}
+
+/* MIPS MT functions */
+target_ulong helper_dmt(void)
+{
+ /* TODO */
+ return 0;
+}
+
+target_ulong helper_emt(void)
+{
+ /* TODO */
+ return 0;
+}
+
+target_ulong helper_dvpe(CPUMIPSState *env)
+{
+ CPUState *other_cs = first_cpu;
+ target_ulong prev = env->mvp->CP0_MVPControl;
+
+ CPU_FOREACH(other_cs) {
+ MIPSCPU *other_cpu = MIPS_CPU(other_cs);
+ /* Turn off all VPEs except the one executing the dvpe. */
+ if (&other_cpu->env != env) {
+ other_cpu->env.mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP);
+ mips_vpe_sleep(other_cpu);
+ }
+ }
+ return prev;
+}
+
+target_ulong helper_evpe(CPUMIPSState *env)
+{
+ CPUState *other_cs = first_cpu;
+ target_ulong prev = env->mvp->CP0_MVPControl;
+
+ CPU_FOREACH(other_cs) {
+ MIPSCPU *other_cpu = MIPS_CPU(other_cs);
+
+ if (&other_cpu->env != env
+ /* If the VPE is WFI, don't disturb its sleep. */
+ && !mips_vpe_is_wfi(other_cpu)) {
+ /* Enable the VPE. */
+ other_cpu->env.mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
+ mips_vpe_wake(other_cpu); /* And wake it up. */
+ }
+ }
+ return prev;
+}
+
+/* R6 Multi-threading */
+target_ulong helper_dvp(CPUMIPSState *env)
+{
+ CPUState *other_cs = first_cpu;
+ target_ulong prev = env->CP0_VPControl;
+
+ if (!((env->CP0_VPControl >> CP0VPCtl_DIS) & 1)) {
+ CPU_FOREACH(other_cs) {
+ MIPSCPU *other_cpu = MIPS_CPU(other_cs);
+ /* Turn off all VPs except the one executing the dvp. */
+ if (&other_cpu->env != env) {
+ mips_vpe_sleep(other_cpu);
+ }
+ }
+ env->CP0_VPControl |= (1 << CP0VPCtl_DIS);
+ }
+ return prev;
+}
+
+target_ulong helper_evp(CPUMIPSState *env)
+{
+ CPUState *other_cs = first_cpu;
+ target_ulong prev = env->CP0_VPControl;
+
+ if ((env->CP0_VPControl >> CP0VPCtl_DIS) & 1) {
+ CPU_FOREACH(other_cs) {
+ MIPSCPU *other_cpu = MIPS_CPU(other_cs);
+ if ((&other_cpu->env != env) && !mips_vp_is_wfi(other_cpu)) {
+ /*
+ * If the VP is WFI, don't disturb its sleep.
+ * Otherwise, wake it up.
+ */
+ mips_vpe_wake(other_cpu);
+ }
+ }
+ env->CP0_VPControl &= ~(1 << CP0VPCtl_DIS);
+ }
+ return prev;
+}
--- /dev/null
+/*
+ * Loongson CSR instructions translation routines
+ *
+ * Copyright (c) 2023 Jiaxun Yang <jiaxun.yang@flygoat.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "exec/helper-proto.h"
+
+#define GET_MEMTXATTRS(cas) \
+ ((MemTxAttrs){.requester_id = env_cpu(cas)->cpu_index})
+
+uint64_t helper_lcsr_rdcsr(CPUMIPSState *env, target_ulong r_addr)
+{
+ return address_space_ldl(&env->iocsr.as, r_addr,
+ GET_MEMTXATTRS(env), NULL);
+}
+
+uint64_t helper_lcsr_drdcsr(CPUMIPSState *env, target_ulong r_addr)
+{
+ return address_space_ldq(&env->iocsr.as, r_addr,
+ GET_MEMTXATTRS(env), NULL);
+}
+
+void helper_lcsr_wrcsr(CPUMIPSState *env, target_ulong w_addr,
+ target_ulong val)
+{
+ address_space_stl(&env->iocsr.as, w_addr,
+ val, GET_MEMTXATTRS(env), NULL);
+}
+
+void helper_lcsr_dwrcsr(CPUMIPSState *env, target_ulong w_addr,
+ target_ulong val)
+{
+ address_space_stq(&env->iocsr.as, w_addr,
+ val, GET_MEMTXATTRS(env), NULL);
+}
--- /dev/null
+mips_system_ss.add(files(
+ 'cp0_helper.c',
+ 'special_helper.c',
+ 'tlb_helper.c',
+))
+mips_system_ss.add(when: ['CONFIG_SEMIHOSTING'],
+ if_true: files('mips-semi.c'),
+ if_false: files('semihosting-stub.c')
+)
+mips_system_ss.add(when: 'TARGET_MIPS64', if_true: files(
+ 'lcsr_helper.c',
+))
--- /dev/null
+/*
+ * Unified Hosting Interface syscalls.
+ *
+ * Copyright (c) 2015 Imagination Technologies
+ *
+ * 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.1 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 "qemu/log.h"
+#include "gdbstub/syscalls.h"
+#include "gdbstub/helpers.h"
+#include "semihosting/uaccess.h"
+#include "semihosting/semihost.h"
+#include "semihosting/console.h"
+#include "semihosting/syscalls.h"
+#include "internal.h"
+
+typedef enum UHIOp {
+ UHI_exit = 1,
+ UHI_open = 2,
+ UHI_close = 3,
+ UHI_read = 4,
+ UHI_write = 5,
+ UHI_lseek = 6,
+ UHI_unlink = 7,
+ UHI_fstat = 8,
+ UHI_argc = 9,
+ UHI_argnlen = 10,
+ UHI_argn = 11,
+ UHI_plog = 13,
+ UHI_assert = 14,
+ UHI_pread = 19,
+ UHI_pwrite = 20,
+ UHI_link = 22
+} UHIOp;
+
+typedef struct UHIStat {
+ int16_t uhi_st_dev;
+ uint16_t uhi_st_ino;
+ uint32_t uhi_st_mode;
+ uint16_t uhi_st_nlink;
+ uint16_t uhi_st_uid;
+ uint16_t uhi_st_gid;
+ int16_t uhi_st_rdev;
+ uint64_t uhi_st_size;
+ uint64_t uhi_st_atime;
+ uint64_t uhi_st_spare1;
+ uint64_t uhi_st_mtime;
+ uint64_t uhi_st_spare2;
+ uint64_t uhi_st_ctime;
+ uint64_t uhi_st_spare3;
+ uint64_t uhi_st_blksize;
+ uint64_t uhi_st_blocks;
+ uint64_t uhi_st_spare4[2];
+} UHIStat;
+
+enum UHIOpenFlags {
+ UHIOpen_RDONLY = 0x0,
+ UHIOpen_WRONLY = 0x1,
+ UHIOpen_RDWR = 0x2,
+ UHIOpen_APPEND = 0x8,
+ UHIOpen_CREAT = 0x200,
+ UHIOpen_TRUNC = 0x400,
+ UHIOpen_EXCL = 0x800
+};
+
+enum UHIErrno {
+ UHI_EACCESS = 13,
+ UHI_EAGAIN = 11,
+ UHI_EBADF = 9,
+ UHI_EBADMSG = 77,
+ UHI_EBUSY = 16,
+ UHI_ECONNRESET = 104,
+ UHI_EEXIST = 17,
+ UHI_EFBIG = 27,
+ UHI_EINTR = 4,
+ UHI_EINVAL = 22,
+ UHI_EIO = 5,
+ UHI_EISDIR = 21,
+ UHI_ELOOP = 92,
+ UHI_EMFILE = 24,
+ UHI_EMLINK = 31,
+ UHI_ENAMETOOLONG = 91,
+ UHI_ENETDOWN = 115,
+ UHI_ENETUNREACH = 114,
+ UHI_ENFILE = 23,
+ UHI_ENOBUFS = 105,
+ UHI_ENOENT = 2,
+ UHI_ENOMEM = 12,
+ UHI_ENOSPC = 28,
+ UHI_ENOSR = 63,
+ UHI_ENOTCONN = 128,
+ UHI_ENOTDIR = 20,
+ UHI_ENXIO = 6,
+ UHI_EOVERFLOW = 139,
+ UHI_EPERM = 1,
+ UHI_EPIPE = 32,
+ UHI_ERANGE = 34,
+ UHI_EROFS = 30,
+ UHI_ESPIPE = 29,
+ UHI_ETIMEDOUT = 116,
+ UHI_ETXTBSY = 26,
+ UHI_EWOULDBLOCK = 11,
+ UHI_EXDEV = 18,
+};
+
+static void report_fault(CPUMIPSState *env)
+{
+ int op = env->active_tc.gpr[25];
+ error_report("Fault during UHI operation %d", op);
+ abort();
+}
+
+static void uhi_cb(CPUState *cs, uint64_t ret, int err)
+{
+ CPUMIPSState *env = cpu_env(cs);
+
+#define E(N) case E##N: err = UHI_E##N; break
+
+ switch (err) {
+ case 0:
+ break;
+ E(PERM);
+ E(NOENT);
+ E(INTR);
+ E(BADF);
+ E(BUSY);
+ E(EXIST);
+ E(NOTDIR);
+ E(ISDIR);
+ E(INVAL);
+ E(NFILE);
+ E(MFILE);
+ E(FBIG);
+ E(NOSPC);
+ E(SPIPE);
+ E(ROFS);
+ E(NAMETOOLONG);
+ default:
+ err = UHI_EINVAL;
+ break;
+ case EFAULT:
+ report_fault(env);
+ }
+
+#undef E
+
+ env->active_tc.gpr[2] = ret;
+ env->active_tc.gpr[3] = err;
+}
+
+static void uhi_fstat_cb(CPUState *cs, uint64_t ret, int err)
+{
+ QEMU_BUILD_BUG_ON(sizeof(UHIStat) < sizeof(struct gdb_stat));
+
+ if (!err) {
+ CPUMIPSState *env = cpu_env(cs);
+ target_ulong addr = env->active_tc.gpr[5];
+ UHIStat *dst = lock_user(VERIFY_WRITE, addr, sizeof(UHIStat), 1);
+ struct gdb_stat s;
+
+ if (!dst) {
+ report_fault(env);
+ }
+
+ memcpy(&s, dst, sizeof(struct gdb_stat));
+ memset(dst, 0, sizeof(UHIStat));
+
+ dst->uhi_st_dev = tswap16(be32_to_cpu(s.gdb_st_dev));
+ dst->uhi_st_ino = tswap16(be32_to_cpu(s.gdb_st_ino));
+ dst->uhi_st_mode = tswap32(be32_to_cpu(s.gdb_st_mode));
+ dst->uhi_st_nlink = tswap16(be32_to_cpu(s.gdb_st_nlink));
+ dst->uhi_st_uid = tswap16(be32_to_cpu(s.gdb_st_uid));
+ dst->uhi_st_gid = tswap16(be32_to_cpu(s.gdb_st_gid));
+ dst->uhi_st_rdev = tswap16(be32_to_cpu(s.gdb_st_rdev));
+ dst->uhi_st_size = tswap64(be64_to_cpu(s.gdb_st_size));
+ dst->uhi_st_atime = tswap64(be32_to_cpu(s.gdb_st_atime));
+ dst->uhi_st_mtime = tswap64(be32_to_cpu(s.gdb_st_mtime));
+ dst->uhi_st_ctime = tswap64(be32_to_cpu(s.gdb_st_ctime));
+ dst->uhi_st_blksize = tswap64(be64_to_cpu(s.gdb_st_blksize));
+ dst->uhi_st_blocks = tswap64(be64_to_cpu(s.gdb_st_blocks));
+
+ unlock_user(dst, addr, sizeof(UHIStat));
+ }
+
+ uhi_cb(cs, ret, err);
+}
+
+void mips_semihosting(CPUMIPSState *env)
+{
+ CPUState *cs = env_cpu(env);
+ target_ulong *gpr = env->active_tc.gpr;
+ const UHIOp op = gpr[25];
+ char *p;
+
+ switch (op) {
+ case UHI_exit:
+ gdb_exit(gpr[4]);
+ exit(gpr[4]);
+
+ case UHI_open:
+ {
+ target_ulong fname = gpr[4];
+ int ret = -1;
+
+ p = lock_user_string(fname);
+ if (!p) {
+ report_fault(env);
+ }
+ if (!strcmp("/dev/stdin", p)) {
+ ret = 0;
+ } else if (!strcmp("/dev/stdout", p)) {
+ ret = 1;
+ } else if (!strcmp("/dev/stderr", p)) {
+ ret = 2;
+ }
+ unlock_user(p, fname, 0);
+
+ /* FIXME: reusing a guest fd doesn't seem correct. */
+ if (ret >= 0) {
+ gpr[2] = ret;
+ break;
+ }
+
+ semihost_sys_open(cs, uhi_cb, fname, 0, gpr[5], gpr[6]);
+ }
+ break;
+
+ case UHI_close:
+ semihost_sys_close(cs, uhi_cb, gpr[4]);
+ break;
+ case UHI_read:
+ semihost_sys_read(cs, uhi_cb, gpr[4], gpr[5], gpr[6]);
+ break;
+ case UHI_write:
+ semihost_sys_write(cs, uhi_cb, gpr[4], gpr[5], gpr[6]);
+ break;
+ case UHI_lseek:
+ semihost_sys_lseek(cs, uhi_cb, gpr[4], gpr[5], gpr[6]);
+ break;
+ case UHI_unlink:
+ semihost_sys_remove(cs, uhi_cb, gpr[4], 0);
+ break;
+ case UHI_fstat:
+ semihost_sys_fstat(cs, uhi_fstat_cb, gpr[4], gpr[5]);
+ break;
+
+ case UHI_argc:
+ gpr[2] = semihosting_get_argc();
+ break;
+ case UHI_argnlen:
+ {
+ const char *s = semihosting_get_arg(gpr[4]);
+ gpr[2] = s ? strlen(s) : -1;
+ }
+ break;
+ case UHI_argn:
+ {
+ const char *s = semihosting_get_arg(gpr[4]);
+ target_ulong addr;
+ size_t len;
+
+ if (!s) {
+ gpr[2] = -1;
+ break;
+ }
+ len = strlen(s) + 1;
+ addr = gpr[5];
+ p = lock_user(VERIFY_WRITE, addr, len, 0);
+ if (!p) {
+ report_fault(env);
+ }
+ memcpy(p, s, len);
+ unlock_user(p, addr, len);
+ gpr[2] = 0;
+ }
+ break;
+
+ case UHI_plog:
+ {
+ target_ulong addr = gpr[4];
+ ssize_t len = target_strlen(addr);
+ GString *str;
+ char *pct_d;
+
+ if (len < 0) {
+ report_fault(env);
+ }
+ p = lock_user(VERIFY_READ, addr, len, 1);
+ if (!p) {
+ report_fault(env);
+ }
+
+ pct_d = strstr(p, "%d");
+ if (!pct_d) {
+ unlock_user(p, addr, 0);
+ semihost_sys_write(cs, uhi_cb, 2, addr, len);
+ break;
+ }
+
+ str = g_string_new_len(p, pct_d - p);
+ g_string_append_printf(str, "%d%s", (int)gpr[5], pct_d + 2);
+ unlock_user(p, addr, 0);
+
+ /*
+ * When we're using gdb, we need a guest address, so
+ * drop the string onto the stack below the stack pointer.
+ */
+ if (use_gdb_syscalls()) {
+ addr = gpr[29] - str->len;
+ p = lock_user(VERIFY_WRITE, addr, str->len, 0);
+ if (!p) {
+ report_fault(env);
+ }
+ memcpy(p, str->str, str->len);
+ unlock_user(p, addr, str->len);
+ semihost_sys_write(cs, uhi_cb, 2, addr, str->len);
+ } else {
+ gpr[2] = qemu_semihosting_console_write(str->str, str->len);
+ }
+ g_string_free(str, true);
+ }
+ break;
+
+ case UHI_assert:
+ {
+ const char *msg, *file;
+
+ msg = lock_user_string(gpr[4]);
+ if (!msg) {
+ msg = "<EFAULT>";
+ }
+ file = lock_user_string(gpr[5]);
+ if (!file) {
+ file = "<EFAULT>";
+ }
+
+ error_report("UHI assertion \"%s\": file \"%s\", line %d",
+ msg, file, (int)gpr[6]);
+ abort();
+ }
+
+ default:
+ error_report("Unknown UHI operation %d", op);
+ abort();
+ }
+ return;
+}
--- /dev/null
+/*
+ * MIPS semihosting stub
+ *
+ * SPDX-FileContributor: Philippe Mathieu-Daudé <philmd@linaro.org>
+ * SPDX-FileCopyrightText: 2024 Linaro Ltd.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "internal.h"
+
+void mips_semihosting(CPUMIPSState *env)
+{
+ g_assert_not_reached();
+}
--- /dev/null
+/*
+ * QEMU MIPS emulation: Special opcode helpers
+ *
+ * Copyright (c) 2004-2005 Jocelyn Mayer
+ *
+ * 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.1 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 "qemu/log.h"
+#include "cpu.h"
+#include "exec/helper-proto.h"
+#include "exec/exec-all.h"
+#include "internal.h"
+
+/* Specials */
+target_ulong helper_di(CPUMIPSState *env)
+{
+ target_ulong t0 = env->CP0_Status;
+
+ env->CP0_Status = t0 & ~(1 << CP0St_IE);
+ return t0;
+}
+
+target_ulong helper_ei(CPUMIPSState *env)
+{
+ target_ulong t0 = env->CP0_Status;
+
+ env->CP0_Status = t0 | (1 << CP0St_IE);
+ return t0;
+}
+
+static void debug_pre_eret(CPUMIPSState *env)
+{
+ if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
+ qemu_log("ERET: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx,
+ env->active_tc.PC, env->CP0_EPC);
+ if (env->CP0_Status & (1 << CP0St_ERL)) {
+ qemu_log(" ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC);
+ }
+ if (env->hflags & MIPS_HFLAG_DM) {
+ qemu_log(" DEPC " TARGET_FMT_lx, env->CP0_DEPC);
+ }
+ qemu_log("\n");
+ }
+}
+
+static void debug_post_eret(CPUMIPSState *env)
+{
+ if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
+ qemu_log(" => PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx,
+ env->active_tc.PC, env->CP0_EPC);
+ if (env->CP0_Status & (1 << CP0St_ERL)) {
+ qemu_log(" ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC);
+ }
+ if (env->hflags & MIPS_HFLAG_DM) {
+ qemu_log(" DEPC " TARGET_FMT_lx, env->CP0_DEPC);
+ }
+ switch (mips_env_mmu_index(env)) {
+ case 3:
+ qemu_log(", ERL\n");
+ break;
+ case MIPS_HFLAG_UM:
+ qemu_log(", UM\n");
+ break;
+ case MIPS_HFLAG_SM:
+ qemu_log(", SM\n");
+ break;
+ case MIPS_HFLAG_KM:
+ qemu_log("\n");
+ break;
+ default:
+ cpu_abort(env_cpu(env), "Invalid MMU mode!\n");
+ break;
+ }
+ }
+}
+
+bool mips_io_recompile_replay_branch(CPUState *cs, const TranslationBlock *tb)
+{
+ CPUMIPSState *env = cpu_env(cs);
+
+ if ((env->hflags & MIPS_HFLAG_BMASK) != 0
+ && !tcg_cflags_has(cs, CF_PCREL) && env->active_tc.PC != tb->pc) {
+ env->active_tc.PC -= (env->hflags & MIPS_HFLAG_B16 ? 2 : 4);
+ env->hflags &= ~MIPS_HFLAG_BMASK;
+ return true;
+ }
+ return false;
+}
+
+static inline void exception_return(CPUMIPSState *env)
+{
+ debug_pre_eret(env);
+ if (env->CP0_Status & (1 << CP0St_ERL)) {
+ mips_env_set_pc(env, env->CP0_ErrorEPC);
+ env->CP0_Status &= ~(1 << CP0St_ERL);
+ } else {
+ mips_env_set_pc(env, env->CP0_EPC);
+ env->CP0_Status &= ~(1 << CP0St_EXL);
+ }
+ compute_hflags(env);
+ debug_post_eret(env);
+}
+
+void helper_eret(CPUMIPSState *env)
+{
+ exception_return(env);
+ env->CP0_LLAddr = 1;
+ env->lladdr = 1;
+}
+
+void helper_eretnc(CPUMIPSState *env)
+{
+ exception_return(env);
+}
+
+void helper_deret(CPUMIPSState *env)
+{
+ debug_pre_eret(env);
+
+ env->hflags &= ~MIPS_HFLAG_DM;
+ compute_hflags(env);
+
+ mips_env_set_pc(env, env->CP0_DEPC);
+
+ debug_post_eret(env);
+}
+
+void helper_cache(CPUMIPSState *env, target_ulong addr, uint32_t op)
+{
+ static const char *const type_name[] = {
+ "Primary Instruction",
+ "Primary Data or Unified Primary",
+ "Tertiary",
+ "Secondary"
+ };
+ uint32_t cache_type = extract32(op, 0, 2);
+ uint32_t cache_operation = extract32(op, 2, 3);
+ target_ulong index = addr & 0x1fffffff;
+
+ switch (cache_operation) {
+ case 0b010: /* Index Store Tag */
+ memory_region_dispatch_write(env->itc_tag, index, env->CP0_TagLo,
+ MO_64, MEMTXATTRS_UNSPECIFIED);
+ break;
+ case 0b001: /* Index Load Tag */
+ memory_region_dispatch_read(env->itc_tag, index, &env->CP0_TagLo,
+ MO_64, MEMTXATTRS_UNSPECIFIED);
+ break;
+ case 0b000: /* Index Invalidate */
+ case 0b100: /* Hit Invalidate */
+ case 0b110: /* Hit Writeback */
+ /* no-op */
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "cache operation:%u (type: %s cache)\n",
+ cache_operation, type_name[cache_type]);
+ break;
+ }
+}
--- /dev/null
+/*
+ * MIPS TLB (Translation lookaside buffer) helpers.
+ *
+ * Copyright (c) 2004-2005 Jocelyn Mayer
+ *
+ * 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.1 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 "qemu/bitops.h"
+
+#include "cpu.h"
+#include "internal.h"
+#include "exec/exec-all.h"
+#include "exec/page-protection.h"
+#include "exec/cpu_ldst.h"
+#include "exec/log.h"
+#include "exec/helper-proto.h"
+
+/* TLB management */
+static void r4k_mips_tlb_flush_extra(CPUMIPSState *env, int first)
+{
+ /* Discard entries from env->tlb[first] onwards. */
+ while (env->tlb->tlb_in_use > first) {
+ r4k_invalidate_tlb(env, --env->tlb->tlb_in_use, 0);
+ }
+}
+
+static inline uint64_t get_tlb_pfn_from_entrylo(uint64_t entrylo)
+{
+#if defined(TARGET_MIPS64)
+ return extract64(entrylo, 6, 54);
+#else
+ return extract64(entrylo, 6, 24) | /* PFN */
+ (extract64(entrylo, 32, 32) << 24); /* PFNX */
+#endif
+}
+
+static void r4k_fill_tlb(CPUMIPSState *env, int idx)
+{
+ r4k_tlb_t *tlb;
+ uint64_t mask = env->CP0_PageMask >> (TARGET_PAGE_BITS + 1);
+
+ /* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */
+ tlb = &env->tlb->mmu.r4k.tlb[idx];
+ if (env->CP0_EntryHi & (1 << CP0EnHi_EHINV)) {
+ tlb->EHINV = 1;
+ return;
+ }
+ tlb->EHINV = 0;
+ tlb->VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1);
+#if defined(TARGET_MIPS64)
+ tlb->VPN &= env->SEGMask;
+#endif
+ tlb->ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
+ tlb->MMID = env->CP0_MemoryMapID;
+ tlb->PageMask = env->CP0_PageMask;
+ tlb->G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1;
+ tlb->V0 = (env->CP0_EntryLo0 & 2) != 0;
+ tlb->D0 = (env->CP0_EntryLo0 & 4) != 0;
+ tlb->C0 = (env->CP0_EntryLo0 >> 3) & 0x7;
+ tlb->XI0 = (env->CP0_EntryLo0 >> CP0EnLo_XI) & 1;
+ tlb->RI0 = (env->CP0_EntryLo0 >> CP0EnLo_RI) & 1;
+ tlb->PFN[0] = (get_tlb_pfn_from_entrylo(env->CP0_EntryLo0) & ~mask) << 12;
+ tlb->V1 = (env->CP0_EntryLo1 & 2) != 0;
+ tlb->D1 = (env->CP0_EntryLo1 & 4) != 0;
+ tlb->C1 = (env->CP0_EntryLo1 >> 3) & 0x7;
+ tlb->XI1 = (env->CP0_EntryLo1 >> CP0EnLo_XI) & 1;
+ tlb->RI1 = (env->CP0_EntryLo1 >> CP0EnLo_RI) & 1;
+ tlb->PFN[1] = (get_tlb_pfn_from_entrylo(env->CP0_EntryLo1) & ~mask) << 12;
+}
+
+static void r4k_helper_tlbinv(CPUMIPSState *env)
+{
+ bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1);
+ uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
+ uint32_t MMID = env->CP0_MemoryMapID;
+ uint32_t tlb_mmid;
+ r4k_tlb_t *tlb;
+ int idx;
+
+ MMID = mi ? MMID : (uint32_t) ASID;
+ for (idx = 0; idx < env->tlb->nb_tlb; idx++) {
+ tlb = &env->tlb->mmu.r4k.tlb[idx];
+ tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID;
+ if (!tlb->G && tlb_mmid == MMID) {
+ tlb->EHINV = 1;
+ }
+ }
+ cpu_mips_tlb_flush(env);
+}
+
+static void r4k_helper_tlbinvf(CPUMIPSState *env)
+{
+ int idx;
+
+ for (idx = 0; idx < env->tlb->nb_tlb; idx++) {
+ env->tlb->mmu.r4k.tlb[idx].EHINV = 1;
+ }
+ cpu_mips_tlb_flush(env);
+}
+
+static void r4k_helper_tlbwi(CPUMIPSState *env)
+{
+ bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1);
+ target_ulong VPN;
+ uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
+ uint32_t MMID = env->CP0_MemoryMapID;
+ uint32_t tlb_mmid;
+ bool EHINV, G, V0, D0, V1, D1, XI0, XI1, RI0, RI1;
+ r4k_tlb_t *tlb;
+ int idx;
+
+ MMID = mi ? MMID : (uint32_t) ASID;
+
+ idx = (env->CP0_Index & ~0x80000000) % env->tlb->nb_tlb;
+ tlb = &env->tlb->mmu.r4k.tlb[idx];
+ VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1);
+#if defined(TARGET_MIPS64)
+ VPN &= env->SEGMask;
+#endif
+ EHINV = (env->CP0_EntryHi & (1 << CP0EnHi_EHINV)) != 0;
+ G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1;
+ V0 = (env->CP0_EntryLo0 & 2) != 0;
+ D0 = (env->CP0_EntryLo0 & 4) != 0;
+ XI0 = (env->CP0_EntryLo0 >> CP0EnLo_XI) &1;
+ RI0 = (env->CP0_EntryLo0 >> CP0EnLo_RI) &1;
+ V1 = (env->CP0_EntryLo1 & 2) != 0;
+ D1 = (env->CP0_EntryLo1 & 4) != 0;
+ XI1 = (env->CP0_EntryLo1 >> CP0EnLo_XI) &1;
+ RI1 = (env->CP0_EntryLo1 >> CP0EnLo_RI) &1;
+
+ tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID;
+ /*
+ * Discard cached TLB entries, unless tlbwi is just upgrading access
+ * permissions on the current entry.
+ */
+ if (tlb->VPN != VPN || tlb_mmid != MMID || tlb->G != G ||
+ (!tlb->EHINV && EHINV) ||
+ (tlb->V0 && !V0) || (tlb->D0 && !D0) ||
+ (!tlb->XI0 && XI0) || (!tlb->RI0 && RI0) ||
+ (tlb->V1 && !V1) || (tlb->D1 && !D1) ||
+ (!tlb->XI1 && XI1) || (!tlb->RI1 && RI1)) {
+ r4k_mips_tlb_flush_extra(env, env->tlb->nb_tlb);
+ }
+
+ r4k_invalidate_tlb(env, idx, 0);
+ r4k_fill_tlb(env, idx);
+}
+
+static void r4k_helper_tlbwr(CPUMIPSState *env)
+{
+ int r = cpu_mips_get_random(env);
+
+ r4k_invalidate_tlb(env, r, 1);
+ r4k_fill_tlb(env, r);
+}
+
+static void r4k_helper_tlbp(CPUMIPSState *env)
+{
+ bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1);
+ r4k_tlb_t *tlb;
+ target_ulong mask;
+ target_ulong tag;
+ target_ulong VPN;
+ uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
+ uint32_t MMID = env->CP0_MemoryMapID;
+ uint32_t tlb_mmid;
+ int i;
+
+ MMID = mi ? MMID : (uint32_t) ASID;
+ for (i = 0; i < env->tlb->nb_tlb; i++) {
+ tlb = &env->tlb->mmu.r4k.tlb[i];
+ /* 1k pages are not supported. */
+ mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
+ tag = env->CP0_EntryHi & ~mask;
+ VPN = tlb->VPN & ~mask;
+#if defined(TARGET_MIPS64)
+ tag &= env->SEGMask;
+#endif
+ tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID;
+ /* Check ASID/MMID, virtual page number & size */
+ if ((tlb->G == 1 || tlb_mmid == MMID) && VPN == tag && !tlb->EHINV) {
+ /* TLB match */
+ env->CP0_Index = i;
+ break;
+ }
+ }
+ if (i == env->tlb->nb_tlb) {
+ /* No match. Discard any shadow entries, if any of them match. */
+ for (i = env->tlb->nb_tlb; i < env->tlb->tlb_in_use; i++) {
+ tlb = &env->tlb->mmu.r4k.tlb[i];
+ /* 1k pages are not supported. */
+ mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
+ tag = env->CP0_EntryHi & ~mask;
+ VPN = tlb->VPN & ~mask;
+#if defined(TARGET_MIPS64)
+ tag &= env->SEGMask;
+#endif
+ tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID;
+ /* Check ASID/MMID, virtual page number & size */
+ if ((tlb->G == 1 || tlb_mmid == MMID) && VPN == tag) {
+ r4k_mips_tlb_flush_extra(env, i);
+ break;
+ }
+ }
+
+ env->CP0_Index |= 0x80000000;
+ }
+}
+
+static inline uint64_t get_entrylo_pfn_from_tlb(uint64_t tlb_pfn)
+{
+#if defined(TARGET_MIPS64)
+ return tlb_pfn << 6;
+#else
+ return (extract64(tlb_pfn, 0, 24) << 6) | /* PFN */
+ (extract64(tlb_pfn, 24, 32) << 32); /* PFNX */
+#endif
+}
+
+static void r4k_helper_tlbr(CPUMIPSState *env)
+{
+ bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1);
+ uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
+ uint32_t MMID = env->CP0_MemoryMapID;
+ uint32_t tlb_mmid;
+ r4k_tlb_t *tlb;
+ int idx;
+
+ MMID = mi ? MMID : (uint32_t) ASID;
+ idx = (env->CP0_Index & ~0x80000000) % env->tlb->nb_tlb;
+ tlb = &env->tlb->mmu.r4k.tlb[idx];
+
+ tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID;
+ /* If this will change the current ASID/MMID, flush qemu's TLB. */
+ if (MMID != tlb_mmid) {
+ cpu_mips_tlb_flush(env);
+ }
+
+ r4k_mips_tlb_flush_extra(env, env->tlb->nb_tlb);
+
+ if (tlb->EHINV) {
+ env->CP0_EntryHi = 1 << CP0EnHi_EHINV;
+ env->CP0_PageMask = 0;
+ env->CP0_EntryLo0 = 0;
+ env->CP0_EntryLo1 = 0;
+ } else {
+ env->CP0_EntryHi = mi ? tlb->VPN : tlb->VPN | tlb->ASID;
+ env->CP0_MemoryMapID = tlb->MMID;
+ env->CP0_PageMask = tlb->PageMask;
+ env->CP0_EntryLo0 = tlb->G | (tlb->V0 << 1) | (tlb->D0 << 2) |
+ ((uint64_t)tlb->RI0 << CP0EnLo_RI) |
+ ((uint64_t)tlb->XI0 << CP0EnLo_XI) | (tlb->C0 << 3) |
+ get_entrylo_pfn_from_tlb(tlb->PFN[0] >> 12);
+ env->CP0_EntryLo1 = tlb->G | (tlb->V1 << 1) | (tlb->D1 << 2) |
+ ((uint64_t)tlb->RI1 << CP0EnLo_RI) |
+ ((uint64_t)tlb->XI1 << CP0EnLo_XI) | (tlb->C1 << 3) |
+ get_entrylo_pfn_from_tlb(tlb->PFN[1] >> 12);
+ }
+}
+
+void helper_tlbwi(CPUMIPSState *env)
+{
+ env->tlb->helper_tlbwi(env);
+}
+
+void helper_tlbwr(CPUMIPSState *env)
+{
+ env->tlb->helper_tlbwr(env);
+}
+
+void helper_tlbp(CPUMIPSState *env)
+{
+ env->tlb->helper_tlbp(env);
+}
+
+void helper_tlbr(CPUMIPSState *env)
+{
+ env->tlb->helper_tlbr(env);
+}
+
+void helper_tlbinv(CPUMIPSState *env)
+{
+ env->tlb->helper_tlbinv(env);
+}
+
+void helper_tlbinvf(CPUMIPSState *env)
+{
+ env->tlb->helper_tlbinvf(env);
+}
+
+static void global_invalidate_tlb(CPUMIPSState *env,
+ uint32_t invMsgVPN2,
+ uint8_t invMsgR,
+ uint32_t invMsgMMid,
+ bool invAll,
+ bool invVAMMid,
+ bool invMMid,
+ bool invVA)
+{
+
+ int idx;
+ r4k_tlb_t *tlb;
+ bool VAMatch;
+ bool MMidMatch;
+
+ for (idx = 0; idx < env->tlb->nb_tlb; idx++) {
+ tlb = &env->tlb->mmu.r4k.tlb[idx];
+ VAMatch =
+ (((tlb->VPN & ~tlb->PageMask) == (invMsgVPN2 & ~tlb->PageMask))
+#ifdef TARGET_MIPS64
+ &&
+ (extract64(env->CP0_EntryHi, 62, 2) == invMsgR)
+#endif
+ );
+ MMidMatch = tlb->MMID == invMsgMMid;
+ if ((invAll && (idx > env->CP0_Wired)) ||
+ (VAMatch && invVAMMid && (tlb->G || MMidMatch)) ||
+ (VAMatch && invVA) ||
+ (MMidMatch && !(tlb->G) && invMMid)) {
+ tlb->EHINV = 1;
+ }
+ }
+ cpu_mips_tlb_flush(env);
+}
+
+void helper_ginvt(CPUMIPSState *env, target_ulong arg, uint32_t type)
+{
+ bool invAll = type == 0;
+ bool invVA = type == 1;
+ bool invMMid = type == 2;
+ bool invVAMMid = type == 3;
+ uint32_t invMsgVPN2 = arg & (TARGET_PAGE_MASK << 1);
+ uint8_t invMsgR = 0;
+ uint32_t invMsgMMid = env->CP0_MemoryMapID;
+ CPUState *other_cs = first_cpu;
+
+#ifdef TARGET_MIPS64
+ invMsgR = extract64(arg, 62, 2);
+#endif
+
+ CPU_FOREACH(other_cs) {
+ MIPSCPU *other_cpu = MIPS_CPU(other_cs);
+ global_invalidate_tlb(&other_cpu->env, invMsgVPN2, invMsgR, invMsgMMid,
+ invAll, invVAMMid, invMMid, invVA);
+ }
+}
+
+/* no MMU emulation */
+static int no_mmu_map_address(CPUMIPSState *env, hwaddr *physical, int *prot,
+ target_ulong address, MMUAccessType access_type)
+{
+ *physical = address;
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ return TLBRET_MATCH;
+}
+
+/* fixed mapping MMU emulation */
+static int fixed_mmu_map_address(CPUMIPSState *env, hwaddr *physical,
+ int *prot, target_ulong address,
+ MMUAccessType access_type)
+{
+ if (address <= (int32_t)0x7FFFFFFFUL) {
+ if (!(env->CP0_Status & (1 << CP0St_ERL))) {
+ *physical = address + 0x40000000UL;
+ } else {
+ *physical = address;
+ }
+ } else if (address <= (int32_t)0xBFFFFFFFUL) {
+ *physical = address & 0x1FFFFFFF;
+ } else {
+ *physical = address;
+ }
+
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ return TLBRET_MATCH;
+}
+
+/* MIPS32/MIPS64 R4000-style MMU emulation */
+static int r4k_map_address(CPUMIPSState *env, hwaddr *physical, int *prot,
+ target_ulong address, MMUAccessType access_type)
+{
+ uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
+ uint32_t MMID = env->CP0_MemoryMapID;
+ bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1);
+ uint32_t tlb_mmid;
+ int i;
+
+ MMID = mi ? MMID : (uint32_t) ASID;
+
+ for (i = 0; i < env->tlb->tlb_in_use; i++) {
+ r4k_tlb_t *tlb = &env->tlb->mmu.r4k.tlb[i];
+ /* 1k pages are not supported. */
+ target_ulong mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
+ target_ulong tag = address & ~mask;
+ target_ulong VPN = tlb->VPN & ~mask;
+#if defined(TARGET_MIPS64)
+ tag &= env->SEGMask;
+#endif
+
+ /* Check ASID/MMID, virtual page number & size */
+ tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID;
+ if ((tlb->G == 1 || tlb_mmid == MMID) && VPN == tag && !tlb->EHINV) {
+ /* TLB match */
+ int n = !!(address & mask & ~(mask >> 1));
+ /* Check access rights */
+ if (!(n ? tlb->V1 : tlb->V0)) {
+ return TLBRET_INVALID;
+ }
+ if (access_type == MMU_INST_FETCH && (n ? tlb->XI1 : tlb->XI0)) {
+ return TLBRET_XI;
+ }
+ if (access_type == MMU_DATA_LOAD && (n ? tlb->RI1 : tlb->RI0)) {
+ return TLBRET_RI;
+ }
+ if (access_type != MMU_DATA_STORE || (n ? tlb->D1 : tlb->D0)) {
+ *physical = tlb->PFN[n] | (address & (mask >> 1));
+ *prot = PAGE_READ;
+ if (n ? tlb->D1 : tlb->D0) {
+ *prot |= PAGE_WRITE;
+ }
+ if (!(n ? tlb->XI1 : tlb->XI0)) {
+ *prot |= PAGE_EXEC;
+ }
+ return TLBRET_MATCH;
+ }
+ return TLBRET_DIRTY;
+ }
+ }
+ return TLBRET_NOMATCH;
+}
+
+static void no_mmu_init(CPUMIPSState *env, const mips_def_t *def)
+{
+ env->tlb->nb_tlb = 1;
+ env->tlb->map_address = &no_mmu_map_address;
+}
+
+static void fixed_mmu_init(CPUMIPSState *env, const mips_def_t *def)
+{
+ env->tlb->nb_tlb = 1;
+ env->tlb->map_address = &fixed_mmu_map_address;
+}
+
+static void r4k_mmu_init(CPUMIPSState *env, const mips_def_t *def)
+{
+ env->tlb->nb_tlb = 1 + ((def->CP0_Config1 >> CP0C1_MMU) & 63);
+ env->tlb->map_address = &r4k_map_address;
+ env->tlb->helper_tlbwi = r4k_helper_tlbwi;
+ env->tlb->helper_tlbwr = r4k_helper_tlbwr;
+ env->tlb->helper_tlbp = r4k_helper_tlbp;
+ env->tlb->helper_tlbr = r4k_helper_tlbr;
+ env->tlb->helper_tlbinv = r4k_helper_tlbinv;
+ env->tlb->helper_tlbinvf = r4k_helper_tlbinvf;
+}
+
+void mmu_init(CPUMIPSState *env, const mips_def_t *def)
+{
+ env->tlb = g_malloc0(sizeof(CPUMIPSTLBContext));
+
+ switch (def->mmu_type) {
+ case MMU_TYPE_NONE:
+ no_mmu_init(env, def);
+ break;
+ case MMU_TYPE_R4000:
+ r4k_mmu_init(env, def);
+ break;
+ case MMU_TYPE_FMT:
+ fixed_mmu_init(env, def);
+ break;
+ case MMU_TYPE_R3000:
+ case MMU_TYPE_R6000:
+ case MMU_TYPE_R8000:
+ default:
+ cpu_abort(env_cpu(env), "MMU type not supported\n");
+ }
+}
+
+void cpu_mips_tlb_flush(CPUMIPSState *env)
+{
+ /* Flush qemu's TLB and discard all shadowed entries. */
+ tlb_flush(env_cpu(env));
+ env->tlb->tlb_in_use = env->tlb->nb_tlb;
+}
+
+static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
+ MMUAccessType access_type, int tlb_error)
+{
+ CPUState *cs = env_cpu(env);
+ int exception = 0, error_code = 0;
+
+ if (access_type == MMU_INST_FETCH) {
+ error_code |= EXCP_INST_NOTAVAIL;
+ }
+
+ switch (tlb_error) {
+ default:
+ case TLBRET_BADADDR:
+ /* Reference to kernel address from user mode or supervisor mode */
+ /* Reference to supervisor address from user mode */
+ if (access_type == MMU_DATA_STORE) {
+ exception = EXCP_AdES;
+ } else {
+ exception = EXCP_AdEL;
+ }
+ break;
+ case TLBRET_NOMATCH:
+ /* No TLB match for a mapped address */
+ if (access_type == MMU_DATA_STORE) {
+ exception = EXCP_TLBS;
+ } else {
+ exception = EXCP_TLBL;
+ }
+ error_code |= EXCP_TLB_NOMATCH;
+ break;
+ case TLBRET_INVALID:
+ /* TLB match with no valid bit */
+ if (access_type == MMU_DATA_STORE) {
+ exception = EXCP_TLBS;
+ } else {
+ exception = EXCP_TLBL;
+ }
+ break;
+ case TLBRET_DIRTY:
+ /* TLB match but 'D' bit is cleared */
+ exception = EXCP_LTLBL;
+ break;
+ case TLBRET_XI:
+ /* Execute-Inhibit Exception */
+ if (env->CP0_PageGrain & (1 << CP0PG_IEC)) {
+ exception = EXCP_TLBXI;
+ } else {
+ exception = EXCP_TLBL;
+ }
+ break;
+ case TLBRET_RI:
+ /* Read-Inhibit Exception */
+ if (env->CP0_PageGrain & (1 << CP0PG_IEC)) {
+ exception = EXCP_TLBRI;
+ } else {
+ exception = EXCP_TLBL;
+ }
+ break;
+ }
+ /* Raise exception */
+ if (!(env->hflags & MIPS_HFLAG_DM)) {
+ env->CP0_BadVAddr = address;
+ }
+ env->CP0_Context = (env->CP0_Context & ~0x007fffff) |
+ ((address >> 9) & 0x007ffff0);
+ env->CP0_EntryHi = (env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask) |
+ (env->CP0_EntryHi & (1 << CP0EnHi_EHINV)) |
+ (address & (TARGET_PAGE_MASK << 1));
+#if defined(TARGET_MIPS64)
+ env->CP0_EntryHi &= env->SEGMask;
+ env->CP0_XContext =
+ (env->CP0_XContext & ((~0ULL) << (env->SEGBITS - 7))) | /* PTEBase */
+ (extract64(address, 62, 2) << (env->SEGBITS - 9)) | /* R */
+ (extract64(address, 13, env->SEGBITS - 13) << 4); /* BadVPN2 */
+#endif
+ cs->exception_index = exception;
+ env->error_code = error_code;
+}
+
+#if !defined(TARGET_MIPS64)
+
+/*
+ * Perform hardware page table walk
+ *
+ * Memory accesses are performed using the KERNEL privilege level.
+ * Synchronous exceptions detected on memory accesses cause a silent exit
+ * from page table walking, resulting in a TLB or XTLB Refill exception.
+ *
+ * Implementations are not required to support page table walk memory
+ * accesses from mapped memory regions. When an unsupported access is
+ * attempted, a silent exit is taken, resulting in a TLB or XTLB Refill
+ * exception.
+ *
+ * Note that if an exception is caused by AddressTranslation or LoadMemory
+ * functions, the exception is not taken, a silent exit is taken,
+ * resulting in a TLB or XTLB Refill exception.
+ */
+
+static bool get_pte(CPUMIPSState *env, uint64_t vaddr, MemOp op,
+ uint64_t *pte, unsigned ptw_mmu_idx)
+{
+ MemOpIdx oi;
+
+ if ((vaddr & (memop_size(op) - 1)) != 0) {
+ return false;
+ }
+
+ oi = make_memop_idx(op | mo_endian_env(env), ptw_mmu_idx);
+ if (op == MO_64) {
+ *pte = cpu_ldq_mmu(env, vaddr, oi, 0);
+ } else {
+ *pte = cpu_ldl_mmu(env, vaddr, oi, 0);
+ }
+
+ return true;
+}
+
+static uint64_t get_tlb_entry_layout(CPUMIPSState *env, uint64_t entry,
+ MemOp op, int ptei)
+{
+ unsigned entry_size = memop_size(op) << 3;
+ uint64_t result = entry;
+ uint64_t rixi;
+ if (ptei > entry_size) {
+ ptei -= 32;
+ }
+ result >>= (ptei - 2);
+ rixi = result & 3;
+ result >>= 2;
+ result |= rixi << CP0EnLo_XI;
+ return result;
+}
+
+static int walk_directory(CPUMIPSState *env, uint64_t *vaddr,
+ int directory_index, bool *huge_page, bool *hgpg_directory_hit,
+ uint64_t *pw_entrylo0, uint64_t *pw_entrylo1,
+ MemOp directory_mop, MemOp leaf_mop, int ptw_mmu_idx)
+{
+ int dph = (env->CP0_PWCtl >> CP0PC_DPH) & 0x1;
+ int psn = (env->CP0_PWCtl >> CP0PC_PSN) & 0x3F;
+ int hugepg = (env->CP0_PWCtl >> CP0PC_HUGEPG) & 0x1;
+ int pf_ptew = (env->CP0_PWField >> CP0PF_PTEW) & 0x3F;
+ uint64_t entry;
+ uint64_t paddr;
+ int prot;
+ uint64_t lsb = 0;
+ uint64_t w = 0;
+
+ if (get_physical_address(env, &paddr, &prot, *vaddr, MMU_DATA_LOAD,
+ ptw_mmu_idx) != TLBRET_MATCH) {
+ /* wrong base address */
+ return 0;
+ }
+ if (!get_pte(env, *vaddr, directory_mop, &entry, ptw_mmu_idx)) {
+ return 0;
+ }
+
+ if ((entry & (1 << psn)) && hugepg) {
+ *huge_page = true;
+ *hgpg_directory_hit = true;
+ entry = get_tlb_entry_layout(env, entry, leaf_mop, pf_ptew);
+ w = directory_index - 1;
+ if (directory_index & 0x1) {
+ /* Generate adjacent page from same PTE for odd TLB page */
+ lsb = BIT_ULL(w) >> 6;
+ *pw_entrylo0 = entry & ~lsb; /* even page */
+ *pw_entrylo1 = entry | lsb; /* odd page */
+ } else if (dph) {
+ int oddpagebit = 1 << leaf_mop;
+ uint64_t vaddr2 = *vaddr ^ oddpagebit;
+ if (*vaddr & oddpagebit) {
+ *pw_entrylo1 = entry;
+ } else {
+ *pw_entrylo0 = entry;
+ }
+ if (get_physical_address(env, &paddr, &prot, vaddr2, MMU_DATA_LOAD,
+ ptw_mmu_idx) != TLBRET_MATCH) {
+ return 0;
+ }
+ if (!get_pte(env, vaddr2, leaf_mop, &entry, ptw_mmu_idx)) {
+ return 0;
+ }
+ entry = get_tlb_entry_layout(env, entry, leaf_mop, pf_ptew);
+ if (*vaddr & oddpagebit) {
+ *pw_entrylo0 = entry;
+ } else {
+ *pw_entrylo1 = entry;
+ }
+ } else {
+ return 0;
+ }
+ return 1;
+ } else {
+ *vaddr = entry;
+ return 2;
+ }
+}
+
+static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
+ int ptw_mmu_idx)
+{
+ int gdw = (env->CP0_PWSize >> CP0PS_GDW) & 0x3F;
+ int udw = (env->CP0_PWSize >> CP0PS_UDW) & 0x3F;
+ int mdw = (env->CP0_PWSize >> CP0PS_MDW) & 0x3F;
+ int ptw = (env->CP0_PWSize >> CP0PS_PTW) & 0x3F;
+ int ptew = (env->CP0_PWSize >> CP0PS_PTEW) & 0x3F;
+
+ /* Initial values */
+ bool huge_page = false;
+ bool hgpg_bdhit = false;
+ bool hgpg_gdhit = false;
+ bool hgpg_udhit = false;
+ bool hgpg_mdhit = false;
+
+ int32_t pw_pagemask = 0;
+ target_ulong pw_entryhi = 0;
+ uint64_t pw_entrylo0 = 0;
+ uint64_t pw_entrylo1 = 0;
+
+ /* Native pointer size */
+ /*For the 32-bit architectures, this bit is fixed to 0.*/
+ MemOp native_op = (((env->CP0_PWSize >> CP0PS_PS) & 1) == 0) ? MO_32 : MO_64;
+
+ /* Indices from PWField */
+ int pf_gdw = (env->CP0_PWField >> CP0PF_GDW) & 0x3F;
+ int pf_udw = (env->CP0_PWField >> CP0PF_UDW) & 0x3F;
+ int pf_mdw = (env->CP0_PWField >> CP0PF_MDW) & 0x3F;
+ int pf_ptw = (env->CP0_PWField >> CP0PF_PTW) & 0x3F;
+ int pf_ptew = (env->CP0_PWField >> CP0PF_PTEW) & 0x3F;
+
+ /* Indices computed from faulting address */
+ int gindex = (address >> pf_gdw) & ((1 << gdw) - 1);
+ int uindex = (address >> pf_udw) & ((1 << udw) - 1);
+ int mindex = (address >> pf_mdw) & ((1 << mdw) - 1);
+ int ptindex = (address >> pf_ptw) & ((1 << ptw) - 1);
+
+ /* Other HTW configs */
+ int hugepg = (env->CP0_PWCtl >> CP0PC_HUGEPG) & 0x1;
+ MemOp directory_mop, leaf_mop;
+
+ /* Offsets into tables */
+ unsigned goffset, uoffset, moffset, ptoffset0, ptoffset1;
+
+ /* Starting address - Page Table Base */
+ uint64_t vaddr = env->CP0_PWBase;
+
+ uint64_t dir_entry;
+ uint64_t paddr;
+ int prot;
+ int m;
+
+ if (!(env->CP0_Config3 & (1 << CP0C3_PW))) {
+ /* walker is unimplemented */
+ return false;
+ }
+ if (!(env->CP0_PWCtl & (1 << CP0PC_PWEN))) {
+ /* walker is disabled */
+ return false;
+ }
+ if (!(gdw > 0 || udw > 0 || mdw > 0)) {
+ /* no structure to walk */
+ return false;
+ }
+ if (ptew > 1) {
+ return false;
+ }
+
+ /* HTW Shift values (depend on entry size) */
+ directory_mop = (hugepg && (ptew == 1)) ? native_op + 1 : native_op;
+ leaf_mop = (ptew == 1) ? native_op + 1 : native_op;
+
+ goffset = gindex << directory_mop;
+ uoffset = uindex << directory_mop;
+ moffset = mindex << directory_mop;
+ ptoffset0 = (ptindex >> 1) << (leaf_mop + 1);
+ ptoffset1 = ptoffset0 | (1 << (leaf_mop));
+
+ /* Global Directory */
+ if (gdw > 0) {
+ vaddr |= goffset;
+ switch (walk_directory(env, &vaddr, pf_gdw, &huge_page, &hgpg_gdhit,
+ &pw_entrylo0, &pw_entrylo1,
+ directory_mop, leaf_mop, ptw_mmu_idx))
+ {
+ case 0:
+ return false;
+ case 1:
+ goto refill;
+ case 2:
+ default:
+ break;
+ }
+ }
+
+ /* Upper directory */
+ if (udw > 0) {
+ vaddr |= uoffset;
+ switch (walk_directory(env, &vaddr, pf_udw, &huge_page, &hgpg_udhit,
+ &pw_entrylo0, &pw_entrylo1,
+ directory_mop, leaf_mop, ptw_mmu_idx))
+ {
+ case 0:
+ return false;
+ case 1:
+ goto refill;
+ case 2:
+ default:
+ break;
+ }
+ }
+
+ /* Middle directory */
+ if (mdw > 0) {
+ vaddr |= moffset;
+ switch (walk_directory(env, &vaddr, pf_mdw, &huge_page, &hgpg_mdhit,
+ &pw_entrylo0, &pw_entrylo1,
+ directory_mop, leaf_mop, ptw_mmu_idx))
+ {
+ case 0:
+ return false;
+ case 1:
+ goto refill;
+ case 2:
+ default:
+ break;
+ }
+ }
+
+ /* Leaf Level Page Table - First half of PTE pair */
+ vaddr |= ptoffset0;
+ if (get_physical_address(env, &paddr, &prot, vaddr, MMU_DATA_LOAD,
+ ptw_mmu_idx) != TLBRET_MATCH) {
+ return false;
+ }
+ if (!get_pte(env, vaddr, leaf_mop, &dir_entry, ptw_mmu_idx)) {
+ return false;
+ }
+ dir_entry = get_tlb_entry_layout(env, dir_entry, leaf_mop, pf_ptew);
+ pw_entrylo0 = dir_entry;
+
+ /* Leaf Level Page Table - Second half of PTE pair */
+ vaddr |= ptoffset1;
+ if (get_physical_address(env, &paddr, &prot, vaddr, MMU_DATA_LOAD,
+ ptw_mmu_idx) != TLBRET_MATCH) {
+ return false;
+ }
+ if (!get_pte(env, vaddr, leaf_mop, &dir_entry, ptw_mmu_idx)) {
+ return false;
+ }
+ dir_entry = get_tlb_entry_layout(env, dir_entry, leaf_mop, pf_ptew);
+ pw_entrylo1 = dir_entry;
+
+refill:
+
+ m = (1 << pf_ptw) - 1;
+
+ if (huge_page) {
+ switch (hgpg_bdhit << 3 | hgpg_gdhit << 2 | hgpg_udhit << 1 |
+ hgpg_mdhit)
+ {
+ case 4:
+ m = (1 << pf_gdw) - 1;
+ if (pf_gdw & 1) {
+ m >>= 1;
+ }
+ break;
+ case 2:
+ m = (1 << pf_udw) - 1;
+ if (pf_udw & 1) {
+ m >>= 1;
+ }
+ break;
+ case 1:
+ m = (1 << pf_mdw) - 1;
+ if (pf_mdw & 1) {
+ m >>= 1;
+ }
+ break;
+ }
+ }
+ pw_pagemask = m >> TARGET_PAGE_BITS_MIN;
+ update_pagemask(env, pw_pagemask << CP0PM_MASK, &pw_pagemask);
+ pw_entryhi = (address & ~0x1fff) | (env->CP0_EntryHi & 0xFF);
+ {
+ target_ulong tmp_entryhi = env->CP0_EntryHi;
+ int32_t tmp_pagemask = env->CP0_PageMask;
+ uint64_t tmp_entrylo0 = env->CP0_EntryLo0;
+ uint64_t tmp_entrylo1 = env->CP0_EntryLo1;
+
+ env->CP0_EntryHi = pw_entryhi;
+ env->CP0_PageMask = pw_pagemask;
+ env->CP0_EntryLo0 = pw_entrylo0;
+ env->CP0_EntryLo1 = pw_entrylo1;
+
+ /*
+ * The hardware page walker inserts a page into the TLB in a manner
+ * identical to a TLBWR instruction as executed by the software refill
+ * handler.
+ */
+ r4k_helper_tlbwr(env);
+
+ env->CP0_EntryHi = tmp_entryhi;
+ env->CP0_PageMask = tmp_pagemask;
+ env->CP0_EntryLo0 = tmp_entrylo0;
+ env->CP0_EntryLo1 = tmp_entrylo1;
+ }
+ return true;
+}
+#endif
+
+bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr)
+{
+ CPUMIPSState *env = cpu_env(cs);
+ hwaddr physical;
+ int prot;
+ int ret = TLBRET_BADADDR;
+
+ /* data access */
+ /* XXX: put correct access by using cpu_restore_state() correctly */
+ ret = get_physical_address(env, &physical, &prot, address,
+ access_type, mmu_idx);
+ switch (ret) {
+ case TLBRET_MATCH:
+ qemu_log_mask(CPU_LOG_MMU,
+ "%s address=%" VADDR_PRIx " physical " HWADDR_FMT_plx
+ " prot %d\n", __func__, address, physical, prot);
+ break;
+ default:
+ qemu_log_mask(CPU_LOG_MMU,
+ "%s address=%" VADDR_PRIx " ret %d\n", __func__, address,
+ ret);
+ break;
+ }
+ if (ret == TLBRET_MATCH) {
+ tlb_set_page(cs, address & TARGET_PAGE_MASK,
+ physical & TARGET_PAGE_MASK, prot,
+ mmu_idx, TARGET_PAGE_SIZE);
+ return true;
+ }
+#if !defined(TARGET_MIPS64)
+ if ((ret == TLBRET_NOMATCH) && (env->tlb->nb_tlb > 1)) {
+ /*
+ * Memory reads during hardware page table walking are performed
+ * as if they were kernel-mode load instructions.
+ */
+ int ptw_mmu_idx = (env->hflags & MIPS_HFLAG_ERL ?
+ MMU_ERL_IDX : MMU_KERNEL_IDX);
+
+ if (page_table_walk_refill(env, address, ptw_mmu_idx)) {
+ ret = get_physical_address(env, &physical, &prot, address,
+ access_type, mmu_idx);
+ if (ret == TLBRET_MATCH) {
+ tlb_set_page(cs, address & TARGET_PAGE_MASK,
+ physical & TARGET_PAGE_MASK, prot,
+ mmu_idx, TARGET_PAGE_SIZE);
+ return true;
+ }
+ }
+ }
+#endif
+ if (probe) {
+ return false;
+ }
+
+ raise_mmu_exception(env, address, access_type, ret);
+ do_raise_exception_err(env, cs->exception_index, env->error_code, retaddr);
+}
+
+hwaddr cpu_mips_translate_address(CPUMIPSState *env, target_ulong address,
+ MMUAccessType access_type, uintptr_t retaddr)
+{
+ hwaddr physical;
+ int prot;
+ int ret = 0;
+ CPUState *cs = env_cpu(env);
+
+ /* data access */
+ ret = get_physical_address(env, &physical, &prot, address, access_type,
+ mips_env_mmu_index(env));
+ if (ret == TLBRET_MATCH) {
+ return physical;
+ }
+
+ raise_mmu_exception(env, address, access_type, ret);
+ cpu_loop_exit_restore(cs, retaddr);
+}
+
+static void set_hflags_for_handler(CPUMIPSState *env)
+{
+ /* Exception handlers are entered in 32-bit mode. */
+ env->hflags &= ~(MIPS_HFLAG_M16);
+ /* ...except that microMIPS lets you choose. */
+ if (env->insn_flags & ASE_MICROMIPS) {
+ env->hflags |= (!!(env->CP0_Config3 &
+ (1 << CP0C3_ISA_ON_EXC))
+ << MIPS_HFLAG_M16_SHIFT);
+ }
+}
+
+static inline void set_badinstr_registers(CPUMIPSState *env)
+{
+ if (env->insn_flags & ISA_NANOMIPS32) {
+ if (env->CP0_Config3 & (1 << CP0C3_BI)) {
+ uint32_t instr = (cpu_lduw_code(env, env->active_tc.PC)) << 16;
+ if ((instr & 0x10000000) == 0) {
+ instr |= cpu_lduw_code(env, env->active_tc.PC + 2);
+ }
+ env->CP0_BadInstr = instr;
+
+ if ((instr & 0xFC000000) == 0x60000000) {
+ instr = cpu_lduw_code(env, env->active_tc.PC + 4) << 16;
+ env->CP0_BadInstrX = instr;
+ }
+ }
+ return;
+ }
+
+ if (env->hflags & MIPS_HFLAG_M16) {
+ /* TODO: add BadInstr support for microMIPS */
+ return;
+ }
+ if (env->CP0_Config3 & (1 << CP0C3_BI)) {
+ env->CP0_BadInstr = cpu_ldl_code(env, env->active_tc.PC);
+ }
+ if ((env->CP0_Config3 & (1 << CP0C3_BP)) &&
+ (env->hflags & MIPS_HFLAG_BMASK)) {
+ env->CP0_BadInstrP = cpu_ldl_code(env, env->active_tc.PC - 4);
+ }
+}
+
+void mips_cpu_do_interrupt(CPUState *cs)
+{
+ MIPSCPU *cpu = MIPS_CPU(cs);
+ CPUMIPSState *env = &cpu->env;
+ bool update_badinstr = 0;
+ target_ulong offset;
+ int cause = -1;
+
+ if (qemu_loglevel_mask(CPU_LOG_INT)
+ && cs->exception_index != EXCP_EXT_INTERRUPT) {
+ qemu_log("%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx
+ " %s exception\n",
+ __func__, env->active_tc.PC, env->CP0_EPC,
+ mips_exception_name(cs->exception_index));
+ }
+ if (cs->exception_index == EXCP_EXT_INTERRUPT &&
+ (env->hflags & MIPS_HFLAG_DM)) {
+ cs->exception_index = EXCP_DINT;
+ }
+ offset = 0x180;
+ switch (cs->exception_index) {
+ case EXCP_SEMIHOST:
+ cs->exception_index = EXCP_NONE;
+ mips_semihosting(env);
+ env->active_tc.PC += env->error_code;
+ return;
+ case EXCP_DSS:
+ env->CP0_Debug |= 1 << CP0DB_DSS;
+ /*
+ * Debug single step cannot be raised inside a delay slot and
+ * resume will always occur on the next instruction
+ * (but we assume the pc has always been updated during
+ * code translation).
+ */
+ env->CP0_DEPC = env->active_tc.PC | !!(env->hflags & MIPS_HFLAG_M16);
+ goto enter_debug_mode;
+ case EXCP_DINT:
+ env->CP0_Debug |= 1 << CP0DB_DINT;
+ goto set_DEPC;
+ case EXCP_DIB:
+ env->CP0_Debug |= 1 << CP0DB_DIB;
+ goto set_DEPC;
+ case EXCP_DBp:
+ env->CP0_Debug |= 1 << CP0DB_DBp;
+ /* Setup DExcCode - SDBBP instruction */
+ env->CP0_Debug = (env->CP0_Debug & ~(0x1fULL << CP0DB_DEC)) |
+ (9 << CP0DB_DEC);
+ goto set_DEPC;
+ case EXCP_DDBS:
+ env->CP0_Debug |= 1 << CP0DB_DDBS;
+ goto set_DEPC;
+ case EXCP_DDBL:
+ env->CP0_Debug |= 1 << CP0DB_DDBL;
+ set_DEPC:
+ env->CP0_DEPC = exception_resume_pc(env);
+ env->hflags &= ~MIPS_HFLAG_BMASK;
+ enter_debug_mode:
+ if (env->insn_flags & ISA_MIPS3) {
+ env->hflags |= MIPS_HFLAG_64;
+ if (!(env->insn_flags & ISA_MIPS_R6) ||
+ env->CP0_Status & (1 << CP0St_KX)) {
+ env->hflags &= ~MIPS_HFLAG_AWRAP;
+ }
+ }
+ env->hflags |= MIPS_HFLAG_DM | MIPS_HFLAG_CP0;
+ env->hflags &= ~(MIPS_HFLAG_KSU);
+ /* EJTAG probe trap enable is not implemented... */
+ if (!(env->CP0_Status & (1 << CP0St_EXL))) {
+ env->CP0_Cause &= ~(1U << CP0Ca_BD);
+ }
+ env->active_tc.PC = env->exception_base + 0x480;
+ set_hflags_for_handler(env);
+ break;
+ case EXCP_RESET:
+ cpu_reset(CPU(cpu));
+ break;
+ case EXCP_SRESET:
+ env->CP0_Status |= (1 << CP0St_SR);
+ memset(env->CP0_WatchLo, 0, sizeof(env->CP0_WatchLo));
+ goto set_error_EPC;
+ case EXCP_NMI:
+ env->CP0_Status |= (1 << CP0St_NMI);
+ set_error_EPC:
+ env->CP0_ErrorEPC = exception_resume_pc(env);
+ env->hflags &= ~MIPS_HFLAG_BMASK;
+ env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
+ if (env->insn_flags & ISA_MIPS3) {
+ env->hflags |= MIPS_HFLAG_64;
+ if (!(env->insn_flags & ISA_MIPS_R6) ||
+ env->CP0_Status & (1 << CP0St_KX)) {
+ env->hflags &= ~MIPS_HFLAG_AWRAP;
+ }
+ }
+ env->hflags |= MIPS_HFLAG_CP0;
+ env->hflags &= ~(MIPS_HFLAG_KSU);
+ if (!(env->CP0_Status & (1 << CP0St_EXL))) {
+ env->CP0_Cause &= ~(1U << CP0Ca_BD);
+ }
+ env->active_tc.PC = env->exception_base;
+ set_hflags_for_handler(env);
+ break;
+ case EXCP_EXT_INTERRUPT:
+ cause = 0;
+ if (env->CP0_Cause & (1 << CP0Ca_IV)) {
+ uint32_t spacing = (env->CP0_IntCtl >> CP0IntCtl_VS) & 0x1f;
+
+ if ((env->CP0_Status & (1 << CP0St_BEV)) || spacing == 0) {
+ offset = 0x200;
+ } else {
+ uint32_t vector = 0;
+ uint32_t pending = (env->CP0_Cause & CP0Ca_IP_mask) >> CP0Ca_IP;
+
+ if (env->CP0_Config3 & (1 << CP0C3_VEIC)) {
+ /*
+ * For VEIC mode, the external interrupt controller feeds
+ * the vector through the CP0Cause IP lines.
+ */
+ vector = pending;
+ } else {
+ /*
+ * Vectored Interrupts
+ * Mask with Status.IM7-IM0 to get enabled interrupts.
+ */
+ pending &= (env->CP0_Status >> CP0St_IM) & 0xff;
+ /* Find the highest-priority interrupt. */
+ while (pending >>= 1) {
+ vector++;
+ }
+ }
+ offset = 0x200 + (vector * (spacing << 5));
+ }
+ }
+ goto set_EPC;
+ case EXCP_LTLBL:
+ cause = 1;
+ update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL);
+ goto set_EPC;
+ case EXCP_TLBL:
+ cause = 2;
+ update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL);
+ if ((env->error_code & EXCP_TLB_NOMATCH) &&
+ !(env->CP0_Status & (1 << CP0St_EXL))) {
+#if defined(TARGET_MIPS64)
+ int R = env->CP0_BadVAddr >> 62;
+ int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
+ int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
+
+ if ((R != 0 || UX) && (R != 3 || KX) &&
+ (!(env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)))) {
+ offset = 0x080;
+ } else {
+#endif
+ offset = 0x000;
+#if defined(TARGET_MIPS64)
+ }
+#endif
+ }
+ goto set_EPC;
+ case EXCP_TLBS:
+ cause = 3;
+ update_badinstr = 1;
+ if ((env->error_code & EXCP_TLB_NOMATCH) &&
+ !(env->CP0_Status & (1 << CP0St_EXL))) {
+#if defined(TARGET_MIPS64)
+ int R = env->CP0_BadVAddr >> 62;
+ int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
+ int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
+
+ if ((R != 0 || UX) && (R != 3 || KX) &&
+ (!(env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)))) {
+ offset = 0x080;
+ } else {
+#endif
+ offset = 0x000;
+#if defined(TARGET_MIPS64)
+ }
+#endif
+ }
+ goto set_EPC;
+ case EXCP_AdEL:
+ cause = 4;
+ update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL);
+ goto set_EPC;
+ case EXCP_AdES:
+ cause = 5;
+ update_badinstr = 1;
+ goto set_EPC;
+ case EXCP_IBE:
+ cause = 6;
+ goto set_EPC;
+ case EXCP_DBE:
+ cause = 7;
+ goto set_EPC;
+ case EXCP_SYSCALL:
+ cause = 8;
+ update_badinstr = 1;
+ goto set_EPC;
+ case EXCP_BREAK:
+ cause = 9;
+ update_badinstr = 1;
+ goto set_EPC;
+ case EXCP_RI:
+ cause = 10;
+ update_badinstr = 1;
+ goto set_EPC;
+ case EXCP_CpU:
+ cause = 11;
+ update_badinstr = 1;
+ env->CP0_Cause = (env->CP0_Cause & ~(0x3 << CP0Ca_CE)) |
+ (env->error_code << CP0Ca_CE);
+ goto set_EPC;
+ case EXCP_OVERFLOW:
+ cause = 12;
+ update_badinstr = 1;
+ goto set_EPC;
+ case EXCP_TRAP:
+ cause = 13;
+ update_badinstr = 1;
+ goto set_EPC;
+ case EXCP_MSAFPE:
+ cause = 14;
+ update_badinstr = 1;
+ goto set_EPC;
+ case EXCP_FPE:
+ cause = 15;
+ update_badinstr = 1;
+ goto set_EPC;
+ case EXCP_C2E:
+ cause = 18;
+ goto set_EPC;
+ case EXCP_TLBRI:
+ cause = 19;
+ update_badinstr = 1;
+ goto set_EPC;
+ case EXCP_TLBXI:
+ cause = 20;
+ goto set_EPC;
+ case EXCP_MSADIS:
+ cause = 21;
+ update_badinstr = 1;
+ goto set_EPC;
+ case EXCP_MDMX:
+ cause = 22;
+ goto set_EPC;
+ case EXCP_DWATCH:
+ cause = 23;
+ /* XXX: TODO: manage deferred watch exceptions */
+ goto set_EPC;
+ case EXCP_MCHECK:
+ cause = 24;
+ goto set_EPC;
+ case EXCP_THREAD:
+ cause = 25;
+ goto set_EPC;
+ case EXCP_DSPDIS:
+ cause = 26;
+ goto set_EPC;
+ case EXCP_CACHE:
+ cause = 30;
+ offset = 0x100;
+ set_EPC:
+ if (!(env->CP0_Status & (1 << CP0St_EXL))) {
+ env->CP0_EPC = exception_resume_pc(env);
+ if (update_badinstr) {
+ set_badinstr_registers(env);
+ }
+ if (env->hflags & MIPS_HFLAG_BMASK) {
+ env->CP0_Cause |= (1U << CP0Ca_BD);
+ } else {
+ env->CP0_Cause &= ~(1U << CP0Ca_BD);
+ }
+ env->CP0_Status |= (1 << CP0St_EXL);
+ if (env->insn_flags & ISA_MIPS3) {
+ env->hflags |= MIPS_HFLAG_64;
+ if (!(env->insn_flags & ISA_MIPS_R6) ||
+ env->CP0_Status & (1 << CP0St_KX)) {
+ env->hflags &= ~MIPS_HFLAG_AWRAP;
+ }
+ }
+ env->hflags |= MIPS_HFLAG_CP0;
+ env->hflags &= ~(MIPS_HFLAG_KSU);
+ }
+ env->hflags &= ~MIPS_HFLAG_BMASK;
+ if (env->CP0_Status & (1 << CP0St_BEV)) {
+ env->active_tc.PC = env->exception_base + 0x200;
+ } else if (cause == 30 && !(env->CP0_Config3 & (1 << CP0C3_SC) &&
+ env->CP0_Config5 & (1 << CP0C5_CV))) {
+ /* Force KSeg1 for cache errors */
+ env->active_tc.PC = KSEG1_BASE | (env->CP0_EBase & 0x1FFFF000);
+ } else {
+ env->active_tc.PC = env->CP0_EBase & ~0xfff;
+ }
+
+ env->active_tc.PC += offset;
+ set_hflags_for_handler(env);
+ env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) |
+ (cause << CP0Ca_EC);
+ break;
+ default:
+ abort();
+ }
+ if (qemu_loglevel_mask(CPU_LOG_INT)
+ && cs->exception_index != EXCP_EXT_INTERRUPT) {
+ qemu_log("%s: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d\n"
+ " S %08x C %08x A " TARGET_FMT_lx " D " TARGET_FMT_lx "\n",
+ __func__, env->active_tc.PC, env->CP0_EPC, cause,
+ env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr,
+ env->CP0_DEPC);
+ }
+ cs->exception_index = EXCP_NONE;
+}
+
+bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+ if (interrupt_request & CPU_INTERRUPT_HARD) {
+ CPUMIPSState *env = cpu_env(cs);
+
+ if (cpu_mips_hw_interrupts_enabled(env) &&
+ cpu_mips_hw_interrupts_pending(env)) {
+ /* Raise it */
+ cs->exception_index = EXCP_EXT_INTERRUPT;
+ env->error_code = 0;
+ mips_cpu_do_interrupt(cs);
+ return true;
+ }
+ }
+ return false;
+}
+
+void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra)
+{
+ CPUState *cs = env_cpu(env);
+ r4k_tlb_t *tlb;
+ target_ulong addr;
+ target_ulong end;
+ uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
+ uint32_t MMID = env->CP0_MemoryMapID;
+ bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1);
+ uint32_t tlb_mmid;
+ target_ulong mask;
+
+ MMID = mi ? MMID : (uint32_t) ASID;
+
+ tlb = &env->tlb->mmu.r4k.tlb[idx];
+ /*
+ * The qemu TLB is flushed when the ASID/MMID changes, so no need to
+ * flush these entries again.
+ */
+ tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID;
+ if (tlb->G == 0 && tlb_mmid != MMID) {
+ return;
+ }
+
+ if (use_extra && env->tlb->tlb_in_use < MIPS_TLB_MAX) {
+ /*
+ * For tlbwr, we can shadow the discarded entry into
+ * a new (fake) TLB entry, as long as the guest can not
+ * tell that it's there.
+ */
+ env->tlb->mmu.r4k.tlb[env->tlb->tlb_in_use] = *tlb;
+ env->tlb->tlb_in_use++;
+ return;
+ }
+
+ /* 1k pages are not supported. */
+ mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
+ if (tlb->V0) {
+ addr = tlb->VPN & ~mask;
+#if defined(TARGET_MIPS64)
+ if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) {
+ addr |= 0x3FFFFF0000000000ULL;
+ }
+#endif
+ end = addr | (mask >> 1);
+ while (addr < end) {
+ tlb_flush_page(cs, addr);
+ addr += TARGET_PAGE_SIZE;
+ }
+ }
+ if (tlb->V1) {
+ addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1);
+#if defined(TARGET_MIPS64)
+ if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) {
+ addr |= 0x3FFFFF0000000000ULL;
+ }
+#endif
+ end = addr | mask;
+ while (addr - 1 < end) {
+ tlb_flush_page(cs, addr);
+ addr += TARGET_PAGE_SIZE;
+ }
+ }
+}
--- /dev/null
+/*
+ * QEMU MIPS TCG system helpers
+ *
+ * Copyright (c) 2004-2005 Jocelyn Mayer
+ * Copyright (c) 2006 Marius Groeger (FPU operations)
+ * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
+ * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+/* CP0 helpers */
+DEF_HELPER_1(mfc0_mvpcontrol, tl, env)
+DEF_HELPER_1(mfc0_mvpconf0, tl, env)
+DEF_HELPER_1(mfc0_mvpconf1, tl, env)
+DEF_HELPER_1(mftc0_vpecontrol, tl, env)
+DEF_HELPER_1(mftc0_vpeconf0, tl, env)
+DEF_HELPER_1(mfc0_random, tl, env)
+DEF_HELPER_1(mfc0_tcstatus, tl, env)
+DEF_HELPER_1(mftc0_tcstatus, tl, env)
+DEF_HELPER_1(mfc0_tcbind, tl, env)
+DEF_HELPER_1(mftc0_tcbind, tl, env)
+DEF_HELPER_1(mfc0_tcrestart, tl, env)
+DEF_HELPER_1(mftc0_tcrestart, tl, env)
+DEF_HELPER_1(mfc0_tchalt, tl, env)
+DEF_HELPER_1(mftc0_tchalt, tl, env)
+DEF_HELPER_1(mfc0_tccontext, tl, env)
+DEF_HELPER_1(mftc0_tccontext, tl, env)
+DEF_HELPER_1(mfc0_tcschedule, tl, env)
+DEF_HELPER_1(mftc0_tcschedule, tl, env)
+DEF_HELPER_1(mfc0_tcschefback, tl, env)
+DEF_HELPER_1(mftc0_tcschefback, tl, env)
+DEF_HELPER_1(mfc0_count, tl, env)
+DEF_HELPER_1(mftc0_entryhi, tl, env)
+DEF_HELPER_1(mftc0_status, tl, env)
+DEF_HELPER_1(mftc0_cause, tl, env)
+DEF_HELPER_1(mftc0_epc, tl, env)
+DEF_HELPER_1(mftc0_ebase, tl, env)
+DEF_HELPER_2(mftc0_configx, tl, env, tl)
+DEF_HELPER_1(mfc0_lladdr, tl, env)
+DEF_HELPER_1(mfc0_maar, tl, env)
+DEF_HELPER_1(mfhc0_maar, tl, env)
+DEF_HELPER_2(mfc0_watchlo, tl, env, i32)
+DEF_HELPER_2(mfc0_watchhi, tl, env, i32)
+DEF_HELPER_2(mfhc0_watchhi, tl, env, i32)
+DEF_HELPER_1(mfc0_debug, tl, env)
+DEF_HELPER_1(mftc0_debug, tl, env)
+#ifdef TARGET_MIPS64
+DEF_HELPER_1(dmfc0_tcrestart, tl, env)
+DEF_HELPER_1(dmfc0_tchalt, tl, env)
+DEF_HELPER_1(dmfc0_tccontext, tl, env)
+DEF_HELPER_1(dmfc0_tcschedule, tl, env)
+DEF_HELPER_1(dmfc0_tcschefback, tl, env)
+DEF_HELPER_1(dmfc0_lladdr, tl, env)
+DEF_HELPER_1(dmfc0_maar, tl, env)
+DEF_HELPER_2(dmfc0_watchlo, tl, env, i32)
+DEF_HELPER_2(dmfc0_watchhi, tl, env, i32)
+#endif /* TARGET_MIPS64 */
+
+DEF_HELPER_2(mtc0_index, void, env, tl)
+DEF_HELPER_2(mtc0_mvpcontrol, void, env, tl)
+DEF_HELPER_2(mtc0_vpecontrol, void, env, tl)
+DEF_HELPER_2(mttc0_vpecontrol, void, env, tl)
+DEF_HELPER_2(mtc0_vpeconf0, void, env, tl)
+DEF_HELPER_2(mttc0_vpeconf0, void, env, tl)
+DEF_HELPER_2(mtc0_vpeconf1, void, env, tl)
+DEF_HELPER_2(mtc0_yqmask, void, env, tl)
+DEF_HELPER_2(mtc0_vpeopt, void, env, tl)
+DEF_HELPER_2(mtc0_entrylo0, void, env, tl)
+DEF_HELPER_2(mtc0_tcstatus, void, env, tl)
+DEF_HELPER_2(mttc0_tcstatus, void, env, tl)
+DEF_HELPER_2(mtc0_tcbind, void, env, tl)
+DEF_HELPER_2(mttc0_tcbind, void, env, tl)
+DEF_HELPER_2(mtc0_tcrestart, void, env, tl)
+DEF_HELPER_2(mttc0_tcrestart, void, env, tl)
+DEF_HELPER_2(mtc0_tchalt, void, env, tl)
+DEF_HELPER_2(mttc0_tchalt, void, env, tl)
+DEF_HELPER_2(mtc0_tccontext, void, env, tl)
+DEF_HELPER_2(mttc0_tccontext, void, env, tl)
+DEF_HELPER_2(mtc0_tcschedule, void, env, tl)
+DEF_HELPER_2(mttc0_tcschedule, void, env, tl)
+DEF_HELPER_2(mtc0_tcschefback, void, env, tl)
+DEF_HELPER_2(mttc0_tcschefback, void, env, tl)
+DEF_HELPER_2(mtc0_entrylo1, void, env, tl)
+DEF_HELPER_2(mtc0_context, void, env, tl)
+DEF_HELPER_2(mtc0_memorymapid, void, env, tl)
+DEF_HELPER_2(mtc0_pagemask, void, env, tl)
+DEF_HELPER_2(mtc0_pagegrain, void, env, tl)
+DEF_HELPER_2(mtc0_segctl0, void, env, tl)
+DEF_HELPER_2(mtc0_segctl1, void, env, tl)
+DEF_HELPER_2(mtc0_segctl2, void, env, tl)
+DEF_HELPER_2(mtc0_pwfield, void, env, tl)
+DEF_HELPER_2(mtc0_pwsize, void, env, tl)
+DEF_HELPER_2(mtc0_wired, void, env, tl)
+DEF_HELPER_2(mtc0_srsconf0, void, env, tl)
+DEF_HELPER_2(mtc0_srsconf1, void, env, tl)
+DEF_HELPER_2(mtc0_srsconf2, void, env, tl)
+DEF_HELPER_2(mtc0_srsconf3, void, env, tl)
+DEF_HELPER_2(mtc0_srsconf4, void, env, tl)
+DEF_HELPER_2(mtc0_hwrena, void, env, tl)
+DEF_HELPER_2(mtc0_pwctl, void, env, tl)
+DEF_HELPER_2(mtc0_count, void, env, tl)
+DEF_HELPER_2(mtc0_entryhi, void, env, tl)
+DEF_HELPER_2(mttc0_entryhi, void, env, tl)
+DEF_HELPER_2(mtc0_compare, void, env, tl)
+DEF_HELPER_2(mtc0_status, void, env, tl)
+DEF_HELPER_2(mttc0_status, void, env, tl)
+DEF_HELPER_2(mtc0_intctl, void, env, tl)
+DEF_HELPER_2(mtc0_srsctl, void, env, tl)
+DEF_HELPER_2(mtc0_cause, void, env, tl)
+DEF_HELPER_2(mttc0_cause, void, env, tl)
+DEF_HELPER_2(mtc0_ebase, void, env, tl)
+DEF_HELPER_2(mttc0_ebase, void, env, tl)
+DEF_HELPER_2(mtc0_config0, void, env, tl)
+DEF_HELPER_2(mtc0_config2, void, env, tl)
+DEF_HELPER_2(mtc0_config3, void, env, tl)
+DEF_HELPER_2(mtc0_config4, void, env, tl)
+DEF_HELPER_2(mtc0_config5, void, env, tl)
+DEF_HELPER_2(mtc0_lladdr, void, env, tl)
+DEF_HELPER_2(mtc0_maar, void, env, tl)
+DEF_HELPER_2(mthc0_maar, void, env, tl)
+DEF_HELPER_2(mtc0_maari, void, env, tl)
+DEF_HELPER_3(mtc0_watchlo, void, env, tl, i32)
+DEF_HELPER_3(mtc0_watchhi, void, env, tl, i32)
+DEF_HELPER_3(mthc0_watchhi, void, env, tl, i32)
+DEF_HELPER_2(mtc0_xcontext, void, env, tl)
+DEF_HELPER_2(mtc0_framemask, void, env, tl)
+DEF_HELPER_2(mtc0_debug, void, env, tl)
+DEF_HELPER_2(mttc0_debug, void, env, tl)
+DEF_HELPER_2(mtc0_performance0, void, env, tl)
+DEF_HELPER_2(mtc0_errctl, void, env, tl)
+DEF_HELPER_2(mtc0_taglo, void, env, tl)
+DEF_HELPER_2(mtc0_datalo, void, env, tl)
+DEF_HELPER_2(mtc0_taghi, void, env, tl)
+DEF_HELPER_2(mtc0_datahi, void, env, tl)
+
+#if defined(TARGET_MIPS64)
+DEF_HELPER_2(dmtc0_entrylo0, void, env, i64)
+DEF_HELPER_2(dmtc0_entrylo1, void, env, i64)
+#endif
+
+/* MIPS MT functions */
+DEF_HELPER_2(mftgpr, tl, env, i32)
+DEF_HELPER_2(mftlo, tl, env, i32)
+DEF_HELPER_2(mfthi, tl, env, i32)
+DEF_HELPER_2(mftacx, tl, env, i32)
+DEF_HELPER_1(mftdsp, tl, env)
+DEF_HELPER_3(mttgpr, void, env, tl, i32)
+DEF_HELPER_3(mttlo, void, env, tl, i32)
+DEF_HELPER_3(mtthi, void, env, tl, i32)
+DEF_HELPER_3(mttacx, void, env, tl, i32)
+DEF_HELPER_2(mttdsp, void, env, tl)
+DEF_HELPER_0(dmt, tl)
+DEF_HELPER_0(emt, tl)
+DEF_HELPER_1(dvpe, tl, env)
+DEF_HELPER_1(evpe, tl, env)
+
+/* R6 Multi-threading */
+DEF_HELPER_1(dvp, tl, env)
+DEF_HELPER_1(evp, tl, env)
+
+/* TLB */
+DEF_HELPER_1(tlbwi, void, env)
+DEF_HELPER_1(tlbwr, void, env)
+DEF_HELPER_1(tlbp, void, env)
+DEF_HELPER_1(tlbr, void, env)
+DEF_HELPER_1(tlbinv, void, env)
+DEF_HELPER_1(tlbinvf, void, env)
+DEF_HELPER_3(ginvt, void, env, tl, i32)
+
+/* Special */
+DEF_HELPER_1(di, tl, env)
+DEF_HELPER_1(ei, tl, env)
+DEF_HELPER_1(eret, void, env)
+DEF_HELPER_1(eretnc, void, env)
+DEF_HELPER_1(deret, void, env)
+DEF_HELPER_3(cache, void, env, tl, i32)
+
+#ifdef TARGET_MIPS64
+/* Longson CSR */
+DEF_HELPER_2(lcsr_rdcsr, i64, env, tl)
+DEF_HELPER_2(lcsr_drdcsr, i64, env, tl)
+DEF_HELPER_3(lcsr_wrcsr, void, env, tl, tl)
+DEF_HELPER_3(lcsr_dwrcsr, void, env, tl, tl)
+#endif
/*
- * Many sysemu-only helpers are not reachable for user-only.
+ * Many system-only helpers are not reachable for user-only.
* Define stub generators here, so that we need not either sprinkle
* ifdefs through the translator, nor provide the helper function.
*/
#include "qemu/osdep.h"
#include "cpu.h"
#include "elf.h"
-#include "sysemu/dump.h"
-#include "sysemu/kvm.h"
+#include "system/dump.h"
+#include "system/kvm.h"
#ifdef TARGET_PPC64
#define ELFCLASS ELFCLASS64
*/
#include "qemu/osdep.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/kvm.h"
+#include "system/hw_accel.h"
+#include "system/kvm.h"
#include "kvm_ppc.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "fpu/softfloat-helpers.h"
#include "mmu-hash64.h"
#include "helper_regs.h"
-#include "sysemu/tcg.h"
+#include "system/tcg.h"
target_ulong cpu_read_xer(const CPUPPCState *env)
{
#include "qemu/osdep.h"
#include "disas/dis-asm.h"
#include "gdbstub/helpers.h"
-#include "sysemu/cpus.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/tcg.h"
+#include "system/cpus.h"
+#include "system/hw_accel.h"
+#include "system/tcg.h"
#include "cpu-models.h"
#include "mmu-hash32.h"
#include "mmu-hash64.h"
#include "qemu/osdep.h"
#include "qemu/main-loop.h"
#include "qemu/log.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/runstate.h"
+#include "system/system.h"
+#include "system/runstate.h"
#include "cpu.h"
#include "exec/exec-all.h"
#include "internal.h"
#include "trace.h"
#ifdef CONFIG_TCG
-#include "sysemu/tcg.h"
+#include "system/tcg.h"
#include "exec/helper-proto.h"
#include "exec/cpu_ldst.h"
#endif
#include "cpu.h"
#include "qemu/main-loop.h"
#include "exec/exec-all.h"
-#include "sysemu/kvm.h"
-#include "sysemu/tcg.h"
+#include "system/kvm.h"
+#include "system/tcg.h"
#include "helper_regs.h"
#include "power8-pmu.h"
#include "cpu-models.h"
#include "cpu.h"
#include "cpu-models.h"
#include "qemu/timer.h"
-#include "sysemu/hw_accel.h"
+#include "system/hw_accel.h"
#include "kvm_ppc.h"
-#include "sysemu/cpus.h"
-#include "sysemu/device_tree.h"
+#include "system/cpus.h"
+#include "system/device_tree.h"
#include "mmu-hash64.h"
#include "hw/ppc/spapr.h"
#include "hw/hw.h"
#include "hw/ppc/ppc.h"
#include "migration/qemu-file-types.h"
-#include "sysemu/watchdog.h"
+#include "system/watchdog.h"
#include "trace.h"
#include "gdbstub/enums.h"
#include "exec/memattrs.h"
#include "exec/ram_addr.h"
-#include "sysemu/hostmem.h"
+#include "system/hostmem.h"
#include "qemu/cutils.h"
#include "qemu/main-loop.h"
#include "qemu/mmap-alloc.h"
#include "elf.h"
-#include "sysemu/kvm_int.h"
-#include "sysemu/kvm.h"
+#include "system/kvm_int.h"
+#include "system/kvm.h"
#include "hw/core/accel-cpu.h"
#include CONFIG_DEVICES
#ifndef KVM_PPC_H
#define KVM_PPC_H
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "exec/hwaddr.h"
#include "cpu.h"
#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/exec-all.h"
-#include "sysemu/kvm.h"
-#include "sysemu/tcg.h"
+#include "system/kvm.h"
+#include "system/tcg.h"
#include "helper_regs.h"
#include "mmu-hash64.h"
#include "migration/cpu.h"
#include "qapi/error.h"
#include "kvm_ppc.h"
#include "power8-pmu.h"
-#include "sysemu/replay.h"
+#include "system/replay.h"
static void post_load_update_msr(CPUPPCState *env)
{
#include "cpu.h"
#include "exec/exec-all.h"
#include "exec/page-protection.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "kvm_ppc.h"
#include "internal.h"
#include "mmu-hash32.h"
#include "exec/page-protection.h"
#include "qemu/error-report.h"
#include "qemu/qemu-print.h"
-#include "sysemu/hw_accel.h"
+#include "system/hw_accel.h"
#include "kvm_ppc.h"
#include "mmu-hash64.h"
#include "exec/log.h"
#include "exec/exec-all.h"
#include "exec/page-protection.h"
#include "qemu/error-report.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "kvm_ppc.h"
#include "exec/log.h"
#include "internal.h"
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "cpu.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "kvm_ppc.h"
#include "mmu-hash64.h"
#include "mmu-hash32.h"
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "cpu.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "kvm_ppc.h"
#include "mmu-hash64.h"
#include "mmu-hash32.h"
#include "qemu/osdep.h"
#include "cpu.h"
#include "elf.h"
-#include "sysemu/dump.h"
+#include "system/dump.h"
/* struct user_regs_struct from arch/riscv/include/uapi/asm/ptrace.h */
struct riscv64_user_regs {
#include "hw/core/qdev-prop-internal.h"
#include "migration/vmstate.h"
#include "fpu/softfloat-helpers.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/kvm.h"
-#include "sysemu/tcg.h"
+#include "system/device_tree.h"
+#include "system/kvm.h"
+#include "system/tcg.h"
#include "kvm/kvm_riscv.h"
#include "tcg/tcg-cpu.h"
#include "tcg/tcg.h"
#include "tcg/tcg-op.h"
#include "trace.h"
#include "semihosting/common-semi.h"
-#include "sysemu/cpu-timers.h"
+#include "system/cpu-timers.h"
#include "cpu_bits.h"
#include "debug.h"
#include "tcg/oversized-guest.h"
#include "time_helper.h"
#include "exec/exec-all.h"
#include "exec/tb-flush.h"
-#include "sysemu/cpu-timers.h"
+#include "system/cpu-timers.h"
#include "qemu/guest-random.h"
#include "qapi/error.h"
#include "trace.h"
#include "exec/exec-all.h"
#include "exec/helper-proto.h"
-#include "sysemu/cpu-timers.h"
+#include "system/cpu-timers.h"
/*
* The following M-mode trigger CSRs are implemented:
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qapi/visitor.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/kvm.h"
-#include "sysemu/kvm_int.h"
+#include "system/system.h"
+#include "system/kvm.h"
+#include "system/kvm_int.h"
#include "cpu.h"
#include "trace.h"
#include "hw/core/accel-cpu.h"
#include "sbi_ecall_interface.h"
#include "chardev/char-fe.h"
#include "migration/misc.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#include "hw/riscv/numa.h"
#define PR_RISCV_V_SET_CONTROL 69
#include "qemu/osdep.h"
#include "cpu.h"
#include "qemu/error-report.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "migration/cpu.h"
-#include "sysemu/cpu-timers.h"
+#include "system/cpu-timers.h"
#include "debug.h"
static bool pmp_needed(void *opaque)
#include "qemu/timer.h"
#include "cpu.h"
#include "pmu.h"
-#include "sysemu/cpu-timers.h"
-#include "sysemu/device_tree.h"
+#include "system/cpu-timers.h"
+#include "system/device_tree.h"
#define RISCV_TIMEBASE_FREQ 1000000000 /* 1Ghz */
#include "qapi/qobject-input-visitor.h"
#include "qapi/visitor.h"
#include "qom/qom-qobject.h"
-#include "sysemu/kvm.h"
-#include "sysemu/tcg.h"
+#include "system/kvm.h"
+#include "system/tcg.h"
#include "cpu-qom.h"
#include "cpu.h"
#include "cpu.h"
#include "s390x-internal.h"
#include "elf.h"
-#include "sysemu/dump.h"
+#include "system/dump.h"
#include "kvm/kvm_s390x.h"
#include "target/s390x/kvm/pv.h"
#include "cpu.h"
#include "s390x-internal.h"
#include "qemu/qemu-print.h"
-#include "sysemu/tcg.h"
+#include "system/tcg.h"
void s390_cpu_dump_state(CPUState *cs, FILE *f, int flags)
{
+++ /dev/null
-/*
- * QEMU S/390 CPU - System Emulation-only code
- *
- * Copyright (c) 2009 Ulrich Hecht
- * Copyright (c) 2011 Alexander Graf
- * Copyright (c) 2012 SUSE LINUX Products GmbH
- * Copyright (c) 2012 IBM Corp.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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
- * General Public License for more details.
- *
- * 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/osdep.h"
-#include "qemu/error-report.h"
-#include "qapi/error.h"
-#include "cpu.h"
-#include "s390x-internal.h"
-#include "kvm/kvm_s390x.h"
-#include "sysemu/kvm.h"
-#include "sysemu/reset.h"
-#include "qemu/timer.h"
-#include "trace.h"
-#include "qapi/qapi-visit-run-state.h"
-#include "sysemu/hw_accel.h"
-
-#include "target/s390x/kvm/pv.h"
-#include "hw/boards.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/tcg.h"
-#include "hw/core/sysemu-cpu-ops.h"
-
-/* S390CPUClass::load_normal() */
-static void s390_cpu_load_normal(CPUState *s)
-{
- S390CPU *cpu = S390_CPU(s);
- uint64_t spsw;
-
- if (!s390_is_pv()) {
- spsw = ldq_phys(s->as, 0);
- cpu->env.psw.mask = spsw & PSW_MASK_SHORT_CTRL;
- /*
- * Invert short psw indication, so SIE will report a specification
- * exception if it was not set.
- */
- cpu->env.psw.mask ^= PSW_MASK_SHORTPSW;
- cpu->env.psw.addr = spsw & PSW_MASK_SHORT_ADDR;
- } else {
- /*
- * Firmware requires us to set the load state before we set
- * the cpu to operating on protected guests.
- */
- s390_cpu_set_state(S390_CPU_STATE_LOAD, cpu);
- }
- s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
-}
-
-void s390_cpu_machine_reset_cb(void *opaque)
-{
- S390CPU *cpu = opaque;
-
- run_on_cpu(CPU(cpu), s390_do_cpu_full_reset, RUN_ON_CPU_NULL);
-}
-
-static GuestPanicInformation *s390_cpu_get_crash_info(CPUState *cs)
-{
- GuestPanicInformation *panic_info;
- S390CPU *cpu = S390_CPU(cs);
-
- cpu_synchronize_state(cs);
- panic_info = g_new0(GuestPanicInformation, 1);
-
- panic_info->type = GUEST_PANIC_INFORMATION_TYPE_S390;
- panic_info->u.s390.core = cpu->env.core_id;
- panic_info->u.s390.psw_mask = cpu->env.psw.mask;
- panic_info->u.s390.psw_addr = cpu->env.psw.addr;
- panic_info->u.s390.reason = cpu->env.crash_reason;
-
- return panic_info;
-}
-
-static void s390_cpu_get_crash_info_qom(Object *obj, Visitor *v,
- const char *name, void *opaque,
- Error **errp)
-{
- CPUState *cs = CPU(obj);
- GuestPanicInformation *panic_info;
-
- if (!cs->crash_occurred) {
- error_setg(errp, "No crash occurred");
- return;
- }
-
- panic_info = s390_cpu_get_crash_info(cs);
-
- visit_type_GuestPanicInformation(v, "crash-information", &panic_info,
- errp);
- qapi_free_GuestPanicInformation(panic_info);
-}
-
-void s390_cpu_init_sysemu(Object *obj)
-{
- CPUState *cs = CPU(obj);
- S390CPU *cpu = S390_CPU(obj);
-
- cs->start_powered_off = true;
- object_property_add(obj, "crash-information", "GuestPanicInformation",
- s390_cpu_get_crash_info_qom, NULL, NULL, NULL);
- cpu->env.tod_timer =
- timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_tod_timer, cpu);
- cpu->env.cpu_timer =
- timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_cpu_timer, cpu);
- s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
-}
-
-bool s390_cpu_realize_sysemu(DeviceState *dev, Error **errp)
-{
- S390CPU *cpu = S390_CPU(dev);
- MachineState *ms = MACHINE(qdev_get_machine());
- unsigned int max_cpus = ms->smp.max_cpus;
-
- if (cpu->env.core_id >= max_cpus) {
- error_setg(errp, "Unable to add CPU with core-id: %" PRIu32
- ", maximum core-id: %d", cpu->env.core_id,
- max_cpus - 1);
- return false;
- }
-
- if (cpu_exists(cpu->env.core_id)) {
- error_setg(errp, "Unable to add CPU with core-id: %" PRIu32
- ", it already exists", cpu->env.core_id);
- return false;
- }
-
- /* sync cs->cpu_index and env->core_id. The latter is needed for TCG. */
- CPU(cpu)->cpu_index = cpu->env.core_id;
- return true;
-}
-
-void s390_cpu_finalize(Object *obj)
-{
- S390CPU *cpu = S390_CPU(obj);
-
- timer_free(cpu->env.tod_timer);
- timer_free(cpu->env.cpu_timer);
-
- qemu_unregister_reset(s390_cpu_machine_reset_cb, cpu);
- g_free(cpu->irqstate);
-}
-
-static const struct SysemuCPUOps s390_sysemu_ops = {
- .get_phys_page_debug = s390_cpu_get_phys_page_debug,
- .get_crash_info = s390_cpu_get_crash_info,
- .write_elf64_note = s390_cpu_write_elf64_note,
- .legacy_vmsd = &vmstate_s390_cpu,
-};
-
-void s390_cpu_class_init_sysemu(CPUClass *cc)
-{
- S390CPUClass *scc = S390_CPU_CLASS(cc);
-
- scc->load_normal = s390_cpu_load_normal;
- cc->sysemu_ops = &s390_sysemu_ops;
-}
-
-static bool disabled_wait(CPUState *cpu)
-{
- return cpu->halted && !(S390_CPU(cpu)->env.psw.mask &
- (PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK));
-}
-
-static unsigned s390_count_running_cpus(void)
-{
- CPUState *cpu;
- int nr_running = 0;
-
- CPU_FOREACH(cpu) {
- uint8_t state = S390_CPU(cpu)->env.cpu_state;
- if (state == S390_CPU_STATE_OPERATING ||
- state == S390_CPU_STATE_LOAD) {
- if (!disabled_wait(cpu)) {
- nr_running++;
- }
- }
- }
-
- return nr_running;
-}
-
-unsigned int s390_cpu_halt(S390CPU *cpu)
-{
- CPUState *cs = CPU(cpu);
- trace_cpu_halt(cs->cpu_index);
-
- if (!cs->halted) {
- cs->halted = 1;
- cs->exception_index = EXCP_HLT;
- }
-
- return s390_count_running_cpus();
-}
-
-void s390_cpu_unhalt(S390CPU *cpu)
-{
- CPUState *cs = CPU(cpu);
- trace_cpu_unhalt(cs->cpu_index);
-
- if (cs->halted) {
- cs->halted = 0;
- cs->exception_index = -1;
- }
-}
-
-unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
- {
- trace_cpu_set_state(CPU(cpu)->cpu_index, cpu_state);
-
- switch (cpu_state) {
- case S390_CPU_STATE_STOPPED:
- case S390_CPU_STATE_CHECK_STOP:
- /* halt the cpu for common infrastructure */
- s390_cpu_halt(cpu);
- break;
- case S390_CPU_STATE_OPERATING:
- case S390_CPU_STATE_LOAD:
- /*
- * Starting a CPU with a PSW WAIT bit set:
- * KVM: handles this internally and triggers another WAIT exit.
- * TCG: will actually try to continue to run. Don't unhalt, will
- * be done when the CPU actually has work (an interrupt).
- */
- if (!tcg_enabled() || !(cpu->env.psw.mask & PSW_MASK_WAIT)) {
- s390_cpu_unhalt(cpu);
- }
- break;
- default:
- error_report("Requested CPU state is not a valid S390 CPU state: %u",
- cpu_state);
- exit(1);
- }
- if (kvm_enabled() && cpu->env.cpu_state != cpu_state) {
- kvm_s390_set_cpu_state(cpu, cpu_state);
- }
- cpu->env.cpu_state = cpu_state;
-
- return s390_count_running_cpus();
-}
-
-int s390_set_memory_limit(uint64_t new_limit, uint64_t *hw_limit)
-{
- if (kvm_enabled()) {
- return kvm_s390_set_mem_limit(new_limit, hw_limit);
- }
- return 0;
-}
-
-void s390_set_max_pagesize(uint64_t pagesize, Error **errp)
-{
- if (kvm_enabled()) {
- kvm_s390_set_max_pagesize(pagesize, errp);
- }
-}
-
-void s390_cmma_reset(void)
-{
- if (kvm_enabled()) {
- kvm_s390_cmma_reset();
- }
-}
-
-int s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch_id,
- int vq, bool assign)
-{
- if (kvm_enabled()) {
- return kvm_s390_assign_subch_ioeventfd(notifier, sch_id, vq, assign);
- } else {
- return 0;
- }
-}
-
-void s390_crypto_reset(void)
-{
- if (kvm_enabled()) {
- kvm_s390_crypto_reset();
- }
-}
-
-void s390_enable_css_support(S390CPU *cpu)
-{
- if (kvm_enabled()) {
- kvm_s390_enable_css_support(cpu);
- }
-}
-
-void s390_do_cpu_set_diag318(CPUState *cs, run_on_cpu_data arg)
-{
- if (kvm_enabled()) {
- kvm_s390_set_diag318(cs, arg.host_ulong);
- }
-}
-
-void s390_cpu_topology_set_changed(bool changed)
-{
- int ret;
-
- if (kvm_enabled()) {
- ret = kvm_s390_topology_set_mtcr(changed);
- if (ret) {
- error_report("Failed to set Modified Topology Change Report: %s",
- strerror(-ret));
- }
- }
-}
--- /dev/null
+/*
+ * QEMU S/390 CPU - System-only code
+ *
+ * Copyright (c) 2009 Ulrich Hecht
+ * Copyright (c) 2011 Alexander Graf
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ * Copyright (c) 2012 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * 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/osdep.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "s390x-internal.h"
+#include "kvm/kvm_s390x.h"
+#include "system/kvm.h"
+#include "system/reset.h"
+#include "qemu/timer.h"
+#include "trace.h"
+#include "qapi/qapi-visit-run-state.h"
+#include "system/hw_accel.h"
+
+#include "target/s390x/kvm/pv.h"
+#include "hw/boards.h"
+#include "system/system.h"
+#include "system/tcg.h"
+#include "hw/core/sysemu-cpu-ops.h"
+
+/* S390CPUClass::load_normal() */
+static void s390_cpu_load_normal(CPUState *s)
+{
+ S390CPU *cpu = S390_CPU(s);
+ uint64_t spsw;
+
+ if (!s390_is_pv()) {
+ spsw = ldq_phys(s->as, 0);
+ cpu->env.psw.mask = spsw & PSW_MASK_SHORT_CTRL;
+ /*
+ * Invert short psw indication, so SIE will report a specification
+ * exception if it was not set.
+ */
+ cpu->env.psw.mask ^= PSW_MASK_SHORTPSW;
+ cpu->env.psw.addr = spsw & PSW_MASK_SHORT_ADDR;
+ } else {
+ /*
+ * Firmware requires us to set the load state before we set
+ * the cpu to operating on protected guests.
+ */
+ s390_cpu_set_state(S390_CPU_STATE_LOAD, cpu);
+ }
+ s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
+}
+
+void s390_cpu_machine_reset_cb(void *opaque)
+{
+ S390CPU *cpu = opaque;
+
+ run_on_cpu(CPU(cpu), s390_do_cpu_full_reset, RUN_ON_CPU_NULL);
+}
+
+static GuestPanicInformation *s390_cpu_get_crash_info(CPUState *cs)
+{
+ GuestPanicInformation *panic_info;
+ S390CPU *cpu = S390_CPU(cs);
+
+ cpu_synchronize_state(cs);
+ panic_info = g_new0(GuestPanicInformation, 1);
+
+ panic_info->type = GUEST_PANIC_INFORMATION_TYPE_S390;
+ panic_info->u.s390.core = cpu->env.core_id;
+ panic_info->u.s390.psw_mask = cpu->env.psw.mask;
+ panic_info->u.s390.psw_addr = cpu->env.psw.addr;
+ panic_info->u.s390.reason = cpu->env.crash_reason;
+
+ return panic_info;
+}
+
+static void s390_cpu_get_crash_info_qom(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ CPUState *cs = CPU(obj);
+ GuestPanicInformation *panic_info;
+
+ if (!cs->crash_occurred) {
+ error_setg(errp, "No crash occurred");
+ return;
+ }
+
+ panic_info = s390_cpu_get_crash_info(cs);
+
+ visit_type_GuestPanicInformation(v, "crash-information", &panic_info,
+ errp);
+ qapi_free_GuestPanicInformation(panic_info);
+}
+
+void s390_cpu_system_init(Object *obj)
+{
+ CPUState *cs = CPU(obj);
+ S390CPU *cpu = S390_CPU(obj);
+
+ cs->start_powered_off = true;
+ object_property_add(obj, "crash-information", "GuestPanicInformation",
+ s390_cpu_get_crash_info_qom, NULL, NULL, NULL);
+ cpu->env.tod_timer =
+ timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_tod_timer, cpu);
+ cpu->env.cpu_timer =
+ timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_cpu_timer, cpu);
+ s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
+}
+
+bool s390_cpu_system_realize(DeviceState *dev, Error **errp)
+{
+ S390CPU *cpu = S390_CPU(dev);
+ MachineState *ms = MACHINE(qdev_get_machine());
+ unsigned int max_cpus = ms->smp.max_cpus;
+
+ if (cpu->env.core_id >= max_cpus) {
+ error_setg(errp, "Unable to add CPU with core-id: %" PRIu32
+ ", maximum core-id: %d", cpu->env.core_id,
+ max_cpus - 1);
+ return false;
+ }
+
+ if (cpu_exists(cpu->env.core_id)) {
+ error_setg(errp, "Unable to add CPU with core-id: %" PRIu32
+ ", it already exists", cpu->env.core_id);
+ return false;
+ }
+
+ /* sync cs->cpu_index and env->core_id. The latter is needed for TCG. */
+ CPU(cpu)->cpu_index = cpu->env.core_id;
+ return true;
+}
+
+void s390_cpu_finalize(Object *obj)
+{
+ S390CPU *cpu = S390_CPU(obj);
+
+ timer_free(cpu->env.tod_timer);
+ timer_free(cpu->env.cpu_timer);
+
+ qemu_unregister_reset(s390_cpu_machine_reset_cb, cpu);
+ g_free(cpu->irqstate);
+}
+
+static const struct SysemuCPUOps s390_sysemu_ops = {
+ .get_phys_page_debug = s390_cpu_get_phys_page_debug,
+ .get_crash_info = s390_cpu_get_crash_info,
+ .write_elf64_note = s390_cpu_write_elf64_note,
+ .legacy_vmsd = &vmstate_s390_cpu,
+};
+
+void s390_cpu_system_class_init(CPUClass *cc)
+{
+ S390CPUClass *scc = S390_CPU_CLASS(cc);
+
+ scc->load_normal = s390_cpu_load_normal;
+ cc->sysemu_ops = &s390_sysemu_ops;
+}
+
+static bool disabled_wait(CPUState *cpu)
+{
+ return cpu->halted && !(S390_CPU(cpu)->env.psw.mask &
+ (PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK));
+}
+
+static unsigned s390_count_running_cpus(void)
+{
+ CPUState *cpu;
+ int nr_running = 0;
+
+ CPU_FOREACH(cpu) {
+ uint8_t state = S390_CPU(cpu)->env.cpu_state;
+ if (state == S390_CPU_STATE_OPERATING ||
+ state == S390_CPU_STATE_LOAD) {
+ if (!disabled_wait(cpu)) {
+ nr_running++;
+ }
+ }
+ }
+
+ return nr_running;
+}
+
+unsigned int s390_cpu_halt(S390CPU *cpu)
+{
+ CPUState *cs = CPU(cpu);
+ trace_cpu_halt(cs->cpu_index);
+
+ if (!cs->halted) {
+ cs->halted = 1;
+ cs->exception_index = EXCP_HLT;
+ }
+
+ return s390_count_running_cpus();
+}
+
+void s390_cpu_unhalt(S390CPU *cpu)
+{
+ CPUState *cs = CPU(cpu);
+ trace_cpu_unhalt(cs->cpu_index);
+
+ if (cs->halted) {
+ cs->halted = 0;
+ cs->exception_index = -1;
+ }
+}
+
+unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
+ {
+ trace_cpu_set_state(CPU(cpu)->cpu_index, cpu_state);
+
+ switch (cpu_state) {
+ case S390_CPU_STATE_STOPPED:
+ case S390_CPU_STATE_CHECK_STOP:
+ /* halt the cpu for common infrastructure */
+ s390_cpu_halt(cpu);
+ break;
+ case S390_CPU_STATE_OPERATING:
+ case S390_CPU_STATE_LOAD:
+ /*
+ * Starting a CPU with a PSW WAIT bit set:
+ * KVM: handles this internally and triggers another WAIT exit.
+ * TCG: will actually try to continue to run. Don't unhalt, will
+ * be done when the CPU actually has work (an interrupt).
+ */
+ if (!tcg_enabled() || !(cpu->env.psw.mask & PSW_MASK_WAIT)) {
+ s390_cpu_unhalt(cpu);
+ }
+ break;
+ default:
+ error_report("Requested CPU state is not a valid S390 CPU state: %u",
+ cpu_state);
+ exit(1);
+ }
+ if (kvm_enabled() && cpu->env.cpu_state != cpu_state) {
+ kvm_s390_set_cpu_state(cpu, cpu_state);
+ }
+ cpu->env.cpu_state = cpu_state;
+
+ return s390_count_running_cpus();
+}
+
+int s390_set_memory_limit(uint64_t new_limit, uint64_t *hw_limit)
+{
+ if (kvm_enabled()) {
+ return kvm_s390_set_mem_limit(new_limit, hw_limit);
+ }
+ return 0;
+}
+
+void s390_set_max_pagesize(uint64_t pagesize, Error **errp)
+{
+ if (kvm_enabled()) {
+ kvm_s390_set_max_pagesize(pagesize, errp);
+ }
+}
+
+void s390_cmma_reset(void)
+{
+ if (kvm_enabled()) {
+ kvm_s390_cmma_reset();
+ }
+}
+
+int s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch_id,
+ int vq, bool assign)
+{
+ if (kvm_enabled()) {
+ return kvm_s390_assign_subch_ioeventfd(notifier, sch_id, vq, assign);
+ } else {
+ return 0;
+ }
+}
+
+void s390_crypto_reset(void)
+{
+ if (kvm_enabled()) {
+ kvm_s390_crypto_reset();
+ }
+}
+
+void s390_enable_css_support(S390CPU *cpu)
+{
+ if (kvm_enabled()) {
+ kvm_s390_enable_css_support(cpu);
+ }
+}
+
+void s390_do_cpu_set_diag318(CPUState *cs, run_on_cpu_data arg)
+{
+ if (kvm_enabled()) {
+ kvm_s390_set_diag318(cs, arg.host_ulong);
+ }
+}
+
+void s390_cpu_topology_set_changed(bool changed)
+{
+ int ret;
+
+ if (kvm_enabled()) {
+ ret = kvm_s390_topology_set_mtcr(changed);
+ if (ret) {
+ error_report("Failed to set Modified Topology Change Report: %s",
+ strerror(-ret));
+ }
+ }
+}
#include "cpu.h"
#include "s390x-internal.h"
#include "kvm/kvm_s390x.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "qemu/module.h"
#include "trace.h"
#include "qapi/qapi-types-machine.h"
-#include "sysemu/hw_accel.h"
+#include "system/hw_accel.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "hw/resettable.h"
#include "fpu/softfloat-helpers.h"
#include "disas/capstone.h"
-#include "sysemu/tcg.h"
+#include "system/tcg.h"
#ifndef CONFIG_USER_ONLY
-#include "sysemu/reset.h"
+#include "system/reset.h"
#endif
#include "hw/s390x/cpu-topology.h"
}
#if !defined(CONFIG_USER_ONLY)
- if (!s390_cpu_realize_sysemu(dev, &err)) {
+ if (!s390_cpu_system_realize(dev, &err)) {
goto out;
}
#endif
cs->exception_index = EXCP_HLT;
#if !defined(CONFIG_USER_ONLY)
- s390_cpu_init_sysemu(obj);
+ s390_cpu_system_init(obj);
#endif
}
cc->gdb_read_register = s390_cpu_gdb_read_register;
cc->gdb_write_register = s390_cpu_gdb_write_register;
#ifndef CONFIG_USER_ONLY
- s390_cpu_class_init_sysemu(cc);
+ s390_cpu_system_class_init(cc);
#endif
cc->disas_set_info = s390_cpu_disas_set_info;
cc->gdb_core_xml_file = "s390x-core64.xml";
#include "cpu.h"
#include "s390x-internal.h"
#include "kvm/kvm_s390x.h"
-#include "sysemu/kvm.h"
-#include "sysemu/tcg.h"
+#include "system/kvm.h"
+#include "system/tcg.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qapi/visitor.h"
#include "qemu/hw-version.h"
#include "qemu/qemu-print.h"
#ifndef CONFIG_USER_ONLY
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "target/s390x/kvm/pv.h"
#include CONFIG_DEVICES
#endif
+++ /dev/null
-/*
- * CPU models for s390x - System Emulation-only
- *
- * Copyright 2016 IBM Corp.
- *
- * Author(s): David Hildenbrand <dahi@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 "qemu/osdep.h"
-#include "cpu.h"
-#include "s390x-internal.h"
-#include "kvm/kvm_s390x.h"
-#include "sysemu/kvm.h"
-#include "qapi/error.h"
-#include "qapi/visitor.h"
-#include "qapi/qobject-input-visitor.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi/qapi-commands-machine-target.h"
-
-static void list_add_feat(const char *name, void *opaque);
-
-static void check_unavailable_features(const S390CPUModel *max_model,
- const S390CPUModel *model,
- strList **unavailable)
-{
- S390FeatBitmap missing;
-
- /* check general model compatibility */
- if (max_model->def->gen < model->def->gen ||
- (max_model->def->gen == model->def->gen &&
- max_model->def->ec_ga < model->def->ec_ga)) {
- list_add_feat("type", unavailable);
- }
-
- /* detect missing features if any to properly report them */
- bitmap_andnot(missing, model->features, max_model->features,
- S390_FEAT_MAX);
- if (!bitmap_empty(missing, S390_FEAT_MAX)) {
- s390_feat_bitmap_to_ascii(missing, unavailable, list_add_feat);
- }
-}
-
-struct CpuDefinitionInfoListData {
- CpuDefinitionInfoList *list;
- S390CPUModel *model;
-};
-
-static void create_cpu_model_list(ObjectClass *klass, void *opaque)
-{
- struct CpuDefinitionInfoListData *cpu_list_data = opaque;
- CpuDefinitionInfoList **cpu_list = &cpu_list_data->list;
- CpuDefinitionInfo *info;
- char *name = g_strdup(object_class_get_name(klass));
- S390CPUClass *scc = S390_CPU_CLASS(klass);
-
- /* strip off the -s390x-cpu */
- g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0;
- info = g_new0(CpuDefinitionInfo, 1);
- info->name = name;
- info->has_migration_safe = true;
- info->migration_safe = scc->is_migration_safe;
- info->q_static = scc->is_static;
- info->q_typename = g_strdup(object_class_get_name(klass));
- /* check for unavailable features */
- if (cpu_list_data->model) {
- Object *obj;
- S390CPU *sc;
- obj = object_new_with_class(klass);
- sc = S390_CPU(obj);
- if (sc->model) {
- info->has_unavailable_features = true;
- check_unavailable_features(cpu_list_data->model, sc->model,
- &info->unavailable_features);
- }
- object_unref(obj);
- }
-
- QAPI_LIST_PREPEND(*cpu_list, info);
-}
-
-CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
-{
- struct CpuDefinitionInfoListData list_data = {
- .list = NULL,
- };
-
- list_data.model = get_max_cpu_model(NULL);
-
- object_class_foreach(create_cpu_model_list, TYPE_S390_CPU, false,
- &list_data);
-
- return list_data.list;
-}
-
-static void cpu_model_from_info(S390CPUModel *model, const CpuModelInfo *info,
- const char *info_arg_name, Error **errp)
-{
- Error *err = NULL;
- const QDict *qdict;
- const QDictEntry *e;
- Visitor *visitor;
- ObjectClass *oc;
- S390CPU *cpu;
- Object *obj;
-
- oc = cpu_class_by_name(TYPE_S390_CPU, info->name);
- if (!oc) {
- error_setg(errp, "The CPU definition \'%s\' is unknown.", info->name);
- return;
- }
- if (S390_CPU_CLASS(oc)->kvm_required && !kvm_enabled()) {
- error_setg(errp, "The CPU definition '%s' requires KVM", info->name);
- return;
- }
- obj = object_new_with_class(oc);
- cpu = S390_CPU(obj);
-
- if (!cpu->model) {
- error_setg(errp, "Details about the host CPU model are not available, "
- "it cannot be used.");
- object_unref(obj);
- return;
- }
-
- if (info->props) {
- g_autofree const char *props_name = g_strdup_printf("%s.props",
- info_arg_name);
-
- visitor = qobject_input_visitor_new(info->props);
- if (!visit_start_struct(visitor, props_name, NULL, 0, errp)) {
- visit_free(visitor);
- object_unref(obj);
- return;
- }
- qdict = qobject_to(QDict, info->props);
- for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
- if (!object_property_set(obj, e->key, visitor, &err)) {
- break;
- }
- }
- if (!err) {
- visit_check_struct(visitor, &err);
- }
- visit_end_struct(visitor, NULL);
- visit_free(visitor);
- if (err) {
- error_propagate(errp, err);
- object_unref(obj);
- return;
- }
- }
-
- /* copy the model and throw the cpu away */
- memcpy(model, cpu->model, sizeof(*model));
- object_unref(obj);
-}
-
-static void qdict_add_disabled_feat(const char *name, void *opaque)
-{
- qdict_put_bool(opaque, name, false);
-}
-
-static void qdict_add_enabled_feat(const char *name, void *opaque)
-{
- qdict_put_bool(opaque, name, true);
-}
-
-/* convert S390CPUDef into a static CpuModelInfo */
-static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model,
- bool delta_changes)
-{
- QDict *qdict = qdict_new();
- S390FeatBitmap bitmap;
-
- /* always fallback to the static base model */
- info->name = g_strdup_printf("%s-base", model->def->name);
-
- if (delta_changes) {
- /* features deleted from the base feature set */
- bitmap_andnot(bitmap, model->def->base_feat, model->features,
- S390_FEAT_MAX);
- if (!bitmap_empty(bitmap, S390_FEAT_MAX)) {
- s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat);
- }
-
- /* features added to the base feature set */
- bitmap_andnot(bitmap, model->features, model->def->base_feat,
- S390_FEAT_MAX);
- if (!bitmap_empty(bitmap, S390_FEAT_MAX)) {
- s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_enabled_feat);
- }
- } else {
- /* expand all features */
- s390_feat_bitmap_to_ascii(model->features, qdict,
- qdict_add_enabled_feat);
- bitmap_complement(bitmap, model->features, S390_FEAT_MAX);
- s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat);
- }
-
- if (!qdict_size(qdict)) {
- qobject_unref(qdict);
- } else {
- info->props = QOBJECT(qdict);
- }
-}
-
-CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
- CpuModelInfo *model,
- Error **errp)
-{
- Error *err = NULL;
- CpuModelExpansionInfo *expansion_info = NULL;
- S390CPUModel s390_model;
- bool delta_changes = false;
- S390FeatBitmap deprecated_feats;
-
- /* convert it to our internal representation */
- cpu_model_from_info(&s390_model, model, "model", &err);
- if (err) {
- error_propagate(errp, err);
- return NULL;
- }
-
- if (type == CPU_MODEL_EXPANSION_TYPE_STATIC) {
- delta_changes = true;
- } else if (type != CPU_MODEL_EXPANSION_TYPE_FULL) {
- error_setg(errp, "The requested expansion type is not supported.");
- return NULL;
- }
-
- /* convert it back to a static representation */
- expansion_info = g_new0(CpuModelExpansionInfo, 1);
- expansion_info->model = g_malloc0(sizeof(*expansion_info->model));
- cpu_info_from_model(expansion_info->model, &s390_model, delta_changes);
-
- /* populate list of deprecated features */
- bitmap_zero(deprecated_feats, S390_FEAT_MAX);
- s390_get_deprecated_features(deprecated_feats);
-
- if (delta_changes) {
- /*
- * Only populate deprecated features that are a
- * subset of the features enabled on the CPU model.
- */
- bitmap_and(deprecated_feats, deprecated_feats,
- s390_model.features, S390_FEAT_MAX);
- }
-
- s390_feat_bitmap_to_ascii(deprecated_feats,
- &expansion_info->deprecated_props, list_add_feat);
- return expansion_info;
-}
-
-static void list_add_feat(const char *name, void *opaque)
-{
- strList **last = (strList **) opaque;
-
- QAPI_LIST_PREPEND(*last, g_strdup(name));
-}
-
-CpuModelCompareInfo *qmp_query_cpu_model_comparison(CpuModelInfo *infoa,
- CpuModelInfo *infob,
- Error **errp)
-{
- Error *err = NULL;
- CpuModelCompareResult feat_result, gen_result;
- CpuModelCompareInfo *compare_info;
- S390FeatBitmap missing, added;
- S390CPUModel modela, modelb;
-
- /* convert both models to our internal representation */
- cpu_model_from_info(&modela, infoa, "modela", &err);
- if (err) {
- error_propagate(errp, err);
- return NULL;
- }
- cpu_model_from_info(&modelb, infob, "modelb", &err);
- if (err) {
- error_propagate(errp, err);
- return NULL;
- }
- compare_info = g_new0(CpuModelCompareInfo, 1);
-
- /* check the cpu generation and ga level */
- if (modela.def->gen == modelb.def->gen) {
- if (modela.def->ec_ga == modelb.def->ec_ga) {
- /* ec and corresponding bc are identical */
- gen_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL;
- } else if (modela.def->ec_ga < modelb.def->ec_ga) {
- gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET;
- } else {
- gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET;
- }
- } else if (modela.def->gen < modelb.def->gen) {
- gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET;
- } else {
- gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET;
- }
- if (gen_result != CPU_MODEL_COMPARE_RESULT_IDENTICAL) {
- /* both models cannot be made identical */
- list_add_feat("type", &compare_info->responsible_properties);
- }
-
- /* check the feature set */
- if (bitmap_equal(modela.features, modelb.features, S390_FEAT_MAX)) {
- feat_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL;
- } else {
- bitmap_andnot(missing, modela.features, modelb.features, S390_FEAT_MAX);
- s390_feat_bitmap_to_ascii(missing,
- &compare_info->responsible_properties,
- list_add_feat);
- bitmap_andnot(added, modelb.features, modela.features, S390_FEAT_MAX);
- s390_feat_bitmap_to_ascii(added, &compare_info->responsible_properties,
- list_add_feat);
- if (bitmap_empty(missing, S390_FEAT_MAX)) {
- feat_result = CPU_MODEL_COMPARE_RESULT_SUBSET;
- } else if (bitmap_empty(added, S390_FEAT_MAX)) {
- feat_result = CPU_MODEL_COMPARE_RESULT_SUPERSET;
- } else {
- feat_result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE;
- }
- }
-
- /* combine the results */
- if (gen_result == feat_result) {
- compare_info->result = gen_result;
- } else if (feat_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) {
- compare_info->result = gen_result;
- } else if (gen_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) {
- compare_info->result = feat_result;
- } else {
- compare_info->result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE;
- }
- return compare_info;
-}
-
-CpuModelBaselineInfo *qmp_query_cpu_model_baseline(CpuModelInfo *infoa,
- CpuModelInfo *infob,
- Error **errp)
-{
- Error *err = NULL;
- CpuModelBaselineInfo *baseline_info;
- S390CPUModel modela, modelb, model;
- uint16_t cpu_type;
- uint8_t max_gen_ga;
- uint8_t max_gen;
-
- /* convert both models to our internal representation */
- cpu_model_from_info(&modela, infoa, "modela", &err);
- if (err) {
- error_propagate(errp, err);
- return NULL;
- }
-
- cpu_model_from_info(&modelb, infob, "modelb", &err);
- if (err) {
- error_propagate(errp, err);
- return NULL;
- }
-
- /* features both models support */
- bitmap_and(model.features, modela.features, modelb.features, S390_FEAT_MAX);
-
- /* detect the maximum model not regarding features */
- if (modela.def->gen == modelb.def->gen) {
- if (modela.def->type == modelb.def->type) {
- cpu_type = modela.def->type;
- } else {
- cpu_type = 0;
- }
- max_gen = modela.def->gen;
- max_gen_ga = MIN(modela.def->ec_ga, modelb.def->ec_ga);
- } else if (modela.def->gen > modelb.def->gen) {
- cpu_type = modelb.def->type;
- max_gen = modelb.def->gen;
- max_gen_ga = modelb.def->ec_ga;
- } else {
- cpu_type = modela.def->type;
- max_gen = modela.def->gen;
- max_gen_ga = modela.def->ec_ga;
- }
-
- model.def = s390_find_cpu_def(cpu_type, max_gen, max_gen_ga,
- model.features);
-
- /* models without early base features (esan3) are bad */
- if (!model.def) {
- error_setg(errp, "No compatible CPU model could be created as"
- " important base features are disabled");
- return NULL;
- }
-
- /* strip off features not part of the max model */
- bitmap_and(model.features, model.features, model.def->full_feat,
- S390_FEAT_MAX);
-
- baseline_info = g_new0(CpuModelBaselineInfo, 1);
- baseline_info->model = g_malloc0(sizeof(*baseline_info->model));
- cpu_info_from_model(baseline_info->model, &model, true);
- return baseline_info;
-}
-
-void apply_cpu_model(const S390CPUModel *model, Error **errp)
-{
- static S390CPUModel applied_model;
- static bool applied;
-
- /*
- * We have the same model for all VCPUs. KVM can only be configured before
- * any VCPUs are defined in KVM.
- */
- if (applied) {
- if (model && memcmp(&applied_model, model, sizeof(S390CPUModel))) {
- error_setg(errp, "Mixed CPU models are not supported on s390x.");
- }
- return;
- }
-
- if (kvm_enabled()) {
- if (!kvm_s390_apply_cpu_model(model, errp)) {
- return;
- }
- }
-
- applied = true;
- if (model) {
- applied_model = *model;
- }
-}
--- /dev/null
+/*
+ * CPU models for s390x - System-only
+ *
+ * Copyright 2016 IBM Corp.
+ *
+ * Author(s): David Hildenbrand <dahi@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 "qemu/osdep.h"
+#include "cpu.h"
+#include "s390x-internal.h"
+#include "kvm/kvm_s390x.h"
+#include "system/kvm.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "qapi/qobject-input-visitor.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qapi-commands-machine-target.h"
+
+static void list_add_feat(const char *name, void *opaque);
+
+static void check_unavailable_features(const S390CPUModel *max_model,
+ const S390CPUModel *model,
+ strList **unavailable)
+{
+ S390FeatBitmap missing;
+
+ /* check general model compatibility */
+ if (max_model->def->gen < model->def->gen ||
+ (max_model->def->gen == model->def->gen &&
+ max_model->def->ec_ga < model->def->ec_ga)) {
+ list_add_feat("type", unavailable);
+ }
+
+ /* detect missing features if any to properly report them */
+ bitmap_andnot(missing, model->features, max_model->features,
+ S390_FEAT_MAX);
+ if (!bitmap_empty(missing, S390_FEAT_MAX)) {
+ s390_feat_bitmap_to_ascii(missing, unavailable, list_add_feat);
+ }
+}
+
+struct CpuDefinitionInfoListData {
+ CpuDefinitionInfoList *list;
+ S390CPUModel *model;
+};
+
+static void create_cpu_model_list(ObjectClass *klass, void *opaque)
+{
+ struct CpuDefinitionInfoListData *cpu_list_data = opaque;
+ CpuDefinitionInfoList **cpu_list = &cpu_list_data->list;
+ CpuDefinitionInfo *info;
+ char *name = g_strdup(object_class_get_name(klass));
+ S390CPUClass *scc = S390_CPU_CLASS(klass);
+
+ /* strip off the -s390x-cpu */
+ g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0;
+ info = g_new0(CpuDefinitionInfo, 1);
+ info->name = name;
+ info->has_migration_safe = true;
+ info->migration_safe = scc->is_migration_safe;
+ info->q_static = scc->is_static;
+ info->q_typename = g_strdup(object_class_get_name(klass));
+ /* check for unavailable features */
+ if (cpu_list_data->model) {
+ Object *obj;
+ S390CPU *sc;
+ obj = object_new_with_class(klass);
+ sc = S390_CPU(obj);
+ if (sc->model) {
+ info->has_unavailable_features = true;
+ check_unavailable_features(cpu_list_data->model, sc->model,
+ &info->unavailable_features);
+ }
+ object_unref(obj);
+ }
+
+ QAPI_LIST_PREPEND(*cpu_list, info);
+}
+
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+{
+ struct CpuDefinitionInfoListData list_data = {
+ .list = NULL,
+ };
+
+ list_data.model = get_max_cpu_model(NULL);
+
+ object_class_foreach(create_cpu_model_list, TYPE_S390_CPU, false,
+ &list_data);
+
+ return list_data.list;
+}
+
+static void cpu_model_from_info(S390CPUModel *model, const CpuModelInfo *info,
+ const char *info_arg_name, Error **errp)
+{
+ Error *err = NULL;
+ const QDict *qdict;
+ const QDictEntry *e;
+ Visitor *visitor;
+ ObjectClass *oc;
+ S390CPU *cpu;
+ Object *obj;
+
+ oc = cpu_class_by_name(TYPE_S390_CPU, info->name);
+ if (!oc) {
+ error_setg(errp, "The CPU definition \'%s\' is unknown.", info->name);
+ return;
+ }
+ if (S390_CPU_CLASS(oc)->kvm_required && !kvm_enabled()) {
+ error_setg(errp, "The CPU definition '%s' requires KVM", info->name);
+ return;
+ }
+ obj = object_new_with_class(oc);
+ cpu = S390_CPU(obj);
+
+ if (!cpu->model) {
+ error_setg(errp, "Details about the host CPU model are not available, "
+ "it cannot be used.");
+ object_unref(obj);
+ return;
+ }
+
+ if (info->props) {
+ g_autofree const char *props_name = g_strdup_printf("%s.props",
+ info_arg_name);
+
+ visitor = qobject_input_visitor_new(info->props);
+ if (!visit_start_struct(visitor, props_name, NULL, 0, errp)) {
+ visit_free(visitor);
+ object_unref(obj);
+ return;
+ }
+ qdict = qobject_to(QDict, info->props);
+ for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
+ if (!object_property_set(obj, e->key, visitor, &err)) {
+ break;
+ }
+ }
+ if (!err) {
+ visit_check_struct(visitor, &err);
+ }
+ visit_end_struct(visitor, NULL);
+ visit_free(visitor);
+ if (err) {
+ error_propagate(errp, err);
+ object_unref(obj);
+ return;
+ }
+ }
+
+ /* copy the model and throw the cpu away */
+ memcpy(model, cpu->model, sizeof(*model));
+ object_unref(obj);
+}
+
+static void qdict_add_disabled_feat(const char *name, void *opaque)
+{
+ qdict_put_bool(opaque, name, false);
+}
+
+static void qdict_add_enabled_feat(const char *name, void *opaque)
+{
+ qdict_put_bool(opaque, name, true);
+}
+
+/* convert S390CPUDef into a static CpuModelInfo */
+static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model,
+ bool delta_changes)
+{
+ QDict *qdict = qdict_new();
+ S390FeatBitmap bitmap;
+
+ /* always fallback to the static base model */
+ info->name = g_strdup_printf("%s-base", model->def->name);
+
+ if (delta_changes) {
+ /* features deleted from the base feature set */
+ bitmap_andnot(bitmap, model->def->base_feat, model->features,
+ S390_FEAT_MAX);
+ if (!bitmap_empty(bitmap, S390_FEAT_MAX)) {
+ s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat);
+ }
+
+ /* features added to the base feature set */
+ bitmap_andnot(bitmap, model->features, model->def->base_feat,
+ S390_FEAT_MAX);
+ if (!bitmap_empty(bitmap, S390_FEAT_MAX)) {
+ s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_enabled_feat);
+ }
+ } else {
+ /* expand all features */
+ s390_feat_bitmap_to_ascii(model->features, qdict,
+ qdict_add_enabled_feat);
+ bitmap_complement(bitmap, model->features, S390_FEAT_MAX);
+ s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat);
+ }
+
+ if (!qdict_size(qdict)) {
+ qobject_unref(qdict);
+ } else {
+ info->props = QOBJECT(qdict);
+ }
+}
+
+CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
+ CpuModelInfo *model,
+ Error **errp)
+{
+ Error *err = NULL;
+ CpuModelExpansionInfo *expansion_info = NULL;
+ S390CPUModel s390_model;
+ bool delta_changes = false;
+ S390FeatBitmap deprecated_feats;
+
+ /* convert it to our internal representation */
+ cpu_model_from_info(&s390_model, model, "model", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return NULL;
+ }
+
+ if (type == CPU_MODEL_EXPANSION_TYPE_STATIC) {
+ delta_changes = true;
+ } else if (type != CPU_MODEL_EXPANSION_TYPE_FULL) {
+ error_setg(errp, "The requested expansion type is not supported.");
+ return NULL;
+ }
+
+ /* convert it back to a static representation */
+ expansion_info = g_new0(CpuModelExpansionInfo, 1);
+ expansion_info->model = g_malloc0(sizeof(*expansion_info->model));
+ cpu_info_from_model(expansion_info->model, &s390_model, delta_changes);
+
+ /* populate list of deprecated features */
+ bitmap_zero(deprecated_feats, S390_FEAT_MAX);
+ s390_get_deprecated_features(deprecated_feats);
+
+ if (delta_changes) {
+ /*
+ * Only populate deprecated features that are a
+ * subset of the features enabled on the CPU model.
+ */
+ bitmap_and(deprecated_feats, deprecated_feats,
+ s390_model.features, S390_FEAT_MAX);
+ }
+
+ s390_feat_bitmap_to_ascii(deprecated_feats,
+ &expansion_info->deprecated_props, list_add_feat);
+ return expansion_info;
+}
+
+static void list_add_feat(const char *name, void *opaque)
+{
+ strList **last = (strList **) opaque;
+
+ QAPI_LIST_PREPEND(*last, g_strdup(name));
+}
+
+CpuModelCompareInfo *qmp_query_cpu_model_comparison(CpuModelInfo *infoa,
+ CpuModelInfo *infob,
+ Error **errp)
+{
+ Error *err = NULL;
+ CpuModelCompareResult feat_result, gen_result;
+ CpuModelCompareInfo *compare_info;
+ S390FeatBitmap missing, added;
+ S390CPUModel modela, modelb;
+
+ /* convert both models to our internal representation */
+ cpu_model_from_info(&modela, infoa, "modela", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return NULL;
+ }
+ cpu_model_from_info(&modelb, infob, "modelb", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return NULL;
+ }
+ compare_info = g_new0(CpuModelCompareInfo, 1);
+
+ /* check the cpu generation and ga level */
+ if (modela.def->gen == modelb.def->gen) {
+ if (modela.def->ec_ga == modelb.def->ec_ga) {
+ /* ec and corresponding bc are identical */
+ gen_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL;
+ } else if (modela.def->ec_ga < modelb.def->ec_ga) {
+ gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET;
+ } else {
+ gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET;
+ }
+ } else if (modela.def->gen < modelb.def->gen) {
+ gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET;
+ } else {
+ gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET;
+ }
+ if (gen_result != CPU_MODEL_COMPARE_RESULT_IDENTICAL) {
+ /* both models cannot be made identical */
+ list_add_feat("type", &compare_info->responsible_properties);
+ }
+
+ /* check the feature set */
+ if (bitmap_equal(modela.features, modelb.features, S390_FEAT_MAX)) {
+ feat_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL;
+ } else {
+ bitmap_andnot(missing, modela.features, modelb.features, S390_FEAT_MAX);
+ s390_feat_bitmap_to_ascii(missing,
+ &compare_info->responsible_properties,
+ list_add_feat);
+ bitmap_andnot(added, modelb.features, modela.features, S390_FEAT_MAX);
+ s390_feat_bitmap_to_ascii(added, &compare_info->responsible_properties,
+ list_add_feat);
+ if (bitmap_empty(missing, S390_FEAT_MAX)) {
+ feat_result = CPU_MODEL_COMPARE_RESULT_SUBSET;
+ } else if (bitmap_empty(added, S390_FEAT_MAX)) {
+ feat_result = CPU_MODEL_COMPARE_RESULT_SUPERSET;
+ } else {
+ feat_result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE;
+ }
+ }
+
+ /* combine the results */
+ if (gen_result == feat_result) {
+ compare_info->result = gen_result;
+ } else if (feat_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) {
+ compare_info->result = gen_result;
+ } else if (gen_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) {
+ compare_info->result = feat_result;
+ } else {
+ compare_info->result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE;
+ }
+ return compare_info;
+}
+
+CpuModelBaselineInfo *qmp_query_cpu_model_baseline(CpuModelInfo *infoa,
+ CpuModelInfo *infob,
+ Error **errp)
+{
+ Error *err = NULL;
+ CpuModelBaselineInfo *baseline_info;
+ S390CPUModel modela, modelb, model;
+ uint16_t cpu_type;
+ uint8_t max_gen_ga;
+ uint8_t max_gen;
+
+ /* convert both models to our internal representation */
+ cpu_model_from_info(&modela, infoa, "modela", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return NULL;
+ }
+
+ cpu_model_from_info(&modelb, infob, "modelb", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return NULL;
+ }
+
+ /* features both models support */
+ bitmap_and(model.features, modela.features, modelb.features, S390_FEAT_MAX);
+
+ /* detect the maximum model not regarding features */
+ if (modela.def->gen == modelb.def->gen) {
+ if (modela.def->type == modelb.def->type) {
+ cpu_type = modela.def->type;
+ } else {
+ cpu_type = 0;
+ }
+ max_gen = modela.def->gen;
+ max_gen_ga = MIN(modela.def->ec_ga, modelb.def->ec_ga);
+ } else if (modela.def->gen > modelb.def->gen) {
+ cpu_type = modelb.def->type;
+ max_gen = modelb.def->gen;
+ max_gen_ga = modelb.def->ec_ga;
+ } else {
+ cpu_type = modela.def->type;
+ max_gen = modela.def->gen;
+ max_gen_ga = modela.def->ec_ga;
+ }
+
+ model.def = s390_find_cpu_def(cpu_type, max_gen, max_gen_ga,
+ model.features);
+
+ /* models without early base features (esan3) are bad */
+ if (!model.def) {
+ error_setg(errp, "No compatible CPU model could be created as"
+ " important base features are disabled");
+ return NULL;
+ }
+
+ /* strip off features not part of the max model */
+ bitmap_and(model.features, model.features, model.def->full_feat,
+ S390_FEAT_MAX);
+
+ baseline_info = g_new0(CpuModelBaselineInfo, 1);
+ baseline_info->model = g_malloc0(sizeof(*baseline_info->model));
+ cpu_info_from_model(baseline_info->model, &model, true);
+ return baseline_info;
+}
+
+void apply_cpu_model(const S390CPUModel *model, Error **errp)
+{
+ static S390CPUModel applied_model;
+ static bool applied;
+
+ /*
+ * We have the same model for all VCPUs. KVM can only be configured before
+ * any VCPUs are defined in KVM.
+ */
+ if (applied) {
+ if (model && memcmp(&applied_model, model, sizeof(S390CPUModel))) {
+ error_setg(errp, "Mixed CPU models are not supported on s390x.");
+ }
+ return;
+ }
+
+ if (kvm_enabled()) {
+ if (!kvm_s390_apply_cpu_model(model, errp)) {
+ return;
+ }
+ }
+
+ applied = true;
+ if (model) {
+ applied_model = *model;
+ }
+}
#include "cpu.h"
#include "s390x-internal.h"
#include "hw/watchdog/wdt_diag288.h"
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
#include "hw/s390x/ipl.h"
#include "hw/s390x/s390-virtio-ccw.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "kvm/kvm_s390x.h"
#include "target/s390x/kvm/pv.h"
#include "qemu/error-report.h"
#include "exec/gdbstub.h"
#include "gdbstub/helpers.h"
#include "qemu/bitops.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/tcg.h"
+#include "system/hw_accel.h"
+#include "system/tcg.h"
int s390_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
{
/*
- * S/390 helpers - sysemu only
+ * S/390 helpers - system only
*
* Copyright (c) 2009 Ulrich Hecht
* Copyright (c) 2011 Alexander Graf
#include "qemu/timer.h"
#include "hw/s390x/ioinst.h"
#include "target/s390x/kvm/pv.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/runstate.h"
+#include "system/hw_accel.h"
+#include "system/runstate.h"
void s390x_tod_timer(void *opaque)
{
#include "kvm/kvm_s390x.h"
#include "s390x-internal.h"
#include "exec/exec-all.h"
-#include "sysemu/kvm.h"
-#include "sysemu/tcg.h"
+#include "system/kvm.h"
+#include "system/tcg.h"
#include "hw/s390x/ioinst.h"
#include "tcg/tcg_s390x.h"
#if !defined(CONFIG_USER_ONLY)
#include "cpu.h"
#include "s390x-internal.h"
#include "kvm_s390x.h"
-#include "sysemu/kvm_int.h"
+#include "system/kvm_int.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qemu/mmap-alloc.h"
#include "qemu/log.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/runstate.h"
-#include "sysemu/device_tree.h"
+#include "system/system.h"
+#include "system/hw_accel.h"
+#include "system/runstate.h"
+#include "system/device_tree.h"
#include "gdbstub/enums.h"
#include "exec/ram_addr.h"
#include "trace.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
-#include "sysemu/kvm.h"
-#include "sysemu/cpus.h"
+#include "system/kvm.h"
+#include "system/cpus.h"
#include "qom/object_interfaces.h"
#include "exec/confidential-guest-support.h"
#include "hw/s390x/ipl.h"
#define HW_S390_PV_H
#include "qapi/error.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
#include "hw/s390x/s390-virtio-ccw.h"
#ifdef CONFIG_KVM
#include "kvm/kvm_s390x.h"
#include "migration/vmstate.h"
#include "tcg/tcg_s390x.h"
-#include "sysemu/kvm.h"
-#include "sysemu/tcg.h"
+#include "system/kvm.h"
+#include "system/tcg.h"
static int cpu_post_load(void *opaque, int version_id)
{
'machine.c',
'mmu_helper.c',
'sigp.c',
- 'cpu-sysemu.c',
- 'cpu_models_sysemu.c',
+ 'cpu-system.c',
+ 'cpu_models_system.c',
))
s390x_user_ss = ss.source_set()
#include "cpu.h"
#include "s390x-internal.h"
#include "kvm/kvm_s390x.h"
-#include "sysemu/kvm.h"
-#include "sysemu/tcg.h"
+#include "system/kvm.h"
+#include "system/tcg.h"
#include "exec/exec-all.h"
#include "exec/page-protection.h"
#include "hw/hw.h"
#ifndef CONFIG_USER_ONLY
unsigned int s390_cpu_halt(S390CPU *cpu);
void s390_cpu_unhalt(S390CPU *cpu);
-void s390_cpu_init_sysemu(Object *obj);
-bool s390_cpu_realize_sysemu(DeviceState *dev, Error **errp);
+void s390_cpu_system_init(Object *obj);
+bool s390_cpu_system_realize(DeviceState *dev, Error **errp);
void s390_cpu_finalize(Object *obj);
-void s390_cpu_class_init_sysemu(CPUClass *cc);
+void s390_cpu_system_class_init(CPUClass *cc);
void s390_cpu_machine_reset_cb(void *opaque);
#else
#include "cpu.h"
#include "s390x-internal.h"
#include "hw/boards.h"
-#include "sysemu/hw_accel.h"
-#include "sysemu/runstate.h"
+#include "system/hw_accel.h"
+#include "system/runstate.h"
#include "exec/address-spaces.h"
#include "exec/exec-all.h"
-#include "sysemu/tcg.h"
+#include "system/tcg.h"
#include "trace.h"
#include "qapi/qapi-types-machine.h"
#include "s390-tod.h"
#if !defined(CONFIG_USER_ONLY)
-#include "sysemu/cpus.h"
-#include "sysemu/sysemu.h"
+#include "system/cpus.h"
+#include "system/system.h"
#include "hw/s390x/ebcdic.h"
#include "hw/s390x/s390-virtio-hcall.h"
#include "hw/s390x/sclp.h"
ioinst_chp_id(const char *insn, int cssid, int chpid) "IOINST: %s (%x.%02x)"
ioinst_chsc_cmd(uint16_t cmd, uint16_t len) "IOINST: chsc command 0x%04x, len 0x%04x"
-# cpu-sysemu.c
+# cpu-system.c
cpu_set_state(int cpu_index, uint8_t state) "setting cpu %d state to %" PRIu8
cpu_halt(int cpu_index) "halting cpu %d"
cpu_unhalt(int cpu_index) "unhalting cpu %d"
#if !defined(CONFIG_USER_ONLY)
#include "hw/sh4/sh_intc.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
#endif
#define MMU_OK 0
#include "trace.h"
#include "exec/cpu_ldst.h"
#include "exec/log.h"
-#include "sysemu/runstate.h"
+#include "system/runstate.h"
static const char * const excp_names[0x80] = {
[TT_TFAULT] = "Instruction Access Fault",
#include "qemu/cutils.h"
#include "qemu/datadir.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/qtest.h"
-#include "sysemu/runstate.h"
+#include "system/system.h"
+#include "system/qtest.h"
+#include "system/runstate.h"
#include "qemu/main-loop.h"
#include "qemu/rcu.h"
#include "tests/qtest/libqtest.h"
#include "qemu/sockets.h"
#include "io/channel.h"
-#include "sysemu/tpm.h"
+#include "system/tpm.h"
#include "libqtest.h"
struct tpm_hdr {
#include "chardev/char-fe.h"
#include "qemu/memfd.h"
#include "qemu/module.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "libqos/libqos.h"
#include "libqos/pci-pc.h"
#include "libqos/virtio-pci.h"
#include "qemu/osdep.h"
#include "block/block_int.h"
#include "block/blockjob_int.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qapi/error.h"
#include "qemu/main-loop.h"
#include "iothread.h"
#include "qapi/error.h"
#include "qemu/main-loop.h"
#include "block/block_int.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
static BlockDriver bdrv_pass_through = {
.format_name = "pass-through",
#include "qemu/osdep.h"
#include "block/block.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qapi/error.h"
#include "qemu/main-loop.h"
#include "block/block.h"
#include "block/block_int-global-state.h"
#include "block/blockjob_int.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "qemu/main-loop.h"
#include "qapi/error.h"
#include "qemu/main-loop.h"
#include "block/blockjob_int.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qapi/qmp/qdict.h"
typedef struct {
#include "qapi/error.h"
#include "qemu/main-loop.h"
#include "block/blockjob_int.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qapi/qmp/qdict.h"
#include "iothread.h"
#include "qemu/option.h"
#include "qemu/sockets.h"
#include "chardev/char-fe.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-char.h"
#include "qapi/qmp/qdict.h"
#include "qemu/osdep.h"
#include "block/block.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "qemu/main-loop.h"
#include "block/replication.h"
#include "block/block_int.h"
#include "block/qdict.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
#define IMG_SIZE (64 * 1024 * 1024)
#include "qemu/osdep.h"
#include "qemu/config-file.h"
#include "qemu/option.h"
-#include "sysemu/seccomp.h"
+#include "system/seccomp.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "block/throttle-groups.h"
-#include "sysemu/block-backend.h"
+#include "system/block-backend.h"
static AioContext *ctx;
static LeakyBucket bkt;
*/
#include "qemu/osdep.h"
-#include "sysemu/cpu-timers.h"
+#include "system/cpu-timers.h"
#include "qemu/timed-average.h"
/* This is the clock for QEMU_CLOCK_VIRTUAL */
#include "qemu/module.h"
#include "qemu/option.h"
#include "chardev/char-fe.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-char.h"
#include "qapi/qapi-types-char.h"
#include "ui/console.h"
#include "ui/input.h"
#include "ui/kbd-state.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/runstate.h"
-#include "sysemu/runstate-action.h"
-#include "sysemu/cpu-throttle.h"
+#include "system/system.h"
+#include "system/runstate.h"
+#include "system/runstate-action.h"
+#include "system/cpu-throttle.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-block.h"
#include "qapi/qapi-commands-machine.h"
#include "qapi/qapi-commands-misc.h"
-#include "sysemu/blockdev.h"
+#include "system/blockdev.h"
#include "qemu-version.h"
#include "qemu/cutils.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "ui/console.h"
#include "ui/input.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#ifdef __APPLE__
#define _XOPEN_SOURCE_EXTENDED 1
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qom/object_interfaces.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qapi/error.h"
#include "trace.h"
#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "dbus.h"
#include "glib.h"
#ifdef G_OS_UNIX
#include "qemu/main-loop.h"
#include "qemu/option.h"
#include "qom/object_interfaces.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "ui/dbus-module.h"
#ifdef CONFIG_OPENGL
#include "ui/egl-helpers.h"
#include "qemu/error-report.h"
#include "ui/console.h"
#include "ui/egl-helpers.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qapi/error.h"
#include "trace.h"
#include "ui/egl-helpers.h"
#include "ui/shader.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
static void gtk_egl_set_scanout_mode(VirtualConsole *vc, bool scanout)
{
#include "ui/gtk.h"
#include "ui/egl-helpers.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
static void gtk_gl_area_set_scanout_mode(VirtualConsole *vc, bool scanout)
{
#include "trace.h"
#include "ui/input.h"
-#include "sysemu/runstate.h"
-#include "sysemu/sysemu.h"
+#include "system/runstate.h"
+#include "system/system.h"
#include "keymaps.h"
#include "chardev/char.h"
#include "qom/object.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qemu/main-loop.h"
#include "qemu/sockets.h"
#include "qapi/error.h"
#include "qemu/sockets.h"
#include "ui/input.h"
#include "qom/object_interfaces.h"
-#include "sysemu/iothread.h"
+#include "system/iothread.h"
#include "block/aio.h"
#include <sys/ioctl.h>
#include "qemu/osdep.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-ui.h"
#include "trace.h"
#include "ui/input.h"
#include "ui/console.h"
-#include "sysemu/replay.h"
-#include "sysemu/runstate.h"
+#include "system/replay.h"
+#include "system/runstate.h"
struct QemuInputHandlerState {
DeviceState *dev;
#include "ui/console.h"
#include "ui/input.h"
#include "ui/sdl2.h"
-#include "sysemu/runstate.h"
-#include "sysemu/runstate-action.h"
-#include "sysemu/sysemu.h"
+#include "system/runstate.h"
+#include "system/runstate-action.h"
+#include "system/system.h"
#include "ui/win32-kbd-hook.h"
#include "qemu/log.h"
#include "qapi/error.h"
#include "io/channel-command.h"
#include "chardev/spice.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "qom/object.h"
static const char *tmp_dir;
#include "qemu/osdep.h"
#include <spice.h>
-#include "sysemu/sysemu.h"
-#include "sysemu/runstate.h"
+#include "system/system.h"
+#include "system/runstate.h"
#include "ui/qemu-spice.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "vnc-jobs.h"
#include "trace.h"
#include "hw/qdev-core.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/runstate.h"
+#include "system/system.h"
+#include "system/runstate.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
*/
#include "qemu/osdep.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "ui/win32-kbd-hook.h"
static Notifier win32_unhook_notifier;
#include "block/raw-aio.h"
#include "qemu/coroutine_int.h"
#include "qemu/coroutine-tls.h"
-#include "sysemu/cpu-timers.h"
+#include "system/cpu-timers.h"
#include "trace.h"
/***********************************************************/
#include "qapi/error.h"
#include "qemu/cutils.h"
#include "qemu/timer.h"
-#include "sysemu/cpu-timers.h"
-#include "sysemu/replay.h"
+#include "system/cpu-timers.h"
+#include "system/replay.h"
#include "qemu/main-loop.h"
#include "block/aio.h"
#include "block/thread-pool.h"
#include <glib/gprintf.h>
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "trace.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qemu/timer.h"
#include "qemu/lockable.h"
-#include "sysemu/cpu-timers.h"
-#include "sysemu/replay.h"
-#include "sysemu/cpus.h"
+#include "system/cpu-timers.h"
+#include "system/replay.h"
+#include "system/cpus.h"
#ifdef CONFIG_POSIX
#include <pthread.h>