]> git.proxmox.com Git - qemu.git/blobdiff - target-i386/misc_helper.c
Merge remote-tracking branch 'jliu/or32' into staging
[qemu.git] / target-i386 / misc_helper.c
index ce675b7218d82f816a206b638ce7b4278dc34942..957926ced7aff8702899b75804a6eb9b05c08968 100644 (file)
  */
 
 #include "cpu.h"
-#include "dyngen-exec.h"
-#include "ioport.h"
+#include "exec/ioport.h"
 #include "helper.h"
 
 #if !defined(CONFIG_USER_ONLY)
-#include "softmmu_exec.h"
+#include "exec/softmmu_exec.h"
 #endif /* !defined(CONFIG_USER_ONLY) */
 
 /* check if Port I/O is allowed in TSS */
-static inline void check_io(int addr, int size)
+static inline void check_io(CPUX86State *env, int addr, int size)
 {
     int io_offset, val, mask;
 
@@ -37,13 +36,13 @@ static inline void check_io(int addr, int size)
         env->tr.limit < 103) {
         goto fail;
     }
-    io_offset = lduw_kernel(env->tr.base + 0x66);
+    io_offset = cpu_lduw_kernel(env, env->tr.base + 0x66);
     io_offset += (addr >> 3);
     /* Note: the check needs two bytes */
     if ((io_offset + 1) > env->tr.limit) {
         goto fail;
     }
-    val = lduw_kernel(env->tr.base + io_offset);
+    val = cpu_lduw_kernel(env, env->tr.base + io_offset);
     val >>= (addr & 7);
     mask = (1 << size) - 1;
     /* all bits must be zero to allow the I/O */
@@ -53,19 +52,19 @@ static inline void check_io(int addr, int size)
     }
 }
 
-void helper_check_iob(uint32_t t0)
+void helper_check_iob(CPUX86State *env, uint32_t t0)
 {
-    check_io(t0, 1);
+    check_io(env, t0, 1);
 }
 
-void helper_check_iow(uint32_t t0)
+void helper_check_iow(CPUX86State *env, uint32_t t0)
 {
-    check_io(t0, 2);
+    check_io(env, t0, 2);
 }
 
-void helper_check_iol(uint32_t t0)
+void helper_check_iol(CPUX86State *env, uint32_t t0)
 {
-    check_io(t0, 4);
+    check_io(env, t0, 4);
 }
 
 void helper_outb(uint32_t port, uint32_t data)
@@ -98,53 +97,54 @@ target_ulong helper_inl(uint32_t port)
     return cpu_inl(port);
 }
 
-void helper_into(int next_eip_addend)
+void helper_into(CPUX86State *env, int next_eip_addend)
 {
     int eflags;
 
-    eflags = helper_cc_compute_all(CC_OP);
+    eflags = cpu_cc_compute_all(env, CC_OP);
     if (eflags & CC_O) {
         raise_interrupt(env, EXCP04_INTO, 1, 0, next_eip_addend);
     }
 }
 
-void helper_single_step(void)
+void helper_single_step(CPUX86State *env)
 {
 #ifndef CONFIG_USER_ONLY
-    check_hw_breakpoints(env, 1);
+    check_hw_breakpoints(env, true);
     env->dr[6] |= DR6_BS;
 #endif
     raise_exception(env, EXCP01_DB);
 }
 
-void helper_cpuid(void)
+void helper_cpuid(CPUX86State *env)
 {
     uint32_t eax, ebx, ecx, edx;
 
     cpu_svm_check_intercept_param(env, SVM_EXIT_CPUID, 0);
 
-    cpu_x86_cpuid(env, (uint32_t)EAX, (uint32_t)ECX, &eax, &ebx, &ecx, &edx);
-    EAX = eax;
-    EBX = ebx;
-    ECX = ecx;
-    EDX = edx;
+    cpu_x86_cpuid(env, (uint32_t)env->regs[R_EAX], (uint32_t)env->regs[R_ECX],
+                  &eax, &ebx, &ecx, &edx);
+    env->regs[R_EAX] = eax;
+    env->regs[R_EBX] = ebx;
+    env->regs[R_ECX] = ecx;
+    env->regs[R_EDX] = edx;
 }
 
 #if defined(CONFIG_USER_ONLY)
-target_ulong helper_read_crN(int reg)
+target_ulong helper_read_crN(CPUX86State *env, int reg)
 {
     return 0;
 }
 
