static TranslationBlock *tb_find_slow(target_ulong pc,
target_ulong cs_base,
- unsigned int flags)
+ uint64_t flags)
{
TranslationBlock *tb, **ptb1;
int code_gen_size;
unsigned int h;
target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
uint8_t *tc_ptr;
-
+
spin_lock(&tb_lock);
tb_invalidated_flag = 0;
-
+
regs_to_env(); /* XXX: do it just before cpu_gen_code() */
-
+
/* find translated block using physical mappings */
phys_pc = get_phys_addr_code(env, pc);
phys_page1 = phys_pc & TARGET_PAGE_MASK;
tb->flags = flags;
cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);
code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
-
+
/* check next page if needed */
virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
phys_page2 = -1;
phys_page2 = get_phys_addr_code(env, virt_page2);
}
tb_link_phys(tb, phys_pc, phys_page2);
-
+
found:
/* we add the TB in the virtual pc hash table */
env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
{
TranslationBlock *tb;
target_ulong cs_base, pc;
- unsigned int flags;
+ uint64_t flags;
/* we record a subset of the CPU state. It will
always be the same before a given translated block
#if defined(TARGET_I386)
flags = env->hflags;
flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
+ flags |= env->intercept;
cs_base = env->segs[R_CS].base;
pc = cs_base + env->eip;
#elif defined(TARGET_ARM)
flags = (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2))
| (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
#else
- // FPU enable . MMU enabled . MMU no-fault . Supervisor
- flags = (env->psref << 3) | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1)
+ // FPU enable . MMU Boot . MMU enabled . MMU no-fault . Supervisor
+ flags = (env->psref << 4) | (((env->mmuregs[0] & MMU_BM) >> 14) << 3)
+ | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1)
| env->psrs;
#endif
cs_base = env->npc;
pc = env->pc;
#elif defined(TARGET_PPC)
- flags = (msr_pr << MSR_PR) | (msr_fp << MSR_FP) |
- (msr_se << MSR_SE) | (msr_le << MSR_LE);
+ flags = env->hflags;
cs_base = 0;
pc = env->nip;
#elif defined(TARGET_MIPS)
#if defined(__sparc__) && !defined(HOST_SOLARIS)
/* g1 can be modified by some libc? functions */
tmp_T0 = T0;
-#endif
+#endif
interrupt_request = env->interrupt_request;
- if (__builtin_expect(interrupt_request, 0)) {
+ if (__builtin_expect(interrupt_request, 0)
+#if defined(TARGET_I386)
+ && env->hflags & HF_GIF_MASK
+#endif
+ ) {
if (interrupt_request & CPU_INTERRUPT_DEBUG) {
env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
env->exception_index = EXCP_DEBUG;
#if defined(TARGET_I386)
if ((interrupt_request & CPU_INTERRUPT_SMI) &&
!(env->hflags & HF_SMM_MASK)) {
+ svm_check_intercept(SVM_EXIT_SMI);
env->interrupt_request &= ~CPU_INTERRUPT_SMI;
do_smm_enter();
#if defined(__sparc__) && !defined(HOST_SOLARIS)
T0 = 0;
#endif
} else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
- (env->eflags & IF_MASK) &&
+ (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) &&
!(env->hflags & HF_INHIBIT_IRQ_MASK)) {
int intno;
- env->interrupt_request &= ~CPU_INTERRUPT_HARD;
+ svm_check_intercept(SVM_EXIT_INTR);
+ env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
intno = cpu_get_pic_interrupt(env);
if (loglevel & CPU_LOG_TB_IN_ASM) {
fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
tmp_T0 = 0;
#else
T0 = 0;
+#endif
+#if !defined(CONFIG_USER_ONLY)
+ } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
+ (env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
+ int intno;
+ /* FIXME: this should respect TPR */
+ env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
+ svm_check_intercept(SVM_EXIT_VINTR);
+ intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
+ if (loglevel & CPU_LOG_TB_IN_ASM)
+ fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno);
+ do_interrupt(intno, 0, 0, -1, 1);
+ stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
+ ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK);
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
+ tmp_T0 = 0;
+#else
+ T0 = 0;
+#endif
#endif
}
#elif defined(TARGET_PPC)
#endif
#if defined(__sparc__) && !defined(HOST_SOLARIS)
T0 = tmp_T0;
-#endif
+#endif
/* see if we can patch the calling TB. When the TB
spans two pages, we cannot safely do a direct
jump. */
saved_env = env;
env = s;
-
+
helper_fsave((target_ulong)ptr, data32);
env = saved_env;
saved_env = env;
env = s;
-
+
helper_frstor((target_ulong)ptr, data32);
env = saved_env;
{
TranslationBlock *tb;
int ret;
-
+
if (cpu_single_env)
env = cpu_single_env; /* XXX: find a correct solution for multithread */
#if defined(DEBUG_SIGNAL)
{
TranslationBlock *tb;
int ret;
-
+
if (cpu_single_env)
env = cpu_single_env; /* XXX: find a correct solution for multithread */
#if defined(DEBUG_SIGNAL)
{
TranslationBlock *tb;
int ret;
-
+
if (cpu_single_env)
env = cpu_single_env; /* XXX: find a correct solution for multithread */
#if defined(DEBUG_SIGNAL)
{
TranslationBlock *tb;
int ret;
-
+
if (cpu_single_env)
env = cpu_single_env; /* XXX: find a correct solution for multithread */
#if defined(DEBUG_SIGNAL)
unsigned long pc;
int is_write;
uint32_t insn;
-
+
/* XXX: is there a standard glibc define ? */
pc = regs[1];
/* XXX: need kernel patch to get write flag faster */
struct ucontext *uc = puc;
unsigned long pc;
int is_write;
-
+
pc = uc->uc_mcontext.gregs[R15];
/* XXX: compute is_write */
is_write = 0;
struct ucontext *uc = puc;
unsigned long pc;
int is_write;
-
+
pc = uc->uc_mcontext.gregs[16];
/* XXX: compute is_write */
is_write = 0;
struct ucontext *uc = puc;
unsigned long pc;
int is_write;
-
+
pc = uc->uc_mcontext.psw.addr;
/* XXX: compute is_write */
is_write = 0;
struct ucontext *uc = puc;
greg_t pc = uc->uc_mcontext.pc;
int is_write;
-
+
/* XXX: compute is_write */
is_write = 0;
return handle_cpu_signal(pc, (unsigned long)info->si_addr,