- make check-tcg
# Check our reduced build configurations
+# requires libfdt: aarch64, arm, i386, loongarch64, microblaze, microblazeel,
+# mips64el, or1k, ppc, ppc64, riscv32, riscv64, rx, x86_64
+# does not build without boards: i386, loongarch64, s390x, sh4, sh4eb, x86_64
build-without-defaults:
extends: .native_build_job_template
needs:
--disable-pie
--disable-qom-cast-debug
--disable-strip
- TARGETS: avr-softmmu s390x-softmmu sh4-softmmu
- sparc64-softmmu hexagon-linux-user i386-linux-user s390x-linux-user
+ TARGETS: alpha-softmmu avr-softmmu cris-softmmu hppa-softmmu m68k-softmmu
+ mips-softmmu mips64-softmmu mipsel-softmmu sparc-softmmu
+ sparc64-softmmu tricore-softmmu xtensa-softmmu xtensaeb-softmmu
+ hexagon-linux-user i386-linux-user s390x-linux-user
MAKE_CHECK_ARGS: check
build-libvhost-user:
# changed to compile QEMU with the --without-default-devices switch
# for this job, because otherwise the build could not complete within
# the project timeout.
- CONFIGURE_ARGS: --target-list=x86_64-softmmu --without-default-devices -Ddebug=false -Doptimization=0
- # qTests don't run successfully with "--without-default-devices",
- # so let's exclude the qtests from CI for now.
- TEST_ARGS: --no-suite qtest
+ CONFIGURE_ARGS: --target-list=sparc-softmmu --without-default-devices -Ddebug=false -Doptimization=0
# The Windows git is a bit older so override the default
GIT_FETCH_EXTRA_FLAGS: --no-tags --prune --quiet
artifacts:
F: include/exec/helper*.h
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/hw/core/tcg-cpu-ops.h
M: Philippe Mathieu-Daudé <philmd@linaro.org>
R: Aurelien Jarno <aurelien@aurel32.net>
R: Jiaxun Yang <jiaxun.yang@flygoat.com>
-R: Aleksandar Rikalo <aleksandar.rikalo@syrmia.com>
+R: Aleksandar Rikalo <arikalo@gmail.com>
S: Odd Fixes
F: target/mips/
F: disas/*mips.c
RISC-V TCG CPUs
M: Palmer Dabbelt <palmer@dabbelt.com>
M: Alistair Francis <alistair.francis@wdc.com>
-M: Bin Meng <bin.meng@windriver.com>
+M: Bin Meng <bmeng.cn@gmail.com>
R: Weiwei Li <liwei1518@gmail.com>
R: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
R: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
Jazz
M: Hervé Poussineau <hpoussin@reactos.org>
-R: Aleksandar Rikalo <aleksandar.rikalo@syrmia.com>
+R: Aleksandar Rikalo <arikalo@gmail.com>
S: Maintained
F: hw/mips/jazz.c
F: hw/display/g364fb.c
F: tests/avocado/machine_mips_malta.py
Mipssim
-R: Aleksandar Rikalo <aleksandar.rikalo@syrmia.com>
+R: Aleksandar Rikalo <arikalo@gmail.com>
S: Orphan
F: hw/mips/mipssim.c
F: hw/net/mipsnet.c
Boston
M: Paul Burton <paulburton@kernel.org>
-R: Aleksandar Rikalo <aleksandar.rikalo@syrmia.com>
+R: Aleksandar Rikalo <arikalo@gmail.com>
S: Odd Fixes
F: hw/core/loader-fit.c
F: hw/mips/boston.c
F: include/hw/*/ibex_*.h
Microchip PolarFire SoC Icicle Kit
-M: Bin Meng <bin.meng@windriver.com>
+M: Bin Meng <bmeng.cn@gmail.com>
L: qemu-riscv@nongnu.org
S: Supported
F: docs/system/riscv/microchip-icicle-kit.rst
SiFive Machines
M: Alistair Francis <Alistair.Francis@wdc.com>
-M: Bin Meng <bin.meng@windriver.com>
+M: Bin Meng <bmeng.cn@gmail.com>
M: Palmer Dabbelt <palmer@dabbelt.com>
L: qemu-riscv@nongnu.org
S: Supported
SD (Secure Card)
M: Philippe Mathieu-Daudé <philmd@linaro.org>
-M: Bin Meng <bin.meng@windriver.com>
+M: Bin Meng <bmeng.cn@gmail.com>
L: qemu-block@nongnu.org
S: Odd Fixes
F: include/hw/sd/sd*
R: Aurelien Jarno <aurelien@aurel32.net>
R: Huacai Chen <chenhuacai@kernel.org>
R: Jiaxun Yang <jiaxun.yang@flygoat.com>
-R: Aleksandar Rikalo <aleksandar.rikalo@syrmia.com>
+R: Aleksandar Rikalo <arikalo@gmail.com>
S: Odd Fixes
F: tcg/mips/
assert(ret == 0);
}
-static void kvm_add_routing_entry(KVMState *s,
- struct kvm_irq_routing_entry *entry)
+void kvm_add_routing_entry(KVMState *s,
+ struct kvm_irq_routing_entry *entry)
{
struct kvm_irq_routing_entry *new;
int n, size;
notifier_list_notify(&kvm_irqchip_change_notifiers, NULL);
}
-static int kvm_irqchip_get_virq(KVMState *s)
+int kvm_irqchip_get_virq(KVMState *s)
{
int next_virq;
return kvm_vm_ioctl(s, KVM_IRQFD, &irqfd);
}
-int kvm_irqchip_add_adapter_route(KVMState *s, AdapterInfo *adapter)
-{
- struct kvm_irq_routing_entry kroute = {};
- int virq;
-
- if (!kvm_gsi_routing_enabled()) {
- return -ENOSYS;
- }
-
- virq = kvm_irqchip_get_virq(s);
- if (virq < 0) {
- return virq;
- }
-
- kroute.gsi = virq;
- kroute.type = KVM_IRQ_ROUTING_S390_ADAPTER;
- kroute.flags = 0;
- kroute.u.adapter.summary_addr = adapter->summary_addr;
- kroute.u.adapter.ind_addr = adapter->ind_addr;
- kroute.u.adapter.summary_offset = adapter->summary_offset;
- kroute.u.adapter.ind_offset = adapter->ind_offset;
- kroute.u.adapter.adapter_id = adapter->adapter_id;
-
- kvm_add_routing_entry(s, &kroute);
-
- return virq;
-}
-
-int kvm_irqchip_add_hv_sint_route(KVMState *s, uint32_t vcpu, uint32_t sint)
-{
- struct kvm_irq_routing_entry kroute = {};
- int virq;
-
- if (!kvm_gsi_routing_enabled()) {
- return -ENOSYS;
- }
- if (!kvm_check_extension(s, KVM_CAP_HYPERV_SYNIC)) {
- return -ENOSYS;
- }
- virq = kvm_irqchip_get_virq(s);
- if (virq < 0) {
- return virq;
- }
-
- kroute.gsi = virq;
- kroute.type = KVM_IRQ_ROUTING_HV_SINT;
- kroute.flags = 0;
- kroute.u.hv_sint.vcpu = vcpu;
- kroute.u.hv_sint.sint = sint;
-
- kvm_add_routing_entry(s, &kroute);
- kvm_irqchip_commit_routes(s);
-
- return virq;
-}
-
#else /* !KVM_CAP_IRQ_ROUTING */
void kvm_init_irq_routing(KVMState *s)
}
#endif /* CONFIG USER ONLY */
+bool tcg_cflags_has(CPUState *cpu, uint32_t flags)
+{
+ return cpu->tcg_cflags & flags;
+}
+
+void tcg_cflags_set(CPUState *cpu, uint32_t flags)
+{
+ cpu->tcg_cflags |= flags;
+}
+
uint32_t curr_cflags(CPUState *cpu)
{
uint32_t cflags = cpu->tcg_cflags;
vaddr pc, TranslationBlock **last_tb,
int *tb_exit)
{
- int32_t insns_left;
-
trace_exec_tb(tb, pc);
tb = cpu_tb_exec(cpu, tb, tb_exit);
if (*tb_exit != TB_EXIT_REQUESTED) {
}
*last_tb = NULL;
- insns_left = qatomic_read(&cpu->neg.icount_decr.u32);
- if (insns_left < 0) {
+ if (cpu_loop_exit_requested(cpu)) {
/* Something asked us to stop executing chained TBs; just
* continue round the main loop. Whatever requested the exit
* will also have set something else (eg exit_request or
/* Ensure global icount has gone forward */
icount_update(cpu);
/* Refill decrementer and continue execution. */
- insns_left = MIN(0xffff, cpu->icount_budget);
+ int32_t insns_left = MIN(0xffff, cpu->icount_budget);
cpu->neg.icount_decr.u16.low = insns_left;
cpu->icount_extra = cpu->icount_budget - insns_left;
#include "qemu/main-loop.h"
#include "hw/core/tcg-cpu-ops.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "exec/memory.h"
#include "exec/cpu_ldst.h"
#include "exec/cputlb.h"
#ifndef ACCEL_TCG_INTERNAL_COMMON_H
#define ACCEL_TCG_INTERNAL_COMMON_H
+#include "exec/cpu-common.h"
#include "exec/translation-block.h"
extern int64_t max_delay;
*/
static inline bool cpu_in_serial_context(CPUState *cs)
{
- return !(cs->tcg_cflags & CF_PARALLEL) || cpu_in_exclusive_context(cs);
+ return !tcg_cflags_has(cs, CF_PARALLEL) || cpu_in_exclusive_context(cs);
+}
+
+/**
+ * cpu_plugin_mem_cbs_enabled() - are plugin memory callbacks enabled?
+ * @cs: CPUState pointer
+ *
+ * The memory callbacks are installed if a plugin has instrumented an
+ * instruction for memory. This can be useful to know if you want to
+ * force a slow path for a series of memory accesses.
+ */
+static inline bool cpu_plugin_mem_cbs_enabled(const CPUState *cpu)
+{
+#ifdef CONFIG_PLUGIN
+ return !!cpu->neg.plugin_mem_cbs;
+#else
+ return false;
+#endif
}
#endif
* Tracking memory accesses performed from helpers requires extra work.
* If an instruction is emulated with helpers, we do two things:
* (1) copy the CB descriptors, and keep track of it so that they can be
- * freed later on, and (2) point CPUState.plugin_mem_cbs to the
+ * freed later on, and (2) point CPUState.neg.plugin_mem_cbs to the
* descriptors, so that we can read them at run-time
* (i.e. when the helper executes).
* This run-time access is performed from qemu_plugin_vcpu_mem_cb.
qemu_plugin_add_dyn_cb_arr(arr);
tcg_gen_st_ptr(tcg_constant_ptr((intptr_t)arr), tcg_env,
- offsetof(CPUState, plugin_mem_cbs) -
+ offsetof(CPUState, neg.plugin_mem_cbs) -
offsetof(ArchCPU, env));
}
static void gen_disable_mem_helper(void)
{
tcg_gen_st_ptr(tcg_constant_ptr(0), tcg_env,
- offsetof(CPUState, plugin_mem_cbs) -
+ offsetof(CPUState, neg.plugin_mem_cbs) -
offsetof(ArchCPU, env));
}
* non-NULL value of 'tb'. Strictly speaking pc is only needed for
* CF_PCREL, but it's used always for simplicity.
*/
-struct CPUJumpCache {
+typedef struct CPUJumpCache {
struct rcu_head rcu;
struct {
TranslationBlock *tb;
vaddr pc;
} array[TB_JMP_CACHE_SIZE];
-};
+} CPUJumpCache;
#endif /* ACCEL_TCG_TB_JMP_CACHE_H */
#include "exec/cputlb.h"
#include "exec/log.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "exec/tb-flush.h"
#include "exec/translate-all.h"
#include "sysemu/tcg.h"
cflags |= parallel ? CF_PARALLEL : 0;
cflags |= icount_enabled() ? CF_USE_ICOUNT : 0;
- cpu->tcg_cflags |= cflags;
+ tcg_cflags_set(cpu, cflags);
}
void tcg_cpu_destroy(CPUState *cpu)
cpu_loop_exit_noexc(cpu);
}
-#else /* CONFIG_USER_ONLY */
-
-void cpu_interrupt(CPUState *cpu, int mask)
-{
- g_assert(bql_locked());
- cpu->interrupt_request |= mask;
- qatomic_set(&cpu->neg.icount_decr.u16.high, -1);
-}
-
#endif /* CONFIG_USER_ONLY */
/*
#include "qemu/bitops.h"
#include "qemu/rcu.h"
#include "exec/cpu_ldst.h"
+#include "qemu/main-loop.h"
#include "exec/translate-all.h"
+#include "exec/page-protection.h"
#include "exec/helper-proto.h"
#include "qemu/atomic128.h"
#include "trace/trace-root.h"
//#define DEBUG_SIGNAL
+void cpu_interrupt(CPUState *cpu, int mask)
+{
+ g_assert(bql_locked());
+ cpu->interrupt_request |= mask;
+ qatomic_set(&cpu->neg.icount_decr.u16.high, -1);
+}
+
/*
* Adjust the pc to pass to cpu_restore_state; return the memop type.
*/
if (prot & PAGE_EXEC) {
prot = (prot & ~PAGE_EXEC) | PAGE_READ;
}
- mprotect((void *)g2h_untagged(start), len, prot & PAGE_BITS);
+ mprotect((void *)g2h_untagged(start), len, prot & PAGE_RWX);
}
mmap_unlock();
--- /dev/null
+/*
+ * SPDX-FileContributor: Philippe Mathieu-Daudé <philmd@linaro.org>
+ * SPDX-FileCopyrightText: 2023 Linaro Ltd.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef ACCEL_TCG_VCPU_STATE_H
+#define ACCEL_TCG_VCPU_STATE_H
+
+#include "hw/core/cpu.h"
+
+#ifdef CONFIG_USER_ONLY
+static inline TaskState *get_task_state(const CPUState *cs)
+{
+ return cs->opaque;
+}
+#endif
+
+#endif
#include <fcntl.h>
#include "qemu-bsd.h"
+#include "exec/page-protection.h"
extern struct bsd_shm_regions bsd_shm_regions[];
extern abi_ulong target_brk;
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
+#include "exec/page-protection.h"
#include "qemu.h"
end = host_end;
}
ret = mprotect(g2h_untagged(host_start),
- qemu_host_page_size, prot1 & PAGE_BITS);
+ qemu_host_page_size, prot1 & PAGE_RWX);
if (ret != 0)
goto error;
host_start += qemu_host_page_size;
prot1 |= page_get_flags(addr);
}
ret = mprotect(g2h_untagged(host_end - qemu_host_page_size),
- qemu_host_page_size, prot1 & PAGE_BITS);
+ qemu_host_page_size, prot1 & PAGE_RWX);
if (ret != 0)
goto error;
host_end -= qemu_host_page_size;
return -1;
prot1 = prot;
}
- prot1 &= PAGE_BITS;
+ prot1 &= PAGE_RWX;
prot_new = prot | prot1;
if (fd != -1) {
#include "target_os_signal.h"
#include "target.h"
#include "exec/gdbstub.h"
+#include "exec/page-protection.h"
#include "qemu/clang-tsa.h"
+#include "accel/tcg/vcpu-state.h"
#include "qemu-os.h"
/*
/*
* NOTE: we force a big alignment so that the stack stored after is aligned too
*/
-typedef struct TaskState {
+struct TaskState {
pid_t ts_tid; /* tid (or pid) of this task */
struct TaskState *next;
/* This thread's sigaltstack, if it has one */
struct target_sigaltstack sigaltstack_used;
-} __attribute__((aligned(16))) TaskState;
-
-static inline TaskState *get_task_state(CPUState *cs)
-{
- return cs->opaque;
-}
+} __attribute__((aligned(16)));
void stop_all_tasks(void);
extern const char *interp_prefix;
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu.h"
+#include "exec/page-protection.h"
#include "user/tswap-target.h"
#include "gdbstub/user.h"
#include "signal-common.h"
#CONFIG_PCI_DEVICES=n
#CONFIG_TEST_DEVICES=n
-# Boards:
-#
-CONFIG_DP264=y
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_DP264=n
# Default configuration for arm-softmmu
+# Uncomment the following lines to disable these optional devices:
+# CONFIG_I2C_DEVICES=n
# CONFIG_PCI_DEVICES=n
# CONFIG_TEST_DEVICES=n
-CONFIG_ARM_VIRT=y
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_ARM_VIRT=n
# These are selected by default when TCG is enabled, uncomment them to
# keep out of the build.
# Default configuration for avr-softmmu
-# Boards:
-#
-CONFIG_ARDUINO=y
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_ARDUINO=n
# Default configuration for cris-softmmu
-# Boards:
-#
-CONFIG_AXIS=y
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_AXIS=n
#
#CONFIG_PCI_DEVICES=n
-# Boards:
-#
-CONFIG_HPPA_B160L=y
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_HPPA_B160L=n
#CONFIG_VTD=n
#CONFIG_SGX=n
-# Boards:
-#
-CONFIG_ISAPC=y
-CONFIG_I440FX=y
-CONFIG_Q35=y
-CONFIG_MICROVM=y
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_ISAPC=n
+# CONFIG_I440FX=n
+# CONFIG_Q35=n
+# CONFIG_MICROVM=n
# Default configuration for loongarch64-softmmu
-CONFIG_LOONGARCH_VIRT=y
+# Uncomment the following lines to disable these optional devices:
+# CONFIG_PCI_DEVICES=n
+
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_LOONGARCH_VIRT=n
# Default configuration for m68k-softmmu
-# Boards:
-#
-CONFIG_AN5206=y
-CONFIG_MCF5208=y
-CONFIG_NEXTCUBE=y
-CONFIG_Q800=y
-CONFIG_M68K_VIRT=y
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_AN5206=n
+# CONFIG_MCF5208=n
+# CONFIG_NEXTCUBE=n
+# CONFIG_Q800=n
+# CONFIG_M68K_VIRT=n
# Default configuration for microblaze-softmmu
-# Boards:
-#
-CONFIG_PETALOGIX_S3ADSP1800=y
-CONFIG_PETALOGIX_ML605=y
-CONFIG_XLNX_ZYNQMP_PMU=y
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_PETALOGIX_S3ADSP1800=n
+# CONFIG_PETALOGIX_ML605=n
+# CONFIG_XLNX_ZYNQMP_PMU=n
# CONFIG_PCI_DEVICES=n
# CONFIG_TEST_DEVICES=n
-CONFIG_MALTA=y
-CONFIG_MIPSSIM=y
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_MALTA=n
+# CONFIG_MIPSSIM=n
# Default configuration for mips64-softmmu
include ../mips-softmmu/common.mak
-CONFIG_JAZZ=y
+
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_JAZZ=n
# Default configuration for mips64el-softmmu
include ../mips-softmmu/common.mak
-CONFIG_FULOONG=y
-CONFIG_LOONGSON3V=y
-CONFIG_JAZZ=y
-CONFIG_MIPS_BOSTON=y
+
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_FULOONG=n
+# CONFIG_LOONGSON3V=n
+# CONFIG_JAZZ=n
+# CONFIG_MIPS_BOSTON=n
# Default configuration for or1k-softmmu
+# Uncomment the following lines to disable these optional devices:
+# CONFIG_PCI_DEVICES=n
+# CONFIG_TEST_DEVICES=n
+
# Boards:
-#
-CONFIG_OR1K_SIM=y
-CONFIG_OR1K_VIRT=y
+# CONFIG_OR1K_SIM=n
+# CONFIG_OR1K_VIRT=n
# Default configuration for ppc-softmmu
-# For embedded PPCs:
-CONFIG_E500PLAT=y
-CONFIG_MPC8544DS=y
-CONFIG_PPC405=y
-CONFIG_PPC440=y
-CONFIG_VIRTEX=y
+# Uncomment the following lines to disable these optional devices:
+# CONFIG_PCI_DEVICES=n
+# CONFIG_TEST_DEVICES=n
+
+# Boards are selected by default, uncomment to keep out of the build.
+
+# Embedded PPCs:
+# CONFIG_E500PLAT=n
+# CONFIG_MPC8544DS=n
+# CONFIG_PPC405=n
+# CONFIG_PPC440=n
+# CONFIG_VIRTEX=n
# For Sam460ex
-CONFIG_SAM460EX=y
+# CONFIG_SAM460EX=n
# For Macs
-CONFIG_MAC_OLDWORLD=y
-CONFIG_MAC_NEWWORLD=y
+# CONFIG_MAC_OLDWORLD=n
+# CONFIG_MAC_NEWWORLD=n
-CONFIG_AMIGAONE=y
-CONFIG_PEGASOS2=y
+# CONFIG_AMIGAONE=n
+# CONFIG_PEGASOS2=n
# For PReP
-CONFIG_PREP=y
+# CONFIG_PREP=n
# Include all 32-bit boards
include ../ppc-softmmu/default.mak
-# For PowerNV
-CONFIG_POWERNV=y
-
-# For pSeries
-CONFIG_PSERIES=y
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_POWERNV=n
+# CONFIG_PSERIES=n
# Default configuration for riscv32-softmmu
# Uncomment the following lines to disable these optional devices:
-#
-#CONFIG_PCI_DEVICES=n
+# CONFIG_PCI_DEVICES=n
+# CONFIG_TEST_DEVICES=n
-# Boards:
-#
-CONFIG_SPIKE=y
-CONFIG_SIFIVE_E=y
-CONFIG_SIFIVE_U=y
-CONFIG_RISCV_VIRT=y
-CONFIG_OPENTITAN=y
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_SPIKE=n
+# CONFIG_SIFIVE_E=n
+# CONFIG_SIFIVE_U=n
+# CONFIG_RISCV_VIRT=n
+# CONFIG_OPENTITAN=n
# Default configuration for riscv64-softmmu
# Uncomment the following lines to disable these optional devices:
-#
-#CONFIG_PCI_DEVICES=n
+# CONFIG_PCI_DEVICES=n
+# CONFIG_TEST_DEVICES=n
-# Boards:
-#
-CONFIG_SPIKE=y
-CONFIG_SIFIVE_E=y
-CONFIG_SIFIVE_U=y
-CONFIG_RISCV_VIRT=y
-CONFIG_MICROCHIP_PFSOC=y
-CONFIG_SHAKTI_C=y
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_SPIKE=n
+# CONFIG_SIFIVE_E=n
+# CONFIG_SIFIVE_U=n
+# CONFIG_RISCV_VIRT=n
+# CONFIG_MICROCHIP_PFSOC=n
+# CONFIG_SHAKTI_C=n
# Default configuration for rx-softmmu
-CONFIG_RX_GDBSIM=y
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_RX_GDBSIM=n
#CONFIG_WDT_DIAG288=n
#CONFIG_PCIE_DEVICES=n
-# Boards:
-#
-CONFIG_S390_CCW_VIRTIO=y
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_S390_CCW_VIRTIO=n
#CONFIG_PCI_DEVICES=n
#CONFIG_TEST_DEVICES=n
-# Boards:
-#
-CONFIG_R2D=y
-CONFIG_SHIX=y
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_R2D=n
+# CONFIG_SHIX=n
#CONFIG_TCX=n
#CONFIG_CG3=n
-# Boards:
-#
-CONFIG_SUN4M=y
-CONFIG_LEON3=y
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_SUN4M=n
+# CONFIG_LEON3=n
#CONFIG_SUNHME=n
#CONFIG_TEST_DEVICES=n
-# Boards:
-#
-CONFIG_SUN4U=y
-CONFIG_NIAGARA=y
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_SUN4U=n
+# CONFIG_NIAGARA=n
-CONFIG_TRICORE_TESTBOARD=y
-CONFIG_TRIBOARD=y
+# Default configuration for tricore-softmmu
+
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_TRICORE_TESTBOARD=n
+# CONFIG_TRIBOARD=n
# Default configuration for Xtensa
-# Boards:
+# Uncomment the following lines to disable these optional devices:
#
-CONFIG_XTENSA_SIM=y
-CONFIG_XTENSA_VIRT=y
-CONFIG_XTENSA_XTFPGA=y
+#CONFIG_PCI_DEVICES=n
+
+# Boards are selected by default, uncomment to keep out of the build.
+# CONFIG_XTENSA_SIM=n
+# CONFIG_XTENSA_VIRT=n
+# CONFIG_XTENSA_XTFPGA=n
#include "qapi/error.h"
#include "exec/target_page.h"
+#include "exec/page-protection.h"
#include "hw/qdev-core.h"
#include "hw/qdev-properties.h"
#include "qemu/error-report.h"
config SUN4M
bool
+ default y
+ depends on SPARC && !SPARC64
imply TCX
imply CG3
select CS4231
directives. A device should be listed under ``select`` if the board
cannot be started at all without it. It should be listed under
``imply`` if (depending on the QEMU command line) the board may or
- may not be started without it. Boards also default to false; they are
- enabled by the ``default-configs/*.mak`` for the target they apply to.
+ may not be started without it. Boards default to true, but also
+ have a ``depends on`` clause to limit them to the appropriate targets.
+ For some targets, not all boards may be supported by hardware
+ virtualization, in which case they also depend on the ``TCG`` symbol,
+ Other symbols that are commonly used as dependencies for boards
+ include libraries (such as ``FDT``) or ``TARGET_BIG_ENDIAN``
+ (possibly negated).
+
+ Boards are listed for convenience in the ``default-configs/*.mak``
+ for the target they apply to.
**internal elements**
term.extend(self._nodes_for_ifcond(member.ifcond))
return term
- def _nodes_for_variant_when(self, variants, variant):
+ def _nodes_for_variant_when(self, branches, variant):
"""Return list of Text, literal nodes for variant 'when' clause
Return a list of doctree nodes which give text like
'when tagname is variant (If: ...)' suitable for use in
- the 'variants' part of a definition list.
+ the 'branches' part of a definition list.
"""
term = [nodes.Text(' when '),
- nodes.literal('', variants.tag_member.name),
+ nodes.literal('', branches.tag_member.name),
nodes.Text(' is '),
nodes.literal('', '"%s"' % variant.name)]
if variant.ifcond.is_present():
term.extend(self._nodes_for_ifcond(variant.ifcond))
return term
- def _nodes_for_members(self, doc, what, base=None, variants=None):
+ def _nodes_for_members(self, doc, what, base=None, branches=None):
"""Return list of doctree nodes for the table of members"""
dlnode = nodes.definition_list()
for section in doc.args.values():
nodes.literal('', base.doc_type())],
None)
- if variants:
- for v in variants.variants:
+ if branches:
+ for v in branches.variants:
if v.type.name == 'q_empty':
continue
assert not v.type.is_implicit()
term = [nodes.Text('The members of '),
nodes.literal('', v.type.doc_type())]
- term.extend(self._nodes_for_variant_when(variants, v))
+ term.extend(self._nodes_for_variant_when(branches, v))
dlnode += self._make_dlitem(term, None)
if not dlnode.children:
+ self._nodes_for_if_section(ifcond))
def visit_object_type(self, name, info, ifcond, features,
- base, members, variants):
+ base, members, branches):
doc = self._cur_doc
if base and base.is_implicit():
base = None
self._add_doc('Object',
- self._nodes_for_members(doc, 'Members', base, variants)
+ self._nodes_for_members(doc, 'Members', base, branches)
+ self._nodes_for_features(doc)
+ self._nodes_for_sections(doc)
+ self._nodes_for_if_section(ifcond))
- def visit_alternate_type(self, name, info, ifcond, features, variants):
+ def visit_alternate_type(self, name, info, ifcond, features,
+ alternatives):
doc = self._cur_doc
self._add_doc('Alternate',
self._nodes_for_members(doc, 'Members')
#include "exec/gdbstub.h"
#include "gdbstub/syscalls.h"
#ifdef CONFIG_USER_ONLY
+#include "accel/tcg/vcpu-state.h"
#include "gdbstub/user.h"
#else
#include "hw/cpu/cluster.h"
#if defined(CONFIG_USER_ONLY)
#if defined(CONFIG_LINUX)
- if (gdbserver_state.c_cpu->opaque) {
+ if (get_task_state(gdbserver_state.c_cpu)) {
g_string_append(gdbserver_state.str_buf, ";qXfer:auxv:read+");
}
g_string_append(gdbserver_state.str_buf, ";QCatchSyscalls+");
{
TaskState *ts;
- ts = gdbserver_state.c_cpu->opaque;
+ ts = get_task_state(gdbserver_state.c_cpu);
g_string_printf(gdbserver_state.str_buf,
"Text=" TARGET_ABI_FMT_lx
";Data=" TARGET_ABI_FMT_lx
offset = get_param(params, 0)->val_ul;
len = get_param(params, 1)->val_ul;
- ts = gdbserver_state.c_cpu->opaque;
+ ts = get_task_state(gdbserver_state.c_cpu);
saved_auxv = ts->info->saved_auxv;
auxv_len = ts->info->auxv_len;
config DP264
bool
+ default y
+ depends on ALPHA
imply PCI_DEVICES
imply TEST_DEVICES
imply E1000_PCI
config ARM_VIRT
bool
+ default y
+ depends on ARM
imply PCI_DEVICES
imply TEST_DEVICES
imply VFIO_AMD_XGBE
select AVR_POWER
config ARDUINO
+ bool
+ default y
+ depends on AVR
select AVR_ATMEGA_MCU
select UNIMP
#include "hw/boards.h"
#include "hw/qdev-properties.h"
#include "trace.h"
+#ifdef CONFIG_PLUGIN
#include "qemu/plugin.h"
+#endif
CPUState *cpu_by_arch_id(int64_t id)
{
CPUState *cpu = CPU(dev);
/* Call the plugin hook before clearing the cpu is fully unrealized */
+#ifdef CONFIG_PLUGIN
if (tcg_enabled()) {
qemu_plugin_vcpu_exit_hook(cpu);
}
+#endif
/* NOTE: latest generic point before the cpu is fully unrealized */
cpu_exec_unrealizefn(cpu);
config AXIS
bool
+ default y
+ depends on CRIS
select ETRAXFS
select PFLASH_CFI02
select NAND
if_false: files('acpi-vga-stub.c'))
hw_display_modules += {'virtio-vga': virtio_vga_ss}
- virtio_vga_gl_ss = ss.source_set()
- virtio_vga_gl_ss.add(when: ['CONFIG_VIRTIO_VGA', virgl, opengl],
- if_true: [files('virtio-vga-gl.c'), pixman])
- virtio_vga_gl_ss.add(when: 'CONFIG_ACPI', if_true: files('acpi-vga.c'),
- if_false: files('acpi-vga-stub.c'))
- hw_display_modules += {'virtio-vga-gl': virtio_vga_gl_ss}
+ if virgl.found() and opengl.found()
+ virtio_vga_gl_ss = ss.source_set()
+ virtio_vga_gl_ss.add(when: ['CONFIG_VIRTIO_VGA', virgl, opengl],
+ if_true: [files('virtio-vga-gl.c'), pixman])
+ virtio_vga_gl_ss.add(when: 'CONFIG_ACPI', if_true: files('acpi-vga.c'),
+ if_false: files('acpi-vga-stub.c'))
+ hw_display_modules += {'virtio-vga-gl': virtio_vga_gl_ss}
+ endif
if rutabaga.found()
virtio_vga_rutabaga_ss = ss.source_set()
#ifndef HW_VGA_INT_H
#define HW_VGA_INT_H
+#include "ui/console.h"
#include "exec/ioport.h"
#include "exec/memory.h"
config HPPA_B160L
bool
+ default y
+ depends on HPPA
imply PCI_DEVICES
imply E1000_PCI
imply USB_OHCI_PCI
return ret;
}
+static int kvm_irqchip_add_hv_sint_route(KVMState *s, uint32_t vcpu, uint32_t sint)
+{
+ struct kvm_irq_routing_entry kroute = {};
+ int virq;
+
+ if (!kvm_gsi_routing_enabled()) {
+ return -ENOSYS;
+ }
+ virq = kvm_irqchip_get_virq(s);
+ if (virq < 0) {
+ return virq;
+ }
+
+ kroute.gsi = virq;
+ kroute.type = KVM_IRQ_ROUTING_HV_SINT;
+ kroute.flags = 0;
+ kroute.u.hv_sint.vcpu = vcpu;
+ kroute.u.hv_sint.sint = sint;
+
+ kvm_add_routing_entry(s, &kroute);
+ kvm_irqchip_commit_routes(s);
+
+ return virq;
+}
+
HvSintRoute *hyperv_sint_route_new(uint32_t vp_index, uint32_t sint,
HvSintMsgCb cb, void *cb_data)
{
config I440FX
bool
+ default y
+ depends on I386
imply E1000_PCI
imply VMPORT
imply VMMOUSE
config ISAPC
bool
+ default y
+ depends on I386
imply VGA_ISA
select ISA_BUS
select PC
config Q35
bool
+ default y
+ depends on I386
imply VTD
imply AMD_IOMMU
imply E1000E_PCI_EXPRESS
config MICROVM
bool
+ default y
+ depends on I386
select SERIAL_ISA # for serial_hds_isa_init()
select ISA_BUS
select APIC
config XEN_EMU
bool
default y
- depends on KVM && (I386 || X86_64)
+ depends on KVM && I386
return r ? -errno : 0;
}
+static int kvm_irqchip_add_adapter_route(KVMState *s, AdapterInfo *adapter)
+{
+ struct kvm_irq_routing_entry kroute = {};
+ int virq;
+
+ if (!kvm_gsi_routing_enabled()) {
+ return -ENOSYS;
+ }
+
+ virq = kvm_irqchip_get_virq(s);
+ if (virq < 0) {
+ return virq;
+ }
+
+ kroute.gsi = virq;
+ kroute.type = KVM_IRQ_ROUTING_S390_ADAPTER;
+ kroute.flags = 0;
+ kroute.u.adapter.summary_addr = adapter->summary_addr;
+ kroute.u.adapter.ind_addr = adapter->ind_addr;
+ kroute.u.adapter.summary_offset = adapter->summary_offset;
+ kroute.u.adapter.ind_offset = adapter->ind_offset;
+ kroute.u.adapter.adapter_id = adapter->adapter_id;
+
+ kvm_add_routing_entry(s, &kroute);
+
+ return virq;
+}
+
static int kvm_s390_add_adapter_routes(S390FLICState *fs,
AdapterRoutes *routes)
{
config LOONGARCH_VIRT
bool
+ default y
+ depends on LOONGARCH64
select PCI
select PCI_EXPRESS_GENERIC_BRIDGE
imply VIRTIO_VGA
config AN5206
bool
+ default y
+ depends on M68K
select COLDFIRE
select PTIMER
config MCF5208
bool
+ default y
+ depends on M68K
select COLDFIRE
select PTIMER
config NEXTCUBE
bool
+ default y
+ depends on M68K
select FRAMEBUFFER
select ESCC
config Q800
bool
+ default y
+ depends on M68K
select MAC_VIA
select NUBUS
select MACFB
config M68K_VIRT
bool
+ default y
+ depends on M68K
select M68K_IRQC
select VIRT_CTRL
select GOLDFISH_PIC
config PETALOGIX_S3ADSP1800
bool
+ default y
+ depends on MICROBLAZE
select PFLASH_CFI01
select XILINX
select XILINX_AXI
config PETALOGIX_ML605
bool
+ default y
+ depends on MICROBLAZE
select PFLASH_CFI01
select SERIAL
select SSI_M25P80
config XLNX_ZYNQMP_PMU
bool
+ default y
+ depends on MICROBLAZE
select XLNX_ZYNQMP
config MALTA
bool
+ default y
+ depends on MIPS
imply PCNET_PCI
imply PCI_DEVICES
imply TEST_DEVICES
config MIPSSIM
bool
+ default y
+ depends on MIPS
select SERIAL
select MIPSNET
config JAZZ
bool
+ default y
+ depends on MIPS64
select ISA_BUS
select RC4030
select I8259
config FULOONG
bool
+ default y
+ depends on MIPS64 && !TARGET_BIG_ENDIAN
imply PCI_DEVICES
imply TEST_DEVICES
imply ATI_VGA
config LOONGSON3V
bool
+ default y
+ depends on MIPS64 && !TARGET_BIG_ENDIAN
imply PCI_DEVICES
imply TEST_DEVICES
imply VIRTIO_PCI
config MIPS_BOSTON
bool
+ default y
+ depends on MIPS64 && !TARGET_BIG_ENDIAN
imply PCI_DEVICES
imply TEST_DEVICES
select FITLOADER
config OR1K_SIM
bool
+ default y
+ depends on OPENRISC
select SERIAL
select OPENCORES_ETH
select OMPIC
config OR1K_VIRT
bool
+ default y
+ depends on OPENRISC
imply PCI_DEVICES
imply VIRTIO_VGA
imply TEST_DEVICES
config PSERIES
bool
+ default y
+ depends on PPC64
imply USB_OHCI_PCI
imply PCI_DEVICES
imply TEST_DEVICES
config POWERNV
bool
+ default y
+ depends on PPC64
imply PCI_DEVICES
imply TEST_DEVICES
select ISA_IPMI_BT
config PPC405
bool
+ default y
+ depends on PPC
select M48T59
select PFLASH_CFI02
select PPC4XX
config PPC440
bool
+ default y
+ depends on PPC
imply PCI_DEVICES
imply TEST_DEVICES
imply E1000_PCI
config SAM460EX
bool
+ default y
+ depends on PPC
select PFLASH_CFI01
select IDE_SII3112
select M41T80
config AMIGAONE
bool
+ default y
+ depends on PPC
imply ATI_VGA
select ARTICIA
select VT82C686
config PEGASOS2
bool
+ default y
+ depends on PPC
imply ATI_VGA
select MV64361
select VT82C686
config PREP
bool
+ default y
+ depends on PPC
imply PCI_DEVICES
imply TEST_DEVICES
select CS4231A
config MAC_OLDWORLD
bool
+ default y
+ depends on PPC
imply PCI_DEVICES
imply SUNGEM
imply TEST_DEVICES
config MAC_NEWWORLD
bool
+ default y
+ depends on PPC
imply PCI_DEVICES
imply SUNGEM
imply TEST_DEVICES
config E500PLAT
bool
+ default y
+ depends on PPC
select E500
config MPC8544DS
bool
+ default y
+ depends on PPC
select E500
config VIRTEX
bool
+ default y
+ depends on PPC
select PPC4XX
select PFLASH_CFI01
select SERIAL
#include "qemu/units.h"
#include "qemu/datadir.h"
#include "qemu/error-report.h"
+#include "exec/page-protection.h"
#include "net/net.h"
#include "hw/pci/pci.h"
#include "hw/boards.h"
#include "kvm_ppc.h"
#include "sysemu/device_tree.h"
#include "sysemu/block-backend.h"
+#include "exec/page-protection.h"
#include "hw/loader.h"
#include "elf.h"
#include "exec/memory.h"
#include "qemu/osdep.h"
#include "qemu/datadir.h"
#include "qemu/units.h"
+#include "exec/page-protection.h"
#include "cpu.h"
#include "hw/sysbus.h"
#include "hw/char/serial.h"
config MICROCHIP_PFSOC
bool
+ default y
+ depends on RISCV64
select CADENCE_SDHCI
select CPU_CLUSTER
select MCHP_PFSOC_DMC
config OPENTITAN
bool
+ default y
+ depends on RISCV32
select IBEX
select SIFIVE_PLIC
select UNIMP
config RISCV_VIRT
bool
+ default y
+ depends on RISCV32 || RISCV64
imply PCI_DEVICES
imply VIRTIO_VGA
imply TEST_DEVICES
config SHAKTI_C
bool
+ default y
+ depends on RISCV64
select RISCV_ACLINT
select SHAKTI_UART
select SIFIVE_PLIC
config SIFIVE_E
bool
+ default y
+ depends on RISCV32 || RISCV64
select RISCV_ACLINT
select SIFIVE_GPIO
select SIFIVE_PLIC
config SIFIVE_U
bool
+ default y
+ depends on RISCV32 || RISCV64
select CADENCE
select CPU_CLUSTER
select RISCV_ACLINT
config SPIKE
bool
+ default y
+ depends on RISCV32 || RISCV64
select RISCV_NUMA
select HTIF
select RISCV_ACLINT
config RX_GDBSIM
bool
+ default y
+ depends on RX
select RX62N_MCU
config S390_CCW_VIRTIO
bool
+ default y
+ depends on S390X
imply VIRTIO_PCI
imply TERMINAL3270
imply VFIO_AP
config R2D
bool
+ default y
+ depends on SH4
imply PCI_DEVICES
imply TEST_DEVICES
imply RTL8139_PCI
config SHIX
bool
+ default y
+ depends on SH4
select SH7750
select TC58128
config SUN4M
bool
+ default y
+ depends on SPARC && !SPARC64
imply TCX
imply CG3
select CS4231
config LEON3
bool
+ default y
+ depends on SPARC && !SPARC64
select GRLIB
config GRLIB
config SUN4U
bool
+ default y
+ depends on SPARC64
imply PCI_DEVICES
imply SUNHME
imply TEST_DEVICES
config NIAGARA
bool
+ default y
+ depends on SPARC64
select EMPTY_SLOT
select SUN4V_RTC
select UNIMP
config TRICORE_TESTBOARD
+ default y
+ depends on TRICORE
bool
config TRIBOARD
bool
+ default y
+ depends on TRICORE
select TC27X_SOC
config TC27X_SOC
static MapCache *mapcache;
-static inline void mapcache_lock(void)
+static inline void mapcache_lock(MapCache *mc)
{
- qemu_mutex_lock(&mapcache->lock);
+ qemu_mutex_lock(&mc->lock);
}
-static inline void mapcache_unlock(void)
+static inline void mapcache_unlock(MapCache *mc)
{
- qemu_mutex_unlock(&mapcache->lock);
+ qemu_mutex_unlock(&mc->lock);
}
static inline int test_bits(int nr, int size, const unsigned long *addr)
return 0;
}
-void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque)
+static MapCache *xen_map_cache_init_single(phys_offset_to_gaddr_t f,
+ void *opaque,
+ unsigned long max_size)
{
unsigned long size;
- struct rlimit rlimit_as;
+ MapCache *mc;
+
+ mc = g_new0(MapCache, 1);
+
+ mc->phys_offset_to_gaddr = f;
+ mc->opaque = opaque;
+ qemu_mutex_init(&mc->lock);
+
+ QTAILQ_INIT(&mc->locked_entries);
- mapcache = g_new0(MapCache, 1);
+ mc->max_mcache_size = max_size;
- mapcache->phys_offset_to_gaddr = f;
- mapcache->opaque = opaque;
- qemu_mutex_init(&mapcache->lock);
+ mc->nr_buckets =
+ (((mc->max_mcache_size >> XC_PAGE_SHIFT) +
+ (1UL << (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT)) - 1) >>
+ (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT));
- QTAILQ_INIT(&mapcache->locked_entries);
+ size = mc->nr_buckets * sizeof(MapCacheEntry);
+ size = (size + XC_PAGE_SIZE - 1) & ~(XC_PAGE_SIZE - 1);
+ trace_xen_map_cache_init(mc->nr_buckets, size);
+ mc->entry = g_malloc0(size);
+ return mc;
+}
+
+void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque)
+{
+ struct rlimit rlimit_as;
+ unsigned long max_mcache_size;
if (geteuid() == 0) {
rlimit_as.rlim_cur = RLIM_INFINITY;
rlimit_as.rlim_max = RLIM_INFINITY;
- mapcache->max_mcache_size = MCACHE_MAX_SIZE;
+ max_mcache_size = MCACHE_MAX_SIZE;
} else {
getrlimit(RLIMIT_AS, &rlimit_as);
rlimit_as.rlim_cur = rlimit_as.rlim_max;
" memory is not infinity");
}
if (rlimit_as.rlim_max < MCACHE_MAX_SIZE + NON_MCACHE_MEMORY_SIZE) {
- mapcache->max_mcache_size = rlimit_as.rlim_max -
- NON_MCACHE_MEMORY_SIZE;
+ max_mcache_size = rlimit_as.rlim_max - NON_MCACHE_MEMORY_SIZE;
} else {
- mapcache->max_mcache_size = MCACHE_MAX_SIZE;
+ max_mcache_size = MCACHE_MAX_SIZE;
}
}
+ mapcache = xen_map_cache_init_single(f, opaque, max_mcache_size);
setrlimit(RLIMIT_AS, &rlimit_as);
-
- mapcache->nr_buckets =
- (((mapcache->max_mcache_size >> XC_PAGE_SHIFT) +
- (1UL << (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT)) - 1) >>
- (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT));
-
- size = mapcache->nr_buckets * sizeof (MapCacheEntry);
- size = (size + XC_PAGE_SIZE - 1) & ~(XC_PAGE_SIZE - 1);
- trace_xen_map_cache_init(mapcache->nr_buckets, size);
- mapcache->entry = g_malloc0(size);
}
-static void xen_remap_bucket(MapCacheEntry *entry,
+static void xen_remap_bucket(MapCache *mc,
+ MapCacheEntry *entry,
void *vaddr,
hwaddr size,
hwaddr address_index,
g_free(err);
}
-static uint8_t *xen_map_cache_unlocked(hwaddr phys_addr, hwaddr size,
- uint8_t lock, bool dma)
+static uint8_t *xen_map_cache_unlocked(MapCache *mc,
+ hwaddr phys_addr, hwaddr size,
+ uint8_t lock, bool dma, bool is_write)
{
MapCacheEntry *entry, *pentry = NULL,
*free_entry = NULL, *free_pentry = NULL;
test_bit_size = XC_PAGE_SIZE;
}
- if (mapcache->last_entry != NULL &&
- mapcache->last_entry->paddr_index == address_index &&
+ if (mc->last_entry != NULL &&
+ mc->last_entry->paddr_index == address_index &&
!lock && !size &&
test_bits(address_offset >> XC_PAGE_SHIFT,
test_bit_size >> XC_PAGE_SHIFT,
- mapcache->last_entry->valid_mapping)) {
+ mc->last_entry->valid_mapping)) {
trace_xen_map_cache_return(
- mapcache->last_entry->vaddr_base + address_offset
+ mc->last_entry->vaddr_base + address_offset
);
- return mapcache->last_entry->vaddr_base + address_offset;
+ return mc->last_entry->vaddr_base + address_offset;
}
/* size is always a multiple of MCACHE_BUCKET_SIZE */
cache_size = MCACHE_BUCKET_SIZE;
}
- entry = &mapcache->entry[address_index % mapcache->nr_buckets];
+ entry = &mc->entry[address_index % mc->nr_buckets];
while (entry && (lock || entry->lock) && entry->vaddr_base &&
(entry->paddr_index != address_index || entry->size != cache_size ||
if (!entry) {
entry = g_new0(MapCacheEntry, 1);
pentry->next = entry;
- xen_remap_bucket(entry, NULL, cache_size, address_index, dummy);
+ xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy);
} else if (!entry->lock) {
if (!entry->vaddr_base || entry->paddr_index != address_index ||
entry->size != cache_size ||
!test_bits(address_offset >> XC_PAGE_SHIFT,
test_bit_size >> XC_PAGE_SHIFT,
entry->valid_mapping)) {
- xen_remap_bucket(entry, NULL, cache_size, address_index, dummy);
+ xen_remap_bucket(mc, entry, NULL, cache_size, address_index, dummy);
}
}
if(!test_bits(address_offset >> XC_PAGE_SHIFT,
test_bit_size >> XC_PAGE_SHIFT,
entry->valid_mapping)) {
- mapcache->last_entry = NULL;
+ mc->last_entry = NULL;
#ifdef XEN_COMPAT_PHYSMAP
- if (!translated && mapcache->phys_offset_to_gaddr) {
- phys_addr = mapcache->phys_offset_to_gaddr(phys_addr, size);
+ if (!translated && mc->phys_offset_to_gaddr) {
+ phys_addr = mc->phys_offset_to_gaddr(phys_addr, size);
translated = true;
goto tryagain;
}
return NULL;
}
- mapcache->last_entry = entry;
+ mc->last_entry = entry;
if (lock) {
MapCacheRev *reventry = g_new0(MapCacheRev, 1);
entry->lock++;
abort();
}
reventry->dma = dma;
- reventry->vaddr_req = mapcache->last_entry->vaddr_base + address_offset;
- reventry->paddr_index = mapcache->last_entry->paddr_index;
+ reventry->vaddr_req = mc->last_entry->vaddr_base + address_offset;
+ reventry->paddr_index = mc->last_entry->paddr_index;
reventry->size = entry->size;
- QTAILQ_INSERT_HEAD(&mapcache->locked_entries, reventry, next);
+ QTAILQ_INSERT_HEAD(&mc->locked_entries, reventry, next);
}
trace_xen_map_cache_return(
- mapcache->last_entry->vaddr_base + address_offset
+ mc->last_entry->vaddr_base + address_offset
);
- return mapcache->last_entry->vaddr_base + address_offset;
+ return mc->last_entry->vaddr_base + address_offset;
}
-uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size,
- uint8_t lock, bool dma)
+uint8_t *xen_map_cache(MemoryRegion *mr,
+ hwaddr phys_addr, hwaddr size,
+ uint8_t lock, bool dma,
+ bool is_write)
{
uint8_t *p;
- mapcache_lock();
- p = xen_map_cache_unlocked(phys_addr, size, lock, dma);
- mapcache_unlock();
+ mapcache_lock(mapcache);
+ p = xen_map_cache_unlocked(mapcache, phys_addr, size, lock, dma, is_write);
+ mapcache_unlock(mapcache);
return p;
}
-ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
+static ram_addr_t xen_ram_addr_from_mapcache_single(MapCache *mc, void *ptr)
{
MapCacheEntry *entry = NULL;
MapCacheRev *reventry;
ram_addr_t raddr;
int found = 0;
- mapcache_lock();
- QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
+ mapcache_lock(mc);
+ QTAILQ_FOREACH(reventry, &mc->locked_entries, next) {
if (reventry->vaddr_req == ptr) {
paddr_index = reventry->paddr_index;
size = reventry->size;
}
if (!found) {
trace_xen_ram_addr_from_mapcache_not_found(ptr);
- QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
- trace_xen_ram_addr_from_mapcache_found(reventry->paddr_index,
- reventry->vaddr_req);
- }
- abort();
- return 0;
+ mapcache_unlock(mc);
+ return RAM_ADDR_INVALID;
}
- entry = &mapcache->entry[paddr_index % mapcache->nr_buckets];
+ entry = &mc->entry[paddr_index % mc->nr_buckets];
while (entry && (entry->paddr_index != paddr_index || entry->size != size)) {
entry = entry->next;
}
if (!entry) {
trace_xen_ram_addr_from_mapcache_not_in_cache(ptr);
- raddr = 0;
+ raddr = RAM_ADDR_INVALID;
} else {
raddr = (reventry->paddr_index << MCACHE_BUCKET_SHIFT) +
((unsigned long) ptr - (unsigned long) entry->vaddr_base);
}
- mapcache_unlock();
+ mapcache_unlock(mc);
return raddr;
}
-static void xen_invalidate_map_cache_entry_unlocked(uint8_t *buffer)
+ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
+{
+ return xen_ram_addr_from_mapcache_single(mapcache, ptr);
+}
+
+static void xen_invalidate_map_cache_entry_unlocked(MapCache *mc,
+ uint8_t *buffer)
{
MapCacheEntry *entry = NULL, *pentry = NULL;
MapCacheRev *reventry;
hwaddr size;
int found = 0;
- QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
+ QTAILQ_FOREACH(reventry, &mc->locked_entries, next) {
if (reventry->vaddr_req == buffer) {
paddr_index = reventry->paddr_index;
size = reventry->size;
}
if (!found) {
trace_xen_invalidate_map_cache_entry_unlocked_not_found(buffer);
- QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
+ QTAILQ_FOREACH(reventry, &mc->locked_entries, next) {
trace_xen_invalidate_map_cache_entry_unlocked_found(
reventry->paddr_index,
reventry->vaddr_req
}
return;
}
- QTAILQ_REMOVE(&mapcache->locked_entries, reventry, next);
+ QTAILQ_REMOVE(&mc->locked_entries, reventry, next);
g_free(reventry);
- if (mapcache->last_entry != NULL &&
- mapcache->last_entry->paddr_index == paddr_index) {
- mapcache->last_entry = NULL;
+ if (mc->last_entry != NULL &&
+ mc->last_entry->paddr_index == paddr_index) {
+ mc->last_entry = NULL;
}
- entry = &mapcache->entry[paddr_index % mapcache->nr_buckets];
+ entry = &mc->entry[paddr_index % mc->nr_buckets];
while (entry && (entry->paddr_index != paddr_index || entry->size != size)) {
pentry = entry;
entry = entry->next;
{
XenMapCacheData *data = opaque;
- mapcache_lock();
- xen_invalidate_map_cache_entry_unlocked(data->buffer);
- mapcache_unlock();
+ mapcache_lock(mapcache);
+ xen_invalidate_map_cache_entry_unlocked(mapcache, data->buffer);
+ mapcache_unlock(mapcache);
aio_co_wake(data->co);
}
xen_invalidate_map_cache_entry_bh, &data);
qemu_coroutine_yield();
} else {
- mapcache_lock();
- xen_invalidate_map_cache_entry_unlocked(buffer);
- mapcache_unlock();
+ mapcache_lock(mapcache);
+ xen_invalidate_map_cache_entry_unlocked(mapcache, buffer);
+ mapcache_unlock(mapcache);
}
}
-void xen_invalidate_map_cache(void)
+static void xen_invalidate_map_cache_single(MapCache *mc)
{
unsigned long i;
MapCacheRev *reventry;
- /* Flush pending AIO before destroying the mapcache */
- bdrv_drain_all();
-
- mapcache_lock();
+ mapcache_lock(mc);
- QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
+ QTAILQ_FOREACH(reventry, &mc->locked_entries, next) {
if (!reventry->dma) {
continue;
}
reventry->vaddr_req);
}
- for (i = 0; i < mapcache->nr_buckets; i++) {
- MapCacheEntry *entry = &mapcache->entry[i];
+ for (i = 0; i < mc->nr_buckets; i++) {
+ MapCacheEntry *entry = &mc->entry[i];
if (entry->vaddr_base == NULL) {
continue;
entry->valid_mapping = NULL;
}
- mapcache->last_entry = NULL;
+ mc->last_entry = NULL;
+
+ mapcache_unlock(mc);
+}
+
+void xen_invalidate_map_cache(void)
+{
+ /* Flush pending AIO before destroying the mapcache */
+ bdrv_drain_all();
- mapcache_unlock();
+ xen_invalidate_map_cache_single(mapcache);
}
-static uint8_t *xen_replace_cache_entry_unlocked(hwaddr old_phys_addr,
+static uint8_t *xen_replace_cache_entry_unlocked(MapCache *mc,
+ hwaddr old_phys_addr,
hwaddr new_phys_addr,
hwaddr size)
{
cache_size += MCACHE_BUCKET_SIZE - (cache_size % MCACHE_BUCKET_SIZE);
}
- entry = &mapcache->entry[address_index % mapcache->nr_buckets];
+ entry = &mc->entry[address_index % mc->nr_buckets];
while (entry && !(entry->paddr_index == address_index &&
entry->size == cache_size)) {
entry = entry->next;
trace_xen_replace_cache_entry_dummy(old_phys_addr, new_phys_addr);
- xen_remap_bucket(entry, entry->vaddr_base,
+ xen_remap_bucket(mc, entry, entry->vaddr_base,
cache_size, address_index, false);
if (!test_bits(address_offset >> XC_PAGE_SHIFT,
test_bit_size >> XC_PAGE_SHIFT,
{
uint8_t *p;
- mapcache_lock();
- p = xen_replace_cache_entry_unlocked(old_phys_addr, new_phys_addr, size);
- mapcache_unlock();
+ mapcache_lock(mapcache);
+ p = xen_replace_cache_entry_unlocked(mapcache, old_phys_addr,
+ new_phys_addr, size);
+ mapcache_unlock(mapcache);
return p;
}
config XTENSA_SIM
+ default y
+ depends on XTENSA
bool
config XTENSA_VIRT
bool
+ default y
+ depends on XTENSA
select XTENSA_SIM
select PCI_EXPRESS_GENERIC_BRIDGE
select PCI_DEVICES
config XTENSA_XTFPGA
bool
+ default y
+ depends on XTENSA
select OPENCORES_ETH
select PFLASH_CFI01
select SERIAL
#ifndef CPU_ALL_H
#define CPU_ALL_H
+#include "exec/page-protection.h"
#include "exec/cpu-common.h"
#include "exec/memory.h"
#include "exec/tswap.h"
#ifdef TARGET_PAGE_BITS_VARY
# include "exec/page-vary.h"
extern const TargetPageBits target_page;
-#ifdef CONFIG_DEBUG_TCG
-#define TARGET_PAGE_BITS ({ assert(target_page.decided); target_page.bits; })
-#define TARGET_PAGE_MASK ({ assert(target_page.decided); \
- (target_long)target_page.mask; })
+# ifdef CONFIG_DEBUG_TCG
+# define TARGET_PAGE_BITS ({ assert(target_page.decided); \
+ target_page.bits; })
+# define TARGET_PAGE_MASK ({ assert(target_page.decided); \
+ (target_long)target_page.mask; })
+# else
+# define TARGET_PAGE_BITS target_page.bits
+# define TARGET_PAGE_MASK ((target_long)target_page.mask)
+# endif
+# define TARGET_PAGE_SIZE (-(int)TARGET_PAGE_MASK)
#else
-#define TARGET_PAGE_BITS target_page.bits
-#define TARGET_PAGE_MASK ((target_long)target_page.mask)
-#endif
-#define TARGET_PAGE_SIZE (-(int)TARGET_PAGE_MASK)
-#else
-#define TARGET_PAGE_BITS_MIN TARGET_PAGE_BITS
-#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
-#define TARGET_PAGE_MASK ((target_long)-1 << TARGET_PAGE_BITS)
+# define TARGET_PAGE_BITS_MIN TARGET_PAGE_BITS
+# define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
+# define TARGET_PAGE_MASK ((target_long)-1 << TARGET_PAGE_BITS)
#endif
#define TARGET_PAGE_ALIGN(addr) ROUND_UP((addr), TARGET_PAGE_SIZE)
-#if defined(CONFIG_BSD) && defined(CONFIG_USER_ONLY)
-/* FIXME: Code that sets/uses this is broken and needs to go away. */
-#define PAGE_RESERVED 0x0100
-#endif
-/*
- * For linux-user, indicates that the page is mapped with the same semantics
- * in both guest and host.
- */
-#define PAGE_PASSTHROUGH 0x0800
-
#if defined(CONFIG_USER_ONLY)
void page_dump(FILE *f);
#endif
#include "hw/core/cpu.h"
#include "tcg/debug-assert.h"
+#include "exec/page-protection.h"
#define EXCP_INTERRUPT 0x10000 /* async interruption */
#define EXCP_HLT 0x10001 /* hlt instruction reached */
void list_cpus(void);
#ifdef CONFIG_TCG
+
+bool tcg_cflags_has(CPUState *cpu, uint32_t flags);
+void tcg_cflags_set(CPUState *cpu, uint32_t flags);
+
+/* current cflags for hashing/comparison */
+uint32_t curr_cflags(CPUState *cpu);
+
/**
* cpu_unwind_state_data:
* @cpu: the cpu context
G_NORETURN void cpu_loop_exit(CPUState *cpu);
G_NORETURN void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc);
-/* same as PROT_xxx */
-#define PAGE_READ 0x0001
-#define PAGE_WRITE 0x0002
-#define PAGE_EXEC 0x0004
-#define PAGE_BITS (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
-#define PAGE_VALID 0x0008
-/*
- * Original state of the write flag (used when tracking self-modifying code)
- */
-#define PAGE_WRITE_ORG 0x0010
-/*
- * Invalidate the TLB entry immediately, helpful for s390x
- * Low-Address-Protection. Used with PAGE_WRITE in tlb_set_page_with_attrs()
- */
-#define PAGE_WRITE_INV 0x0020
-/* For use with page_set_flags: page is being replaced; target_data cleared. */
-#define PAGE_RESET 0x0040
-/* For linux-user, indicates that the page is MAP_ANON. */
-#define PAGE_ANON 0x0080
-
-/* Target-specific bits that will be used via page_get_flags(). */
-#define PAGE_TARGET_1 0x0200
-#define PAGE_TARGET_2 0x0400
-
-/*
- * For linux-user, indicates that the page is mapped with the same semantics
- * in both guest and host.
- */
-#define PAGE_PASSTHROUGH 0x0800
-
/* accel/tcg/cpu-exec.c */
int cpu_exec(CPUState *cpu);
#endif
}
-/* current cflags for hashing/comparison */
-uint32_t curr_cflags(CPUState *cpu);
-
/* TranslationBlock invalidate API */
void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t last);
--- /dev/null
+/*
+ * QEMU page protection definitions.
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+#ifndef EXEC_PAGE_PROT_COMMON_H
+#define EXEC_PAGE_PROT_COMMON_H
+
+/* same as PROT_xxx */
+#define PAGE_READ 0x0001
+#define PAGE_WRITE 0x0002
+#define PAGE_EXEC 0x0004
+#define PAGE_RWX (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
+#define PAGE_VALID 0x0008
+/*
+ * Original state of the write flag (used when tracking self-modifying code)
+ */
+#define PAGE_WRITE_ORG 0x0010
+/*
+ * Invalidate the TLB entry immediately, helpful for s390x
+ * Low-Address-Protection. Used with PAGE_WRITE in tlb_set_page_with_attrs()
+ */
+#define PAGE_WRITE_INV 0x0020
+/* For use with page_set_flags: page is being replaced; target_data cleared. */
+#define PAGE_RESET 0x0040
+/* For linux-user, indicates that the page is MAP_ANON. */
+#define PAGE_ANON 0x0080
+
+/* Target-specific bits that will be used via page_get_flags(). */
+#define PAGE_TARGET_1 0x0200
+#define PAGE_TARGET_2 0x0400
+
+/*
+ * For linux-user, indicates that the page is mapped with the same semantics
+ * in both guest and host.
+ */
+#define PAGE_PASSTHROUGH 0x0800
+
+#endif
#include "exec/memattrs.h"
#include "exec/mmu-access-type.h"
#include "exec/tlb-common.h"
+#include "qapi/qapi-types-machine.h"
#include "qapi/qapi-types-run-state.h"
#include "qemu/bitmap.h"
#include "qemu/rcu_queue.h"
typedef struct CPUWatchpoint CPUWatchpoint;
+/* see physmem.c */
+struct CPUAddressSpace;
+
+/* see accel/tcg/tb-jmp-cache.h */
+struct CPUJumpCache;
+
/* see accel-cpu.h */
struct AccelCPUClass;
} u16;
} IcountDecr;
-/*
- * Elements of CPUState most efficiently accessed from CPUArchState,
- * via small negative offsets.
+/**
+ * CPUNegativeOffsetState: Elements of CPUState most efficiently accessed
+ * from CPUArchState, via small negative offsets.
+ * @can_do_io: True if memory-mapped IO is allowed.
+ * @plugin_mem_cbs: active plugin memory callbacks
*/
typedef struct CPUNegativeOffsetState {
CPUTLB tlb;
+#ifdef CONFIG_PLUGIN
+ /*
+ * The callback pointer are accessed via TCG (see gen_empty_mem_helper).
+ */
+ GArray *plugin_mem_cbs;
+#endif
IcountDecr icount_decr;
bool can_do_io;
} CPUNegativeOffsetState;
* @crash_occurred: Indicates the OS reported a crash (panic) for this CPU
* @singlestep_enabled: Flags for single-stepping.
* @icount_extra: Instructions until next timer event.
- * @neg.can_do_io: True if memory-mapped IO is allowed.
* @cpu_ases: Pointer to array of CPUAddressSpaces (which define the
* AddressSpaces this CPU has)
* @num_ases: number of CPUAddressSpaces in @cpu_ases
* @kvm_fd: vCPU file descriptor for KVM.
* @work_mutex: Lock to prevent multiple access to @work_list.
* @work_list: List of pending asynchronous work.
- * @plugin_mem_cbs: active plugin memory callbacks
* @plugin_state: per-CPU plugin state
* @ignore_memory_transaction_failures: Cached copy of the MachineState
* flag of the same name: allows the board to suppress calling of the
QemuMutex work_mutex;
QSIMPLEQ_HEAD(, qemu_work_item) work_list;
- CPUAddressSpace *cpu_ases;
+ struct CPUAddressSpace *cpu_ases;
int num_ases;
AddressSpace *as;
MemoryRegion *memory;
- CPUJumpCache *tb_jmp_cache;
+ struct CPUJumpCache *tb_jmp_cache;
GArray *gdb_regs;
int gdb_num_regs;
QemuLockCnt in_ioctl_lock;
#ifdef CONFIG_PLUGIN
- /*
- * The callback pointer stays in the main CPUState as it is
- * accessed via TCG (see gen_empty_mem_helper).
- */
- GArray *plugin_mem_cbs;
CPUPluginState *plugin_state;
#endif
void cpu_watchpoint_remove_all(CPUState *cpu, int mask);
#endif
-/**
- * cpu_plugin_mem_cbs_enabled() - are plugin memory callbacks enabled?
- * @cs: CPUState pointer
- *
- * The memory callbacks are installed if a plugin has instrumented an
- * instruction for memory. This can be useful to know if you want to
- * force a slow path for a series of memory accesses.
- */
-static inline bool cpu_plugin_mem_cbs_enabled(const CPUState *cpu)
-{
-#ifdef CONFIG_PLUGIN
- return !!cpu->plugin_mem_cbs;
-#else
- return false;
-#endif
-}
-
/**
* cpu_get_address_space:
* @cpu: CPU to get address space from
/* i8259.c */
+typedef struct PICCommonState PICCommonState;
+
extern PICCommonState *isa_pic;
/*
typedef void (*FWCfgCallback)(void *opaque);
typedef void (*FWCfgWriteCallback)(void *opaque, off_t start, size_t len);
+typedef struct FWCfgEntry FWCfgEntry;
+
struct FWCfgState {
/*< private >*/
SysBusDevice parent_obj;
#include "hw/pci/pcie_sriov.h"
#include "hw/hotplug.h"
+typedef struct PCIEPort PCIEPort;
+typedef struct PCIESlot PCIESlot;
+
typedef enum {
/* these bits must match the bits in Slot Control/Status registers.
* PCI_EXP_HP_EV_xxx = PCI_EXP_SLTCTL_xxxE = PCI_EXP_SLTSTA_xxx
/* definitions which PCIExpressDevice uses */
+/* error */
+typedef struct PCIEAERErr {
+ uint32_t status; /* error status bits */
+ uint16_t source_id; /* bdf */
+
+#define PCIE_AER_ERR_IS_CORRECTABLE 0x1 /* correctable/uncorrectable */
+#define PCIE_AER_ERR_MAYBE_ADVISORY 0x2 /* maybe advisory non-fatal */
+#define PCIE_AER_ERR_HEADER_VALID 0x4 /* TLP header is logged */
+#define PCIE_AER_ERR_TLP_PREFIX_PRESENT 0x8 /* TLP Prefix is logged */
+ uint16_t flags;
+
+ uint32_t header[4]; /* TLP header */
+ uint32_t prefix[4]; /* TLP header prefix */
+} PCIEAERErr;
+
/* AER log */
-struct PCIEAERLog {
+typedef struct PCIEAERLog {
/* This structure is saved/loaded.
So explicitly size them instead of unsigned int */
/* Error log. log_max-sized array */
PCIEAERErr *log;
-};
+} PCIEAERLog;
/* aer error message: error signaling message has only error severity and
source id. See 2.2.8.3 error signaling messages */
-struct PCIEAERMsg {
+typedef struct PCIEAERMsg {
/*
* PCI_ERR_ROOT_CMD_{COR, NONFATAL, FATAL}_EN
* = PCI_EXP_DEVCTL_{CERE, NFERE, FERE}
uint32_t severity;
uint16_t source_id; /* bdf */
-};
+} PCIEAERMsg;
static inline bool
pcie_aer_msg_is_uncor(const PCIEAERMsg *msg)
msg->severity == PCI_ERR_ROOT_CMD_FATAL_EN;
}
-/* error */
-struct PCIEAERErr {
- uint32_t status; /* error status bits */
- uint16_t source_id; /* bdf */
-
-#define PCIE_AER_ERR_IS_CORRECTABLE 0x1 /* correctable/uncorrectable */
-#define PCIE_AER_ERR_MAYBE_ADVISORY 0x2 /* maybe advisory non-fatal */
-#define PCIE_AER_ERR_HEADER_VALID 0x4 /* TLP header is logged */
-#define PCIE_AER_ERR_TLP_PREFIX_PRESENT 0x8 /* TLP Prefix is logged */
- uint16_t flags;
-
- uint32_t header[4]; /* TLP header */
- uint32_t prefix[4]; /* TLP header prefix */
-};
-
extern const VMStateDescription vmstate_pcie_aer_log;
int pcie_aer_init(PCIDevice *dev, uint8_t cap_ver, uint16_t offset,
#include "hw/pci/pci.h"
-struct PCIESriovPF {
+typedef struct PCIESriovPF {
uint16_t num_vfs; /* Number of virtual functions created */
uint8_t vf_bar_type[PCI_NUM_REGIONS]; /* Store type for each VF bar */
const char *vfname; /* Reference to the device type used for the VFs */
PCIDevice **vf; /* Pointer to an array of num_vfs VF devices */
-};
+} PCIESriovPF;
-struct PCIESriovVF {
+typedef struct PCIESriovVF {
PCIDevice *pf; /* Pointer back to owner physical function */
uint16_t vf_number; /* Logical VF number of this function */
-};
+} PCIESriovVF;
void pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
const char *vfname, uint16_t vf_dev_id,
MemReentrancyGuard mem_reentrancy_guard;
};
+typedef struct DeviceListener DeviceListener;
struct DeviceListener {
void (*realize)(DeviceListener *listener, DeviceState *dev);
void (*unrealize)(DeviceListener *listener, DeviceState *dev);
#ifndef S390X_ADAPTER_H
#define S390X_ADAPTER_H
-struct AdapterInfo {
+typedef struct AdapterInfo {
uint64_t ind_addr;
uint64_t summary_addr;
uint64_t ind_offset;
uint32_t summary_offset;
uint32_t adapter_id;
-};
+} AdapterInfo;
#endif
#ifndef MONITOR_HMP_TARGET_H
#define MONITOR_HMP_TARGET_H
-#include "cpu.h"
-
-#define MD_TLONG 0
-#define MD_I32 1
+typedef struct MonitorDef MonitorDef;
+#ifdef COMPILING_PER_TARGET
+#include "cpu.h"
struct MonitorDef {
const char *name;
int offset;
int val);
int type;
};
+#endif
+
+#define MD_TLONG 0
+#define MD_I32 1
const MonitorDef *target_monitor_defs(void);
int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval);
#include "qapi/qapi-types-net.h"
#include "qemu/timer.h"
-struct AnnounceTimer {
+typedef struct AnnounceTimer {
QEMUTimer *tm;
AnnounceParameters params;
QEMUClockType type;
int round;
-};
+} AnnounceTimer;
/* Returns: update the timer to the next time point */
int64_t qemu_announce_timer_step(AnnounceTimer *timer);
static inline unsigned long *bitmap_try_new(long nbits)
{
- long len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
- return g_try_malloc0(len);
+ long nelem = BITS_TO_LONGS(nbits);
+ return g_try_new0(unsigned long, nelem);
}
static inline unsigned long *bitmap_new(long nbits)
{
- unsigned long *ptr = bitmap_try_new(nbits);
- if (ptr == NULL) {
- abort();
- }
- return ptr;
+ long nelem = BITS_TO_LONGS(nbits);
+ return g_new0(unsigned long, nelem);
}
static inline void bitmap_zero(unsigned long *dst, long nbits)
static inline unsigned long *bitmap_zero_extend(unsigned long *old,
long old_nbits, long new_nbits)
{
- long new_len = BITS_TO_LONGS(new_nbits) * sizeof(unsigned long);
- unsigned long *new = g_realloc(old, new_len);
- bitmap_clear(new, old_nbits, new_nbits - old_nbits);
- return new;
+ long new_nelem = BITS_TO_LONGS(new_nbits);
+ unsigned long *ptr = g_renew(unsigned long, old, new_nelem);
+ bitmap_clear(ptr, old_nbits, new_nbits - old_nbits);
+ return ptr;
}
void bitmap_to_le(unsigned long *dst, const unsigned long *src,
mutex->holder == qemu_coroutine_self());
}
+#include "qemu/lockable.h"
+
/**
* CoQueues are a mechanism to queue coroutines in order to continue executing
* them later. They are similar to condition variables, but they need help
*/
void qemu_coroutine_dec_pool_size(unsigned int additional_pool_size);
-#include "qemu/lockable.h"
-
/**
* Sends a (part of) iovec down a socket, yielding when the socket is full, or
* Receives data into a (part of) iovec from a socket,
typedef void QemuLockUnlockFunc(void *);
-struct QemuLockable {
+typedef struct QemuLockable {
void *object;
QemuLockUnlockFunc *lock;
QemuLockUnlockFunc *unlock;
-};
+} QemuLockable;
static inline __attribute__((__always_inline__)) QemuLockable *
qemu_make_lockable(void *x, QemuLockable *lockable)
QEMU_OPT_SIZE, /* size, accepts (K)ilo, (M)ega, (G)iga, (T)era postfix */
};
+typedef struct QemuOpt QemuOpt;
+
typedef struct QemuOptDesc {
const char *name;
enum QemuOptType type;
static inline void qemu_plugin_disable_mem_helpers(CPUState *cpu)
{
- cpu->plugin_mem_cbs = NULL;
+ cpu->neg.plugin_mem_cbs = NULL;
}
/**
*/
typedef struct AccelCPUState AccelCPUState;
typedef struct AccelState AccelState;
-typedef struct AdapterInfo AdapterInfo;
typedef struct AddressSpace AddressSpace;
typedef struct AioContext AioContext;
typedef struct Aml Aml;
-typedef struct AnnounceTimer AnnounceTimer;
typedef struct ArchCPU ArchCPU;
typedef struct BdrvDirtyBitmap BdrvDirtyBitmap;
typedef struct BdrvDirtyBitmapIter BdrvDirtyBitmapIter;
typedef struct BusState BusState;
typedef struct Chardev Chardev;
typedef struct Clock Clock;
-typedef struct CompatProperty CompatProperty;
typedef struct ConfidentialGuestSupport ConfidentialGuestSupport;
-typedef struct CPUAddressSpace CPUAddressSpace;
typedef struct CPUArchState CPUArchState;
typedef struct CPUPluginState CPUPluginState;
-typedef struct CpuInfoFast CpuInfoFast;
-typedef struct CPUJumpCache CPUJumpCache;
typedef struct CPUState CPUState;
-typedef struct CPUTLBEntryFull CPUTLBEntryFull;
-typedef struct DeviceListener DeviceListener;
typedef struct DeviceState DeviceState;
typedef struct DirtyBitmapSnapshot DirtyBitmapSnapshot;
typedef struct DisplayChangeListener DisplayChangeListener;
typedef struct Error Error;
typedef struct EventNotifier EventNotifier;
typedef struct FlatView FlatView;
-typedef struct FWCfgEntry FWCfgEntry;
-typedef struct FWCfgIoState FWCfgIoState;
-typedef struct FWCfgMemState FWCfgMemState;
typedef struct FWCfgState FWCfgState;
-typedef struct GraphicHwOps GraphicHwOps;
typedef struct HostMemoryBackend HostMemoryBackend;
typedef struct I2CBus I2CBus;
typedef struct I2SCodec I2SCodec;
typedef struct MigrationIncomingState MigrationIncomingState;
typedef struct MigrationState MigrationState;
typedef struct Monitor Monitor;
-typedef struct MonitorDef MonitorDef;
typedef struct MSIMessage MSIMessage;
typedef struct NetClientState NetClientState;
typedef struct NetFilterState NetFilterState;
typedef struct NICInfo NICInfo;
-typedef struct NodeInfo NodeInfo;
-typedef struct NumaNodeMem NumaNodeMem;
typedef struct Object Object;
typedef struct ObjectClass ObjectClass;
typedef struct PCIBridge PCIBridge;
typedef struct PCIBus PCIBus;
typedef struct PCIDevice PCIDevice;
-typedef struct PCIEAERErr PCIEAERErr;
-typedef struct PCIEAERLog PCIEAERLog;
-typedef struct PCIEAERMsg PCIEAERMsg;
typedef struct PCIEPort PCIEPort;
typedef struct PCIESlot PCIESlot;
-typedef struct PCIESriovPF PCIESriovPF;
-typedef struct PCIESriovVF PCIESriovVF;
typedef struct PCIExpressDevice PCIExpressDevice;
typedef struct PCIExpressHost PCIExpressHost;
typedef struct PCIHostDeviceAddress PCIHostDeviceAddress;
typedef struct PCIHostState PCIHostState;
-typedef struct PICCommonState PICCommonState;
-typedef struct PostcopyDiscardState PostcopyDiscardState;
typedef struct Property Property;
typedef struct PropertyInfo PropertyInfo;
typedef struct QBool QBool;
typedef struct QemuConsole QemuConsole;
typedef struct QEMUCursor QEMUCursor;
typedef struct QEMUFile QEMUFile;
-typedef struct QemuLockable QemuLockable;
typedef struct QemuMutex QemuMutex;
-typedef struct QemuOpt QemuOpt;
typedef struct QemuOpts QemuOpts;
typedef struct QemuOptsList QemuOptsList;
typedef struct QEMUSGList QEMUSGList;
typedef struct SSIBus SSIBus;
typedef struct TCGCPUOps TCGCPUOps;
typedef struct TCGHelperInfo TCGHelperInfo;
+typedef struct TaskState TaskState;
typedef struct TranslationBlock TranslationBlock;
typedef struct VirtIODevice VirtIODevice;
typedef struct Visitor Visitor;
#include "exec/cpu-common.h"
#include "exec/cpu-defs.h"
#include "exec/tswap.h"
+#include "exec/page-protection.h"
#define get_user_u64(val, addr) \
({ uint64_t val_ = 0; \
}
}
+int kvm_irqchip_get_virq(KVMState *s);
void kvm_irqchip_release_virq(KVMState *s, int virq);
-int kvm_irqchip_add_adapter_route(KVMState *s, AdapterInfo *adapter);
-int kvm_irqchip_add_hv_sint_route(KVMState *s, uint32_t vcpu, uint32_t sint);
+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);
#define UINT16_BITS 16
-struct NodeInfo {
+typedef struct NodeInfo {
uint64_t node_mem;
struct HostMemoryBackend *node_memdev;
bool present;
uint8_t lb_info_provided;
uint16_t initiator;
uint8_t distance[MAX_NODES];
-};
+} NodeInfo;
-struct NumaNodeMem {
+typedef struct NumaNodeMem {
uint64_t node_mem;
uint64_t node_plugged_mem;
-};
+} NumaNodeMem;
struct HMAT_LB_Data {
uint8_t initiator;
void xen_map_cache_init(phys_offset_to_gaddr_t f,
void *opaque);
-uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size,
- uint8_t lock, bool dma);
+uint8_t *xen_map_cache(MemoryRegion *mr, hwaddr phys_addr, hwaddr size,
+ 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);
{
}
-static inline uint8_t *xen_map_cache(hwaddr phys_addr,
+static inline uint8_t *xen_map_cache(MemoryRegion *mr,
+ hwaddr phys_addr,
hwaddr size,
uint8_t lock,
- bool dma)
+ bool dma,
+ bool is_write)
{
abort();
}
#include "cpu_loop-common.h"
#include "signal-common.h"
#include "semihosting/common-semi.h"
+#include "exec/page-protection.h"
#include "target/arm/syndrome.h"
#define get_user_code_u32(x, gaddr, env) \
#include "qemu.h"
#include "user/tswap-target.h"
+#include "exec/page-protection.h"
#include "user/guest-base.h"
#include "user-internals.h"
#include "signal-common.h"
if (start_bss < align_bss) {
int flags = page_get_flags(start_bss);
- if (!(flags & PAGE_BITS)) {
+ if (!(flags & PAGE_RWX)) {
/*
* The whole address space of the executable was reserved
* at the start, therefore all pages will be VALID.
#include <sys/shm.h>
#include "trace.h"
#include "exec/log.h"
+#include "exec/page-protection.h"
#include "qemu.h"
#include "user-internals.h"
#include "user-mmap.h"
static int validate_prot_to_pageflags(int prot)
{
int valid = PROT_READ | PROT_WRITE | PROT_EXEC | TARGET_PROT_SEM;
- int page_flags = (prot & PAGE_BITS) | PAGE_VALID;
+ int page_flags = (prot & PAGE_RWX) | PAGE_VALID;
#ifdef TARGET_AARCH64
{
*/
if (ret != -1 && (flags & MAP_TYPE) != MAP_PRIVATE) {
CPUState *cpu = thread_cpu;
- if (!(cpu->tcg_cflags & CF_PARALLEL)) {
- cpu->tcg_cflags |= CF_PARALLEL;
+ if (!tcg_cflags_has(cpu, CF_PARALLEL)) {
+ tcg_cflags_set(cpu, CF_PARALLEL);
tb_flush(cpu);
}
}
* supported by the host -- anything that requires EXCP_ATOMIC will not
* be atomic with respect to an external process.
*/
- if (!(cpu->tcg_cflags & CF_PARALLEL)) {
- cpu->tcg_cflags |= CF_PARALLEL;
+ if (!tcg_cflags_has(cpu, CF_PARALLEL)) {
+ tcg_cflags_set(cpu, CF_PARALLEL);
tb_flush(cpu);
}
#include "syscall_defs.h"
#include "target_syscall.h"
+#include "accel/tcg/vcpu-state.h"
/*
* This is the size of the host kernel's sigset_t, needed where we make
target_siginfo_t info;
};
-typedef struct TaskState {
+struct TaskState {
pid_t ts_tid; /* tid (or pid) of this task */
#ifdef TARGET_ARM
# ifdef TARGET_ABI32
/* Start time of task after system boot in clock ticks */
uint64_t start_boottime;
-} TaskState;
-
-static inline TaskState *get_task_state(CPUState *cs)
-{
- return cs->opaque;
-}
+};
abi_long do_brk(abi_ulong new_brk);
int do_guest_openat(CPUArchState *cpu_env, int dirfd, const char *pathname,
#include "qemu/osdep.h"
#include "qemu/bitops.h"
#include "gdbstub/user.h"
+#include "exec/page-protection.h"
#include "hw/core/tcg-cpu-ops.h"
#include <sys/ucontext.h>
#include "qemu/plugin.h"
#include "tcg/startup.h"
#include "target_mman.h"
+#include "exec/page-protection.h"
#include <elf.h>
#include <endian.h>
#include <grp.h>
case PR_GET_TID_ADDRESS:
{
- TaskState *ts = env_cpu(env)->opaque;
+ TaskState *ts = get_task_state(env_cpu(env));
return put_user_ual(ts->child_tidptr, arg2);
}
* generate code for parallel execution and flush old translations.
* Do this now so that the copy gets CF_PARALLEL too.
*/
- if (!(cpu->tcg_cflags & CF_PARALLEL)) {
- cpu->tcg_cflags |= CF_PARALLEL;
+ if (!tcg_cflags_has(cpu, CF_PARALLEL)) {
+ tcg_cflags_set(cpu, CF_PARALLEL);
tb_flush(cpu);
}
static int open_self_maps_1(CPUArchState *env, int fd, bool smaps)
{
struct open_self_maps_data d = {
- .ts = env_cpu(env)->opaque,
+ .ts = get_task_state(env_cpu(env)),
.host_maps = read_self_maps(),
.fd = fd,
.smaps = smaps
}
endif
- accel_kconfig = []
+ target_kconfig = []
foreach sym: accelerators
if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
config_target += { sym: 'y' }
else
config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
endif
- accel_kconfig += [ sym + '=y' ]
+ target_kconfig += [ sym + '=y' ]
endif
endforeach
- if accel_kconfig.length() == 0
+ if target_kconfig.length() == 0
if default_targets
continue
endif
configuration: config_target_data)}
if target.endswith('-softmmu')
+ target_kconfig += 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'
+ target_kconfig += 'CONFIG_TARGET_BIG_ENDIAN=' + config_target['TARGET_BIG_ENDIAN']
+
config_input = meson.get_external_property(target, 'default')
config_devices_mak = target + '-config-devices.mak'
config_devices_mak = configure_file(
command: [minikconf,
get_option('default_devices') ? '--defconfig' : '--allnoconfig',
config_devices_mak, '@DEPFILE@', '@INPUT@',
- host_kconfig, accel_kconfig,
- 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
+ host_kconfig, target_kconfig])
config_devices_data = configuration_data()
config_devices = keyval.load(config_devices_mak)
#include "qapi/qapi-types-migration.h"
#include "qapi/qmp/json-writer.h"
#include "qemu/thread.h"
-#include "qemu/coroutine_int.h"
+#include "qemu/coroutine.h"
#include "io/channel.h"
#include "io/channel-buffer.h"
#include "net/announce.h"
*/
#define MAX_DISCARDS_PER_COMMAND 12
-struct PostcopyDiscardState {
+typedef struct PostcopyDiscardState {
const char *ramblock_name;
uint16_t cur_entry;
/*
uint64_t length_list[MAX_DISCARDS_PER_COMMAND];
unsigned int nsentwords;
unsigned int nsentcmds;
-};
+} PostcopyDiscardState;
static NotifierWithReturnList postcopy_notifier_list;
void qemu_plugin_vcpu_mem_cb(CPUState *cpu, uint64_t vaddr,
MemOpIdx oi, enum qemu_plugin_mem_rw rw)
{
- GArray *arr = cpu->plugin_mem_cbs;
+ GArray *arr = cpu->neg.plugin_mem_cbs;
size_t i;
if (arr == NULL) {
}
#ifdef __FreeBSD__
- g_autofree char *chpasswdata = g_strdup(rawpasswddata);
+ g_autofree char *chpasswddata = g_strdup(rawpasswddata);
const char *crypt_flag = crypted ? "-H" : "-h";
const char *argv[] = {"pw", "usermod", "-n", username,
crypt_flag, "0", NULL};
assert arg_type
argstr = '&arg, '
elif arg_type:
- assert not arg_type.variants
+ assert not arg_type.branches
for memb in arg_type.members:
assert not memb.ifcond.is_present()
if memb.need_has():
Initialize it with the function arguments defined in `gen_event_send`.
"""
- assert not typ.variants
+ assert not typ.branches
ret = mcgen('''
%(c_name)s param = {
''',
ret += '%s arg' % arg_type.c_param_type()
sep = ', '
elif arg_type:
- assert not arg_type.variants
+ assert not arg_type.branches
for memb in arg_type.members:
assert not memb.ifcond.is_present()
ret += sep
from .gen import QAPISchemaMonolithicCVisitor
from .schema import (
QAPISchema,
+ QAPISchemaAlternatives,
+ QAPISchemaBranches,
QAPISchemaArrayType,
QAPISchemaBuiltinType,
QAPISchemaEntity,
QAPISchemaObjectTypeMember,
QAPISchemaType,
QAPISchemaVariant,
- QAPISchemaVariants,
)
from .source import QAPISourceInfo
ifcond: QAPISchemaIfCond,
features: List[QAPISchemaFeature],
members: List[QAPISchemaObjectTypeMember],
- variants: Optional[QAPISchemaVariants]) -> None:
+ branches: Optional[QAPISchemaBranches]) -> None:
obj: SchemaInfoObject = {
'members': [self._gen_object_member(m) for m in members]
}
- if variants:
- obj['tag'] = variants.tag_member.name
- obj['variants'] = [self._gen_variant(v) for v in variants.variants]
+ if branches:
+ obj['tag'] = branches.tag_member.name
+ obj['variants'] = [self._gen_variant(v) for v in branches.variants]
self._gen_tree(name, 'object', obj, ifcond, features)
def visit_alternate_type(self, name: str, info: Optional[QAPISourceInfo],
ifcond: QAPISchemaIfCond,
features: List[QAPISchemaFeature],
- variants: QAPISchemaVariants) -> None:
+ alternatives: QAPISchemaAlternatives) -> None:
self._gen_tree(
name, 'alternate',
{'members': [Annotated({'type': self._use_type(m.type)},
m.ifcond)
- for m in variants.variants]},
+ for m in alternatives.variants]},
ifcond, features
)
features: List[QAPISchemaFeature],
base: Optional[QAPISchemaObjectType],
members: List[QAPISchemaObjectTypeMember],
- variants: Optional[QAPISchemaVariants],
+ branches: Optional[QAPISchemaBranches],
) -> None:
pass
ifcond: QAPISchemaIfCond,
features: List[QAPISchemaFeature],
members: List[QAPISchemaObjectTypeMember],
- variants: Optional[QAPISchemaVariants],
+ branches: Optional[QAPISchemaBranches],
) -> None:
pass
info: Optional[QAPISourceInfo],
ifcond: QAPISchemaIfCond,
features: List[QAPISchemaFeature],
- variants: QAPISchemaVariants,
+ alternatives: QAPISchemaAlternatives,
) -> None:
pass
features: Optional[List[QAPISchemaFeature]],
base: Optional[str],
local_members: List[QAPISchemaObjectTypeMember],
- variants: Optional[QAPISchemaVariants],
+ branches: Optional[QAPISchemaBranches],
):
- # struct has local_members, optional base, and no variants
- # union has base, variants, and no local_members
+ # struct has local_members, optional base, and no branches
+ # union has base, branches, and no local_members
super().__init__(name, info, doc, ifcond, features)
- self.meta = 'union' if variants else 'struct'
+ self.meta = 'union' if branches else 'struct'
for m in local_members:
m.set_defined_in(name)
- if variants is not None:
- variants.set_defined_in(name)
+ if branches is not None:
+ branches.set_defined_in(name)
self._base_name = base
self.base = None
self.local_members = local_members
- self.variants = variants
+ self.branches = branches
self.members: List[QAPISchemaObjectTypeMember]
self._check_complete = False
self.base = schema.resolve_type(self._base_name, self.info,
"'base'")
if (not isinstance(self.base, QAPISchemaObjectType)
- or self.base.variants):
+ or self.base.branches):
raise QAPISemError(
self.info,
"'base' requires a struct type, %s isn't"
# Cast down to the subtype.
members = cast(List[QAPISchemaObjectTypeMember], list(seen.values()))
- if self.variants:
- self.variants.check(schema, seen)
- self.variants.check_clash(self.info, seen)
+ if self.branches:
+ self.branches.check(schema, seen)
+ self.branches.check_clash(self.info, seen)
self.members = members
self._check_complete = True # mark completed
assert self._checked
for m in self.members:
m.check_clash(info, seen)
- if self.variants:
- self.variants.check_clash(info, seen)
+ if self.branches:
+ self.branches.check_clash(info, seen)
def connect_doc(self, doc: Optional[QAPIDoc] = None) -> None:
super().connect_doc(doc)
return self.name.startswith('q_')
def is_empty(self) -> bool:
- return not self.members and not self.variants
+ return not self.members and not self.branches
def has_conditional_members(self) -> bool:
return any(m.ifcond.is_present() for m in self.members)
super().visit(visitor)
visitor.visit_object_type(
self.name, self.info, self.ifcond, self.features,
- self.base, self.local_members, self.variants)
+ self.base, self.local_members, self.branches)
visitor.visit_object_type_flat(
self.name, self.info, self.ifcond, self.features,
- self.members, self.variants)
+ self.members, self.branches)
class QAPISchemaAlternateType(QAPISchemaType):
doc: Optional[QAPIDoc],
ifcond: Optional[QAPISchemaIfCond],
features: List[QAPISchemaFeature],
- variants: QAPISchemaVariants,
+ alternatives: QAPISchemaAlternatives,
):
super().__init__(name, info, doc, ifcond, features)
- assert variants.tag_member
- variants.set_defined_in(name)
- variants.tag_member.set_defined_in(self.name)
- self.variants = variants
+ assert alternatives.tag_member
+ alternatives.set_defined_in(name)
+ alternatives.tag_member.set_defined_in(self.name)
+ self.alternatives = alternatives
def check(self, schema: QAPISchema) -> None:
super().check(schema)
- self.variants.tag_member.check(schema)
- # Not calling self.variants.check_clash(), because there's nothing
- # to clash with
- self.variants.check(schema, {})
+ self.alternatives.tag_member.check(schema)
+ # Not calling self.alternatives.check_clash(), because there's
+ # nothing to clash with
+ self.alternatives.check(schema, {})
# Alternate branch names have no relation to the tag enum values;
# so we have to check for potential name collisions ourselves.
seen: Dict[str, QAPISchemaMember] = {}
types_seen: Dict[str, str] = {}
- for v in self.variants.variants:
+ for v in self.alternatives.variants:
v.check_clash(self.info, seen)
qtype = v.type.alternate_qtype()
if not qtype:
def connect_doc(self, doc: Optional[QAPIDoc] = None) -> None:
super().connect_doc(doc)
doc = doc or self.doc
- for v in self.variants.variants:
+ for v in self.alternatives.variants:
v.connect_doc(doc)
def c_type(self) -> str:
def visit(self, visitor: QAPISchemaVisitor) -> None:
super().visit(visitor)
visitor.visit_alternate_type(
- self.name, self.info, self.ifcond, self.features, self.variants)
+ self.name, self.info, self.ifcond, self.features,
+ self.alternatives)
class QAPISchemaVariants:
def __init__(
self,
- tag_name: Optional[str],
info: QAPISourceInfo,
- tag_member: Optional[QAPISchemaObjectTypeMember],
variants: List[QAPISchemaVariant],
):
- # Unions pass tag_name but not tag_member.
- # Alternates pass tag_member but not tag_name.
- # After check(), tag_member is always set.
- assert bool(tag_member) != bool(tag_name)
- assert (isinstance(tag_name, str) or
- isinstance(tag_member, QAPISchemaObjectTypeMember))
- self._tag_name = tag_name
self.info = info
- self._tag_member = tag_member
+ self.tag_member: QAPISchemaObjectTypeMember
self.variants = variants
- @property
- def tag_member(self) -> QAPISchemaObjectTypeMember:
- if self._tag_member is None:
- raise RuntimeError(
- "QAPISchemaVariants has no tag_member property until "
- "after check() has been run."
- )
- return self._tag_member
-
def set_defined_in(self, name: str) -> None:
for v in self.variants:
v.set_defined_in(name)
def check(
- self, schema: QAPISchema, seen: Dict[str, QAPISchemaMember]
+ self, schema: QAPISchema, seen: Dict[str, QAPISchemaMember]
) -> None:
- if self._tag_name: # union
- # We need to narrow the member type:
- tmp = seen.get(c_name(self._tag_name))
- assert tmp is None or isinstance(tmp, QAPISchemaObjectTypeMember)
- self._tag_member = tmp
-
- base = "'base'"
- # Pointing to the base type when not implicit would be
- # nice, but we don't know it here
- if not self._tag_member or self._tag_name != self._tag_member.name:
- raise QAPISemError(
- self.info,
- "discriminator '%s' is not a member of %s"
- % (self._tag_name, base))
- # Here we do:
- assert self.tag_member.defined_in
- base_type = schema.lookup_type(self.tag_member.defined_in)
- assert base_type
- if not base_type.is_implicit():
- base = "base type '%s'" % self.tag_member.defined_in
- if not isinstance(self.tag_member.type, QAPISchemaEnumType):
- raise QAPISemError(
- self.info,
- "discriminator member '%s' of %s must be of enum type"
- % (self._tag_name, base))
- if self.tag_member.optional:
- raise QAPISemError(
- self.info,
- "discriminator member '%s' of %s must not be optional"
- % (self._tag_name, base))
- if self.tag_member.ifcond.is_present():
- raise QAPISemError(
- self.info,
- "discriminator member '%s' of %s must not be conditional"
- % (self._tag_name, base))
- else: # alternate
- assert self._tag_member
- assert isinstance(self.tag_member.type, QAPISchemaEnumType)
- assert not self.tag_member.optional
- assert not self.tag_member.ifcond.is_present()
- if self._tag_name: # union
- # branches that are not explicitly covered get an empty type
- assert self.tag_member.defined_in
- cases = {v.name for v in self.variants}
- for m in self.tag_member.type.members:
- if m.name not in cases:
- v = QAPISchemaVariant(m.name, self.info,
- 'q_empty', m.ifcond)
- v.set_defined_in(self.tag_member.defined_in)
- self.variants.append(v)
+ for v in self.variants:
+ v.check(schema)
+
+
+class QAPISchemaBranches(QAPISchemaVariants):
+ def __init__(self,
+ info: QAPISourceInfo,
+ variants: List[QAPISchemaVariant],
+ tag_name: str):
+ super().__init__(info, variants)
+ self._tag_name = tag_name
+
+ def check(
+ self, schema: QAPISchema, seen: Dict[str, QAPISchemaMember]
+ ) -> None:
+ # We need to narrow the member type:
+ tag_member = seen.get(c_name(self._tag_name))
+ assert (tag_member is None
+ or isinstance(tag_member, QAPISchemaObjectTypeMember))
+
+ base = "'base'"
+ # Pointing to the base type when not implicit would be
+ # nice, but we don't know it here
+ if not tag_member or self._tag_name != tag_member.name:
+ raise QAPISemError(
+ self.info,
+ "discriminator '%s' is not a member of %s"
+ % (self._tag_name, base))
+ self.tag_member = tag_member
+ # Here we do:
+ assert tag_member.defined_in
+ base_type = schema.lookup_type(tag_member.defined_in)
+ assert base_type
+ if not base_type.is_implicit():
+ base = "base type '%s'" % tag_member.defined_in
+ if not isinstance(tag_member.type, QAPISchemaEnumType):
+ raise QAPISemError(
+ self.info,
+ "discriminator member '%s' of %s must be of enum type"
+ % (self._tag_name, base))
+ if tag_member.optional:
+ raise QAPISemError(
+ self.info,
+ "discriminator member '%s' of %s must not be optional"
+ % (self._tag_name, base))
+ if tag_member.ifcond.is_present():
+ raise QAPISemError(
+ self.info,
+ "discriminator member '%s' of %s must not be conditional"
+ % (self._tag_name, base))
+ # branches that are not explicitly covered get an empty type
+ assert tag_member.defined_in
+ cases = {v.name for v in self.variants}
+ for m in tag_member.type.members:
+ if m.name not in cases:
+ v = QAPISchemaVariant(m.name, self.info,
+ 'q_empty', m.ifcond)
+ v.set_defined_in(tag_member.defined_in)
+ self.variants.append(v)
if not self.variants:
raise QAPISemError(self.info, "union has no branches")
for v in self.variants:
# Union names must match enum values; alternate names are
# checked separately. Use 'seen' to tell the two apart.
if seen:
- if v.name not in self.tag_member.type.member_names():
+ if v.name not in tag_member.type.member_names():
raise QAPISemError(
self.info,
"branch '%s' is not a value of %s"
- % (v.name, self.tag_member.type.describe()))
+ % (v.name, tag_member.type.describe()))
if not isinstance(v.type, QAPISchemaObjectType):
raise QAPISemError(
self.info,
v.type.check_clash(info, dict(seen))
+class QAPISchemaAlternatives(QAPISchemaVariants):
+ def __init__(self,
+ info: QAPISourceInfo,
+ variants: List[QAPISchemaVariant],
+ tag_member: QAPISchemaObjectTypeMember):
+ super().__init__(info, variants)
+ self.tag_member = tag_member
+
+ def check(
+ self, schema: QAPISchema, seen: Dict[str, QAPISchemaMember]
+ ) -> None:
+ super().check(schema, seen)
+ assert isinstance(self.tag_member.type, QAPISchemaEnumType)
+ assert not self.tag_member.optional
+ assert not self.tag_member.ifcond.is_present()
+
+
class QAPISchemaMember:
""" Represents object members, enum members and features """
role = 'member'
"command's 'data' cannot take %s"
% arg_type.describe())
self.arg_type = arg_type
- if self.arg_type.variants and not self.boxed:
+ if self.arg_type.branches and not self.boxed:
raise QAPISemError(
self.info,
"command's 'data' can take %s only with 'boxed': true"
"event's 'data' cannot take %s"
% typ.describe())
self.arg_type = typ
- if self.arg_type.variants and not self.boxed:
+ if self.arg_type.branches and not self.boxed:
raise QAPISemError(
self.info,
"event's 'data' can take %s only with 'boxed': true"
self._def_definition(
QAPISchemaObjectType(name, info, expr.doc, ifcond, features,
base, members,
- QAPISchemaVariants(
- tag_name, info, None, variants)))
+ QAPISchemaBranches(
+ info, variants, tag_name)))
def _def_alternate_type(self, expr: QAPIExpression) -> None:
name = expr['alternate']
self._def_definition(
QAPISchemaAlternateType(
name, info, expr.doc, ifcond, features,
- QAPISchemaVariants(None, info, tag_member, variants)))
+ QAPISchemaAlternatives(info, variants, tag_member)))
def _def_command(self, expr: QAPIExpression) -> None:
name = expr['command']
)
from .schema import (
QAPISchema,
+ QAPISchemaAlternatives,
+ QAPISchemaBranches,
QAPISchemaEnumMember,
QAPISchemaFeature,
QAPISchemaIfCond,
if not isinstance(obj, QAPISchemaObjectType):
continue
ret += gen_object(obj.name, obj.ifcond, obj.base,
- obj.local_members, obj.variants)
+ obj.local_members, obj.branches)
ret += mcgen('''
features: List[QAPISchemaFeature],
base: Optional[QAPISchemaObjectType],
members: List[QAPISchemaObjectTypeMember],
- variants: Optional[QAPISchemaVariants]) -> None:
+ branches: Optional[QAPISchemaBranches]) -> None:
# Nothing to do for the special empty builtin
if name == 'q_empty':
return
with ifcontext(ifcond, self._genh):
self._genh.preamble_add(gen_fwd_object_or_array(name))
- self._genh.add(gen_object(name, ifcond, base, members, variants))
+ self._genh.add(gen_object(name, ifcond, base, members, branches))
with ifcontext(ifcond, self._genh, self._genc):
if base and not base.is_implicit():
self._genh.add(gen_upcast(name, base))
info: Optional[QAPISourceInfo],
ifcond: QAPISchemaIfCond,
features: List[QAPISchemaFeature],
- variants: QAPISchemaVariants) -> None:
+ alternatives: QAPISchemaAlternatives) -> None:
with ifcontext(ifcond, self._genh):
self._genh.preamble_add(gen_fwd_object_or_array(name))
self._genh.add(gen_object(name, ifcond, None,
- [variants.tag_member], variants))
+ [alternatives.tag_member], alternatives))
with ifcontext(ifcond, self._genh, self._genc):
self._gen_type_cleanup(name)
)
from .schema import (
QAPISchema,
+ QAPISchemaAlternatives,
+ QAPISchemaBranches,
QAPISchemaEnumMember,
QAPISchemaEnumType,
QAPISchemaFeature,
QAPISchemaObjectType,
QAPISchemaObjectTypeMember,
QAPISchemaType,
- QAPISchemaVariants,
)
from .source import QAPISourceInfo
def gen_visit_object_members(name: str,
base: Optional[QAPISchemaObjectType],
members: List[QAPISchemaObjectTypeMember],
- variants: Optional[QAPISchemaVariants]) -> str:
+ branches: Optional[QAPISchemaBranches]) -> str:
ret = mcgen('''
bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
''')
ret += memb.ifcond.gen_endif()
- if variants:
- tag_member = variants.tag_member
+ if branches:
+ tag_member = branches.tag_member
assert isinstance(tag_member.type, QAPISchemaEnumType)
ret += mcgen('''
''',
c_name=c_name(tag_member.name))
- for var in variants.variants:
+ for var in branches.variants:
case_str = c_enum_const(tag_member.type.name, var.name,
tag_member.type.prefix)
ret += var.ifcond.gen_if()
c_name=c_name(name))
-def gen_visit_alternate(name: str, variants: QAPISchemaVariants) -> str:
+def gen_visit_alternate(name: str,
+ alternatives: QAPISchemaAlternatives) -> str:
ret = mcgen('''
bool visit_type_%(c_name)s(Visitor *v, const char *name,
''',
c_name=c_name(name))
- for var in variants.variants:
+ for var in alternatives.variants:
ret += var.ifcond.gen_if()
ret += mcgen('''
case %(case)s:
features: List[QAPISchemaFeature],
base: Optional[QAPISchemaObjectType],
members: List[QAPISchemaObjectTypeMember],
- variants: Optional[QAPISchemaVariants]) -> None:
+ branches: Optional[QAPISchemaBranches]) -> None:
# Nothing to do for the special empty builtin
if name == 'q_empty':
return
with ifcontext(ifcond, self._genh, self._genc):
self._genh.add(gen_visit_members_decl(name))
self._genc.add(gen_visit_object_members(name, base,
- members, variants))
+ members, branches))
# TODO Worth changing the visitor signature, so we could
# directly use rather than repeat type.is_implicit()?
if not name.startswith('q_'):
info: Optional[QAPISourceInfo],
ifcond: QAPISchemaIfCond,
features: List[QAPISchemaFeature],
- variants: QAPISchemaVariants) -> None:
+ alternatives: QAPISchemaAlternatives) -> None:
with ifcontext(ifcond, self._genh, self._genc):
self._genh.add(gen_visit_decl(name))
- self._genc.add(gen_visit_alternate(name, variants))
+ self._genc.add(gen_visit_alternate(name, alternatives))
def gen_visit(schema: QAPISchema,
#include "qemu/osdep.h"
-
-const MonitorDef *target_monitor_defs(void);
+#include "monitor/hmp-target.h"
const MonitorDef *target_monitor_defs(void)
{
#endif /* CONFIG_TCG */
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "exec/target_page.h"
#include "hw/qdev-core.h"
#include "hw/qdev-properties.h"
* @memory_dispatch: its dispatch pointer (cached, RCU protected)
* @tcg_as_listener: listener for tracking changes to the AddressSpace
*/
-struct CPUAddressSpace {
+typedef struct CPUAddressSpace {
CPUState *cpu;
AddressSpace *as;
struct AddressSpaceDispatch *memory_dispatch;
MemoryListener tcg_as_listener;
-};
+} CPUAddressSpace;
struct DirtyBitmapSnapshot {
ram_addr_t start;
}
#endif /* !_WIN32 */
-/* Return a host pointer to ram allocated with qemu_ram_alloc.
- * This should not be used for general purpose DMA. Use address_space_map
- * or address_space_rw instead. For local memory (e.g. video ram) that the
- * device owns, use memory_region_get_ram_ptr.
+/*
+ * Return a host pointer to guest's ram.
+ * For Xen, foreign mappings get created if they don't already exist.
*
- * Called within RCU critical section.
- */
-void *qemu_map_ram_ptr(RAMBlock *block, ram_addr_t addr)
-{
- if (block == NULL) {
- block = qemu_get_ram_block(addr);
- addr -= block->offset;
- }
-
- if (xen_enabled() && block->host == NULL) {
- /* We need to check if the requested address is in the RAM
- * because we don't want to map the entire memory in QEMU.
- * In that case just map until the end of the page.
- */
- if (block->offset == 0) {
- return xen_map_cache(addr, 0, 0, false);
- }
-
- block->host = xen_map_cache(block->offset, block->max_length, 1, false);
- }
- return ramblock_ptr(block, addr);
-}
-
-/* Return a host pointer to guest's ram. Similar to qemu_map_ram_ptr
- * but takes a size argument.
+ * @block: block for the RAM to lookup (optional and may be NULL).
+ * @addr: address within the memory region.
+ * @size: pointer to requested size (optional and may be NULL).
+ * size may get modified and return a value smaller than
+ * what was requested.
+ * @lock: wether to lock the mapping in xen-mapcache until invalidated.
+ * @is_write: hint wether to map RW or RO in the xen-mapcache.
+ * (optional and may always be set to true).
*
* Called within RCU critical section.
*/
static void *qemu_ram_ptr_length(RAMBlock *block, ram_addr_t addr,
- hwaddr *size, bool lock)
+ hwaddr *size, bool lock,
+ bool is_write)
{
- if (*size == 0) {
+ hwaddr len = 0;
+
+ if (size && *size == 0) {
return NULL;
}
block = qemu_get_ram_block(addr);
addr -= block->offset;
}
- *size = MIN(*size, block->max_length - addr);
+ if (size) {
+ *size = MIN(*size, block->max_length - addr);
+ len = *size;
+ }
if (xen_enabled() && block->host == NULL) {
/* We need to check if the requested address is in the RAM
* In that case just map the requested area.
*/
if (block->offset == 0) {
- return xen_map_cache(addr, *size, lock, lock);
+ return xen_map_cache(block->mr, addr, len, lock, lock,
+ is_write);
}
- block->host = xen_map_cache(block->offset, block->max_length, 1, lock);
+ block->host = xen_map_cache(block->mr, block->offset,
+ block->max_length, 1,
+ lock, is_write);
}
return ramblock_ptr(block, addr);
}
+/*
+ * Return a host pointer to ram allocated with qemu_ram_alloc.
+ * This should not be used for general purpose DMA. Use address_space_map
+ * or address_space_rw instead. For local memory (e.g. video ram) that the
+ * device owns, use memory_region_get_ram_ptr.
+ *
+ * Called within RCU critical section.
+ */
+void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
+{
+ return qemu_ram_ptr_length(ram_block, addr, NULL, false, true);
+}
+
/* Return the offset of a hostpointer within a ramblock */
ram_addr_t qemu_ram_block_host_offset(RAMBlock *rb, void *host)
{
} else {
/* RAM case */
uint8_t *ram_ptr = qemu_ram_ptr_length(mr->ram_block, mr_addr, l,
- false);
+ false, true);
memmove(ram_ptr, buf, *l);
invalidate_and_set_dirty(mr, mr_addr, *l);
} else {
/* RAM case */
uint8_t *ram_ptr = qemu_ram_ptr_length(mr->ram_block, mr_addr, l,
- false);
+ false, false);
memcpy(buf, ram_ptr, *l);
*plen = flatview_extend_translation(fv, addr, len, mr, xlat,
l, is_write, attrs);
fuzz_dma_read_cb(addr, *plen, mr);
- return qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
+ return qemu_ram_ptr_length(mr->ram_block, xlat, plen, true, is_write);
}
/* Unmaps a memory region previously mapped by address_space_map().
l = flatview_extend_translation(cache->fv, addr, len, mr,
cache->xlat, l, is_write,
MEMTXATTRS_UNSPECIFIED);
- cache->ptr = qemu_ram_ptr_length(mr->ram_block, cache->xlat, &l, true);
+ cache->ptr = qemu_ram_ptr_length(mr->ram_block, cache->xlat, &l, true,
+ is_write);
} else {
cache->ptr = NULL;
}
source sparc/Kconfig
source tricore/Kconfig
source xtensa/Kconfig
+
+config TARGET_BIG_ENDIAN
+ bool
#include "qemu/log.h"
#include "cpu.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "fpu/softfloat-types.h"
#include "exec/helper-proto.h"
#include "qemu/qemu-print.h"
config AARCH64
bool
select ARM
+ # kvm_arch_fixup_msi_route() needs to access PCIDevice
+ select PCI if KVM
#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
/* Use pc-relative instructions in system-mode */
- cs->tcg_cflags |= CF_PCREL;
+ tcg_cflags_set(cs, CF_PCREL);
#endif
/* If we needed to query the host kernel for the CPU features
#include "cpu-qom.h"
#include "exec/cpu-defs.h"
#include "exec/gdbstub.h"
+#include "exec/page-protection.h"
#include "qapi/qapi-types-common.h"
#include "target/arm/multiprocessing.h"
#include "target/arm/gtimer.h"
#include "qemu/range.h"
#include "qemu/main-loop.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "cpu.h"
#include "internals.h"
#include "cpu-features.h"
#include "qemu/bitops.h"
#include "qemu/log.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#ifdef CONFIG_TCG
#include "exec/cpu_ldst.h"
#include "semihosting/common-semi.h"
#include "cpu.h"
#include "internals.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "exec/ram_addr.h"
#include "exec/cpu_ldst.h"
#include "exec/helper-proto.h"
#include "cpu.h"
#include "internals.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "exec/helper-proto.h"
#include "tcg/tcg-gvec-desc.h"
#include "fpu/softfloat.h"
static void avr_cpu_synchronize_from_tb(CPUState *cs,
const TranslationBlock *tb)
{
- tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ tcg_debug_assert(!tcg_cflags_has(cs, CF_PCREL));
cpu_env(cs)->pc_w = tb->pc / 2; /* internally PC points to words */
}
#include "cpu.h"
#include "hw/core/tcg-cpu-ops.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "exec/cpu_ldst.h"
#include "exec/address-spaces.h"
#include "exec/helper-proto.h"
#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "mmu.h"
#ifdef DEBUG
if (!cris_mmu_enabled(env->sregs[SFR_RW_GC_CFG])) {
res->phy = vaddr;
- res->prot = PAGE_BITS;
+ res->prot = PAGE_RWX;
goto done;
}
miss = 0;
base = cris_mmu_translate_seg(env, seg);
res->phy = base | (0x0fffffff & vaddr);
- res->prot = PAGE_BITS;
+ res->prot = PAGE_RWX;
} else {
miss = cris_mmu_translate_page(res, env, vaddr, access_type,
is_user, debug);
That file is consumed by the following python scripts to produce the indicated
header files in <BUILD_DIR>/target/hexagon
gen_opcodes_def.py -> opcodes_def_generated.h.inc
- gen_op_regs.py -> op_regs_generated.h.inc
gen_printinsn.py -> printinsn_generated.h.inc
gen_op_attribs.py -> op_attribs_generated.h.inc
gen_helper_protos.py -> helper_protos_generated.h.inc
- gen_shortcode.py -> shortcode_generated.h.inc
gen_tcg_funcs.py -> tcg_funcs_generated.c.inc
gen_tcg_func_table.py -> tcg_func_table_generated.c.inc
gen_helper_funcs.py -> helper_funcs_generated.c.inc
}
We also generate an analyze_<tag> function for each instruction. Currently,
-these functions record the writes to registers by calling ctx_log_*. During
-gen_start_packet, we invoke the analyze_<tag> function for each instruction in
-the packet, and we mark the implicit writes. After the analysis is performed,
-we initialize the result register for each of the predicated assignments.
+these functions record the reads and writes to registers by calling ctx_log_*.
+During gen_start_packet, we invoke the analyze_<tag> function for each instruction in
+the packet, and we mark the implicit writes. The analysis determines if the packet
+semantics can be short-circuited. If not, we initialize the result register for each
+of the predicated assignments.
In addition to instruction semantics, we use a generator to create the decode
tree. This generation is a four step process.
/*
- * Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ * Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* 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
DEF_ATTRIB(IMPLICIT_READS_P2, "Reads the P2 register", "", "")
DEF_ATTRIB(IMPLICIT_READS_P3, "Reads the P3 register", "", "")
DEF_ATTRIB(IMPLICIT_WRITES_USR, "May write USR", "", "")
+DEF_ATTRIB(IMPLICIT_READS_SP, "Reads the SP register", "", "")
DEF_ATTRIB(COMMUTES, "The operation is communitive", "", "")
DEF_ATTRIB(DEALLOCRET, "dealloc_return", "", "")
DEF_ATTRIB(DEALLOCFRAME, "deallocframe", "", "")
static void hexagon_cpu_synchronize_from_tb(CPUState *cs,
const TranslationBlock *tb)
{
- tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ tcg_debug_assert(!tcg_cflags_has(cs, CF_PCREL));
cpu_env(cs)->gpr[HEX_REG_PC] = tb->pc;
}
decode_fill_newvalue_regno(Packet *packet)
{
int i, use_regidx, offset, def_idx, dst_idx;
- uint16_t def_opcode, use_opcode;
- char *dststr;
for (i = 1; i < packet->num_insns; i++) {
if (GET_ATTRIB(packet->insn[i].opcode, A_DOTNEWVALUE) &&
!GET_ATTRIB(packet->insn[i].opcode, A_EXTENSION)) {
- use_opcode = packet->insn[i].opcode;
-
- /* It's a store, so we're adjusting the Nt field */
- if (GET_ATTRIB(use_opcode, A_STORE)) {
- use_regidx = strchr(opcode_reginfo[use_opcode], 't') -
- opcode_reginfo[use_opcode];
- } else { /* It's a Jump, so we're adjusting the Ns field */
- use_regidx = strchr(opcode_reginfo[use_opcode], 's') -
- opcode_reginfo[use_opcode];
- }
+
+ g_assert(packet->insn[i].new_read_idx != -1);
+ use_regidx = packet->insn[i].new_read_idx;
/*
* What's encoded at the N-field is the offset to who's producing
*/
g_assert(!((def_idx < 0) || (def_idx > (packet->num_insns - 1))));
- /*
- * packet->insn[def_idx] is the producer
- * Figure out which type of destination it produces
- * and the corresponding index in the reginfo
- */
- def_opcode = packet->insn[def_idx].opcode;
- dststr = strstr(opcode_wregs[def_opcode], "Rd");
- if (dststr) {
- dststr = strchr(opcode_reginfo[def_opcode], 'd');
- } else {
- dststr = strstr(opcode_wregs[def_opcode], "Rx");
- if (dststr) {
- dststr = strchr(opcode_reginfo[def_opcode], 'x');
- } else {
- dststr = strstr(opcode_wregs[def_opcode], "Re");
- if (dststr) {
- dststr = strchr(opcode_reginfo[def_opcode], 'e');
- } else {
- dststr = strstr(opcode_wregs[def_opcode], "Ry");
- if (dststr) {
- dststr = strchr(opcode_reginfo[def_opcode], 'y');
- } else {
- g_assert_not_reached();
- }
- }
- }
- }
- g_assert(dststr != NULL);
-
/* Now patch up the consumer with the register number */
- dst_idx = dststr - opcode_reginfo[def_opcode];
+ g_assert(packet->insn[def_idx].dest_idx != -1);
+ dst_idx = packet->insn[def_idx].dest_idx;
packet->insn[i].regno[use_regidx] =
packet->insn[def_idx].regno[dst_idx];
/*
for (flag = false, i = 0; i < last_insn + 1; i++) {
int opcode = packet->insn[i].opcode;
- if ((strstr(opcode_wregs[opcode], "Pd4") ||
- strstr(opcode_wregs[opcode], "Pe4")) &&
+ if (packet->insn[i].has_pred_dest &&
GET_ATTRIB(opcode, A_STORE) == 0) {
/* This should be a compare (not a store conditional) */
if (flag) {
#!/usr/bin/env python3
##
-## Copyright(c) 2022-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+## Copyright(c) 2022-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
##
## 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
f.write("{\n")
f.write(" Insn *insn G_GNUC_UNUSED = ctx->insn;\n")
-
- i = 0
- ## Analyze all the registers
- for regtype, regid in regs:
- reg = hex_common.get_register(tag, regtype, regid)
- if reg.is_written():
- reg.analyze_write(f, tag, i)
+ if (hex_common.is_hvx_insn(tag)):
+ if hex_common.has_hvx_helper(tag):
+ f.write(
+ " const bool G_GNUC_UNUSED insn_has_hvx_helper = true;\n"
+ )
+ f.write(" ctx_start_hvx_insn(ctx);\n")
else:
- reg.analyze_read(f, i)
- i += 1
-
- has_generated_helper = not hex_common.skip_qemu_helper(
- tag
- ) and not hex_common.is_idef_parser_enabled(tag)
-
- ## Mark HVX instructions with generated helpers
- if (has_generated_helper and
- "A_CVI" in hex_common.attribdict[tag]):
- f.write(" ctx->has_hvx_helper = true;\n")
+ f.write(
+ " const bool G_GNUC_UNUSED insn_has_hvx_helper = false;\n"
+ )
+
+ ## Declare all the registers
+ for regno, register in enumerate(regs):
+ reg_type, reg_id = register
+ reg = hex_common.get_register(tag, reg_type, reg_id)
+ reg.decl_reg_num(f, regno)
+
+ ## Analyze the register reads
+ for regno, register in enumerate(regs):
+ reg_type, reg_id = register
+ reg = hex_common.get_register(tag, reg_type, reg_id)
+ if reg.is_read():
+ reg.analyze_read(f, regno)
+
+ ## Analyze the register writes
+ for regno, register in enumerate(regs):
+ reg_type, reg_id = register
+ reg = hex_common.get_register(tag, reg_type, reg_id)
+ if reg.is_written():
+ reg.analyze_write(f, tag, regno)
f.write("}\n\n")
def main():
- hex_common.read_semantics_file(sys.argv[1])
- hex_common.read_attribs_file(sys.argv[2])
- hex_common.read_overrides_file(sys.argv[3])
- hex_common.read_overrides_file(sys.argv[4])
- ## Whether or not idef-parser is enabled is
- ## determined by the number of arguments to
- ## this script:
- ##
- ## 5 args. -> not enabled,
- ## 6 args. -> idef-parser enabled.
- ##
- ## The 6:th arg. then holds a list of the successfully
- ## parsed instructions.
- is_idef_parser_enabled = len(sys.argv) > 6
- if is_idef_parser_enabled:
- hex_common.read_idef_parser_enabled_file(sys.argv[5])
- hex_common.calculate_attribs()
- hex_common.init_registers()
+ hex_common.read_common_files()
tagregs = hex_common.get_tagregs()
tagimms = hex_common.get_tagimms()
with open(sys.argv[-1], "w") as f:
- f.write("#ifndef HEXAGON_TCG_FUNCS_H\n")
- f.write("#define HEXAGON_TCG_FUNCS_H\n\n")
+ f.write("#ifndef HEXAGON_ANALYZE_FUNCS_C_INC\n")
+ f.write("#define HEXAGON_ANALYZE_FUNCS_C_INC\n\n")
for tag in hex_common.tags:
gen_analyze_func(f, tag, tagregs[tag], tagimms[tag])
- f.write("#endif /* HEXAGON_TCG_FUNCS_H */\n")
+ f.write("#endif /* HEXAGON_ANALYZE_FUNCS_C_INC */\n")
if __name__ == "__main__":
#!/usr/bin/env python3
##
-## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+## Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
##
## 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
def main():
- hex_common.read_semantics_file(sys.argv[1])
- hex_common.read_attribs_file(sys.argv[2])
- hex_common.read_overrides_file(sys.argv[3])
- hex_common.read_overrides_file(sys.argv[4])
- ## Whether or not idef-parser is enabled is
- ## determined by the number of arguments to
- ## this script:
- ##
- ## 5 args. -> not enabled,
- ## 6 args. -> idef-parser enabled.
- ##
- ## The 6:th arg. then holds a list of the successfully
- ## parsed instructions.
- is_idef_parser_enabled = len(sys.argv) > 6
- if is_idef_parser_enabled:
- hex_common.read_idef_parser_enabled_file(sys.argv[5])
- hex_common.calculate_attribs()
- hex_common.init_registers()
+ hex_common.read_common_files()
tagregs = hex_common.get_tagregs()
tagimms = hex_common.get_tagimms()
#!/usr/bin/env python3
##
-## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+## Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
##
## 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
declared.append(arg.proto_arg)
arguments = ", ".join(declared)
- f.write(f"DEF_HELPER_{len(declared) - 1}({tag}, {arguments})\n")
+
+ ## Add the TCG_CALL_NO_RWG_SE flag to helpers that don't take the env
+ ## argument and aren't HVX instructions. Since HVX instructions take
+ ## pointers to their arguments, they will have side effects.
+ if hex_common.need_env(tag) or hex_common.is_hvx_insn(tag):
+ f.write(f"DEF_HELPER_{len(declared) - 1}({tag}, {arguments})\n")
+ else:
+ f.write(f"DEF_HELPER_FLAGS_{len(declared) - 1}({tag}, "
+ f"TCG_CALL_NO_RWG_SE, {arguments})\n")
def main():
- hex_common.read_semantics_file(sys.argv[1])
- hex_common.read_attribs_file(sys.argv[2])
- hex_common.read_overrides_file(sys.argv[3])
- hex_common.read_overrides_file(sys.argv[4])
- ## Whether or not idef-parser is enabled is
- ## determined by the number of arguments to
- ## this script:
- ##
- ## 5 args. -> not enabled,
- ## 6 args. -> idef-parser enabled.
- ##
- ## The 6:th arg. then holds a list of the successfully
- ## parsed instructions.
- is_idef_parser_enabled = len(sys.argv) > 6
- if is_idef_parser_enabled:
- hex_common.read_idef_parser_enabled_file(sys.argv[5])
- hex_common.calculate_attribs()
- hex_common.init_registers()
+ hex_common.read_common_files()
tagregs = hex_common.get_tagregs()
tagimms = hex_common.get_tagimms()
#!/usr/bin/env python3
##
-## Copyright(c) 2019-2023 rev.ng Labs Srl. All Rights Reserved.
+## Copyright(c) 2019-2024 rev.ng Labs Srl. All Rights Reserved.
##
## 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
##
def main():
hex_common.read_semantics_file(sys.argv[1])
- hex_common.read_attribs_file(sys.argv[2])
hex_common.calculate_attribs()
hex_common.init_registers()
tagregs = hex_common.get_tagregs()
tagimms = hex_common.get_tagimms()
- with open(sys.argv[3], "w") as f:
+ with open(sys.argv[-1], "w") as f:
f.write('#include "macros.inc"\n\n')
for tag in hex_common.tags:
#!/usr/bin/env python3
##
-## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+## Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
##
## 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
def main():
hex_common.read_semantics_file(sys.argv[1])
- hex_common.read_attribs_file(sys.argv[2])
hex_common.calculate_attribs()
##
## Generate all the attributes associated with each instruction
##
- with open(sys.argv[3], "w") as f:
+ with open(sys.argv[-1], "w") as f:
for tag in hex_common.tags:
f.write(
f"OP_ATTRIB({tag},ATTRIBS("
+++ /dev/null
-#!/usr/bin/env python3
-
-##
-## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
-##
-## 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/>.
-##
-
-import sys
-import re
-import string
-import hex_common
-
-
-##
-## Generate the register and immediate operands for each instruction
-##
-def calculate_regid_reg(tag):
- def letter_inc(x):
- return chr(ord(x) + 1)
-
- ordered_implregs = ["SP", "FP", "LR"]
- srcdst_lett = "X"
- src_lett = "S"
- dst_lett = "D"
- retstr = ""
- mapdict = {}
- for reg in ordered_implregs:
- reg_rd = 0
- reg_wr = 0
- if ("A_IMPLICIT_WRITES_" + reg) in hex_common.attribdict[tag]:
- reg_wr = 1
- if reg_rd and reg_wr:
- retstr += srcdst_lett
- mapdict[srcdst_lett] = reg
- srcdst_lett = letter_inc(srcdst_lett)
- elif reg_rd:
- retstr += src_lett
- mapdict[src_lett] = reg
- src_lett = letter_inc(src_lett)
- elif reg_wr:
- retstr += dst_lett
- mapdict[dst_lett] = reg
- dst_lett = letter_inc(dst_lett)
- return retstr, mapdict
-
-
-def calculate_regid_letters(tag):
- retstr, mapdict = calculate_regid_reg(tag)
- return retstr
-
-
-def strip_reg_prefix(x):
- y = x.replace("UREG.", "")
- y = y.replace("MREG.", "")
- return y.replace("GREG.", "")
-
-
-def main():
- hex_common.read_semantics_file(sys.argv[1])
- hex_common.read_attribs_file(sys.argv[2])
- hex_common.init_registers()
- tagregs = hex_common.get_tagregs(full=True)
- tagimms = hex_common.get_tagimms()
-
- with open(sys.argv[3], "w") as f:
- for tag in hex_common.tags:
- regs = tagregs[tag]
- rregs = []
- wregs = []
- regids = ""
- for regtype, regid, _, numregs in regs:
- reg = hex_common.get_register(tag, regtype, regid)
- if reg.is_read():
- if regid[0] not in regids:
- regids += regid[0]
- rregs.append(regtype + regid + numregs)
- if reg.is_written():
- wregs.append(regtype + regid + numregs)
- if regid[0] not in regids:
- regids += regid[0]
- for attrib in hex_common.attribdict[tag]:
- if hex_common.attribinfo[attrib]["rreg"]:
- rregs.append(strip_reg_prefix(attribinfo[attrib]["rreg"]))
- if hex_common.attribinfo[attrib]["wreg"]:
- wregs.append(strip_reg_prefix(attribinfo[attrib]["wreg"]))
- regids += calculate_regid_letters(tag)
- f.write(
- f'REGINFO({tag},"{regids}",\t/*RD:*/\t"{",".join(rregs)}",'
- f'\t/*WR:*/\t"{",".join(wregs)}")\n'
- )
-
- for tag in hex_common.tags:
- imms = tagimms[tag]
- f.write(f"IMMINFO({tag}")
- if not imms:
- f.write(""",'u',0,0,'U',0,0""")
- for sign, size, shamt in imms:
- if sign == "r":
- sign = "s"
- if not shamt:
- shamt = "0"
- f.write(f""",'{sign}',{size},{shamt}""")
- if len(imms) == 1:
- if sign.isupper():
- myu = "u"
- else:
- myu = "U"
- f.write(f""",'{myu}',0,0""")
- f.write(")\n")
-
-
-if __name__ == "__main__":
- main()
#!/usr/bin/env python3
##
-## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+## Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
##
## 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
##
## Generate a list of all the opcodes
##
- with open(sys.argv[3], "w") as f:
+ with open(sys.argv[-1], "w") as f:
for tag in hex_common.tags:
f.write(f"OPCODE({tag}),\n")
#!/usr/bin/env python3
##
-## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+## Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
##
## 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
def main():
hex_common.read_semantics_file(sys.argv[1])
- hex_common.read_attribs_file(sys.argv[2])
immext_casere = re.compile(r"IMMEXT\(([A-Za-z])")
- with open(sys.argv[3], "w") as f:
+ with open(sys.argv[-1], "w") as f:
for tag in hex_common.tags:
if not hex_common.behdict[tag]:
continue
+++ /dev/null
-#!/usr/bin/env python3
-
-##
-## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
-##
-## 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/>.
-##
-
-import sys
-import re
-import string
-import hex_common
-
-
-def gen_shortcode(f, tag):
- f.write(f"DEF_SHORTCODE({tag}, {hex_common.semdict[tag]})\n")
-
-
-def main():
- hex_common.read_semantics_file(sys.argv[1])
- hex_common.read_attribs_file(sys.argv[2])
- hex_common.calculate_attribs()
- tagregs = hex_common.get_tagregs()
- tagimms = hex_common.get_tagimms()
-
- with open(sys.argv[3], "w") as f:
- f.write("#ifndef DEF_SHORTCODE\n")
- f.write("#define DEF_SHORTCODE(TAG,SHORTCODE) /* Nothing */\n")
- f.write("#endif\n")
-
- for tag in hex_common.tags:
- ## Skip the priv instructions
- if "A_PRIV" in hex_common.attribdict[tag]:
- continue
- ## Skip the guest instructions
- if "A_GUEST" in hex_common.attribdict[tag]:
- continue
- ## Skip the diag instructions
- if tag == "Y6_diag":
- continue
- if tag == "Y6_diag0":
- continue
- if tag == "Y6_diag1":
- continue
-
- gen_shortcode(f, tag)
-
- f.write("#undef DEF_SHORTCODE\n")
-
-
-if __name__ == "__main__":
- main()
/*
- * Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ * Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* 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
gen_helper_raise_exception(tcg_env, excp); \
} while (0)
#endif
+
+#define fGEN_TCG_A2_nop(SHORTCODE) do { } while (0)
+#define fGEN_TCG_SA1_setin1(SHORTCODE) tcg_gen_movi_tl(RdV, -1)
#!/usr/bin/env python3
##
-## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+## Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
##
## 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
def main():
hex_common.read_semantics_file(sys.argv[1])
- hex_common.read_attribs_file(sys.argv[2])
hex_common.calculate_attribs()
tagregs = hex_common.get_tagregs()
tagimms = hex_common.get_tagimms()
- with open(sys.argv[3], "w") as f:
+ with open(sys.argv[-1], "w") as f:
f.write("#ifndef HEXAGON_FUNC_TABLE_H\n")
f.write("#define HEXAGON_FUNC_TABLE_H\n\n")
#!/usr/bin/env python3
##
-## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+## Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
##
## 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
def main():
- hex_common.read_semantics_file(sys.argv[1])
- hex_common.read_attribs_file(sys.argv[2])
- hex_common.read_overrides_file(sys.argv[3])
- hex_common.read_overrides_file(sys.argv[4])
- hex_common.calculate_attribs()
- hex_common.init_registers()
- ## Whether or not idef-parser is enabled is
- ## determined by the number of arguments to
- ## this script:
- ##
- ## 5 args. -> not enabled,
- ## 6 args. -> idef-parser enabled.
- ##
- ## The 6:th arg. then holds a list of the successfully
- ## parsed instructions.
- is_idef_parser_enabled = len(sys.argv) > 6
- if is_idef_parser_enabled:
- hex_common.read_idef_parser_enabled_file(sys.argv[5])
+ is_idef_parser_enabled = hex_common.read_common_files()
tagregs = hex_common.get_tagregs()
tagimms = hex_common.get_tagimms()
## insn->regno[0] = args->Rd;
## insn->regno[1] = args->Rs;
## insn->regno[2] = args->Rt;
+## insn->new_read_idx = -1;
+## insn->dest_idx = 0;
+## insn->has_pred_dest = false;
## return true;
## }
##
insn->opcode = {tag};
"""))
- regno = 0
- for reg in regs:
- reg_type = reg[0]
- reg_id = reg[1]
+ new_read_idx = -1
+ dest_idx = -1
+ has_pred_dest = "false"
+ for regno, (reg_type, reg_id, *_) in enumerate(regs):
+ reg = hex_common.get_register(tag, reg_type, reg_id)
f.write(code_fmt(f"""\
insn->regno[{regno}] = args->{reg_type}{reg_id};
"""))
- regno += 1
+ if reg.is_read() and reg.is_new():
+ new_read_idx = regno
+ # dest_idx should be the first destination, so check for -1
+ if reg.is_written() and dest_idx == -1:
+ dest_idx = regno
+ if reg_type == "P" and reg.is_written() and not reg.is_read():
+ has_pred_dest = "true"
if len(imms) != 0:
mark_which_imm_extended(f, tag)
insn->immed[{immno}] = args->{imm_type}{imm_letter};
"""))
+ f.write(code_fmt(f"""\
+ insn->new_read_idx = {new_read_idx};
+ insn->dest_idx = {dest_idx};
+ insn->has_pred_dest = {has_pred_dest};
+ """))
f.write(textwrap.dedent(f"""\
return true;
{close_curly}
if __name__ == "__main__":
hex_common.read_semantics_file(sys.argv[1])
+ hex_common.init_registers()
with open(sys.argv[2], "w") as f:
gen_trans_funcs(f)
#!/usr/bin/env python3
##
-## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+## Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
##
## 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
semdict = {} # tag -> semantics
attribdict = {} # tag -> attributes
macros = {} # macro -> macro information...
-attribinfo = {} # Register information and misc
registers = {} # register -> register functions
new_registers = {}
tags = [] # list of all tags
add_qemu_macro_attrib('fLSBNEW1', 'A_IMPLICIT_READS_P1')
add_qemu_macro_attrib('fLSBNEW1NOT', 'A_IMPLICIT_READS_P1')
add_qemu_macro_attrib('fREAD_P3', 'A_IMPLICIT_READS_P3')
+ add_qemu_macro_attrib('fREAD_SP', 'A_IMPLICIT_READS_SP')
# Recurse down macros, find attributes from sub-macros
macroValues = list(macros.values())
return dict(zip(tags, list(map(compute_tag_immediates, tags))))
+def need_p0(tag):
+ return "A_IMPLICIT_READS_P0" in attribdict[tag]
+
+
+def need_sp(tag):
+ return "A_IMPLICIT_READS_SP" in attribdict[tag]
+
+
+def is_hvx_insn(tag):
+ return "A_CVI" in attribdict[tag]
+
+
+def need_env(tag):
+ return ("A_STORE" in attribdict[tag] or
+ "A_LOAD" in attribdict[tag] or
+ "A_CVI_GATHER" in attribdict[tag] or
+ "A_CVI_SCATTER" in attribdict[tag] or
+ "A_IMPLICIT_WRITES_USR" in attribdict[tag])
+
+
def need_slot(tag):
if (
"A_CVI_SCATTER" not in attribdict[tag]
return tag in idef_parser_enabled
+def is_hvx_insn(tag):
+ return "A_CVI" in attribdict[tag]
+
+
+def has_hvx_helper(tag):
+ return (is_hvx_insn(tag) and
+ not skip_qemu_helper(tag) and
+ not is_idef_parser_enabled(tag))
+
+
def imm_name(immlett):
return f"{immlett}iV"
eval_line = ""
-def read_attribs_file(name):
- attribre = re.compile(
- r"DEF_ATTRIB\(([A-Za-z0-9_]+), ([^,]*), "
- + r'"([A-Za-z0-9_\.]*)", "([A-Za-z0-9_\.]*)"\)'
- )
- for line in open(name, "rt").readlines():
- if not attribre.match(line):
- continue
- (attrib_base, descr, rreg, wreg) = attribre.findall(line)[0]
- attrib_base = "A_" + attrib_base
- attribinfo[attrib_base] = {"rreg": rreg, "wreg": wreg, "descr": descr}
-
-
def read_overrides_file(name):
overridere = re.compile(r"#define fGEN_TCG_([A-Za-z0-9_]+)\(.*")
for line in open(name, "rt").readlines():
class OldSource(Source):
def reg_tcg(self):
return f"{self.regtype}{self.regid}V"
+ def is_old(self):
+ return True
+ def is_new(self):
+ return False
class NewSource(Source):
def reg_tcg(self):
return f"{self.regtype}{self.regid}N"
+ def is_old(self):
+ return False
+ def is_new(self):
+ return True
class ReadWrite:
def reg_tcg(self):
return True
def is_readwrite(self):
return True
+ def is_old(self):
+ return True
+ def is_new(self):
+ return False
class GprDest(Register, Single, Dest):
def decl_tcg(self, f, tag, regno):
gen_log_reg_write(ctx, {self.reg_num}, {self.reg_tcg()});
"""))
def analyze_write(self, f, tag, regno):
- self.decl_reg_num(f, regno)
predicated = "true" if is_predicated(tag) else "false"
f.write(code_fmt(f"""\
ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
TCGv {self.reg_tcg()} = hex_gpr[{self.reg_num}];
"""))
def analyze_read(self, f, regno):
- self.decl_reg_num(f, regno)
f.write(code_fmt(f"""\
ctx_log_reg_read(ctx, {self.reg_num});
"""))
TCGv {self.reg_tcg()} = get_result_gpr(ctx, insn->regno[{regno}]);
"""))
def analyze_read(self, f, regno):
- self.decl_reg_num(f, regno)
f.write(code_fmt(f"""\
- ctx_log_reg_read(ctx, {self.reg_num});
+ ctx_log_reg_read_new(ctx, {self.reg_num});
"""))
class GprReadWrite(Register, Single, ReadWrite):
f.write(code_fmt(f"""\
gen_log_reg_write(ctx, {self.reg_num}, {self.reg_tcg()});
"""))
+ def analyze_read(self, f, regno):
+ f.write(code_fmt(f"""\
+ ctx_log_reg_read(ctx, {self.reg_num});
+ """))
def analyze_write(self, f, tag, regno):
- self.decl_reg_num(f, regno)
predicated = "true" if is_predicated(tag) else "false"
f.write(code_fmt(f"""\
ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
gen_write_ctrl_reg(ctx, {self.reg_num}, {self.reg_tcg()});
"""))
def analyze_write(self, f, tag, regno):
- self.decl_reg_num(f, regno)
predicated = "true" if is_predicated(tag) else "false"
f.write(code_fmt(f"""\
ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
gen_read_ctrl_reg(ctx, {self.reg_num}, {self.reg_tcg()});
"""))
def analyze_read(self, f, regno):
- self.decl_reg_num(f, regno)
f.write(code_fmt(f"""\
ctx_log_reg_read(ctx, {self.reg_num});
"""))
declared.append(self.reg_tcg())
declared.append("CS")
def analyze_read(self, f, regno):
- self.decl_reg_num(f, regno)
f.write(code_fmt(f"""\
ctx_log_reg_read(ctx, {self.reg_num});
"""))
gen_log_pred_write(ctx, {self.reg_num}, {self.reg_tcg()});
"""))
def analyze_write(self, f, tag, regno):
- self.decl_reg_num(f, regno)
f.write(code_fmt(f"""\
ctx_log_pred_write(ctx, {self.reg_num});
"""))
TCGv {self.reg_tcg()} = hex_pred[{self.reg_num}];
"""))
def analyze_read(self, f, regno):
- self.decl_reg_num(f, regno)
f.write(code_fmt(f"""\
ctx_log_pred_read(ctx, {self.reg_num});
"""))
TCGv {self.reg_tcg()} = get_result_pred(ctx, insn->regno[{regno}]);
"""))
def analyze_read(self, f, regno):
- self.decl_reg_num(f, regno)
f.write(code_fmt(f"""\
- ctx_log_pred_read(ctx, {self.reg_num});
+ ctx_log_pred_read_new(ctx, {self.reg_num});
"""))
class PredReadWrite(Register, Single, ReadWrite):
f.write(code_fmt(f"""\
gen_log_pred_write(ctx, {self.reg_num}, {self.reg_tcg()});
"""))
+ def analyze_read(self, f, regno):
+ f.write(code_fmt(f"""\
+ ctx_log_pred_read(ctx, {self.reg_num});
+ """))
def analyze_write(self, f, tag, regno):
- self.decl_reg_num(f, regno)
f.write(code_fmt(f"""\
ctx_log_pred_write(ctx, {self.reg_num});
"""))
gen_log_reg_write_pair(ctx, {self.reg_num}, {self.reg_tcg()});
"""))
def analyze_write(self, f, tag, regno):
- self.decl_reg_num(f, regno)
predicated = "true" if is_predicated(tag) else "false"
f.write(code_fmt(f"""\
ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
hex_gpr[{self.reg_num} + 1]);
"""))
def analyze_read(self, f, regno):
- self.decl_reg_num(f, regno)
f.write(code_fmt(f"""\
ctx_log_reg_read_pair(ctx, {self.reg_num});
"""))
f.write(code_fmt(f"""\
gen_log_reg_write_pair(ctx, {self.reg_num}, {self.reg_tcg()});
"""))
+ def analyze_read(self, f, regno):
+ f.write(code_fmt(f"""\
+ ctx_log_reg_read_pair(ctx, {self.reg_num});
+ """))
def analyze_write(self, f, tag, regno):
- self.decl_reg_num(f, regno)
predicated = "true" if is_predicated(tag) else "false"
f.write(code_fmt(f"""\
ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
gen_write_ctrl_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
"""))
def analyze_write(self, f, tag, regno):
- self.decl_reg_num(f, regno)
predicated = "true" if is_predicated(tag) else "false"
f.write(code_fmt(f"""\
ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
gen_read_ctrl_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
"""))
def analyze_read(self, f, regno):
- self.decl_reg_num(f, regno)
f.write(code_fmt(f"""\
ctx_log_reg_read_pair(ctx, {self.reg_num});
"""))
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
"""))
def analyze_write(self, f, tag, regno):
- self.decl_reg_num(f, regno)
newv = hvx_newv(tag)
predicated = "true" if is_predicated(tag) else "false"
f.write(code_fmt(f"""\
- ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated});
+ ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated},
+ insn_has_hvx_helper);
"""))
class VRegSource(Register, Hvx, OldSource):
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
"""))
def analyze_read(self, f, regno):
- self.decl_reg_num(f, regno)
f.write(code_fmt(f"""\
- ctx_log_vreg_read(ctx, {self.reg_num});
+ ctx_log_vreg_read(ctx, {self.reg_num}, insn_has_hvx_helper);
"""))
class VRegNewSource(Register, Hvx, NewSource):
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
"""))
def analyze_read(self, f, regno):
- self.decl_reg_num(f, regno)
f.write(code_fmt(f"""\
- ctx_log_vreg_read(ctx, {self.reg_num});
+ ctx_log_vreg_read_new(ctx, {self.reg_num}, insn_has_hvx_helper);
"""))
class VRegReadWrite(Register, Hvx, ReadWrite):
f.write(code_fmt(f"""\
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
"""))
+ def analyze_read(self, f, regno):
+ f.write(code_fmt(f"""\
+ ctx_log_vreg_read(ctx, {self.reg_num}, insn_has_hvx_helper);
+ """))
def analyze_write(self, f, tag, regno):
- self.decl_reg_num(f, regno)
newv = hvx_newv(tag)
predicated = "true" if is_predicated(tag) else "false"
f.write(code_fmt(f"""\
- ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated});
+ ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated},
+ insn_has_hvx_helper);
"""))
class VRegTmp(Register, Hvx, ReadWrite):
f.write(code_fmt(f"""\
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
"""))
+ def analyze_read(self, f, regno):
+ f.write(code_fmt(f"""\
+ ctx_log_vreg_read(ctx, {self.reg_num}, insn_has_hvx_helper);
+ """))
def analyze_write(self, f, tag, regno):
- self.decl_reg_num(f, regno)
newv = hvx_newv(tag)
predicated = "true" if is_predicated(tag) else "false"
f.write(code_fmt(f"""\
- ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated});
+ ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated},
+ insn_has_hvx_helper);
"""))
class VRegPairDest(Register, Hvx, Dest):
/* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
"""))
def analyze_write(self, f, tag, regno):
- self.decl_reg_num(f, regno)
newv = hvx_newv(tag)
predicated = "true" if is_predicated(tag) else "false"
f.write(code_fmt(f"""\
- ctx_log_vreg_write_pair(ctx, {self.reg_num}, {newv}, {predicated});
+ ctx_log_vreg_write_pair(ctx, {self.reg_num}, {newv}, {predicated},
+ insn_has_hvx_helper);
"""))
class VRegPairSource(Register, Hvx, OldSource):
/* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
"""))
def analyze_read(self, f, regno):
- self.decl_reg_num(f, regno)
f.write(code_fmt(f"""\
- ctx_log_vreg_read_pair(ctx, {self.reg_num});
+ ctx_log_vreg_read_pair(ctx, {self.reg_num}, insn_has_hvx_helper);
"""))
class VRegPairReadWrite(Register, Hvx, ReadWrite):
f.write(code_fmt(f"""\
/* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
"""))
+ def analyze_read(self, f, regno):
+ f.write(code_fmt(f"""\
+ ctx_log_vreg_read_pair(ctx, {self.reg_num}, insn_has_hvx_helper);
+ """))
def analyze_write(self, f, tag, regno):
- self.decl_reg_num(f, regno)
newv = hvx_newv(tag)
predicated = "true" if is_predicated(tag) else "false"
f.write(code_fmt(f"""\
- ctx_log_vreg_write_pair(ctx, {self.reg_num}, {newv}, {predicated});
+ ctx_log_vreg_write_pair(ctx, {self.reg_num}, {newv}, {predicated},
+ insn_has_hvx_helper);
"""))
class QRegDest(Register, Hvx, Dest):
/* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
"""))
def analyze_write(self, f, tag, regno):
- self.decl_reg_num(f, regno)
f.write(code_fmt(f"""\
- ctx_log_qreg_write(ctx, {self.reg_num});
+ ctx_log_qreg_write(ctx, {self.reg_num}, insn_has_hvx_helper);
"""))
class QRegSource(Register, Hvx, OldSource):
/* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
"""))
def analyze_read(self, f, regno):
- self.decl_reg_num(f, regno)
f.write(code_fmt(f"""\
- ctx_log_qreg_read(ctx, {self.reg_num});
+ ctx_log_qreg_read(ctx, {self.reg_num}, insn_has_hvx_helper);
"""))
class QRegReadWrite(Register, Hvx, ReadWrite):
f.write(code_fmt(f"""\
/* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
"""))
+ def analyze_read(self, f, regno):
+ f.write(code_fmt(f"""\
+ ctx_log_qreg_read(ctx, {self.reg_num}, insn_has_hvx_helper);
+ """))
def analyze_write(self, f, tag, regno):
- self.decl_reg_num(f, regno)
f.write(code_fmt(f"""\
- ctx_log_qreg_write(ctx, {self.reg_num});
+ ctx_log_qreg_write(ctx, {self.reg_num}, insn_has_hvx_helper);
"""))
def init_registers():
args = []
## First argument is the CPU state
- args.append(HelperArg(
- "env",
- "tcg_env",
- "CPUHexagonState *env"
- ))
+ if need_env(tag):
+ args.append(HelperArg(
+ "env",
+ "tcg_env",
+ "CPUHexagonState *env"
+ ))
## For predicated instructions, we pass in the destination register
if is_predicated(tag):
"tcg_constant_tl(ctx->next_PC)",
"target_ulong next_PC"
))
+ if need_p0(tag):
+ args.append(HelperArg(
+ "i32",
+ "hex_pred[0]",
+ "uint32_t P0"
+ ))
+ if need_sp(tag):
+ args.append(HelperArg(
+ "i32",
+ "hex_gpr[HEX_REG_SP]",
+ "uint32_t SP"
+ ))
if need_slot(tag):
args.append(HelperArg(
"i32",
"uint32_t part1"
))
return args
+
+
+def read_common_files():
+ read_semantics_file(sys.argv[1])
+ read_overrides_file(sys.argv[2])
+ read_overrides_file(sys.argv[3])
+ ## Whether or not idef-parser is enabled is
+ ## determined by the number of arguments to
+ ## this script:
+ ##
+ ## 4 args. -> not enabled,
+ ## 5 args. -> idef-parser enabled.
+ ##
+ ## The 5:th arg. then holds a list of the successfully
+ ## parsed instructions.
+ is_idef_parser_enabled = len(sys.argv) > 5
+ if is_idef_parser_enabled:
+ read_idef_parser_enabled_file(sys.argv[4])
+ calculate_attribs()
+ init_registers()
+ return is_idef_parser_enabled
/*
- * Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ * Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* 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
uint32_t slot:3;
uint32_t which_extended:1; /* If has an extender, which immediate */
uint32_t new_value_producer_slot:4;
+ int32_t new_read_idx;
+ int32_t dest_idx;
+ bool has_pred_dest;
bool part1; /*
* cmp-jumps are split into two insns.
/*
- * Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ * Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* 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
#define fREAD_LR() (env->gpr[HEX_REG_LR])
-#define fREAD_SP() (env->gpr[HEX_REG_SP])
+#define fREAD_SP() (SP)
#define fREAD_LC0 (env->gpr[HEX_REG_LC0])
#define fREAD_LC1 (env->gpr[HEX_REG_LC1])
#define fREAD_SA0 (env->gpr[HEX_REG_SA0])
#endif
#define fREAD_PC() (PC)
-#define fREAD_P0() (env->pred[0])
+#define fREAD_P0() (P0)
#define fCHECK_PCALIGN(A)
##
-## Copyright(c) 2020-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+## Copyright(c) 2020-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
##
## 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
hexagon_ss = ss.source_set()
hex_common_py = 'hex_common.py'
-attribs_def = meson.current_source_dir() / 'attribs_def.h.inc'
gen_tcg_h = meson.current_source_dir() / 'gen_tcg.h'
gen_tcg_hvx_h = meson.current_source_dir() / 'gen_tcg_hvx.h'
idef_parser_dir = meson.current_source_dir() / 'idef-parser'
#
# Step 2
# We use Python scripts to generate the following files
-# shortcode_generated.h.inc
# tcg_func_table_generated.c.inc
# printinsn_generated.h.inc
-# op_regs_generated.h.inc
# op_attribs_generated.h.inc
# opcodes_def_generated.h.inc
#
-shortcode_generated = custom_target(
- 'shortcode_generated.h.inc',
- output: 'shortcode_generated.h.inc',
- depends: [semantics_generated],
- depend_files: [hex_common_py, attribs_def],
- command: [python, files('gen_shortcode.py'), semantics_generated, attribs_def, '@OUTPUT@'],
-)
-hexagon_ss.add(shortcode_generated)
-
tcg_func_table_generated = custom_target(
'tcg_func_table_generated.c.inc',
output: 'tcg_func_table_generated.c.inc',
depends: [semantics_generated],
- depend_files: [hex_common_py, attribs_def],
- command: [python, files('gen_tcg_func_table.py'), semantics_generated, attribs_def, '@OUTPUT@'],
+ depend_files: [hex_common_py],
+ command: [python, files('gen_tcg_func_table.py'), semantics_generated, '@OUTPUT@'],
)
hexagon_ss.add(tcg_func_table_generated)
'printinsn_generated.h.inc',
output: 'printinsn_generated.h.inc',
depends: [semantics_generated],
- depend_files: [hex_common_py, attribs_def],
- command: [python, files('gen_printinsn.py'), semantics_generated, attribs_def, '@OUTPUT@'],
+ depend_files: [hex_common_py],
+ command: [python, files('gen_printinsn.py'), semantics_generated, '@OUTPUT@'],
)
hexagon_ss.add(printinsn_generated)
-op_regs_generated = custom_target(
- 'op_regs_generated.h.inc',
- output: 'op_regs_generated.h.inc',
- depends: [semantics_generated],
- depend_files: [hex_common_py, attribs_def],
- command: [python, files('gen_op_regs.py'), semantics_generated, attribs_def, '@OUTPUT@'],
-)
-hexagon_ss.add(op_regs_generated)
-
op_attribs_generated = custom_target(
'op_attribs_generated.h.inc',
output: 'op_attribs_generated.h.inc',
depends: [semantics_generated],
- depend_files: [hex_common_py, attribs_def],
- command: [python, files('gen_op_attribs.py'), semantics_generated, attribs_def, '@OUTPUT@'],
+ depend_files: [hex_common_py],
+ command: [python, files('gen_op_attribs.py'), semantics_generated, '@OUTPUT@'],
)
hexagon_ss.add(op_attribs_generated)
'opcodes_def_generated.h.inc',
output: 'opcodes_def_generated.h.inc',
depends: [semantics_generated],
- depend_files: [hex_common_py, attribs_def],
- command: [python, files('gen_opcodes_def.py'), semantics_generated, attribs_def, '@OUTPUT@'],
+ depend_files: [hex_common_py],
+ command: [python, files('gen_opcodes_def.py'), semantics_generated, '@OUTPUT@'],
)
hexagon_ss.add(opcodes_def_generated)
#
gen_dectree_import = executable(
'gen_dectree_import',
- 'gen_dectree_import.c', opcodes_def_generated, op_regs_generated,
+ 'gen_dectree_import.c', opcodes_def_generated,
native: true, build_by_default: false)
iset_py = custom_target(
output: 'idef_parser_input.h.inc',
depends: [semantics_generated],
depend_files: [hex_common_py],
- command: [python, files('gen_idef_parser_funcs.py'), semantics_generated, attribs_def, '@OUTPUT@'],
+ command: [python, files('gen_idef_parser_funcs.py'), semantics_generated, '@OUTPUT@'],
)
preprocessed_idef_parser_input_generated = custom_target(
# Setup input and dependencies for the next step, this depends on whether or
# not idef-parser is enabled
helper_dep = [semantics_generated, idef_generated_tcg_c, idef_generated_tcg]
- helper_in = [semantics_generated, attribs_def, gen_tcg_h, gen_tcg_hvx_h, idef_generated_list]
+ helper_in = [semantics_generated, gen_tcg_h, gen_tcg_hvx_h, idef_generated_list]
else
# Setup input and dependencies for the next step, this depends on whether or
# not idef-parser is enabled
helper_dep = [semantics_generated]
- helper_in = [semantics_generated, attribs_def, gen_tcg_h, gen_tcg_hvx_h]
+ helper_in = [semantics_generated, gen_tcg_h, gen_tcg_hvx_h]
endif
#
'helper_protos_generated.h.inc',
output: 'helper_protos_generated.h.inc',
depends: helper_dep,
- depend_files: [hex_common_py, attribs_def, gen_tcg_h, gen_tcg_hvx_h],
+ depend_files: [hex_common_py, gen_tcg_h, gen_tcg_hvx_h],
command: [python, files('gen_helper_protos.py'), helper_in, '@OUTPUT@'],
)
hexagon_ss.add(helper_protos_generated)
'helper_funcs_generated.c.inc',
output: 'helper_funcs_generated.c.inc',
depends: helper_dep,
- depend_files: [hex_common_py, attribs_def, gen_tcg_h, gen_tcg_hvx_h],
+ depend_files: [hex_common_py, gen_tcg_h, gen_tcg_hvx_h],
command: [python, files('gen_helper_funcs.py'), helper_in, '@OUTPUT@'],
)
hexagon_ss.add(helper_funcs_generated)
'tcg_funcs_generated.c.inc',
output: 'tcg_funcs_generated.c.inc',
depends: helper_dep,
- depend_files: [hex_common_py, attribs_def, gen_tcg_h, gen_tcg_hvx_h],
+ depend_files: [hex_common_py, gen_tcg_h, gen_tcg_hvx_h],
command: [python, files('gen_tcg_funcs.py'), helper_in, '@OUTPUT@'],
)
hexagon_ss.add(tcg_funcs_generated)
'analyze_funcs_generated.c.inc',
output: 'analyze_funcs_generated.c.inc',
depends: helper_dep,
- depend_files: [hex_common_py, attribs_def, gen_tcg_h, gen_tcg_hvx_h],
+ depend_files: [hex_common_py, gen_tcg_h, gen_tcg_hvx_h],
command: [python, files('gen_analyze_funcs.py'), helper_in, '@OUTPUT@'],
)
hexagon_ss.add(analyze_funcs_generated)
{
/* .new value for a MMVector store */
int i, j;
- const char *reginfo;
- const char *destletters;
- const char *dststr = NULL;
uint16_t def_opcode;
- char letter;
for (i = 1; i < pkt->num_insns; i++) {
uint16_t use_opcode = pkt->insn[i].opcode;
if (GET_ATTRIB(use_opcode, A_DOTNEWVALUE) &&
GET_ATTRIB(use_opcode, A_CVI) &&
GET_ATTRIB(use_opcode, A_STORE)) {
- int use_regidx = strchr(opcode_reginfo[use_opcode], 's') -
- opcode_reginfo[use_opcode];
+ int use_regidx = pkt->insn[i].new_read_idx;
+ g_assert(pkt->insn[i].new_read_idx != -1);
/*
* What's encoded at the N-field is the offset to who's producing
* the value.
/* def_idx is the index of the producer */
def_opcode = pkt->insn[def_idx].opcode;
- reginfo = opcode_reginfo[def_opcode];
- destletters = "dexy";
- for (j = 0; (letter = destletters[j]) != 0; j++) {
- dststr = strchr(reginfo, letter);
- if (dststr != NULL) {
- break;
- }
- }
- if ((dststr == NULL) && GET_ATTRIB(def_opcode, A_CVI_GATHER)) {
+ if ((pkt->insn[def_idx].dest_idx == -1) &&
+ GET_ATTRIB(def_opcode, A_CVI_GATHER)) {
pkt->insn[i].regno[use_regidx] = def_oreg;
pkt->insn[i].new_value_producer_slot = pkt->insn[def_idx].slot;
} else {
- if (dststr == NULL) {
+ if (pkt->insn[def_idx].dest_idx == -1) {
/* still not there, we have a bad packet */
g_assert_not_reached();
}
- int def_regnum = pkt->insn[def_idx].regno[dststr - reginfo];
+ int def_regnum =
+ pkt->insn[def_idx].regno[pkt->insn[def_idx].dest_idx];
/* Now patch up the consumer with the register number */
pkt->insn[i].regno[use_regidx] = def_regnum ^ def_oreg;
- /* special case for (Vx,Vy) */
- dststr = strchr(reginfo, 'y');
- if (def_oreg && strchr(reginfo, 'x') && dststr) {
- def_regnum = pkt->insn[def_idx].regno[dststr - reginfo];
- pkt->insn[i].regno[use_regidx] = def_regnum;
- }
/*
* We need to remember who produces this value to later
* check if it was dynamically cancelled
#undef OPCODE
};
-const char * const opcode_reginfo[] = {
-#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing */
-#define REGINFO(TAG, REGINFO, RREGS, WREGS) REGINFO,
-#include "op_regs_generated.h.inc"
- NULL
-#undef REGINFO
-#undef IMMINFO
-};
-
-
-const char * const opcode_rregs[] = {
-#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing */
-#define REGINFO(TAG, REGINFO, RREGS, WREGS) RREGS,
-#include "op_regs_generated.h.inc"
- NULL
-#undef REGINFO
-#undef IMMINFO
-};
-
-
-const char * const opcode_wregs[] = {
-#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing */
-#define REGINFO(TAG, REGINFO, RREGS, WREGS) WREGS,
-#include "op_regs_generated.h.inc"
- NULL
-#undef REGINFO
-#undef IMMINFO
-};
-
-const char * const opcode_short_semantics[] = {
-#define DEF_SHORTCODE(TAG, SHORTCODE) [TAG] = #SHORTCODE,
-#include "shortcode_generated.h.inc"
-#undef DEF_SHORTCODE
- NULL
-};
DECLARE_BITMAP(opcode_attribs[XX_LAST_OPCODE], A_ZZ_LASTATTRIB);
extern const char * const opcode_names[];
-extern const char * const opcode_reginfo[];
-extern const char * const opcode_rregs[];
-extern const char * const opcode_wregs[];
-
typedef struct {
const char * const encoding;
const EncClass enc_class;
/*
- * Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ * Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* 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
return true;
}
- if (pkt->num_insns == 1) {
- if (pkt->pkt_has_hvx) {
- /*
- * The HVX instructions with generated helpers use
- * pass-by-reference, so they need the read/write overlap
- * check below.
- * The HVX instructions with overrides are OK.
- */
- if (!ctx->has_hvx_helper) {
- return false;
- }
- } else {
- return false;
- }
- }
-
- /* Check for overlap between register reads and writes */
- for (int i = 0; i < ctx->reg_log_idx; i++) {
- int rnum = ctx->reg_log[i];
- if (test_bit(rnum, ctx->regs_read)) {
- return true;
- }
- }
-
- /* Check for overlap between predicate reads and writes */
- for (int i = 0; i < ctx->preg_log_idx; i++) {
- int pnum = ctx->preg_log[i];
- if (test_bit(pnum, ctx->pregs_read)) {
- return true;
- }
- }
-
- /* Check for overlap between HVX reads and writes */
- for (int i = 0; i < ctx->vreg_log_idx; i++) {
- int vnum = ctx->vreg_log[i];
- if (test_bit(vnum, ctx->vregs_read)) {
- return true;
- }
- }
- if (!bitmap_empty(ctx->vregs_updated_tmp, NUM_VREGS)) {
- int i = find_first_bit(ctx->vregs_updated_tmp, NUM_VREGS);
- while (i < NUM_VREGS) {
- if (test_bit(i, ctx->vregs_read)) {
- return true;
- }
- i = find_next_bit(ctx->vregs_updated_tmp, NUM_VREGS, i + 1);
- }
- }
- if (!bitmap_empty(ctx->vregs_select, NUM_VREGS)) {
- int i = find_first_bit(ctx->vregs_select, NUM_VREGS);
- while (i < NUM_VREGS) {
- if (test_bit(i, ctx->vregs_read)) {
- return true;
- }
- i = find_next_bit(ctx->vregs_select, NUM_VREGS, i + 1);
- }
- }
-
- /* Check for overlap between HVX predicate reads and writes */
- for (int i = 0; i < ctx->qreg_log_idx; i++) {
- int qnum = ctx->qreg_log[i];
- if (test_bit(qnum, ctx->qregs_read)) {
- return true;
- }
+ if (ctx->read_after_write || ctx->has_hvx_overlap) {
+ return true;
}
return false;
static void analyze_packet(DisasContext *ctx)
{
Packet *pkt = ctx->pkt;
- ctx->has_hvx_helper = false;
+ ctx->read_after_write = false;
+ ctx->has_hvx_overlap = false;
for (int i = 0; i < pkt->num_insns; i++) {
Insn *insn = &pkt->insn[i];
ctx->insn = insn;
ctx->next_PC = next_PC;
ctx->reg_log_idx = 0;
bitmap_zero(ctx->regs_written, TOTAL_PER_THREAD_REGS);
- bitmap_zero(ctx->regs_read, TOTAL_PER_THREAD_REGS);
bitmap_zero(ctx->predicated_regs, TOTAL_PER_THREAD_REGS);
ctx->preg_log_idx = 0;
bitmap_zero(ctx->pregs_written, NUM_PREGS);
- bitmap_zero(ctx->pregs_read, NUM_PREGS);
ctx->future_vregs_idx = 0;
ctx->tmp_vregs_idx = 0;
ctx->vreg_log_idx = 0;
+ bitmap_zero(ctx->vregs_written, NUM_VREGS);
bitmap_zero(ctx->vregs_updated_tmp, NUM_VREGS);
bitmap_zero(ctx->vregs_updated, NUM_VREGS);
bitmap_zero(ctx->vregs_select, NUM_VREGS);
bitmap_zero(ctx->predicated_future_vregs, NUM_VREGS);
bitmap_zero(ctx->predicated_tmp_vregs, NUM_VREGS);
- bitmap_zero(ctx->vregs_read, NUM_VREGS);
- bitmap_zero(ctx->qregs_read, NUM_QREGS);
+ bitmap_zero(ctx->qregs_written, NUM_QREGS);
ctx->qreg_log_idx = 0;
for (i = 0; i < STORES_MAX; i++) {
ctx->store_width[i] = 0;
/*
- * Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ * Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* 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
int reg_log[REG_WRITES_MAX];
int reg_log_idx;
DECLARE_BITMAP(regs_written, TOTAL_PER_THREAD_REGS);
- DECLARE_BITMAP(regs_read, TOTAL_PER_THREAD_REGS);
DECLARE_BITMAP(predicated_regs, TOTAL_PER_THREAD_REGS);
int preg_log[PRED_WRITES_MAX];
int preg_log_idx;
DECLARE_BITMAP(pregs_written, NUM_PREGS);
- DECLARE_BITMAP(pregs_read, NUM_PREGS);
uint8_t store_width[STORES_MAX];
bool s1_store_processed;
int future_vregs_idx;
int tmp_vregs_num[VECTOR_TEMPS_MAX];
int vreg_log[NUM_VREGS];
int vreg_log_idx;
+ DECLARE_BITMAP(vregs_written, NUM_VREGS);
+ DECLARE_BITMAP(insn_vregs_written, NUM_VREGS);
DECLARE_BITMAP(vregs_updated_tmp, NUM_VREGS);
DECLARE_BITMAP(vregs_updated, NUM_VREGS);
DECLARE_BITMAP(vregs_select, NUM_VREGS);
DECLARE_BITMAP(predicated_future_vregs, NUM_VREGS);
DECLARE_BITMAP(predicated_tmp_vregs, NUM_VREGS);
- DECLARE_BITMAP(vregs_read, NUM_VREGS);
+ DECLARE_BITMAP(insn_vregs_read, NUM_VREGS);
int qreg_log[NUM_QREGS];
int qreg_log_idx;
- DECLARE_BITMAP(qregs_read, NUM_QREGS);
+ DECLARE_BITMAP(qregs_written, NUM_QREGS);
+ DECLARE_BITMAP(insn_qregs_written, NUM_QREGS);
+ DECLARE_BITMAP(insn_qregs_read, NUM_QREGS);
bool pre_commit;
bool need_commit;
TCGCond branch_cond;
target_ulong branch_dest;
bool is_tight_loop;
bool short_circuit;
- bool has_hvx_helper;
+ bool read_after_write;
+ bool has_hvx_overlap;
TCGv new_value[TOTAL_PER_THREAD_REGS];
TCGv new_pred_value[NUM_PREGS];
TCGv pred_written;
TCGv dczero_addr;
} DisasContext;
+bool is_gather_store_insn(DisasContext *ctx);
+
static inline void ctx_log_pred_write(DisasContext *ctx, int pnum)
{
if (!test_bit(pnum, ctx->pregs_written)) {
static inline void ctx_log_pred_read(DisasContext *ctx, int pnum)
{
- set_bit(pnum, ctx->pregs_read);
+ if (test_bit(pnum, ctx->pregs_written)) {
+ ctx->read_after_write = true;
+ }
+}
+
+static inline void ctx_log_pred_read_new(DisasContext *ctx, int pnum)
+{
+ g_assert(test_bit(pnum, ctx->pregs_written));
}
static inline void ctx_log_reg_write(DisasContext *ctx, int rnum,
static inline void ctx_log_reg_read(DisasContext *ctx, int rnum)
{
- set_bit(rnum, ctx->regs_read);
+ if (test_bit(rnum, ctx->regs_written)) {
+ ctx->read_after_write = true;
+ }
+}
+
+static inline void ctx_log_reg_read_new(DisasContext *ctx, int rnum)
+{
+ g_assert(test_bit(rnum, ctx->regs_written));
}
static inline void ctx_log_reg_read_pair(DisasContext *ctx, int rnum)
intptr_t ctx_tmp_vreg_off(DisasContext *ctx, int regnum,
int num, bool alloc_ok);
+static inline void ctx_start_hvx_insn(DisasContext *ctx)
+{
+ bitmap_zero(ctx->insn_vregs_written, NUM_VREGS);
+ bitmap_zero(ctx->insn_vregs_read, NUM_VREGS);
+ bitmap_zero(ctx->insn_qregs_written, NUM_QREGS);
+ bitmap_zero(ctx->insn_qregs_read, NUM_QREGS);
+}
+
static inline void ctx_log_vreg_write(DisasContext *ctx,
int rnum, VRegWriteType type,
- bool is_predicated)
+ bool is_predicated, bool has_helper)
{
+ if (has_helper) {
+ set_bit(rnum, ctx->insn_vregs_written);
+ if (test_bit(rnum, ctx->insn_vregs_read)) {
+ ctx->has_hvx_overlap = true;
+ }
+ }
+ set_bit(rnum, ctx->vregs_written);
if (type != EXT_TMP) {
if (!test_bit(rnum, ctx->vregs_updated)) {
ctx->vreg_log[ctx->vreg_log_idx] = rnum;
static inline void ctx_log_vreg_write_pair(DisasContext *ctx,
int rnum, VRegWriteType type,
- bool is_predicated)
+ bool is_predicated, bool has_helper)
{
- ctx_log_vreg_write(ctx, rnum ^ 0, type, is_predicated);
- ctx_log_vreg_write(ctx, rnum ^ 1, type, is_predicated);
+ ctx_log_vreg_write(ctx, rnum ^ 0, type, is_predicated, has_helper);
+ ctx_log_vreg_write(ctx, rnum ^ 1, type, is_predicated, has_helper);
}
-static inline void ctx_log_vreg_read(DisasContext *ctx, int rnum)
+static inline void ctx_log_vreg_read(DisasContext *ctx, int rnum,
+ bool has_helper)
{
- set_bit(rnum, ctx->vregs_read);
+ if (has_helper) {
+ set_bit(rnum, ctx->insn_vregs_read);
+ if (test_bit(rnum, ctx->insn_vregs_written)) {
+ ctx->has_hvx_overlap = true;
+ }
+ }
+ if (test_bit(rnum, ctx->vregs_written)) {
+ ctx->read_after_write = true;
+ }
}
-static inline void ctx_log_vreg_read_pair(DisasContext *ctx, int rnum)
+static inline void ctx_log_vreg_read_new(DisasContext *ctx, int rnum,
+ bool has_helper)
{
- ctx_log_vreg_read(ctx, rnum ^ 0);
- ctx_log_vreg_read(ctx, rnum ^ 1);
+ g_assert(is_gather_store_insn(ctx) ||
+ test_bit(rnum, ctx->vregs_updated) ||
+ test_bit(rnum, ctx->vregs_select) ||
+ test_bit(rnum, ctx->vregs_updated_tmp));
+ if (has_helper) {
+ set_bit(rnum, ctx->insn_vregs_read);
+ if (test_bit(rnum, ctx->insn_vregs_written)) {
+ ctx->has_hvx_overlap = true;
+ }
+ }
+ if (is_gather_store_insn(ctx)) {
+ ctx->read_after_write = true;
+ }
+}
+
+static inline void ctx_log_vreg_read_pair(DisasContext *ctx, int rnum,
+ bool has_helper)
+{
+ ctx_log_vreg_read(ctx, rnum ^ 0, has_helper);
+ ctx_log_vreg_read(ctx, rnum ^ 1, has_helper);
}
static inline void ctx_log_qreg_write(DisasContext *ctx,
- int rnum)
+ int rnum, bool has_helper)
{
+ if (has_helper) {
+ set_bit(rnum, ctx->insn_qregs_written);
+ if (test_bit(rnum, ctx->insn_qregs_read)) {
+ ctx->has_hvx_overlap = true;
+ }
+ }
+ set_bit(rnum, ctx->qregs_written);
ctx->qreg_log[ctx->qreg_log_idx] = rnum;
ctx->qreg_log_idx++;
}
-static inline void ctx_log_qreg_read(DisasContext *ctx, int qnum)
+static inline void ctx_log_qreg_read(DisasContext *ctx,
+ int qnum, bool has_helper)
{
- set_bit(qnum, ctx->qregs_read);
+ if (has_helper) {
+ set_bit(qnum, ctx->insn_qregs_read);
+ if (test_bit(qnum, ctx->insn_qregs_written)) {
+ ctx->has_hvx_overlap = true;
+ }
+ }
+ if (test_bit(qnum, ctx->qregs_written)) {
+ ctx->read_after_write = true;
+ }
}
extern TCGv hex_gpr[TOTAL_PER_THREAD_REGS];
extern TCGv hex_vstore_size[VSTORES_MAX];
extern TCGv hex_vstore_pending[VSTORES_MAX];
-bool is_gather_store_insn(DisasContext *ctx);
void process_store(DisasContext *ctx, int slot_num);
FIELD(PROBE_PKT_SCALAR_STORE_S0, MMU_IDX, 0, 2)
{
HPPACPU *cpu = HPPA_CPU(cs);
- tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ tcg_debug_assert(!tcg_cflags_has(cs, CF_PCREL));
#ifdef CONFIG_USER_ONLY
cpu->env.iaoq_f = tb->pc;
#include "qemu/log.h"
#include "cpu.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "exec/helper-proto.h"
#include "hw/core/cpu.h"
#include "trace.h"
#include "disas/disas.h"
#include "qemu/host-utils.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "tcg/tcg-op.h"
#include "tcg/tcg-op-gvec.h"
#include "exec/helper-proto.h"
config I386
bool
+ # kvm_arch_fixup_msi_route() needs to access PCIDevice
+ select PCI if KVM
config X86_64
bool
+ select I386
{ /* end of list */ }
}
},
+ {
+ .version = 3,
+ .props = (PropValue[]) {
+ { "ss", "on" },
+ { "tsc-adjust", "on" },
+ { "cldemote", "on" },
+ { "movdiri", "on" },
+ { "movdir64b", "on" },
+ { /* end of list */ }
+ }
+ },
{ /* end of list */ }
}
},
#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
/* Use pc-relative instructions in system-mode */
- cs->tcg_cflags |= CF_PCREL;
+ tcg_cflags_set(cs, CF_PCREL);
#endif
if (cpu->apic_id == UNASSIGNED_APIC_ID) {
}
/* Per x86_restore_state_to_opc. */
- if (cs->tcg_cflags & CF_PCREL) {
+ if (tcg_cflags_has(cs, CF_PCREL)) {
return (env->eip & TARGET_PAGE_MASK) | data[0];
} else {
return data[0] - env->segs[R_CS].base;
#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 {
static void
do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr)
{
+ bool inhibit_reset;
+
gen_update_cc_op(s);
/* If several instructions disable interrupts, only the first does it. */
- if (inhibit && !(s->flags & HF_INHIBIT_IRQ_MASK)) {
- gen_set_hflag(s, HF_INHIBIT_IRQ_MASK);
- } else {
+ inhibit_reset = false;
+ if (s->flags & HF_INHIBIT_IRQ_MASK) {
gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK);
+ inhibit_reset = true;
+ } else if (inhibit) {
+ gen_set_hflag(s, HF_INHIBIT_IRQ_MASK);
}
if (s->base.tb->flags & HF_RF_MASK) {
tcg_gen_exit_tb(NULL, 0);
} else if (s->flags & HF_TF_MASK) {
gen_helper_single_step(tcg_env);
- } else if (jr) {
+ } else if (jr &&
+ /* give irqs a chance to happen */
+ !inhibit_reset) {
tcg_gen_lookup_and_goto_ptr();
} else {
tcg_gen_exit_tb(NULL, 0);
static void loongarch_cpu_synchronize_from_tb(CPUState *cs,
const TranslationBlock *tb)
{
- tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ tcg_debug_assert(!tcg_cflags_has(cs, CF_PCREL));
set_pc(cpu_env(cs), tb->pc);
}
#include "internals.h"
#include "exec/helper-proto.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "exec/cpu_ldst.h"
#include "exec/log.h"
#include "cpu-csr.h"
#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "exec/gdbstub.h"
#include "exec/helper-proto.h"
#include "gdbstub/helpers.h"
{
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
- tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ tcg_debug_assert(!tcg_cflags_has(cs, CF_PCREL));
cpu->env.pc = tb->pc;
cpu->env.iflags = tb->flags & IFLAGS_TB_MASK;
}
#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "qemu/host-utils.h"
#include "exec/log.h"
if (mmu_idx == MMU_NOMMU_IDX) {
/* MMU disabled or not available. */
address &= TARGET_PAGE_MASK;
- prot = PAGE_BITS;
+ prot = PAGE_RWX;
tlb_set_page_with_attrs(cs, address, address, attrs, prot, mmu_idx,
TARGET_PAGE_SIZE);
return true;
#include "qemu/log.h"
#include "cpu.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
static unsigned int tlb_decode_size(unsigned int f)
{
#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)
{
CPUMIPSState *env = cpu_env(cs);
- tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ tcg_debug_assert(!tcg_cflags_has(cs, CF_PCREL));
env->active_tc.PC = tb->pc;
env->hflags &= ~MIPS_HFLAG_BMASK;
env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
CPUMIPSState *env = cpu_env(cs);
if ((env->hflags & MIPS_HFLAG_BMASK) != 0
- && !(cs->tcg_cflags & CF_PCREL) && env->active_tc.PC != tb->pc) {
+ && !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;
#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"
{
OpenRISCCPU *cpu = OPENRISC_CPU(cs);
- tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ tcg_debug_assert(!tcg_cflags_has(cs, CF_PCREL));
cpu->env.pc = tb->pc;
}
#include "qemu/log.h"
#include "cpu.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "gdbstub/helpers.h"
#include "qemu/host-utils.h"
#include "hw/loader.h"
config PPC64
bool
+ select PPC
#include "exec/breakpoint.h"
#include "hw/registerfields.h"
+#include "exec/page-protection.h"
/* PM instructions */
typedef enum {
#include "elf.h"
#include "sysemu/kvm_int.h"
+#include CONFIG_DEVICES
+
#define PROC_DEVTREE_CPU "/proc/device-tree/cpus/"
#define DEBUG_RETURN_GUEST 0
static int cap_one_reg;
static int cap_epr;
static int cap_ppc_watchdog;
-static int cap_papr;
static int cap_htab_fd;
static int cap_fixup_hcalls;
static int cap_htm; /* Hardware transactional memory support */
static int cap_rpt_invalidate;
static int cap_ail_mode_3;
+#ifdef CONFIG_PSERIES
+static int cap_papr;
+#else
+#define cap_papr (0)
+#endif
+
static uint32_t debug_inst_opcode;
/*
trace_kvm_handle_halt();
ret = kvmppc_handle_halt(cpu);
break;
-#if defined(TARGET_PPC64)
+#if defined(CONFIG_PSERIES)
case KVM_EXIT_PAPR_HCALL:
trace_kvm_handle_papr_hcall(run->papr_hcall.nr);
run->papr_hcall.ret = spapr_hypercall(cpu,
ret = 0;
break;
-#if defined(TARGET_PPC64)
+#if defined(CONFIG_PSERIES)
case KVM_EXIT_NMI:
trace_kvm_handle_nmi_exception();
ret = kvm_handle_nmi(cpu, run);
kvmppc_enable_hcall(kvm_state, H_RPT_INVALIDATE);
}
+#ifdef CONFIG_PSERIES
void kvmppc_set_papr(PowerPCCPU *cpu)
{
CPUState *cs = CPU(cpu);
*/
cap_papr = 1;
}
+#endif
int kvmppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr)
{
return data & 0xffff;
}
-#if defined(TARGET_PPC64)
+#if defined(CONFIG_PSERIES)
int kvm_handle_nmi(PowerPCCPU *cpu, struct kvm_run *run)
{
uint16_t flags = run->flags & KVM_RUN_PPC_NMI_DISP_MASK;
#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "sysemu/kvm.h"
#include "kvm_ppc.h"
#include "internal.h"
#include "qemu/units.h"
#include "cpu.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "qemu/error-report.h"
#include "qemu/qemu-print.h"
#include "sysemu/hw_accel.h"
#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "qemu/error-report.h"
#include "sysemu/kvm.h"
#include "kvm_ppc.h"
#ifndef CONFIG_USER_ONLY
+#include "exec/page-protection.h"
+
/* Radix Quadrants */
#define R_EADDR_MASK 0x3FFFFFFFFFFFFFFF
#define R_EADDR_VALID_MASK 0xC00FFFFFFFFFFFFF
#include "mmu-hash64.h"
#include "mmu-hash32.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "exec/log.h"
#include "helper_regs.h"
#include "qemu/error-report.h"
#include "mmu-hash64.h"
#include "mmu-hash32.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "exec/log.h"
#include "helper_regs.h"
#include "qemu/error-report.h"
#include "internals.h"
#include "pmu.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "instmap.h"
#include "tcg/tcg-op.h"
#include "trace.h"
#include "cpu.h"
#include "trace.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
static bool pmp_write_cfg(CPURISCVState *env, uint32_t addr_index,
uint8_t val);
CPURISCVState *env = &cpu->env;
RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
- tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ tcg_debug_assert(!tcg_cflags_has(cs, CF_PCREL));
if (xl == MXL_RV32) {
env->pc = (int32_t) tb->pc;
CPURISCVState *env = &cpu->env;
Error *local_err = NULL;
- CPU(cs)->tcg_cflags |= CF_PCREL;
+ tcg_cflags_set(CPU(cs), CF_PCREL);
if (cpu->cfg.ext_sstc) {
riscv_timer_init(cpu);
#include "exec/memop.h"
#include "exec/exec-all.h"
#include "exec/cpu_ldst.h"
+#include "exec/page-protection.h"
#include "exec/helper-proto.h"
#include "fpu/softfloat.h"
#include "tcg/tcg-gvec-desc.h"
#include "cpu.h"
#include "migration/vmstate.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "hw/loader.h"
#include "fpu/softfloat.h"
#include "tcg/debug-assert.h"
{
RXCPU *cpu = RX_CPU(cs);
- tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ tcg_debug_assert(!tcg_cflags_has(cs, CF_PCREL));
cpu->env.pc = tb->pc;
}
#include "sysemu/kvm.h"
#include "sysemu/tcg.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "trace.h"
#include "hw/hw.h"
#include "hw/s390x/storage-keys.h"
#include "tcg_s390x.h"
#include "exec/helper-proto.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "exec/cpu_ldst.h"
#include "hw/core/tcg-cpu-ops.h"
#include "qemu/int128.h"
{
SuperHCPU *cpu = SUPERH_CPU(cs);
- tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ tcg_debug_assert(!tcg_cflags_has(cs, CF_PCREL));
cpu->env.pc = tb->pc;
cpu->env.flags = tb->flags & TB_FLAG_ENVFLAGS_MASK;
}
CPUSH4State *env = cpu_env(cs);
if ((env->flags & (TB_FLAG_DELAY_SLOT | TB_FLAG_DELAY_SLOT_COND))
- && !(cs->tcg_cflags & CF_PCREL) && env->pc != tb->pc) {
+ && !tcg_cflags_has(cs, CF_PCREL) && env->pc != tb->pc) {
env->pc -= 2;
env->flags &= ~(TB_FLAG_DELAY_SLOT | TB_FLAG_DELAY_SLOT_COND);
return true;
#include "cpu.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "exec/log.h"
#if !defined(CONFIG_USER_ONLY)
{
SPARCCPU *cpu = SPARC_CPU(cs);
- tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ tcg_debug_assert(!tcg_cflags_has(cs, CF_PCREL));
cpu->env.pc = tb->pc;
cpu->env.npc = tb->cs_base;
}
#include "tcg/tcg.h"
#include "exec/helper-proto.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "exec/cpu_ldst.h"
#include "asi.h"
#include "qemu/log.h"
#include "cpu.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "qemu/qemu-print.h"
#include "trace.h"
static void tricore_cpu_synchronize_from_tb(CPUState *cs,
const TranslationBlock *tb)
{
- tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ tcg_debug_assert(!tcg_cflags_has(cs, CF_PCREL));
cpu_env(cs)->PC = tb->pc;
}
#include "hw/registerfields.h"
#include "cpu.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#include "fpu/softfloat-helpers.h"
#include "qemu/qemu-print.h"
#include "exec/helper-proto.h"
#include "qemu/host-utils.h"
#include "exec/exec-all.h"
+#include "exec/page-protection.h"
#define XTENSA_MPU_SEGMENT_MASK 0x0000001f
#define XTENSA_MPU_ACC_RIGHTS_MASK 0x00000f00
#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/helper-proto.h"
+#include "exec/page-protection.h"
#include "qemu/host-utils.h"
#include "exec/exec-all.h"
#include "qemu/atomic.h"
self._print_if(ifcond)
def visit_object_type(self, name, info, ifcond, features,
- base, members, variants):
+ base, members, branches):
print('object %s' % name)
if base:
print(' base %s' % base.name)
% (m.name, m.type.name, m.optional))
self._print_if(m.ifcond, 8)
self._print_features(m.features, indent=8)
- self._print_variants(variants)
+ self._print_variants(branches)
self._print_if(ifcond)
self._print_features(features)
- def visit_alternate_type(self, name, info, ifcond, features, variants):
+ def visit_alternate_type(self, name, info, ifcond, features,
+ alternatives):
print('alternate %s' % name)
- self._print_variants(variants)
+ self._print_variants(alternatives)
self._print_if(ifcond)
self._print_features(features)
base_setup();
g_test_init(&argc, &argv, NULL);
-
- if (g_test_slow()) {
- /* Do not run this in timing-sensitive environments */
- qtest_add_func("/rtc/bcd-check-time", bcd_check_time);
+ if (qtest_has_machine(base_machine)) {
+ if (g_test_slow()) {
+ /* Do not run this in timing-sensitive environments */
+ qtest_add_func("/rtc/bcd-check-time", bcd_check_time);
+ }
+ qtest_add_func("/rtc/fuzz-registers", fuzz_registers);
}
- qtest_add_func("/rtc/fuzz-registers", fuzz_registers);
return g_test_run();
}
/*
- * Copyright(c) 2021-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ * Copyright(c) 2021-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* 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
static void test_new_value_store(void)
{
void *p0 = buffer0;
+ void *p1 = buffer1;
void *pout = output;
asm("{\n\t"
expect[0] = buffer0[0];
check_output_w(__LINE__, 1);
+
+ /* Test the .new read from the high half of a pair */
+ asm("v7 = vmem(%0 + #0)\n\t"
+ "v12 = vmem(%1 + #0)\n\t"
+ "{\n\t"
+ " v5:4 = vcombine(v12, v7)\n\t"
+ " vmem(%2 + #0) = v5.new\n\t"
+ "}\n\t"
+ : : "r"(p0), "r"(p1), "r"(pout) : "v4", "v5", "v7", "v12", "memory");
+
+ expect[0] = buffer1[0];
+
+ check_output_w(__LINE__, 1);
}
static void test_max_temps()