Merge remote-tracking branch 'remotes/afaerber/tags/qom-cpu-for-2.0' into staging

QOM CPUState refactorings / X86CPU

* Deadlock fix for exit requests around CPU reset
* X86CPU x2apic for KVM
* X86CPU model subclasses
* SPARCCPU preparations for model subclasses
* -cpu arguments for arm, cris, lm32, moxie, openrisc, ppc, sh4, uc32
* m68k assertion cleanups
* CPUClass hooks for cpu.h inline functions
* Field movements from CPU_COMMON to CPUState and follow-up cleanups

# gpg: Signature made Thu 13 Mar 2014 19:06:56 GMT using RSA key ID 3E7E013F
# gpg: Good signature from "Andreas Färber <afaerber@suse.de>"
# gpg:                 aka "Andreas Färber <afaerber@suse.com>"

* remotes/afaerber/tags/qom-cpu-for-2.0: (58 commits)
  user-exec: Change exception_action() argument to CPUState
  cputlb: Change tlb_set_page() argument to CPUState
  cputlb: Change tlb_flush() argument to CPUState
  cputlb: Change tlb_flush_page() argument to CPUState
  target-microblaze: Replace DisasContext::env field with MicroBlazeCPU
  target-cris: Replace DisasContext::env field with CRISCPU
  exec: Change cpu_abort() argument to CPUState
  exec: Change memory_region_section_get_iotlb() argument to CPUState
  cputlb: Change tlb_unprotect_code_phys() argument to CPUState
  cpu-exec: Change cpu_resume_from_signal() argument to CPUState
  exec: Change cpu_breakpoint_{insert,remove{,_by_ref,_all}} argument
  exec: Change cpu_watchpoint_{insert,remove{,_by_ref,_all}} argument
  target-ppc: Use PowerPCCPU in PowerPCCPUClass::handle_mmu_fault hook
  translate-all: Change tb_flush_jmp_cache() argument to CPUState
  translate-all: Change tb_gen_code() argument to CPUState
  translate-all: Change cpu_io_recompile() argument to CPUState
  translate-all: Change tb_check_watchpoint() argument to CPUState
  translate-all: Change cpu_restore_state_from_tb() argument to CPUState
  translate-all: Change cpu_restore_state() argument to CPUState
  cpu-exec: Change cpu_loop_exit() argument to CPUState
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2014-03-13 19:13:33 +00:00
155 changed files with 2455 additions and 1887 deletions
+1 -1
View File
@@ -1000,7 +1000,7 @@ int main(int argc, char **argv)
memset(ts, 0, sizeof(TaskState));
init_task_state(ts);
ts->info = info;
env->opaque = ts;
cpu->opaque = ts;
#if defined(TARGET_I386)
cpu_x86_set_cpl(env, 3);
+51 -55
View File
@@ -23,29 +23,22 @@
#include "qemu/atomic.h"
#include "sysemu/qtest.h"
bool qemu_cpu_has_work(CPUState *cpu)
void cpu_loop_exit(CPUState *cpu)
{
return cpu_has_work(cpu);
}
void cpu_loop_exit(CPUArchState *env)
{
CPUState *cpu = ENV_GET_CPU(env);
cpu->current_tb = NULL;
siglongjmp(env->jmp_env, 1);
siglongjmp(cpu->jmp_env, 1);
}
/* exit the current TB from a signal handler. The host registers are
restored in a state compatible with the CPU emulator
*/
#if defined(CONFIG_SOFTMMU)
void cpu_resume_from_signal(CPUArchState *env, void *puc)
void cpu_resume_from_signal(CPUState *cpu, void *puc)
{
/* XXX: restore cpu registers saved in host registers */
env->exception_index = -1;
siglongjmp(env->jmp_env, 1);
cpu->exception_index = -1;
siglongjmp(cpu->jmp_env, 1);
}
#endif
@@ -108,7 +101,7 @@ static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
if (max_cycles > CF_COUNT_MASK)
max_cycles = CF_COUNT_MASK;
tb = tb_gen_code(env, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
tb = tb_gen_code(cpu, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
max_cycles);
cpu->current_tb = tb;
/* execute the generated code */
@@ -123,6 +116,7 @@ static TranslationBlock *tb_find_slow(CPUArchState *env,
target_ulong cs_base,
uint64_t flags)
{
CPUState *cpu = ENV_GET_CPU(env);
TranslationBlock *tb, **ptb1;
unsigned int h;
tb_page_addr_t phys_pc, phys_page1;
@@ -160,7 +154,7 @@ static TranslationBlock *tb_find_slow(CPUArchState *env,
}
not_found:
/* if no translated code available, then translate it now */
tb = tb_gen_code(env, pc, cs_base, flags, 0);
tb = tb_gen_code(cpu, pc, cs_base, flags, 0);
found:
/* Move the last found TB to the head of the list */
@@ -170,12 +164,13 @@ static TranslationBlock *tb_find_slow(CPUArchState *env,
tcg_ctx.tb_ctx.tb_phys_hash[h] = tb;
}
/* we add the TB in the virtual pc hash table */
env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
return tb;
}
static inline TranslationBlock *tb_find_fast(CPUArchState *env)
{
CPUState *cpu = ENV_GET_CPU(env);
TranslationBlock *tb;
target_ulong cs_base, pc;
int flags;
@@ -184,7 +179,7 @@ static inline TranslationBlock *tb_find_fast(CPUArchState *env)
always be the same before a given translated block
is executed. */
cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
tb = cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
tb->flags != flags)) {
tb = tb_find_slow(env, pc, cs_base, flags);
@@ -201,10 +196,11 @@ void cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler)
static void cpu_handle_debug_exception(CPUArchState *env)
{
CPUState *cpu = ENV_GET_CPU(env);
CPUWatchpoint *wp;
if (!env->watchpoint_hit) {
QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
if (!cpu->watchpoint_hit) {
QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
wp->flags &= ~BP_WATCHPOINT_HIT;
}
}
@@ -283,16 +279,16 @@ int cpu_exec(CPUArchState *env)
#else
#error unsupported target CPU
#endif
env->exception_index = -1;
cpu->exception_index = -1;
/* prepare setjmp context for exception handling */
for(;;) {
if (sigsetjmp(env->jmp_env, 0) == 0) {
if (sigsetjmp(cpu->jmp_env, 0) == 0) {
/* if an exception is pending, we execute it here */
if (env->exception_index >= 0) {
if (env->exception_index >= EXCP_INTERRUPT) {
if (cpu->exception_index >= 0) {
if (cpu->exception_index >= EXCP_INTERRUPT) {
/* exit request from the cpu execution loop */
ret = env->exception_index;
ret = cpu->exception_index;
if (ret == EXCP_DEBUG) {
cpu_handle_debug_exception(env);
}
@@ -305,11 +301,11 @@ int cpu_exec(CPUArchState *env)
#if defined(TARGET_I386)
cc->do_interrupt(cpu);
#endif
ret = env->exception_index;
ret = cpu->exception_index;
break;
#else
cc->do_interrupt(cpu);
env->exception_index = -1;
cpu->exception_index = -1;
#endif
}
}
@@ -324,8 +320,8 @@ int cpu_exec(CPUArchState *env)
}
if (interrupt_request & CPU_INTERRUPT_DEBUG) {
cpu->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
env->exception_index = EXCP_DEBUG;
cpu_loop_exit(env);
cpu->exception_index = EXCP_DEBUG;
cpu_loop_exit(cpu);
}
#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
@@ -333,8 +329,8 @@ int cpu_exec(CPUArchState *env)
if (interrupt_request & CPU_INTERRUPT_HALT) {
cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
cpu->halted = 1;
env->exception_index = EXCP_HLT;
cpu_loop_exit(env);
cpu->exception_index = EXCP_HLT;
cpu_loop_exit(cpu);
}
#endif
#if defined(TARGET_I386)
@@ -348,8 +344,8 @@ int cpu_exec(CPUArchState *env)
cpu_svm_check_intercept_param(env, SVM_EXIT_INIT,
0);
do_cpu_init(x86_cpu);
env->exception_index = EXCP_HALTED;
cpu_loop_exit(env);
cpu->exception_index = EXCP_HALTED;
cpu_loop_exit(cpu);
} else if (interrupt_request & CPU_INTERRUPT_SIPI) {
do_cpu_sipi(x86_cpu);
} else if (env->hflags2 & HF2_GIF_MASK) {
@@ -420,7 +416,7 @@ int cpu_exec(CPUArchState *env)
#elif defined(TARGET_LM32)
if ((interrupt_request & CPU_INTERRUPT_HARD)
&& (env->ie & IE_IE)) {
env->exception_index = EXCP_IRQ;
cpu->exception_index = EXCP_IRQ;
cc->do_interrupt(cpu);
next_tb = 0;
}
@@ -429,7 +425,7 @@ int cpu_exec(CPUArchState *env)
&& (env->sregs[SR_MSR] & MSR_IE)
&& !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
&& !(env->iflags & (D_FLAG | IMM_FLAG))) {
env->exception_index = EXCP_IRQ;
cpu->exception_index = EXCP_IRQ;
cc->do_interrupt(cpu);
next_tb = 0;
}
@@ -437,7 +433,7 @@ int cpu_exec(CPUArchState *env)
if ((interrupt_request & CPU_INTERRUPT_HARD) &&
cpu_mips_hw_interrupts_pending(env)) {
/* Raise it */
env->exception_index = EXCP_EXT_INTERRUPT;
cpu->exception_index = EXCP_EXT_INTERRUPT;
env->error_code = 0;
cc->do_interrupt(cpu);
next_tb = 0;
@@ -454,7 +450,7 @@ int cpu_exec(CPUArchState *env)
idx = EXCP_TICK;
}
if (idx >= 0) {
env->exception_index = idx;
cpu->exception_index = idx;
cc->do_interrupt(cpu);
next_tb = 0;
}
@@ -469,7 +465,7 @@ int cpu_exec(CPUArchState *env)
if (((type == TT_EXTINT) &&
cpu_pil_allowed(env, pil)) ||
type != TT_EXTINT) {
env->exception_index = env->interrupt_index;
cpu->exception_index = env->interrupt_index;
cc->do_interrupt(cpu);
next_tb = 0;
}
@@ -478,7 +474,7 @@ int cpu_exec(CPUArchState *env)
#elif defined(TARGET_ARM)
if (interrupt_request & CPU_INTERRUPT_FIQ
&& !(env->daif & PSTATE_F)) {
env->exception_index = EXCP_FIQ;
cpu->exception_index = EXCP_FIQ;
cc->do_interrupt(cpu);
next_tb = 0;
}
@@ -494,14 +490,14 @@ int cpu_exec(CPUArchState *env)
if (interrupt_request & CPU_INTERRUPT_HARD
&& ((IS_M(env) && env->regs[15] < 0xfffffff0)
|| !(env->daif & PSTATE_I))) {
env->exception_index = EXCP_IRQ;
cpu->exception_index = EXCP_IRQ;
cc->do_interrupt(cpu);
next_tb = 0;
}
#elif defined(TARGET_UNICORE32)
if (interrupt_request & CPU_INTERRUPT_HARD
&& !(env->uncached_asr & ASR_I)) {
env->exception_index = UC32_EXCP_INTR;
cpu->exception_index = UC32_EXCP_INTR;
cc->do_interrupt(cpu);
next_tb = 0;
}
@@ -536,7 +532,7 @@ int cpu_exec(CPUArchState *env)
}
}
if (idx >= 0) {
env->exception_index = idx;
cpu->exception_index = idx;
env->error_code = 0;
cc->do_interrupt(cpu);
next_tb = 0;
@@ -546,7 +542,7 @@ int cpu_exec(CPUArchState *env)
if (interrupt_request & CPU_INTERRUPT_HARD
&& (env->pregs[PR_CCS] & I_FLAG)
&& !env->locked_irq) {
env->exception_index = EXCP_IRQ;
cpu->exception_index = EXCP_IRQ;
cc->do_interrupt(cpu);
next_tb = 0;
}
@@ -558,7 +554,7 @@ int cpu_exec(CPUArchState *env)
m_flag_archval = M_FLAG_V32;
}
if ((env->pregs[PR_CCS] & m_flag_archval)) {
env->exception_index = EXCP_NMI;
cpu->exception_index = EXCP_NMI;
cc->do_interrupt(cpu);
next_tb = 0;
}
@@ -572,7 +568,7 @@ int cpu_exec(CPUArchState *env)
hardware doesn't rely on this, so we
provide/save the vector when the interrupt is
first signalled. */
env->exception_index = env->pending_vector;
cpu->exception_index = env->pending_vector;
do_interrupt_m68k_hardirq(env);
next_tb = 0;
}
@@ -584,7 +580,7 @@ int cpu_exec(CPUArchState *env)
}
#elif defined(TARGET_XTENSA)
if (interrupt_request & CPU_INTERRUPT_HARD) {
env->exception_index = EXC_IRQ;
cpu->exception_index = EXC_IRQ;
cc->do_interrupt(cpu);
next_tb = 0;
}
@@ -600,8 +596,8 @@ int cpu_exec(CPUArchState *env)
}
if (unlikely(cpu->exit_request)) {
cpu->exit_request = 0;
env->exception_index = EXCP_INTERRUPT;
cpu_loop_exit(env);
cpu->exception_index = EXCP_INTERRUPT;
cpu_loop_exit(cpu);
}
spin_lock(&tcg_ctx.tb_ctx.tb_lock);
tb = tb_find_fast(env);
@@ -654,25 +650,25 @@ int cpu_exec(CPUArchState *env)
/* Instruction counter expired. */
int insns_left;
tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
insns_left = env->icount_decr.u32;
if (env->icount_extra && insns_left >= 0) {
insns_left = cpu->icount_decr.u32;
if (cpu->icount_extra && insns_left >= 0) {
/* Refill decrementer and continue execution. */
env->icount_extra += insns_left;
if (env->icount_extra > 0xffff) {
cpu->icount_extra += insns_left;
if (cpu->icount_extra > 0xffff) {
insns_left = 0xffff;
} else {
insns_left = env->icount_extra;
insns_left = cpu->icount_extra;
}
env->icount_extra -= insns_left;
env->icount_decr.u16.low = insns_left;
cpu->icount_extra -= insns_left;
cpu->icount_decr.u16.low = insns_left;
} else {
if (insns_left > 0) {
/* Execute remaining instructions. */
cpu_exec_nocache(env, insns_left, tb);
}
env->exception_index = EXCP_INTERRUPT;
cpu->exception_index = EXCP_INTERRUPT;
next_tb = 0;
cpu_loop_exit(env);
cpu_loop_exit(cpu);
}
break;
}
+12 -13
View File
@@ -76,7 +76,7 @@ static bool cpu_thread_is_idle(CPUState *cpu)
if (cpu_is_stopped(cpu)) {
return true;
}
if (!cpu->halted || qemu_cpu_has_work(cpu) ||
if (!cpu->halted || cpu_has_work(cpu) ||
kvm_halt_in_kernel()) {
return false;
}
@@ -139,11 +139,10 @@ static int64_t cpu_get_icount_locked(void)
icount = qemu_icount;
if (cpu) {
CPUArchState *env = cpu->env_ptr;
if (!can_do_io(env)) {
if (!cpu_can_do_io(cpu)) {
fprintf(stderr, "Bad clock read\n");
}
icount -= (env->icount_decr.u16.low + env->icount_extra);
icount -= (cpu->icount_decr.u16.low + cpu->icount_extra);
}
return qemu_icount_bias + (icount << icount_time_shift);
}
@@ -1236,6 +1235,7 @@ int vm_stop_force_state(RunState state)
static int tcg_cpu_exec(CPUArchState *env)
{
CPUState *cpu = ENV_GET_CPU(env);
int ret;
#ifdef CONFIG_PROFILER
int64_t ti;
@@ -1248,9 +1248,9 @@ static int tcg_cpu_exec(CPUArchState *env)
int64_t count;
int64_t deadline;
int decr;
qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
env->icount_decr.u16.low = 0;
env->icount_extra = 0;
qemu_icount -= (cpu->icount_decr.u16.low + cpu->icount_extra);
cpu->icount_decr.u16.low = 0;
cpu->icount_extra = 0;
deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
/* Maintain prior (possibly buggy) behaviour where if no deadline
@@ -1266,8 +1266,8 @@ static int tcg_cpu_exec(CPUArchState *env)
qemu_icount += count;
decr = (count > 0xffff) ? 0xffff : count;
count -= decr;
env->icount_decr.u16.low = decr;
env->icount_extra = count;
cpu->icount_decr.u16.low = decr;
cpu->icount_extra = count;
}
ret = cpu_exec(env);
#ifdef CONFIG_PROFILER
@@ -1276,10 +1276,9 @@ static int tcg_cpu_exec(CPUArchState *env)
if (use_icount) {
/* Fold pending instructions back into the
instruction counter, and clear the interrupt flag. */
qemu_icount -= (env->icount_decr.u16.low
+ env->icount_extra);
env->icount_decr.u32 = 0;
env->icount_extra = 0;
qemu_icount -= (cpu->icount_decr.u16.low + cpu->icount_extra);
cpu->icount_decr.u32 = 0;
cpu->icount_extra = 0;
}
return ret;
}
+12 -12
View File
@@ -46,9 +46,9 @@ int tlb_flush_count;
* entries from the TLB at any time, so flushing more entries than
* required is only an efficiency issue, not a correctness issue.
*/
void tlb_flush(CPUArchState *env, int flush_global)
void tlb_flush(CPUState *cpu, int flush_global)
{
CPUState *cpu = ENV_GET_CPU(env);
CPUArchState *env = cpu->env_ptr;
#if defined(DEBUG_TLB)
printf("tlb_flush:\n");
@@ -58,7 +58,7 @@ void tlb_flush(CPUArchState *env, int flush_global)
cpu->current_tb = NULL;
memset(env->tlb_table, -1, sizeof(env->tlb_table));
memset(env->tb_jmp_cache, 0, sizeof(env->tb_jmp_cache));
memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache));
env->tlb_flush_addr = -1;
env->tlb_flush_mask = 0;
@@ -77,9 +77,9 @@ static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
}
}
void tlb_flush_page(CPUArchState *env, target_ulong addr)
void tlb_flush_page(CPUState *cpu, target_ulong addr)
{
CPUState *cpu = ENV_GET_CPU(env);
CPUArchState *env = cpu->env_ptr;
int i;
int mmu_idx;
@@ -93,7 +93,7 @@ void tlb_flush_page(CPUArchState *env, target_ulong addr)
TARGET_FMT_lx "/" TARGET_FMT_lx ")\n",
env->tlb_flush_addr, env->tlb_flush_mask);
#endif
tlb_flush(env, 1);
tlb_flush(cpu, 1);
return;
}
/* must reset current TB so that interrupts cannot modify the
@@ -106,7 +106,7 @@ void tlb_flush_page(CPUArchState *env, target_ulong addr)
tlb_flush_entry(&env->tlb_table[mmu_idx][i], addr);
}
tb_flush_jmp_cache(env, addr);
tb_flush_jmp_cache(cpu, addr);
}
/* update the TLBs so that writes to code in the virtual page 'addr'
@@ -119,7 +119,7 @@ void tlb_protect_code(ram_addr_t ram_addr)
/* update the TLB so that writes in physical page 'phys_addr' are no longer
tested for self modifying code */
void tlb_unprotect_code_phys(CPUArchState *env, ram_addr_t ram_addr,
void tlb_unprotect_code_phys(CPUState *cpu, ram_addr_t ram_addr,
target_ulong vaddr)
{
cpu_physical_memory_set_dirty_flag(ram_addr, DIRTY_MEMORY_CODE);
@@ -221,10 +221,11 @@ static void tlb_add_large_page(CPUArchState *env, target_ulong vaddr,
/* Add a new TLB entry. At most one entry for a given virtual address
is permitted. Only a single TARGET_PAGE_SIZE region is mapped, the
supplied size is only used by tlb_flush_page. */
void tlb_set_page(CPUArchState *env, target_ulong vaddr,
void tlb_set_page(CPUState *cpu, target_ulong vaddr,
hwaddr paddr, int prot,
int mmu_idx, target_ulong size)
{
CPUArchState *env = cpu->env_ptr;
MemoryRegionSection *section;
unsigned int index;
target_ulong address;
@@ -232,7 +233,6 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr,
uintptr_t addend;
CPUTLBEntry *te;
hwaddr iotlb, xlat, sz;
CPUState *cpu = ENV_GET_CPU(env);
assert(size >= TARGET_PAGE_SIZE);
if (size != TARGET_PAGE_SIZE) {
@@ -261,7 +261,7 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr,
}
code_address = address;
iotlb = memory_region_section_get_iotlb(env, section, vaddr, paddr, xlat,
iotlb = memory_region_section_get_iotlb(cpu, section, vaddr, paddr, xlat,
prot, &address);
index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
@@ -322,7 +322,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
if (cc->do_unassigned_access) {
cc->do_unassigned_access(cpu, addr, false, true, 0, 4);
} else {
cpu_abort(env1, "Trying to execute code outside RAM or ROM at 0x"
cpu_abort(cpu, "Trying to execute code outside RAM or ROM at 0x"
TARGET_FMT_lx "\n", addr);
}
}
+60 -58
View File
@@ -33,6 +33,7 @@
#include "hw/xen/xen.h"
#include "qemu/timer.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "exec/memory.h"
#include "sysemu/dma.h"
#include "exec/address-spaces.h"
@@ -484,8 +485,8 @@ void cpu_exec_init(CPUArchState *env)
}
cpu->cpu_index = cpu_index;
cpu->numa_node = 0;
QTAILQ_INIT(&env->breakpoints);
QTAILQ_INIT(&env->watchpoints);
QTAILQ_INIT(&cpu->breakpoints);
QTAILQ_INIT(&cpu->watchpoints);
#ifndef CONFIG_USER_ONLY
cpu->as = &address_space_memory;
cpu->thread_id = qemu_get_thread_id();
@@ -527,29 +528,29 @@ static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
#endif /* TARGET_HAS_ICE */
#if defined(CONFIG_USER_ONLY)
void cpu_watchpoint_remove_all(CPUArchState *env, int mask)
void cpu_watchpoint_remove_all(CPUState *cpu, int mask)
{
}
int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len,
int cpu_watchpoint_insert(CPUState *cpu, vaddr addr, vaddr len,
int flags, CPUWatchpoint **watchpoint)
{
return -ENOSYS;
}
#else
/* Add a watchpoint. */
int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len,
int cpu_watchpoint_insert(CPUState *cpu, vaddr addr, vaddr len,
int flags, CPUWatchpoint **watchpoint)
{
target_ulong len_mask = ~(len - 1);
vaddr len_mask = ~(len - 1);
CPUWatchpoint *wp;
/* sanity checks: allow power-of-2 lengths, deny unaligned watchpoints */
if ((len & (len - 1)) || (addr & ~len_mask) ||
len == 0 || len > TARGET_PAGE_SIZE) {
fprintf(stderr, "qemu: tried to set invalid watchpoint at "
TARGET_FMT_lx ", len=" TARGET_FMT_lu "\n", addr, len);
error_report("tried to set invalid watchpoint at %"
VADDR_PRIx ", len=%" VADDR_PRIu, addr, len);
return -EINVAL;
}
wp = g_malloc(sizeof(*wp));
@@ -559,12 +560,13 @@ int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len
wp->flags = flags;
/* keep all GDB-injected watchpoints in front */
if (flags & BP_GDB)
QTAILQ_INSERT_HEAD(&env->watchpoints, wp, entry);
else
QTAILQ_INSERT_TAIL(&env->watchpoints, wp, entry);
if (flags & BP_GDB) {
QTAILQ_INSERT_HEAD(&cpu->watchpoints, wp, entry);
} else {
QTAILQ_INSERT_TAIL(&cpu->watchpoints, wp, entry);
}
tlb_flush_page(env, addr);
tlb_flush_page(cpu, addr);
if (watchpoint)
*watchpoint = wp;
@@ -572,16 +574,16 @@ int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len
}
/* Remove a specific watchpoint. */
int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr, target_ulong len,
int cpu_watchpoint_remove(CPUState *cpu, vaddr addr, vaddr len,
int flags)
{
target_ulong len_mask = ~(len - 1);
vaddr len_mask = ~(len - 1);
CPUWatchpoint *wp;
QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
if (addr == wp->vaddr && len_mask == wp->len_mask
&& flags == (wp->flags & ~BP_WATCHPOINT_HIT)) {
cpu_watchpoint_remove_by_ref(env, wp);
cpu_watchpoint_remove_by_ref(cpu, wp);
return 0;
}
}
@@ -589,29 +591,30 @@ int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr, target_ulong len
}
/* Remove a specific watchpoint by reference. */
void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint)
void cpu_watchpoint_remove_by_ref(CPUState *cpu, CPUWatchpoint *watchpoint)
{
QTAILQ_REMOVE(&env->watchpoints, watchpoint, entry);
QTAILQ_REMOVE(&cpu->watchpoints, watchpoint, entry);
tlb_flush_page(env, watchpoint->vaddr);
tlb_flush_page(cpu, watchpoint->vaddr);
g_free(watchpoint);
}
/* Remove all matching watchpoints. */
void cpu_watchpoint_remove_all(CPUArchState *env, int mask)
void cpu_watchpoint_remove_all(CPUState *cpu, int mask)
{
CPUWatchpoint *wp, *next;
QTAILQ_FOREACH_SAFE(wp, &env->watchpoints, entry, next) {
if (wp->flags & mask)
cpu_watchpoint_remove_by_ref(env, wp);
QTAILQ_FOREACH_SAFE(wp, &cpu->watchpoints, entry, next) {
if (wp->flags & mask) {
cpu_watchpoint_remove_by_ref(cpu, wp);
}
}
}
#endif
/* Add a breakpoint. */
int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int flags,
CPUBreakpoint **breakpoint)
{
#if defined(TARGET_HAS_ICE)
@@ -624,12 +627,12 @@ int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
/* keep all GDB-injected breakpoints in front */
if (flags & BP_GDB) {
QTAILQ_INSERT_HEAD(&env->breakpoints, bp, entry);
QTAILQ_INSERT_HEAD(&cpu->breakpoints, bp, entry);
} else {
QTAILQ_INSERT_TAIL(&env->breakpoints, bp, entry);
QTAILQ_INSERT_TAIL(&cpu->breakpoints, bp, entry);
}
breakpoint_invalidate(ENV_GET_CPU(env), pc);
breakpoint_invalidate(cpu, pc);
if (breakpoint) {
*breakpoint = bp;
@@ -641,14 +644,14 @@ int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
}
/* Remove a specific breakpoint. */
int cpu_breakpoint_remove(CPUArchState *env, target_ulong pc, int flags)
int cpu_breakpoint_remove(CPUState *cpu, vaddr pc, int flags)
{
#if defined(TARGET_HAS_ICE)
CPUBreakpoint *bp;
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
if (bp->pc == pc && bp->flags == flags) {
cpu_breakpoint_remove_by_ref(env, bp);
cpu_breakpoint_remove_by_ref(cpu, bp);
return 0;
}
}
@@ -659,26 +662,27 @@ int cpu_breakpoint_remove(CPUArchState *env, target_ulong pc, int flags)
}
/* Remove a specific breakpoint by reference. */
void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint *breakpoint)
void cpu_breakpoint_remove_by_ref(CPUState *cpu, CPUBreakpoint *breakpoint)
{
#if defined(TARGET_HAS_ICE)
QTAILQ_REMOVE(&env->breakpoints, breakpoint, entry);
QTAILQ_REMOVE(&cpu->breakpoints, breakpoint, entry);
breakpoint_invalidate(ENV_GET_CPU(env), breakpoint->pc);
breakpoint_invalidate(cpu, breakpoint->pc);
g_free(breakpoint);
#endif
}
/* Remove all matching breakpoints. */
void cpu_breakpoint_remove_all(CPUArchState *env, int mask)
void cpu_breakpoint_remove_all(CPUState *cpu, int mask)
{
#if defined(TARGET_HAS_ICE)
CPUBreakpoint *bp, *next;
QTAILQ_FOREACH_SAFE(bp, &env->breakpoints, entry, next) {
if (bp->flags & mask)
cpu_breakpoint_remove_by_ref(env, bp);
QTAILQ_FOREACH_SAFE(bp, &cpu->breakpoints, entry, next) {
if (bp->flags & mask) {
cpu_breakpoint_remove_by_ref(cpu, bp);
}
}
#endif
}
@@ -702,9 +706,8 @@ void cpu_single_step(CPUState *cpu, int enabled)
#endif
}
void cpu_abort(CPUArchState *env, const char *fmt, ...)
void cpu_abort(CPUState *cpu, const char *fmt, ...)
{
CPUState *cpu = ENV_GET_CPU(env);
va_list ap;
va_list ap2;
@@ -792,7 +795,7 @@ static void cpu_physical_memory_set_dirty_tracking(bool enable)
in_migration = enable;
}
hwaddr memory_region_section_get_iotlb(CPUArchState *env,
hwaddr memory_region_section_get_iotlb(CPUState *cpu,
MemoryRegionSection *section,
target_ulong vaddr,
hwaddr paddr, hwaddr xlat,
@@ -818,7 +821,7 @@ hwaddr memory_region_section_get_iotlb(CPUArchState *env,
/* Make accesses to pages with watchpoints go via the
watchpoint trap routines. */
QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
if (vaddr == (wp->vaddr & TARGET_PAGE_MASK)) {
/* Avoid trapping reads of pages with a write breakpoint. */
if ((prot & PAGE_WRITE) || (wp->flags & BP_MEM_READ)) {
@@ -1553,7 +1556,7 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
flushed */
if (!cpu_physical_memory_is_clean(ram_addr)) {
CPUArchState *env = current_cpu->env_ptr;
tlb_set_dirty(env, env->mem_io_vaddr);
tlb_set_dirty(env, current_cpu->mem_io_vaddr);
}
}
@@ -1572,34 +1575,35 @@ static const MemoryRegionOps notdirty_mem_ops = {
/* Generate a debug exception if a watchpoint has been hit. */
static void check_watchpoint(int offset, int len_mask, int flags)
{
CPUArchState *env = current_cpu->env_ptr;
CPUState *cpu = current_cpu;
CPUArchState *env = cpu->env_ptr;
target_ulong pc, cs_base;
target_ulong vaddr;
CPUWatchpoint *wp;
int cpu_flags;
if (env->watchpoint_hit) {
if (cpu->watchpoint_hit) {
/* We re-entered the check after replacing the TB. Now raise
* the debug interrupt so that is will trigger after the
* current instruction. */
cpu_interrupt(ENV_GET_CPU(env), CPU_INTERRUPT_DEBUG);
cpu_interrupt(cpu, CPU_INTERRUPT_DEBUG);
return;
}
vaddr = (env->mem_io_vaddr & TARGET_PAGE_MASK) + offset;
QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
vaddr = (cpu->mem_io_vaddr & TARGET_PAGE_MASK) + offset;
QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
if ((vaddr == (wp->vaddr & len_mask) ||
(vaddr & wp->len_mask) == wp->vaddr) && (wp->flags & flags)) {
wp->flags |= BP_WATCHPOINT_HIT;
if (!env->watchpoint_hit) {
env->watchpoint_hit = wp;
tb_check_watchpoint(env);
if (!cpu->watchpoint_hit) {
cpu->watchpoint_hit = wp;
tb_check_watchpoint(cpu);
if (wp->flags & BP_STOP_BEFORE_ACCESS) {
env->exception_index = EXCP_DEBUG;
cpu_loop_exit(env);
cpu->exception_index = EXCP_DEBUG;
cpu_loop_exit(cpu);
} else {
cpu_get_tb_cpu_state(env, &pc, &cs_base, &cpu_flags);
tb_gen_code(env, pc, cs_base, cpu_flags, 1);
cpu_resume_from_signal(env, NULL);
tb_gen_code(cpu, pc, cs_base, cpu_flags, 1);
cpu_resume_from_signal(cpu, NULL);
}
}
} else {
@@ -1830,14 +1834,12 @@ static void tcg_commit(MemoryListener *listener)
reset the modified entries */
/* XXX: slow ! */
CPU_FOREACH(cpu) {
CPUArchState *env = cpu->env_ptr;
/* FIXME: Disentangle the cpu.h circular files deps so we can
directly get the right CPU from listener. */
if (cpu->tcg_as_listener != listener) {
continue;
}
tlb_flush(env, 1);
tlb_flush(cpu, 1);
}
}
+22 -26
View File
@@ -635,7 +635,6 @@ static const int xlat_gdb_type[] = {
static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
{
CPUState *cpu;
CPUArchState *env;
int err = 0;
if (kvm_enabled()) {
@@ -646,10 +645,10 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
case GDB_BREAKPOINT_SW:
case GDB_BREAKPOINT_HW:
CPU_FOREACH(cpu) {
env = cpu->env_ptr;
err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
if (err)
err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
if (err) {
break;
}
}
return err;
#ifndef CONFIG_USER_ONLY
@@ -657,8 +656,7 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
case GDB_WATCHPOINT_READ:
case GDB_WATCHPOINT_ACCESS:
CPU_FOREACH(cpu) {
env = cpu->env_ptr;
err = cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type],
err = cpu_watchpoint_insert(cpu, addr, len, xlat_gdb_type[type],
NULL);
if (err)
break;
@@ -673,7 +671,6 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
{
CPUState *cpu;
CPUArchState *env;
int err = 0;
if (kvm_enabled()) {
@@ -684,10 +681,10 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
case GDB_BREAKPOINT_SW:
case GDB_BREAKPOINT_HW:
CPU_FOREACH(cpu) {
env = cpu->env_ptr;
err = cpu_breakpoint_remove(env, addr, BP_GDB);
if (err)
err = cpu_breakpoint_remove(cpu, addr, BP_GDB);
if (err) {
break;
}
}
return err;
#ifndef CONFIG_USER_ONLY
@@ -695,8 +692,7 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
case GDB_WATCHPOINT_READ:
case GDB_WATCHPOINT_ACCESS:
CPU_FOREACH(cpu) {
env = cpu->env_ptr;
err = cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]);
err = cpu_watchpoint_remove(cpu, addr, len, xlat_gdb_type[type]);
if (err)
break;
}
@@ -710,7 +706,6 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
static void gdb_breakpoint_remove_all(void)
{
CPUState *cpu;
CPUArchState *env;
if (kvm_enabled()) {
kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
@@ -718,10 +713,9 @@ static void gdb_breakpoint_remove_all(void)
}
CPU_FOREACH(cpu) {
env = cpu->env_ptr;
cpu_breakpoint_remove_all(env, BP_GDB);
cpu_breakpoint_remove_all(cpu, BP_GDB);
#ifndef CONFIG_USER_ONLY
cpu_watchpoint_remove_all(env, BP_GDB);
cpu_watchpoint_remove_all(cpu, BP_GDB);
#endif
}
}
@@ -1086,8 +1080,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
}
#ifdef CONFIG_USER_ONLY
else if (strncmp(p, "Offsets", 7) == 0) {
CPUArchState *env = s->c_cpu->env_ptr;
TaskState *ts = env->opaque;
TaskState *ts = s->c_cpu->opaque;
snprintf(buf, sizeof(buf),
"Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx
@@ -1205,8 +1198,8 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
}
switch (state) {
case RUN_STATE_DEBUG:
if (env->watchpoint_hit) {
switch (env->watchpoint_hit->flags & BP_MEM_ACCESS) {
if (cpu->watchpoint_hit) {
switch (cpu->watchpoint_hit->flags & BP_MEM_ACCESS) {
case BP_MEM_READ:
type = "r";
break;
@@ -1220,8 +1213,8 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
snprintf(buf, sizeof(buf),
"T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
GDB_SIGNAL_TRAP, cpu_index(cpu), type,
env->watchpoint_hit->vaddr);
env->watchpoint_hit = NULL;
(target_ulong)cpu->watchpoint_hit->vaddr);
cpu->watchpoint_hit = NULL;
goto send_packet;
}
tb_flush(env);
@@ -1594,13 +1587,16 @@ int gdbserver_start(int port)
/* Disable gdb stub for child processes. */
void gdbserver_fork(CPUArchState *env)
{
CPUState *cpu = ENV_GET_CPU(env);
GDBState *s = gdbserver_state;
if (gdbserver_fd < 0 || s->fd < 0)
return;
if (gdbserver_fd < 0 || s->fd < 0) {
return;
}
close(s->fd);
s->fd = -1;
cpu_breakpoint_remove_all(env, BP_GDB);
cpu_watchpoint_remove_all(env, BP_GDB);
cpu_breakpoint_remove_all(cpu, BP_GDB);
cpu_watchpoint_remove_all(cpu, BP_GDB);
}
#else
static int gdb_chr_can_receive(void *opaque)
+3 -3
View File
@@ -406,7 +406,7 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
}
if (!kvm_enabled()) {
cpu_restore_state(env, env->mem_io_pc);
cpu_restore_state(cs, cs->mem_io_pc);
cpu_get_tb_cpu_state(env, &current_pc, &current_cs_base,
&current_flags);
}
@@ -448,8 +448,8 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
if (!kvm_enabled()) {
cs->current_tb = NULL;
tb_gen_code(env, current_pc, current_cs_base, current_flags, 1);
cpu_resume_from_signal(env, NULL);
tb_gen_code(cs, current_pc, current_cs_base, current_flags, 1);
cpu_resume_from_signal(cs, NULL);
}
}
+4 -3
View File
@@ -267,6 +267,7 @@ static void pc_compat_1_7(QEMUMachineInitArgs *args)
smbios_type1_defaults = false;
gigabyte_align = false;
option_rom_has_mr = true;
x86_cpu_compat_disable_kvm_features(FEAT_1_ECX, CPUID_EXT_X2APIC);
}
static void pc_compat_1_6(QEMUMachineInitArgs *args)
@@ -299,7 +300,7 @@ static void pc_compat_1_3(QEMUMachineInitArgs *args)
static void pc_compat_1_2(QEMUMachineInitArgs *args)
{
pc_compat_1_3(args);
disable_kvm_pv_eoi();
x86_cpu_compat_disable_kvm_features(FEAT_KVM, KVM_FEATURE_PV_EOI);
}
static void pc_init_pci_1_7(QEMUMachineInitArgs *args)
@@ -345,7 +346,7 @@ static void pc_init_pci_no_kvmclock(QEMUMachineInitArgs *args)
has_pci_info = false;
has_acpi_build = false;
smbios_type1_defaults = false;
disable_kvm_pv_eoi();
x86_cpu_compat_disable_kvm_features(FEAT_KVM, KVM_FEATURE_PV_EOI);
enable_compat_apic_id_mode();
pc_init1(args, 1, 0);
}
@@ -358,7 +359,7 @@ static void pc_init_isa(QEMUMachineInitArgs *args)
if (!args->cpu_model) {
args->cpu_model = "486";
}
disable_kvm_pv_eoi();
x86_cpu_compat_disable_kvm_features(FEAT_KVM, KVM_FEATURE_PV_EOI);
enable_compat_apic_id_mode();
pc_init1(args, 0, 1);
}
+1
View File
@@ -245,6 +245,7 @@ static void pc_compat_1_7(QEMUMachineInitArgs *args)
smbios_type1_defaults = false;
gigabyte_align = false;
option_rom_has_mr = true;
x86_cpu_compat_disable_kvm_features(FEAT_1_ECX, CPUID_EXT_X2APIC);
}
static void pc_compat_1_6(QEMUMachineInitArgs *args)
+1 -2
View File
@@ -472,14 +472,13 @@ static void ppce500_cpu_reset_sec(void *opaque)
{
PowerPCCPU *cpu = opaque;
CPUState *cs = CPU(cpu);
CPUPPCState *env = &cpu->env;
cpu_reset(cs);
/* Secondary CPU starts in halted state for now. Needs to change when
implementing non-kernel boot. */
cs->halted = 1;
env->exception_index = EXCP_HLT;
cs->exception_index = EXCP_HLT;
}
static void ppce500_cpu_reset(void *opaque)
+1 -1
View File
@@ -44,7 +44,7 @@
ram_addr_t ppc405_set_bootinfo (CPUPPCState *env, ppc4xx_bd_info_t *bd,
uint32_t flags)
{
CPUState *cs = ENV_GET_CPU(env);
CPUState *cs = CPU(ppc_env_get_cpu(env));
ram_addr_t bdloc;
int i, n;
+1 -1
View File
@@ -117,7 +117,7 @@ static void spin_kick(void *data)
mmubooke_create_initial_mapping(env, 0, map_start, map_size);
cpu->halted = 0;
env->exception_index = -1;
cpu->exception_index = -1;
cpu->stopped = false;
qemu_cpu_kick(cpu);
}
+4 -4
View File
@@ -356,7 +356,7 @@ static target_ulong h_set_dabr(PowerPCCPU *cpu, sPAPREnvironment *spapr,
static target_ulong register_vpa(CPUPPCState *env, target_ulong vpa)
{
CPUState *cs = ENV_GET_CPU(env);
CPUState *cs = CPU(ppc_env_get_cpu(env));
uint16_t size;
uint8_t tmp;
@@ -406,7 +406,7 @@ static target_ulong deregister_vpa(CPUPPCState *env, target_ulong vpa)
static target_ulong register_slb_shadow(CPUPPCState *env, target_ulong addr)
{
CPUState *cs = ENV_GET_CPU(env);
CPUState *cs = CPU(ppc_env_get_cpu(env));
uint32_t size;
if (addr == 0) {
@@ -442,7 +442,7 @@ static target_ulong deregister_slb_shadow(CPUPPCState *env, target_ulong addr)
static target_ulong register_dtl(CPUPPCState *env, target_ulong addr)
{
CPUState *cs = ENV_GET_CPU(env);
CPUState *cs = CPU(ppc_env_get_cpu(env));
uint32_t size;
if (addr == 0) {
@@ -529,7 +529,7 @@ static target_ulong h_cede(PowerPCCPU *cpu, sPAPREnvironment *spapr,
hreg_compute_hflags(env);
if (!cpu_has_work(cs)) {
cs->halted = 1;
env->exception_index = EXCP_HLT;
cs->exception_index = EXCP_HLT;
cs->exit_request = 1;
}
return H_SUCCESS;
+3 -5
View File
@@ -135,25 +135,23 @@ static unsigned s390_running_cpus;
void s390_add_running_cpu(S390CPU *cpu)
{
CPUState *cs = CPU(cpu);
CPUS390XState *env = &cpu->env;
if (cs->halted) {
s390_running_cpus++;
cs->halted = 0;
env->exception_index = -1;
cs->exception_index = -1;
}
}
unsigned s390_del_running_cpu(S390CPU *cpu)
{
CPUState *cs = CPU(cpu);
CPUS390XState *env = &cpu->env;
if (cs->halted == 0) {
assert(s390_running_cpus >= 1);
s390_running_cpus--;
cs->halted = 1;
env->exception_index = EXCP_HLT;
cs->exception_index = EXCP_HLT;
}
return s390_running_cpus;
}
@@ -196,7 +194,7 @@ void s390_init_cpus(const char *cpu_model, uint8_t *storage_keys)
ipi_states[i] = cpu;
cs->halted = 1;
cpu->env.exception_index = EXCP_HLT;
cs->exception_index = EXCP_HLT;
cpu->env.storage_keys = storage_keys;
}
}
+1 -1
View File
@@ -416,7 +416,7 @@ static void sh7750_mem_writel(void *opaque, hwaddr addr,
case SH7750_PTEH_A7:
/* If asid changes, clear all registered tlb entries. */
if ((s->cpu->env.pteh & 0xff) != (mem_value & 0xff)) {
tlb_flush(&s->cpu->env, 1);
tlb_flush(CPU(s->cpu), 1);
}
s->cpu->env.pteh = mem_value;
return;
-24
View File
@@ -360,9 +360,6 @@ int page_check_range(target_ulong start, target_ulong len, int flags);
CPUArchState *cpu_copy(CPUArchState *env);
void QEMU_NORETURN cpu_abort(CPUArchState *env, const char *fmt, ...)
GCC_FMT_ATTR(2, 3);
/* Flags for use in ENV->INTERRUPT_PENDING.
The numbers assigned here are non-sequential in order to preserve
@@ -413,27 +410,6 @@ void QEMU_NORETURN cpu_abort(CPUArchState *env, const char *fmt, ...)
| CPU_INTERRUPT_TGT_EXT_3 \
| CPU_INTERRUPT_TGT_EXT_4)
/* Breakpoint/watchpoint flags */
#define BP_MEM_READ 0x01
#define BP_MEM_WRITE 0x02
#define BP_MEM_ACCESS (BP_MEM_READ | BP_MEM_WRITE)
#define BP_STOP_BEFORE_ACCESS 0x04
#define BP_WATCHPOINT_HIT 0x08
#define BP_GDB 0x10
#define BP_CPU 0x20
int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
CPUBreakpoint **breakpoint);
int cpu_breakpoint_remove(CPUArchState *env, target_ulong pc, int flags);
void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint *breakpoint);
void cpu_breakpoint_remove_all(CPUArchState *env, int mask);
int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len,
int flags, CPUWatchpoint **watchpoint);
int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr,
target_ulong len, int flags);
void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint);
void cpu_watchpoint_remove_all(CPUArchState *env, int mask);
#if !defined(CONFIG_USER_ONLY)
/* memory API */
-61
View File
@@ -24,7 +24,6 @@
#endif
#include "config.h"
#include <setjmp.h>
#include <inttypes.h>
#include "qemu/osdep.h"
#include "qemu/queue.h"
@@ -61,9 +60,6 @@ typedef uint64_t target_ulong;
#define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external event) */
#define EXCP_YIELD 0x10004 /* cpu wants to yield timeslice to another */
#define TB_JMP_CACHE_BITS 12
#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
/* Only the bottom TB_JMP_PAGE_BITS of the jump cache hash bits vary for
addresses on the same page. The top bits are the same. This allows
TLB invalidation to quickly clear a subset of the hash table. */
@@ -118,66 +114,9 @@ QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));
#endif
#ifdef HOST_WORDS_BIGENDIAN
typedef struct icount_decr_u16 {
uint16_t high;
uint16_t low;
} icount_decr_u16;
#else
typedef struct icount_decr_u16 {
uint16_t low;
uint16_t high;
} icount_decr_u16;
#endif
typedef struct CPUBreakpoint {
target_ulong pc;
int flags; /* BP_* */
QTAILQ_ENTRY(CPUBreakpoint) entry;
} CPUBreakpoint;
typedef struct CPUWatchpoint {
target_ulong vaddr;
target_ulong len_mask;
int flags; /* BP_* */
QTAILQ_ENTRY(CPUWatchpoint) entry;
} CPUWatchpoint;
#define CPU_TEMP_BUF_NLONGS 128
#define CPU_COMMON \
/* soft mmu support */ \
/* in order to avoid passing too many arguments to the MMIO \
helpers, we store some rarely used information in the CPU \
context) */ \
uintptr_t mem_io_pc; /* host pc at which the memory was \
accessed */ \
target_ulong mem_io_vaddr; /* target virtual addr at which the \
memory was accessed */ \
CPU_COMMON_TLB \
struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; \
\
int64_t icount_extra; /* Instructions until next timer event. */ \
/* Number of cycles left, with interrupt flag in high bit. \
This allows a single read-compare-cbranch-write sequence to test \
for both decrementer underflow and exceptions. */ \
union { \
uint32_t u32; \
icount_decr_u16 u16; \
} icount_decr; \
uint32_t can_do_io; /* nonzero if memory mapped IO is safe. */ \
\
/* from this point: preserved by CPU reset */ \
/* ice debug support */ \
QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints; \
\
QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints; \
CPUWatchpoint *watchpoint_hit; \
\
/* Core interrupt code */ \
sigjmp_buf jmp_env; \
int exception_index; \
\
/* user data */ \
void *opaque; \
#endif
+3 -3
View File
@@ -22,7 +22,7 @@
#if !defined(CONFIG_USER_ONLY)
/* cputlb.c */
void tlb_protect_code(ram_addr_t ram_addr);
void tlb_unprotect_code_phys(CPUArchState *env, ram_addr_t ram_addr,
void tlb_unprotect_code_phys(CPUState *cpu, ram_addr_t ram_addr,
target_ulong vaddr);
void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start,
uintptr_t length);
@@ -31,12 +31,12 @@ void tlb_set_dirty(CPUArchState *env, target_ulong vaddr);
extern int tlb_flush_count;
/* exec.c */
void tb_flush_jmp_cache(CPUArchState *env, target_ulong addr);
void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr);
MemoryRegionSection *
address_space_translate_for_iotlb(AddressSpace *as, hwaddr addr, hwaddr *xlat,
hwaddr *plen);
hwaddr memory_region_section_get_iotlb(CPUArchState *env,
hwaddr memory_region_section_get_iotlb(CPUState *cpu,
MemoryRegionSection *section,
target_ulong vaddr,
hwaddr paddr, hwaddr xlat,
+24 -19
View File
@@ -80,16 +80,16 @@ void restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb,
void cpu_gen_init(void);
int cpu_gen_code(CPUArchState *env, struct TranslationBlock *tb,
int *gen_code_size_ptr);
bool cpu_restore_state(CPUArchState *env, uintptr_t searched_pc);
bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc);
void page_size_init(void);
void QEMU_NORETURN cpu_resume_from_signal(CPUArchState *env1, void *puc);
void QEMU_NORETURN cpu_io_recompile(CPUArchState *env, uintptr_t retaddr);
TranslationBlock *tb_gen_code(CPUArchState *env,
void QEMU_NORETURN cpu_resume_from_signal(CPUState *cpu, void *puc);
void QEMU_NORETURN cpu_io_recompile(CPUState *cpu, uintptr_t retaddr);
TranslationBlock *tb_gen_code(CPUState *cpu,
target_ulong pc, target_ulong cs_base, int flags,
int cflags);
void cpu_exec_init(CPUArchState *env);
void QEMU_NORETURN cpu_loop_exit(CPUArchState *env1);
void QEMU_NORETURN cpu_loop_exit(CPUState *cpu);
int page_unprotect(target_ulong address, uintptr_t pc, void *puc);
void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
int is_cpu_write_access);
@@ -98,18 +98,18 @@ void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end,
#if !defined(CONFIG_USER_ONLY)
void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as);
/* cputlb.c */
void tlb_flush_page(CPUArchState *env, target_ulong addr);
void tlb_flush(CPUArchState *env, int flush_global);
void tlb_set_page(CPUArchState *env, target_ulong vaddr,
void tlb_flush_page(CPUState *cpu, target_ulong addr);
void tlb_flush(CPUState *cpu, int flush_global);
void tlb_set_page(CPUState *cpu, target_ulong vaddr,
hwaddr paddr, int prot,
int mmu_idx, target_ulong size);
void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr);
#else
static inline void tlb_flush_page(CPUArchState *env, target_ulong addr)
static inline void tlb_flush_page(CPUState *cpu, target_ulong addr)
{
}
static inline void tlb_flush(CPUArchState *env, int flush_global)
static inline void tlb_flush(CPUState *cpu, int flush_global)
{
}
#endif
@@ -332,7 +332,7 @@ bool io_mem_read(struct MemoryRegion *mr, hwaddr addr,
bool io_mem_write(struct MemoryRegion *mr, hwaddr addr,
uint64_t value, unsigned size);
void tlb_fill(CPUArchState *env1, target_ulong addr, int is_write, int mmu_idx,
void tlb_fill(CPUState *cpu, target_ulong addr, int is_write, int mmu_idx,
uintptr_t retaddr);
uint8_t helper_ldb_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
@@ -380,20 +380,25 @@ extern int singlestep;
/* cpu-exec.c */
extern volatile sig_atomic_t exit_request;
/* Deterministic execution requires that IO only be performed on the last
instruction of a TB so that interrupts take effect immediately. */
static inline int can_do_io(CPUArchState *env)
/**
* cpu_can_do_io:
* @cpu: The CPU for which to check IO.
*
* Deterministic execution requires that IO only be performed on the last
* instruction of a TB so that interrupts take effect immediately.
*
* Returns: %true if memory-mapped IO is safe, %false otherwise.
*/
static inline bool cpu_can_do_io(CPUState *cpu)
{
CPUState *cpu = ENV_GET_CPU(env);
if (!use_icount) {
return 1;
return true;
}
/* If not executing code then assume we are ok. */
if (cpu->current_tb == NULL) {
return 1;
return true;
}
return env->can_do_io != 0;
return cpu->can_do_io != 0;
}
#endif
+6 -4
View File
@@ -26,13 +26,15 @@ static inline void gen_tb_start(void)
icount_label = gen_new_label();
count = tcg_temp_local_new_i32();
tcg_gen_ld_i32(count, cpu_env, offsetof(CPUArchState, icount_decr.u32));
tcg_gen_ld_i32(count, cpu_env,
-ENV_OFFSET + offsetof(CPUState, icount_decr.u32));
/* This is a horrid hack to allow fixing up the value later. */
icount_arg = tcg_ctx.gen_opparam_ptr + 1;
tcg_gen_subi_i32(count, count, 0xdeadbeef);
tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, icount_label);
tcg_gen_st16_i32(count, cpu_env, offsetof(CPUArchState, icount_decr.u16.low));
tcg_gen_st16_i32(count, cpu_env,
-ENV_OFFSET + offsetof(CPUState, icount_decr.u16.low));
tcg_temp_free_i32(count);
}
@@ -51,14 +53,14 @@ static void gen_tb_end(TranslationBlock *tb, int num_insns)
static inline void gen_io_start(void)
{
TCGv_i32 tmp = tcg_const_i32(1);
tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUArchState, can_do_io));
tcg_gen_st_i32(tmp, cpu_env, -ENV_OFFSET + offsetof(CPUState, can_do_io));
tcg_temp_free_i32(tmp);
}
static inline void gen_io_end(void)
{
TCGv_i32 tmp = tcg_const_i32(0);
tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUArchState, can_do_io));
tcg_gen_st_i32(tmp, cpu_env, -ENV_OFFSET + offsetof(CPUState, can_do_io));
tcg_temp_free_i32(tmp);
}

Some files were not shown because too many files have changed in this diff Show More