blob: ea5a370c2eac8141d3f0278d238fef937312d4a8 [file] [log] [blame]
/*
* QEMU CPU model
*
* Copyright (c) 2012 SUSE LINUX Products GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see
* <http://www.gnu.org/licenses/gpl-2.0.html>
*/
#ifndef QEMU_CPU_H
#define QEMU_CPU_H
#include <signal.h>
#include <setjmp.h>
#include "hw/qdev-core.h"
#include "exec/hwaddr.h"
#include "qemu/queue.h"
#include "qemu/thread.h"
#include "qemu/tls.h"
#include "qemu/typedefs.h"
typedef int (*WriteCoreDumpFunction)(const void *buf, size_t size,
void *opaque);
/**
* vaddr:
* Type wide enough to contain any #target_ulong virtual address.
*/
typedef uint64_t vaddr;
#define VADDR_PRId PRId64
#define VADDR_PRIu PRIu64
#define VADDR_PRIo PRIo64
#define VADDR_PRIx PRIx64
#define VADDR_PRIX PRIX64
#define VADDR_MAX UINT64_MAX
/* Since this macro is used a lot in hot code paths and in conjunction with
* FooCPU *foo_env_get_cpu(), we deviate from usual QOM practice by using
* an unchecked cast.
*/
#define CPU(obj) ((CPUState *)(obj))
typedef struct CPUState CPUState;
typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr,
bool is_write, bool is_exec, int opaque,
unsigned size);
struct TranslationBlock;
struct KVMState;
struct kvm_run;
// TODO(digit): Make this a proper QOM object that inherits from
// DeviceState/DeviceClass.
struct CPUState {
int nr_cores;
int nr_threads;
int numa_node;
struct QemuThread *thread;
uint32_t host_tid; /* host thread ID */
bool running;
struct QemuCond *halt_cond;
struct qemu_work_item *queued_work_first, *queued_work_last;
uint32_t created;
uint32_t stop; /* Stop request */
uint32_t stopped; /* Artificially stopped */
volatile sig_atomic_t exit_request;
uint32_t interrupt_request;
void *env_ptr; /* CPUArchState */
struct TranslationBlock *current_tb; /* currently executing TB */
int singlestep_enabled;
struct GDBRegisterState *gdb_regs;
QTAILQ_ENTRY(CPUState) node; /* next CPU sharing TB cache */
const char *cpu_model_str;
int kvm_fd;
bool kvm_vcpu_dirty;
struct KVMState *kvm_state;
struct kvm_run *kvm_run;
struct hax_vcpu_state *hax_vcpu;
/* TODO Move common fields from CPUArchState here. */
int cpu_index; /* used by alpha TCG */
uint32_t halted; /* used by alpha, cris, ppc TCG */
};
QTAILQ_HEAD(CPUTailQ, CPUState);
extern struct CPUTailQ cpus;
#define CPU_NEXT(cpu) QTAILQ_NEXT(cpu, node)
#define CPU_FOREACH(cpu) QTAILQ_FOREACH(cpu, &cpus, node)
#define CPU_FOREACH_SAFE(cpu, next_cpu) \
QTAILQ_FOREACH_SAFE(cpu, &cpus, node, next_cpu)
#define first_cpu QTAILQ_FIRST(&cpus)
DECLARE_TLS(CPUState *, current_cpu);
#define current_cpu tls_var(current_cpu)
// TODO(digit): Remove this.
#define cpu_single_env ((CPUArchState*)current_cpu->env_ptr)
/**
* CPUDumpFlags:
* @CPU_DUMP_CODE:
* @CPU_DUMP_FPU: dump FPU register state, not just integer
* @CPU_DUMP_CCOP: dump info about TCG QEMU's condition code optimization state
*/
enum CPUDumpFlags {
CPU_DUMP_CODE = 0x00010000,
CPU_DUMP_FPU = 0x00020000,
CPU_DUMP_CCOP = 0x00040000,
};
/**
* cpu_dump_state:
* @cpu: The CPU whose state is to be dumped.
* @f: File to dump to.
* @cpu_fprintf: Function to dump with.
* @flags: Flags what to dump.
*
* Dumps CPU state.
*/
void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
int flags);
/**
* cpu_dump_statistics:
* @cpu: The CPU whose state is to be dumped.
* @f: File to dump to.
* @cpu_fprintf: Function to dump with.
* @flags: Flags what to dump.
*
* Dumps CPU statistics.
*/
void cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
int flags);
/**
* cpu_reset:
* @cpu: The CPU whose state is to be reset.
*/
void cpu_reset(CPUState *cpu);
/**
* qemu_cpu_has_work:
* @cpu: The vCPU to check.
*
* Checks whether the CPU has work to do.
*
* Returns: %true if the CPU has work, %false otherwise.
*/
bool qemu_cpu_has_work(CPUState *cpu);
/**
* qemu_cpu_is_self:
* @cpu: The vCPU to check against.
*
* Checks whether the caller is executing on the vCPU thread.
*
* Returns: %true if called from @cpu's thread, %false otherwise.
*/
bool qemu_cpu_is_self(CPUState *cpu);
/**
* qemu_cpu_kick:
* @cpu: The vCPU to kick.
*
* Kicks @cpu's thread.
*/
void qemu_cpu_kick(CPUState *cpu);
/**
* cpu_is_stopped:
* @cpu: The CPU to check.
*
* Checks whether the CPU is stopped.
*
* Returns: %true if run state is not running or if artificially stopped;
* %false otherwise.
*/
bool cpu_is_stopped(CPUState *cpu);
/**
* run_on_cpu:
* @cpu: The vCPU to run on.
* @func: The function to be executed.
* @data: Data to pass to the function.
*
* Schedules the function @func for execution on the vCPU @cpu.
*/
void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data);
/**
* qemu_get_cpu:
* @index: The CPUState@cpu_index value of the CPU to obtain.
*
* Gets a CPU matching @index.
*
* Returns: The CPU or %NULL if there is no matching CPU.
*/
CPUState *qemu_get_cpu(int index);
/**
* cpu_interrupt:
* @cpu: The CPU to set an interrupt on.
* @mask: The interupts to set.
*
* Invokes the interrupt handler.
*/
void cpu_interrupt(CPUState *cpu, int mask);
/**
* cpu_reset_interrupt:
* @cpu: The CPU to clear the interrupt on.
* @mask: The interrupt mask to clear.
*
* Resets interrupts on the vCPU @cpu.
*/
void cpu_reset_interrupt(CPUState *cpu, int mask);
/**
* cpu_exit:
* @cpu: The CPU to exit.
*
* Requests the CPU @cpu to exit execution.
*/
void cpu_exit(CPUState *cpu);
/**
* cpu_resume:
* @cpu: The CPU to resume.
*
* Resumes CPU, i.e. puts CPU into runnable state.
*/
void cpu_resume(CPUState *cpu);
/**
* qemu_init_vcpu:
* @cpu: The vCPU to initialize.
*
* Initializes a vCPU.
*/
void qemu_init_vcpu(CPUState *cpu);
#define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */
#define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */
#define SSTEP_NOTIMER 0x4 /* Do not Timers while single stepping */
/**
* cpu_single_step:
* @cpu: CPU to the flags for.
* @enabled: Flags to enable.
*
* Enables or disables single-stepping for @cpu.
*/
void cpu_single_step(CPUState *cpu, int enabled);
void QEMU_NORETURN cpu_abort(CPUState *cpu, const char *fmt, ...)
GCC_FMT_ATTR(2, 3);
#endif // QEMU_CPU_H