-void helper_write_crN(int reg, target_ulong t0)
+void helper_write_crN(CPUX86State *env, int reg, target_ulong t0)
 {
 }
 
-void helper_movl_drN_T0(int reg, target_ulong t0)
+void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0)
 {
 }
 #else
-target_ulong helper_read_crN(int reg)
+target_ulong helper_read_crN(CPUX86State *env, int reg)
 {
     target_ulong val;
 
@@ -164,7 +164,7 @@ target_ulong helper_read_crN(int reg)
     return val;
 }
 
-void helper_write_crN(int reg, target_ulong t0)
+void helper_write_crN(CPUX86State *env, int reg, target_ulong t0)
 {
     cpu_svm_check_intercept_param(env, SVM_EXIT_WRITE_CR0 + reg, 0);
     switch (reg) {
@@ -189,7 +189,7 @@ void helper_write_crN(int reg, target_ulong t0)
     }
 }
 
-void helper_movl_drN_T0(int reg, target_ulong t0)
+void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0)
 {
     int i;
 
@@ -198,11 +198,11 @@ void helper_movl_drN_T0(int reg, target_ulong t0)
         env->dr[reg] = t0;
         hw_breakpoint_insert(env, reg);
     } else if (reg == 7) {
-        for (i = 0; i < 4; i++) {
+        for (i = 0; i < DR7_MAX_BP; i++) {
             hw_breakpoint_remove(env, i);
         }
         env->dr[7] = t0;
-        for (i = 0; i < 4; i++) {
+        for (i = 0; i < DR7_MAX_BP; i++) {
             hw_breakpoint_insert(env, i);
         }
     } else {
@@ -211,21 +211,21 @@ void helper_movl_drN_T0(int reg, target_ulong t0)
 }
 #endif
 
-void helper_lmsw(target_ulong t0)
+void helper_lmsw(CPUX86State *env, target_ulong t0)
 {
     /* only 4 lower bits of CR0 are modified. PE cannot be set to zero
        if already set to one. */
     t0 = (env->cr[0] & ~0xe) | (t0 & 0xf);
-    helper_write_crN(0, t0);
+    helper_write_crN(env, 0, t0);
 }
 
-void helper_invlpg(target_ulong addr)
+void helper_invlpg(CPUX86State *env, target_ulong addr)
 {
     cpu_svm_check_intercept_param(env, SVM_EXIT_INVLPG, 0);
     tlb_flush_page(env, addr);
 }
 
-void helper_rdtsc(void)
+void helper_rdtsc(CPUX86State *env)
 {
     uint64_t val;
 
@@ -235,17 +235,17 @@ void helper_rdtsc(void)
     cpu_svm_check_intercept_param(env, SVM_EXIT_RDTSC, 0);
 
     val = cpu_get_tsc(env) + env->tsc_offset;
-    EAX = (uint32_t)(val);
-    EDX = (uint32_t)(val >> 32);
+    env->regs[R_EAX] = (uint32_t)(val);
+    env->regs[R_EDX] = (uint32_t)(val >> 32);
 }
 
-void helper_rdtscp(void)
+void helper_rdtscp(CPUX86State *env)
 {
-    helper_rdtsc();
-    ECX = (uint32_t)(env->tsc_aux);
+    helper_rdtsc(env);
+    env->regs[R_ECX] = (uint32_t)(env->tsc_aux);
 }
 
-void helper_rdpmc(void)
+void helper_rdpmc(CPUX86State *env)
 {
     if ((env->cr[4] & CR4_PCE_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
         raise_exception(env, EXCP0D_GPF);
@@ -258,23 +258,24 @@ void helper_rdpmc(void)
 }
 
 #if defined(CONFIG_USER_ONLY)
-void helper_wrmsr(void)
+void helper_wrmsr(CPUX86State *env)
 {
 }
 
-void helper_rdmsr(void)
+void helper_rdmsr(CPUX86State *env)
 {
 }
 #else
-void helper_wrmsr(void)
+void helper_wrmsr(CPUX86State *env)
 {
     uint64_t val;
 
     cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1);
 
-    val = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
+    val = ((uint32_t)env->regs[R_EAX]) |
+        ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
 
-    switch ((uint32_t)ECX) {
+    switch ((uint32_t)env->regs[R_ECX]) {
     case MSR_IA32_SYSENTER_CS:
         env->sysenter_cs = val & 0xffff;
         break;
@@ -292,22 +293,22 @@ void helper_wrmsr(void)
             uint64_t update_mask;
 
             update_mask = 0;
-            if (env->cpuid_ext2_features & CPUID_EXT2_SYSCALL) {
+            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_SYSCALL) {
                 update_mask |= MSR_EFER_SCE;
             }
-            if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
+            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
                 update_mask |= MSR_EFER_LME;
             }
-            if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR) {
+            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) {
                 update_mask |= MSR_EFER_FFXSR;
             }
-            if (env->cpuid_ext2_features & CPUID_EXT2_NX) {
+            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_NX) {
                 update_mask |= MSR_EFER_NXE;
             }
-            if (env->cpuid_ext3_features & CPUID_EXT3_SVM) {
+            if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
                 update_mask |= MSR_EFER_SVME;
             }
-            if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR) {
+            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) {
                 update_mask |= MSR_EFER_FFXSR;
             }
             cpu_load_efer(env, (env->efer & ~update_mask) |
@@ -351,7 +352,8 @@ void helper_wrmsr(void)
     case MSR_MTRRphysBase(5):
     case MSR_MTRRphysBase(6):
     case MSR_MTRRphysBase(7):
-        env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysBase(0)) / 2].base = val;
+        env->mtrr_var[((uint32_t)env->regs[R_ECX] -
+                       MSR_MTRRphysBase(0)) / 2].base = val;
         break;
     case MSR_MTRRphysMask(0):
     case MSR_MTRRphysMask(1):
@@ -361,14 +363,17 @@ void helper_wrmsr(void)
     case MSR_MTRRphysMask(5):
     case MSR_MTRRphysMask(6):
     case MSR_MTRRphysMask(7):
-        env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysMask(0)) / 2].mask = val;
+        env->mtrr_var[((uint32_t)env->regs[R_ECX] -
+                       MSR_MTRRphysMask(0)) / 2].mask = val;
         break;
     case MSR_MTRRfix64K_00000:
