mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
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:
+1
-1
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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, ¤t_pc, ¤t_cs_base,
|
||||
¤t_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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user