Move it to qom/cpu.h.
Signed-off-by: Andreas Färber <afaerber@suse.de>
cpu->halted = 0;
}
- cpu_single_env = env;
+ current_cpu = cpu;
- /* As long as cpu_single_env is null, up to the assignment just above,
+ /* As long as current_cpu is null, up to the assignment just above,
* requests by other threads to exit the execution loop are expected to
* be issued using the exit_request global. We must make sure that our
- * evaluation of the global value is performed past the cpu_single_env
+ * evaluation of the global value is performed past the current_cpu
* value transition point, which requires a memory barrier as well as
* an instruction scheduling constraint on modern architectures. */
smp_mb();
} else {
/* Reload env after longjmp - the compiler may have smashed all
* local variables as longjmp is marked 'noreturn'. */
- env = cpu_single_env;
+ cpu = current_cpu;
+ env = cpu->env_ptr;
}
} /* for(;;) */
#error unsupported target CPU
#endif
- /* fail safe : never use cpu_single_env outside cpu_exec() */
- cpu_single_env = NULL;
+ /* fail safe : never use current_cpu outside cpu_exec() */
+ current_cpu = NULL;
return ret;
}
int64_t cpu_get_icount(void)
{
int64_t icount;
- CPUArchState *env = cpu_single_env;
+ CPUState *cpu = current_cpu;
icount = qemu_icount;
- if (env) {
+ if (cpu) {
+ CPUArchState *env = cpu->env_ptr;
if (!can_do_io(env)) {
fprintf(stderr, "Bad clock read\n");
}
static void cpu_signal(int sig)
{
- if (cpu_single_env) {
- cpu_exit(ENV_GET_CPU(cpu_single_env));
+ if (current_cpu) {
+ cpu_exit(current_cpu);
}
exit_request = 1;
}
qemu_cpu_kick(cpu);
while (!wi.done) {
- CPUArchState *self_env = cpu_single_env;
+ CPUState *self_cpu = current_cpu;
qemu_cond_wait(&qemu_work_cond, &qemu_global_mutex);
- cpu_single_env = self_env;
+ current_cpu = self_cpu;
}
}
qemu_mutex_lock(&qemu_global_mutex);
qemu_thread_get_self(cpu->thread);
cpu->thread_id = qemu_get_thread_id();
- cpu_single_env = cpu->env_ptr;
+ current_cpu = cpu;
r = kvm_init_vcpu(cpu);
if (r < 0) {
cpu->created = true;
qemu_cond_signal(&qemu_cpu_cond);
- cpu_single_env = cpu->env_ptr;
+ current_cpu = cpu;
while (1) {
- cpu_single_env = NULL;
+ current_cpu = NULL;
qemu_mutex_unlock_iothread();
do {
int sig;
exit(1);
}
qemu_mutex_lock_iothread();
- cpu_single_env = cpu->env_ptr;
+ current_cpu = cpu;
qemu_wait_io_event_common(cpu);
}
void qemu_cpu_kick_self(void)
{
#ifndef _WIN32
- assert(cpu_single_env);
- CPUState *cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
+ assert(current_cpu);
- if (!cpu_single_cpu->thread_kicked) {
- qemu_cpu_kick_thread(cpu_single_cpu);
- cpu_single_cpu->thread_kicked = true;
+ if (!current_cpu->thread_kicked) {
+ qemu_cpu_kick_thread(current_cpu);
+ current_cpu->thread_kicked = true;
}
#else
abort();
static bool qemu_in_vcpu_thread(void)
{
- return cpu_single_env && qemu_cpu_is_self(ENV_GET_CPU(cpu_single_env));
+ return current_cpu && qemu_cpu_is_self(current_cpu);
}
void qemu_mutex_lock_iothread(void)
void cpu_stop_current(void)
{
- if (cpu_single_env) {
- CPUState *cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
- cpu_single_cpu->stop = false;
- cpu_single_cpu->stopped = true;
- cpu_exit(cpu_single_cpu);
+ if (current_cpu) {
+ current_cpu->stop = false;
+ current_cpu->stopped = true;
+ cpu_exit(current_cpu);
qemu_cond_signal(&qemu_pause_cond);
}
}
CPUArchState *first_cpu;
/* current CPU in the current thread. It is only valid inside
cpu_exec() */
-DEFINE_TLS(CPUArchState *,cpu_single_env);
+DEFINE_TLS(CPUState *, current_cpu);
/* 0 = Do not count executed instructions.
1 = Precise instruction counting.
2 = Adaptive rate instruction counting. */
cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags);
/* we remove the notdirty callback only if the code has been
flushed */
- if (dirty_flags == 0xff)
- tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr);
+ if (dirty_flags == 0xff) {
+ CPUArchState *env = current_cpu->env_ptr;
+ tlb_set_dirty(env, env->mem_io_vaddr);
+ }
}
static bool notdirty_mem_accepts(void *opaque, hwaddr addr,
/* Generate a debug exception if a watchpoint has been hit. */
static void check_watchpoint(int offset, int len_mask, int flags)
{
- CPUArchState *env = cpu_single_env;
+ CPUArchState *env = current_cpu->env_ptr;
target_ulong pc, cs_base;
target_ulong vaddr;
CPUWatchpoint *wp;
if (is_write) {
if (!memory_access_is_direct(mr, is_write)) {
l = memory_access_size(mr, l, addr1);
- /* XXX: could force cpu_single_env to NULL to avoid
+ /* XXX: could force current_cpu to NULL to avoid
potential bugs */
if (l == 4) {
/* 32 bit write access */
static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
{
- CPUAlphaState *env = cpu_single_env;
+ CPUState *cpu = current_cpu;
TyphoonState *s = opaque;
- CPUState *cpu;
uint64_t ret = 0;
if (addr & 4) {
case 0x0080:
/* MISC: Miscellaneous Register. */
- cpu = ENV_GET_CPU(env);
ret = s->cchip.misc | (cpu->cpu_index & 3);
break;
break;
default:
- cpu = CPU(alpha_env_get_cpu(cpu_single_env));
cpu_unassigned_access(cpu, addr, false, false, 0, size);
return -1;
}
static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
{
TyphoonState *s = opaque;
- CPUState *cs;
uint64_t ret = 0;
if (addr & 4) {
break;
default:
- cs = CPU(alpha_env_get_cpu(cpu_single_env));
- cpu_unassigned_access(cs, addr, false, false, 0, size);
+ cpu_unassigned_access(current_cpu, addr, false, false, 0, size);
return -1;
}
uint64_t v32, unsigned size)
{
TyphoonState *s = opaque;
- CPUState *cpu_single_cpu = CPU(alpha_env_get_cpu(cpu_single_env));
uint64_t val, oldval, newval;
if (addr & 4) {
break;
default:
- cpu_unassigned_access(cpu_single_cpu, addr, true, false, 0, size);
+ cpu_unassigned_access(current_cpu, addr, true, false, 0, size);
return;
}
}
uint64_t v32, unsigned size)
{
TyphoonState *s = opaque;
- CPUState *cs;
uint64_t val, oldval;
if (addr & 4) {
break;
default:
- cs = CPU(alpha_env_get_cpu(cpu_single_env));
- cpu_unassigned_access(cs, addr, true, false, 0, size);
+ cpu_unassigned_access(current_cpu, addr, true, false, 0, size);
return;
}
}
#endif
/* Suspend */
- cpu_interrupt(CPU(arm_env_get_cpu(cpu_single_env)),
- CPU_INTERRUPT_HALT);
+ cpu_interrupt(current_cpu, CPU_INTERRUPT_HALT);
goto message;
static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
unsigned int size)
{
- CPUX86State *env = cpu_single_env;
+ CPUState *cs = current_cpu;
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
hwaddr rom_paddr;
VAPICROMState *s = opaque;
- cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
+ cpu_synchronize_state(cs);
/*
* The VAPIC supports two PIO-based hypercalls, both via port 0x7E.
DeviceState *cpu_get_current_apic(void)
{
- if (cpu_single_env) {
- return cpu_single_env->apic_state;
+ if (current_cpu) {
+ X86CPU *cpu = X86_CPU(current_cpu);
+ return cpu->env.apic_state;
} else {
return NULL;
}
static void cpu_request_exit(void *opaque, int irq, int level)
{
- CPUX86State *env = cpu_single_env;
+ CPUState *cpu = current_cpu;
- if (env && level) {
- cpu_exit(CPU(x86_env_get_cpu(env)));
+ if (cpu && level) {
+ cpu_exit(cpu);
}
}
static inline int gic_get_current_cpu(GICState *s)
{
if (s->num_cpu > 1) {
- CPUState *cpu = ENV_GET_CPU(cpu_single_env);
- return cpu->cpu_index;
+ return current_cpu->cpu_index;
}
return 0;
}
static uint32_t nvic_readl(nvic_state *s, uint32_t offset)
{
+ ARMCPU *cpu;
uint32_t val;
int irq;
case 0x1c: /* SysTick Calibration Value. */
return 10000;
case 0xd00: /* CPUID Base. */
- return cpu_single_env->cp15.c0_cpuid;
+ cpu = ARM_CPU(current_cpu);
+ return cpu->env.cp15.c0_cpuid;
case 0xd04: /* Interrupt Control State. */
/* VECTACTIVE */
val = s->gic.running_irq[0];
val |= (1 << 31);
return val;
case 0xd08: /* Vector Table Offset. */
- return cpu_single_env->v7m.vecbase;
+ cpu = ARM_CPU(current_cpu);
+ return cpu->env.v7m.vecbase;
case 0xd0c: /* Application Interrupt/Reset Control. */
return 0xfa05000;
case 0xd10: /* System Control. */
static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value)
{
+ ARMCPU *cpu;
uint32_t oldval;
switch (offset) {
case 0x10: /* SysTick Control and Status. */
}
break;
case 0xd08: /* Vector Table Offset. */
- cpu_single_env->v7m.vecbase = value & 0xffffff80;
+ cpu = ARM_CPU(current_cpu);
+ cpu->env.v7m.vecbase = value & 0xffffff80;
break;
case 0xd0c: /* Application Interrupt/Reset Control. */
if ((value >> 16) == 0x05fa) {
static int get_current_cpu(void)
{
- CPUState *cpu_single_cpu;
-
- if (!cpu_single_env) {
+ if (!current_cpu) {
return -1;
}
- cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
- return cpu_single_cpu->cpu_index;
+ return current_cpu->cpu_index;
}
static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
static void cpu_request_exit(void *opaque, int irq, int level)
{
- CPUMIPSState *env = cpu_single_env;
+ CPUState *cpu = current_cpu;
- if (env && level) {
- cpu_exit(CPU(mips_env_get_cpu(env)));
+ if (cpu && level) {
+ cpu_exit(cpu);
}
}
static void cpu_request_exit(void *opaque, int irq, int level)
{
- CPUMIPSState *env = cpu_single_env;
+ CPUState *cpu = current_cpu;
- if (env && level) {
- cpu_exit(CPU(mips_env_get_cpu(env)));
+ if (cpu && level) {
+ cpu_exit(cpu);
}
}
static void cpu_request_exit(void *opaque, int irq, int level)
{
- CPUMIPSState *env = cpu_single_env;
+ CPUState *cpu = current_cpu;
- if (env && level) {
- cpu_exit(CPU(mips_env_get_cpu(env)));
+ if (cpu && level) {
+ cpu_exit(cpu);
}
}
unsigned size)
{
VMPortState *s = opaque;
- CPUX86State *env = cpu_single_env;
+ CPUState *cs = current_cpu;
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
unsigned char command;
uint32_t eax;
- cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
+ cpu_synchronize_state(cs);
eax = env->regs[R_EAX];
if (eax != VMPORT_MAGIC)
static void vmport_ioport_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
- CPUX86State *env = cpu_single_env;
+ X86CPU *cpu = X86_CPU(current_cpu);
- env->regs[R_EAX] = vmport_ioport_read(opaque, addr, 4);
+ cpu->env.regs[R_EAX] = vmport_ioport_read(opaque, addr, 4);
}
static uint32_t vmport_cmd_get_version(void *opaque, uint32_t addr)
{
- CPUX86State *env = cpu_single_env;
- env->regs[R_EBX] = VMPORT_MAGIC;
+ X86CPU *cpu = X86_CPU(current_cpu);
+
+ cpu->env.regs[R_EBX] = VMPORT_MAGIC;
return 6;
}
static uint32_t vmport_cmd_ram_size(void *opaque, uint32_t addr)
{
- CPUX86State *env = cpu_single_env;
- env->regs[R_EBX] = 0x1177;
+ X86CPU *cpu = X86_CPU(current_cpu);
+
+ cpu->env.regs[R_EBX] = 0x1177;
return ram_size;
}
/* vmmouse helpers */
void vmmouse_get_data(uint32_t *data)
{
- CPUX86State *env = cpu_single_env;
+ X86CPU *cpu = X86_CPU(current_cpu);
+ CPUX86State *env = &cpu->env;
data[0] = env->regs[R_EAX]; data[1] = env->regs[R_EBX];
data[2] = env->regs[R_ECX]; data[3] = env->regs[R_EDX];
void vmmouse_set_data(const uint32_t *data)
{
- CPUX86State *env = cpu_single_env;
+ X86CPU *cpu = X86_CPU(current_cpu);
+ CPUX86State *env = &cpu->env;
env->regs[R_EAX] = data[0]; env->regs[R_EBX] = data[1];
env->regs[R_ECX] = data[2]; env->regs[R_EDX] = data[3];
unsigned size)
{
uint32_t value = 0;
- CPUPPCState *env = cpu_single_env;
+ PowerPCCPU *cpu = POWERPC_CPU(current_cpu);
+ CPUPPCState *env = &cpu->env;
addr &= MPC8544_GUTS_MMIO_SIZE - 1;
switch (addr) {
static void cpu_request_exit(void *opaque, int irq, int level)
{
- CPUPPCState *env = cpu_single_env;
+ CPUState *cpu = current_cpu;
- if (env && level) {
- cpu_exit(CPU(ppc_env_get_cpu(env)));
+ if (cpu && level) {
+ cpu_exit(cpu);
}
}
static void cpu_halt_signal(void *opaque, int irq, int level)
{
- if (level && cpu_single_env) {
- cpu_interrupt(CPU(sparc_env_get_cpu(cpu_single_env)),
- CPU_INTERRUPT_HALT);
+ if (level && current_cpu) {
+ cpu_interrupt(current_cpu, CPU_INTERRUPT_HALT);
}
}
static inline int get_current_cpu(ARMMPTimerState *s)
{
- CPUState *cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
-
- if (cpu_single_cpu->cpu_index >= s->num_cpu) {
+ if (current_cpu->cpu_index >= s->num_cpu) {
hw_error("arm_mptimer: num-cpu %d but this cpu is %d!\n",
- s->num_cpu, cpu_single_cpu->cpu_index);
+ s->num_cpu, current_cpu->cpu_index);
}
- return cpu_single_cpu->cpu_index;
+ return current_cpu->cpu_index;
}
static inline void timerblock_update_irq(TimerBlock *tb)
#define CPU_ALL_H
#include "qemu-common.h"
-#include "qemu/tls.h"
#include "exec/cpu-common.h"
#include "qemu/thread.h"
void QEMU_NORETURN cpu_abort(CPUArchState *env, const char *fmt, ...)
GCC_FMT_ATTR(2, 3);
extern CPUArchState *first_cpu;
-DECLARE_TLS(CPUArchState *,cpu_single_env);
-#define cpu_single_env tls_var(cpu_single_env)
/* Flags for use in ENV->INTERRUPT_PENDING.
#include "hw/qdev-core.h"
#include "exec/hwaddr.h"
#include "qemu/thread.h"
+#include "qemu/tls.h"
#include "qemu/typedefs.h"
typedef int (*WriteCoreDumpFunction)(void *buf, size_t size, void *opaque);
uint32_t halted; /* used by alpha, cris, ppc TCG */
};
+DECLARE_TLS(CPUState *, current_cpu);
+#define current_cpu tls_var(current_cpu)
+
/**
* cpu_paging_enabled:
* @cpu: The CPU whose state is to be inspected.
#ifdef DEBUG_UNASSIGNED
printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
#endif
- if (cpu_single_env != NULL) {
- cpu_unassigned_access(ENV_GET_CPU(cpu_single_env),
- addr, false, false, 0, size);
+ if (current_cpu != NULL) {
+ cpu_unassigned_access(current_cpu, addr, false, false, 0, size);
}
return 0;
}
#ifdef DEBUG_UNASSIGNED
printf("Unassigned mem write " TARGET_FMT_plx " = 0x%"PRIx64"\n", addr, val);
#endif
- if (cpu_single_env != NULL) {
- cpu_unassigned_access(ENV_GET_CPU(cpu_single_env),
- addr, true, false, 0, size);
+ if (current_cpu != NULL) {
+ cpu_unassigned_access(current_cpu, addr, true, false, 0, size);
}
}
int is_cpu_write_access)
{
TranslationBlock *tb, *tb_next, *saved_tb;
- CPUArchState *env = cpu_single_env;
- CPUState *cpu = NULL;
+ CPUState *cpu = current_cpu;
+#if defined(TARGET_HAS_PRECISE_SMC) || !defined(CONFIG_USER_ONLY)
+ CPUArchState *env = NULL;
+#endif
tb_page_addr_t tb_start, tb_end;
PageDesc *p;
int n;
/* build code bitmap */
build_page_bitmap(p);
}
- if (env != NULL) {
- cpu = ENV_GET_CPU(env);
+#if defined(TARGET_HAS_PRECISE_SMC) || !defined(CONFIG_USER_ONLY)
+ if (cpu != NULL) {
+ env = cpu->env_ptr;
}
+#endif
/* we remove all the TBs in the range [start, end[ */
/* XXX: see if in some cases it could be faster to invalidate all
int n;
#ifdef TARGET_HAS_PRECISE_SMC
TranslationBlock *current_tb = NULL;
- CPUArchState *env = cpu_single_env;
- CPUState *cpu = NULL;
+ CPUState *cpu = current_cpu;
+ CPUArchState *env = NULL;
int current_tb_modified = 0;
target_ulong current_pc = 0;
target_ulong current_cs_base = 0;
if (tb && pc != 0) {
current_tb = tb_find_pc(pc);
}
- if (env != NULL) {
- cpu = ENV_GET_CPU(env);
+ if (cpu != NULL) {
+ env = cpu->env_ptr;
}
#endif
while (tb != NULL) {
int is_write, sigset_t *old_set,
void *puc)
{
+ CPUArchState *env;
int ret;
#if defined(DEBUG_SIGNAL)
return 1;
}
+ env = current_cpu->env_ptr;
/* see if it is an MMU fault */
- ret = cpu_handle_mmu_fault(cpu_single_env, address, is_write,
- MMU_USER_IDX);
+ ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX);
if (ret < 0) {
return 0; /* not an MMU fault */
}
return 1; /* the MMU fault was handled without causing real CPU fault */
}
/* now we have a real cpu fault */
- cpu_restore_state(cpu_single_env, pc);
+ cpu_restore_state(env, pc);
/* we restore the process signal mask as the sigreturn should
do it (XXX: use sigsetjmp) */
sigprocmask(SIG_SETMASK, old_set, NULL);
- exception_action(cpu_single_env);
+ exception_action(env);
/* never comes here */
return 1;