-        env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix64K_00000] = val;
+        env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+                        MSR_MTRRfix64K_00000] = val;
         break;
     case MSR_MTRRfix16K_80000:
     case MSR_MTRRfix16K_A0000:
-        env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix16K_80000 + 1] = val;
+        env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+                        MSR_MTRRfix16K_80000 + 1] = val;
         break;
     case MSR_MTRRfix4K_C0000:
     case MSR_MTRRfix4K_C8000:
@@ -378,7 +383,8 @@ void helper_wrmsr(void)
     case MSR_MTRRfix4K_E8000:
     case MSR_MTRRfix4K_F0000:
     case MSR_MTRRfix4K_F8000:
-        env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix4K_C0000 + 3] = val;
+        env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+                        MSR_MTRRfix4K_C0000 + 3] = val;
         break;
     case MSR_MTRRdefType:
         env->mtrr_deftype = val;
@@ -399,9 +405,10 @@ void helper_wrmsr(void)
         env->msr_ia32_misc_enable = val;
         break;
     default:
-        if ((uint32_t)ECX >= MSR_MC0_CTL
-            && (uint32_t)ECX < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) {
-            uint32_t offset = (uint32_t)ECX - MSR_MC0_CTL;
+        if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL
+            && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL +
+            (4 * env->mcg_cap & 0xff)) {
+            uint32_t offset = (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL;
             if ((offset & 0x3) != 0
                 || (val == 0 || val == ~(uint64_t)0)) {
                 env->mce_banks[offset] = val;
@@ -413,13 +420,13 @@ void helper_wrmsr(void)
     }
 }
 
-void helper_rdmsr(void)
+void helper_rdmsr(CPUX86State *env)
 {
     uint64_t val;
 
     cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0);
 
-    switch ((uint32_t)ECX) {
+    switch ((uint32_t)env->regs[R_ECX]) {
     case MSR_IA32_SYSENTER_CS:
         val = env->sysenter_cs;
         break;
@@ -481,7 +488,8 @@ void helper_rdmsr(void)
     case MSR_MTRRphysBase(5):
     case MSR_MTRRphysBase(6):
     case MSR_MTRRphysBase(7):
-        val = env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysBase(0)) / 2].base;
+        val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
+                             MSR_MTRRphysBase(0)) / 2].base;
         break;
     case MSR_MTRRphysMask(0):
     case MSR_MTRRphysMask(1):
@@ -491,14 +499,16 @@ void helper_rdmsr(void)
     case MSR_MTRRphysMask(5):
     case MSR_MTRRphysMask(6):
     case MSR_MTRRphysMask(7):
-        val = env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysMask(0)) / 2].mask;
+        val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
+                             MSR_MTRRphysMask(0)) / 2].mask;
         break;
     case MSR_MTRRfix64K_00000:
         val = env->mtrr_fixed[0];
         break;
     case MSR_MTRRfix16K_80000:
     case MSR_MTRRfix16K_A0000:
-        val = env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix16K_80000 + 1];
+        val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+                              MSR_MTRRfix16K_80000 + 1];
         break;
     case MSR_MTRRfix4K_C0000:
     case MSR_MTRRfix4K_C8000:
@@ -508,13 +518,14 @@ void helper_rdmsr(void)
     case MSR_MTRRfix4K_E8000:
     case MSR_MTRRfix4K_F0000:
     case MSR_MTRRfix4K_F8000:
-        val = env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix4K_C0000 + 3];
+        val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+                              MSR_MTRRfix4K_C0000 + 3];
         break;
     case MSR_MTRRdefType:
         val = env->mtrr_deftype;
         break;
     case MSR_MTRRcap:
-        if (env->cpuid_features & CPUID_MTRR) {
+        if (env->features[FEAT_1_EDX] & CPUID_MTRR) {
             val = MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT |
                 MSR_MTRRcap_WC_SUPPORTED;
         } else {
@@ -539,9 +550,10 @@ void helper_rdmsr(void)
         val = env->msr_ia32_misc_enable;
         break;
     default:
-        if ((uint32_t)ECX >= MSR_MC0_CTL
-            && (uint32_t)ECX < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) {
-            uint32_t offset = (uint32_t)ECX - MSR_MC0_CTL;
+        if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL
+            && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL +
+            (4 * env->mcg_cap & 0xff)) {
+            uint32_t offset = (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL;
             val = env->mce_banks[offset];
             break;
         }
@@ -549,54 +561,64 @@ void helper_rdmsr(void)
         val = 0;
         break;
     }
-    EAX = (uint32_t)(val);
-    EDX = (uint32_t)(val >> 32);
+    env->regs[R_EAX] = (uint32_t)(val);
+    env->regs[R_EDX] = (uint32_t)(val >> 32);
 }
 #endif
 
-static void do_hlt(void)
+static void do_hlt(X86CPU *cpu)
 {
+    CPUState *cs = CPU(cpu);
+    CPUX86State *env = &cpu->env;
+
     env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
-    env->halted = 1;
+    cs->halted = 1;
     env->exception_index = EXCP_HLT;
     cpu_loop_exit(env);
 }
 
-void helper_hlt(int next_eip_addend)
+void helper_hlt(CPUX86State *env, int next_eip_addend)
 {
+    X86CPU *cpu = x86_env_get_cpu(env);
+
     cpu_svm_check_intercept_param(env, SVM_EXIT_HLT, 0);
-    EIP += next_eip_addend;
+    env->eip += next_eip_addend;
 
-    do_hlt();
+    do_hlt(cpu);
 }
 
-void helper_monitor(target_ulong ptr)
+void helper_monitor(CPUX86State *env, target_ulong ptr)
 {
-    if ((uint32_t)ECX != 0) {
+    if ((uint32_t)env->regs[R_ECX] != 0) {
         raise_exception(env, EXCP0D_GPF);
     }
     /* XXX: store address? */
     cpu_svm_check_intercept_param(env, SVM_EXIT_MONITOR, 0);
 }
 
-void helper_mwait(int next_eip_addend)
+void helper_mwait(CPUX86State *env, int next_eip_addend)
 {
-    if ((uint32_t)ECX != 0) {
+    CPUState *cs;
+    X86CPU *cpu;
+
+    if ((uint32_t)env->regs[R_ECX] != 0) {
         raise_exception(env, EXCP0D_GPF);
     }
     cpu_svm_check_intercept_param(env, SVM_EXIT_MWAIT, 0);
-    EIP += next_eip_addend;
+    env->eip += next_eip_addend;
 
+    cpu = x86_env_get_cpu(env);
+    cs = CPU(cpu);
     /* XXX: not complete but not completely erroneous */
-    if (env->cpu_index != 0 || env->next_cpu != NULL) {
+    if (cs->cpu_index != 0 || cs->next_cpu != NULL) {
         /* more than one CPU: do not sleep because another CPU may
            wake this one */
     } else {
-        do_hlt();
+        do_hlt(cpu);
     }
 }
 
-void helper_debug(void)
+void helper_debug(CPUX86State *env)
 {
     env->exception_index = EXCP_DEBUG;
     cpu_loop_exit(env);