target-i386: Purely cosmetic integration. This modifies files under target-i386 to get stylistic-only changes from upstream (QEMU 2.0.0), i.e.: - in cpu.h: Remove the EAX, EBX, ... DF macros and replace them with direct access to env->eip, env->df or env->regs[] instead. - add or refine declarations in cpu.h, but doesn't modify behaviour. - Add opening / closing braces where appropriate. Change-Id: Ie4a024ff6ed6db9bb7d843221f4ad1fb59af925f
diff --git a/cpu-exec.c b/cpu-exec.c index 9bc29d3..e0bd8d1 100644 --- a/cpu-exec.c +++ b/cpu-exec.c
@@ -259,7 +259,7 @@ if (!kvm_enabled()) { /* put eflags in CPU temporary format */ CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); - DF = 1 - (2 * ((env->eflags >> 10) & 1)); + env->df = 1 - (2 * ((env->eflags >> 10) & 1)); CC_OP = CC_OP_EFLAGS; env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); } @@ -546,7 +546,7 @@ /* restore flags in standard format */ #if defined(TARGET_I386) env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP) - | (DF & DF_MASK); + | (env->df & DF_MASK); log_cpu_state(cpu, X86_DUMP_CCOP); env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); #elif defined(TARGET_M68K) @@ -641,7 +641,7 @@ #if defined(TARGET_I386) /* restore flags in standard format */ env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP) - | (DF & DF_MASK); + | (env->df & DF_MASK); #elif defined(TARGET_ARM) /* XXX: Save/restore host fpu exception state?. */ #elif defined(TARGET_UNICORE32)
diff --git a/target-i386/cc_helper.c b/target-i386/cc_helper.c index 91c9c25..4e37d49 100644 --- a/target-i386/cc_helper.c +++ b/target-i386/cc_helper.c
@@ -14,8 +14,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA + * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ #include "cpu.h" @@ -241,7 +240,7 @@ { uint32_t eflags; eflags = helper_cc_compute_all(env, CC_OP); - eflags |= (DF & DF_MASK); + eflags |= (env->df & DF_MASK); eflags |= env->eflags & ~(VM_MASK | RF_MASK); return eflags; }
diff --git a/target-i386/cc_helper_template.h b/target-i386/cc_helper_template.h index 16f5d91..0664818 100644 --- a/target-i386/cc_helper_template.h +++ b/target-i386/cc_helper_template.h
@@ -1,5 +1,5 @@ /* - * i386 helpers + * x86 condition code helpers * * Copyright (c) 2008 Fabrice Bellard * @@ -14,8 +14,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA + * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ #define DATA_BITS (1 << (3 + SHIFT)) #define SHIFT_MASK (DATA_BITS - 1)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 45bac7d..e3a3885 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h
@@ -38,8 +38,10 @@ #ifdef TARGET_X86_64 #define ELF_MACHINE EM_X86_64 +#define ELF_MACHINE_UNAME "x86_64" #else #define ELF_MACHINE EM_386 +#define ELF_MACHINE_UNAME "i686" #endif // TODO(digit): Remove this define. @@ -195,35 +197,35 @@ #define CR0_PE_SHIFT 0 #define CR0_MP_SHIFT 1 -#define CR0_PE_MASK (1 << 0) -#define CR0_MP_MASK (1 << 1) -#define CR0_EM_MASK (1 << 2) -#define CR0_TS_MASK (1 << 3) -#define CR0_ET_MASK (1 << 4) -#define CR0_NE_MASK (1 << 5) -#define CR0_WP_MASK (1 << 16) -#define CR0_AM_MASK (1 << 18) -#define CR0_PG_MASK (1 << 31) +#define CR0_PE_MASK (1U << 0) +#define CR0_MP_MASK (1U << 1) +#define CR0_EM_MASK (1U << 2) +#define CR0_TS_MASK (1U << 3) +#define CR0_ET_MASK (1U << 4) +#define CR0_NE_MASK (1U << 5) +#define CR0_WP_MASK (1U << 16) +#define CR0_AM_MASK (1U << 18) +#define CR0_PG_MASK (1U << 31) -#define CR4_VME_MASK (1 << 0) -#define CR4_PVI_MASK (1 << 1) -#define CR4_TSD_MASK (1 << 2) -#define CR4_DE_MASK (1 << 3) -#define CR4_PSE_MASK (1 << 4) -#define CR4_PAE_MASK (1 << 5) -#define CR4_MCE_MASK (1 << 6) -#define CR4_PGE_MASK (1 << 7) -#define CR4_PCE_MASK (1 << 8) +#define CR4_VME_MASK (1U << 0) +#define CR4_PVI_MASK (1U << 1) +#define CR4_TSD_MASK (1U << 2) +#define CR4_DE_MASK (1U << 3) +#define CR4_PSE_MASK (1U << 4) +#define CR4_PAE_MASK (1U << 5) +#define CR4_MCE_MASK (1U << 6) +#define CR4_PGE_MASK (1U << 7) +#define CR4_PCE_MASK (1U << 8) #define CR4_OSFXSR_SHIFT 9 -#define CR4_OSFXSR_MASK (1 << CR4_OSFXSR_SHIFT) -#define CR4_OSXMMEXCPT_MASK (1 << 10) -#define CR4_VMXE_MASK (1 << 13) -#define CR4_SMXE_MASK (1 << 14) -#define CR4_FSGSBASE_MASK (1 << 16) -#define CR4_PCIDE_MASK (1 << 17) -#define CR4_OSXSAVE_MASK (1 << 18) -#define CR4_SMEP_MASK (1 << 20) -#define CR4_SMAP_MASK (1 << 21) +#define CR4_OSFXSR_MASK (1U << CR4_OSFXSR_SHIFT) +#define CR4_OSXMMEXCPT_MASK (1U << 10) +#define CR4_VMXE_MASK (1U << 13) +#define CR4_SMXE_MASK (1U << 14) +#define CR4_FSGSBASE_MASK (1U << 16) +#define CR4_PCIDE_MASK (1U << 17) +#define CR4_OSXSAVE_MASK (1U << 18) +#define CR4_SMEP_MASK (1U << 20) +#define CR4_SMAP_MASK (1U << 21) #define DR6_BD (1 << 13) #define DR6_BS (1 << 14) @@ -278,7 +280,9 @@ #define MCE_CAP_DEF MCG_CTL_P #define MCE_BANKS_DEF 10 -#define MCG_STATUS_MCIP (1UL<<2) /* machine check in progress */ +#define MCG_STATUS_RIPV (1ULL<<0) /* restart ip valid */ +#define MCG_STATUS_EIPV (1ULL<<1) /* ip points to correct instruction */ +#define MCG_STATUS_MCIP (1ULL<<2) /* machine check in progress */ #define MCI_STATUS_VAL (1ULL<<63) /* valid error */ #define MCI_STATUS_OVER (1ULL<<62) /* previous errors lost */ @@ -381,9 +385,13 @@ #define MSR_VM_HSAVE_PA 0xc0010117 -#define XSTATE_FP 1 -#define XSTATE_SSE 2 -#define XSTATE_YMM 4 +#define MSR_IA32_BNDCFGS 0x00000d90 + +#define XSTATE_FP (1ULL << 0) +#define XSTATE_SSE (1ULL << 1) +#define XSTATE_YMM (1ULL << 2) +#define XSTATE_BNDREGS (1ULL << 3) +#define XSTATE_BNDCSR (1ULL << 4) /* CPUID feature words */ typedef enum FeatureWord { @@ -401,96 +409,96 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS]; /* cpuid_features bits */ -#define CPUID_FP87 (1 << 0) -#define CPUID_VME (1 << 1) -#define CPUID_DE (1 << 2) -#define CPUID_PSE (1 << 3) -#define CPUID_TSC (1 << 4) -#define CPUID_MSR (1 << 5) -#define CPUID_PAE (1 << 6) -#define CPUID_MCE (1 << 7) -#define CPUID_CX8 (1 << 8) -#define CPUID_APIC (1 << 9) -#define CPUID_SEP (1 << 11) /* sysenter/sysexit */ -#define CPUID_MTRR (1 << 12) -#define CPUID_PGE (1 << 13) -#define CPUID_MCA (1 << 14) -#define CPUID_CMOV (1 << 15) -#define CPUID_PAT (1 << 16) -#define CPUID_PSE36 (1 << 17) -#define CPUID_PN (1 << 18) -#define CPUID_CLFLUSH (1 << 19) -#define CPUID_DTS (1 << 21) -#define CPUID_ACPI (1 << 22) -#define CPUID_MMX (1 << 23) -#define CPUID_FXSR (1 << 24) -#define CPUID_SSE (1 << 25) -#define CPUID_SSE2 (1 << 26) -#define CPUID_SS (1 << 27) -#define CPUID_HT (1 << 28) -#define CPUID_TM (1 << 29) -#define CPUID_IA64 (1 << 30) -#define CPUID_PBE (1 << 31) +#define CPUID_FP87 (1U << 0) +#define CPUID_VME (1U << 1) +#define CPUID_DE (1U << 2) +#define CPUID_PSE (1U << 3) +#define CPUID_TSC (1U << 4) +#define CPUID_MSR (1U << 5) +#define CPUID_PAE (1U << 6) +#define CPUID_MCE (1U << 7) +#define CPUID_CX8 (1U << 8) +#define CPUID_APIC (1U << 9) +#define CPUID_SEP (1U << 11) /* sysenter/sysexit */ +#define CPUID_MTRR (1U << 12) +#define CPUID_PGE (1U << 13) +#define CPUID_MCA (1U << 14) +#define CPUID_CMOV (1U << 15) +#define CPUID_PAT (1U << 16) +#define CPUID_PSE36 (1U << 17) +#define CPUID_PN (1U << 18) +#define CPUID_CLFLUSH (1U << 19) +#define CPUID_DTS (1U << 21) +#define CPUID_ACPI (1U << 22) +#define CPUID_MMX (1U << 23) +#define CPUID_FXSR (1U << 24) +#define CPUID_SSE (1U << 25) +#define CPUID_SSE2 (1U << 26) +#define CPUID_SS (1U << 27) +#define CPUID_HT (1U << 28) +#define CPUID_TM (1U << 29) +#define CPUID_IA64 (1U << 30) +#define CPUID_PBE (1U << 31) -#define CPUID_EXT_SSE3 (1 << 0) -#define CPUID_EXT_PCLMULQDQ (1 << 1) -#define CPUID_EXT_DTES64 (1 << 2) -#define CPUID_EXT_MONITOR (1 << 3) -#define CPUID_EXT_DSCPL (1 << 4) -#define CPUID_EXT_VMX (1 << 5) -#define CPUID_EXT_SMX (1 << 6) -#define CPUID_EXT_EST (1 << 7) -#define CPUID_EXT_TM2 (1 << 8) -#define CPUID_EXT_SSSE3 (1 << 9) -#define CPUID_EXT_CID (1 << 10) -#define CPUID_EXT_FMA (1 << 12) -#define CPUID_EXT_CX16 (1 << 13) -#define CPUID_EXT_XTPR (1 << 14) -#define CPUID_EXT_PDCM (1 << 15) -#define CPUID_EXT_PCID (1 << 17) -#define CPUID_EXT_DCA (1 << 18) -#define CPUID_EXT_SSE41 (1 << 19) -#define CPUID_EXT_SSE42 (1 << 20) -#define CPUID_EXT_X2APIC (1 << 21) -#define CPUID_EXT_MOVBE (1 << 22) -#define CPUID_EXT_POPCNT (1 << 23) -#define CPUID_EXT_TSC_DEADLINE_TIMER (1 << 24) -#define CPUID_EXT_AES (1 << 25) -#define CPUID_EXT_XSAVE (1 << 26) -#define CPUID_EXT_OSXSAVE (1 << 27) -#define CPUID_EXT_AVX (1 << 28) -#define CPUID_EXT_F16C (1 << 29) -#define CPUID_EXT_RDRAND (1 << 30) -#define CPUID_EXT_HYPERVISOR (1 << 31) +#define CPUID_EXT_SSE3 (1U << 0) +#define CPUID_EXT_PCLMULQDQ (1U << 1) +#define CPUID_EXT_DTES64 (1U << 2) +#define CPUID_EXT_MONITOR (1U << 3) +#define CPUID_EXT_DSCPL (1U << 4) +#define CPUID_EXT_VMX (1U << 5) +#define CPUID_EXT_SMX (1U << 6) +#define CPUID_EXT_EST (1U << 7) +#define CPUID_EXT_TM2 (1U << 8) +#define CPUID_EXT_SSSE3 (1U << 9) +#define CPUID_EXT_CID (1U << 10) +#define CPUID_EXT_FMA (1U << 12) +#define CPUID_EXT_CX16 (1U << 13) +#define CPUID_EXT_XTPR (1U << 14) +#define CPUID_EXT_PDCM (1U << 15) +#define CPUID_EXT_PCID (1U << 17) +#define CPUID_EXT_DCA (1U << 18) +#define CPUID_EXT_SSE41 (1U << 19) +#define CPUID_EXT_SSE42 (1U << 20) +#define CPUID_EXT_X2APIC (1U << 21) +#define CPUID_EXT_MOVBE (1U << 22) +#define CPUID_EXT_POPCNT (1U << 23) +#define CPUID_EXT_TSC_DEADLINE_TIMER (1U << 24) +#define CPUID_EXT_AES (1U << 25) +#define CPUID_EXT_XSAVE (1U << 26) +#define CPUID_EXT_OSXSAVE (1U << 27) +#define CPUID_EXT_AVX (1U << 28) +#define CPUID_EXT_F16C (1U << 29) +#define CPUID_EXT_RDRAND (1U << 30) +#define CPUID_EXT_HYPERVISOR (1U << 31) -#define CPUID_EXT2_FPU (1 << 0) -#define CPUID_EXT2_VME (1 << 1) -#define CPUID_EXT2_DE (1 << 2) -#define CPUID_EXT2_PSE (1 << 3) -#define CPUID_EXT2_TSC (1 << 4) -#define CPUID_EXT2_MSR (1 << 5) -#define CPUID_EXT2_PAE (1 << 6) -#define CPUID_EXT2_MCE (1 << 7) -#define CPUID_EXT2_CX8 (1 << 8) -#define CPUID_EXT2_APIC (1 << 9) -#define CPUID_EXT2_SYSCALL (1 << 11) -#define CPUID_EXT2_MTRR (1 << 12) -#define CPUID_EXT2_PGE (1 << 13) -#define CPUID_EXT2_MCA (1 << 14) -#define CPUID_EXT2_CMOV (1 << 15) -#define CPUID_EXT2_PAT (1 << 16) -#define CPUID_EXT2_PSE36 (1 << 17) -#define CPUID_EXT2_MP (1 << 19) -#define CPUID_EXT2_NX (1 << 20) -#define CPUID_EXT2_MMXEXT (1 << 22) -#define CPUID_EXT2_MMX (1 << 23) -#define CPUID_EXT2_FXSR (1 << 24) -#define CPUID_EXT2_FFXSR (1 << 25) -#define CPUID_EXT2_PDPE1GB (1 << 26) -#define CPUID_EXT2_RDTSCP (1 << 27) -#define CPUID_EXT2_LM (1 << 29) -#define CPUID_EXT2_3DNOWEXT (1 << 30) -#define CPUID_EXT2_3DNOW (1 << 31) +#define CPUID_EXT2_FPU (1U << 0) +#define CPUID_EXT2_VME (1U << 1) +#define CPUID_EXT2_DE (1U << 2) +#define CPUID_EXT2_PSE (1U << 3) +#define CPUID_EXT2_TSC (1U << 4) +#define CPUID_EXT2_MSR (1U << 5) +#define CPUID_EXT2_PAE (1U << 6) +#define CPUID_EXT2_MCE (1U << 7) +#define CPUID_EXT2_CX8 (1U << 8) +#define CPUID_EXT2_APIC (1U << 9) +#define CPUID_EXT2_SYSCALL (1U << 11) +#define CPUID_EXT2_MTRR (1U << 12) +#define CPUID_EXT2_PGE (1U << 13) +#define CPUID_EXT2_MCA (1U << 14) +#define CPUID_EXT2_CMOV (1U << 15) +#define CPUID_EXT2_PAT (1U << 16) +#define CPUID_EXT2_PSE36 (1U << 17) +#define CPUID_EXT2_MP (1U << 19) +#define CPUID_EXT2_NX (1U << 20) +#define CPUID_EXT2_MMXEXT (1U << 22) +#define CPUID_EXT2_MMX (1U << 23) +#define CPUID_EXT2_FXSR (1U << 24) +#define CPUID_EXT2_FFXSR (1U << 25) +#define CPUID_EXT2_PDPE1GB (1U << 26) +#define CPUID_EXT2_RDTSCP (1U << 27) +#define CPUID_EXT2_LM (1U << 29) +#define CPUID_EXT2_3DNOWEXT (1U << 30) +#define CPUID_EXT2_3DNOW (1U << 31) /* CPUID[8000_0001].EDX bits that are aliase of CPUID[1].EDX bits on AMD CPUs */ #define CPUID_EXT2_AMD_ALIASES (CPUID_EXT2_FPU | CPUID_EXT2_VME | \ @@ -503,52 +511,53 @@ CPUID_EXT2_PAT | CPUID_EXT2_PSE36 | \ CPUID_EXT2_MMX | CPUID_EXT2_FXSR) -#define CPUID_EXT3_LAHF_LM (1 << 0) -#define CPUID_EXT3_CMP_LEG (1 << 1) -#define CPUID_EXT3_SVM (1 << 2) -#define CPUID_EXT3_EXTAPIC (1 << 3) -#define CPUID_EXT3_CR8LEG (1 << 4) -#define CPUID_EXT3_ABM (1 << 5) -#define CPUID_EXT3_SSE4A (1 << 6) -#define CPUID_EXT3_MISALIGNSSE (1 << 7) -#define CPUID_EXT3_3DNOWPREFETCH (1 << 8) -#define CPUID_EXT3_OSVW (1 << 9) -#define CPUID_EXT3_IBS (1 << 10) -#define CPUID_EXT3_XOP (1 << 11) -#define CPUID_EXT3_SKINIT (1 << 12) -#define CPUID_EXT3_WDT (1 << 13) -#define CPUID_EXT3_LWP (1 << 15) -#define CPUID_EXT3_FMA4 (1 << 16) -#define CPUID_EXT3_TCE (1 << 17) -#define CPUID_EXT3_NODEID (1 << 19) -#define CPUID_EXT3_TBM (1 << 21) -#define CPUID_EXT3_TOPOEXT (1 << 22) -#define CPUID_EXT3_PERFCORE (1 << 23) -#define CPUID_EXT3_PERFNB (1 << 24) +#define CPUID_EXT3_LAHF_LM (1U << 0) +#define CPUID_EXT3_CMP_LEG (1U << 1) +#define CPUID_EXT3_SVM (1U << 2) +#define CPUID_EXT3_EXTAPIC (1U << 3) +#define CPUID_EXT3_CR8LEG (1U << 4) +#define CPUID_EXT3_ABM (1U << 5) +#define CPUID_EXT3_SSE4A (1U << 6) +#define CPUID_EXT3_MISALIGNSSE (1U << 7) +#define CPUID_EXT3_3DNOWPREFETCH (1U << 8) +#define CPUID_EXT3_OSVW (1U << 9) +#define CPUID_EXT3_IBS (1U << 10) +#define CPUID_EXT3_XOP (1U << 11) +#define CPUID_EXT3_SKINIT (1U << 12) +#define CPUID_EXT3_WDT (1U << 13) +#define CPUID_EXT3_LWP (1U << 15) +#define CPUID_EXT3_FMA4 (1U << 16) +#define CPUID_EXT3_TCE (1U << 17) +#define CPUID_EXT3_NODEID (1U << 19) +#define CPUID_EXT3_TBM (1U << 21) +#define CPUID_EXT3_TOPOEXT (1U << 22) +#define CPUID_EXT3_PERFCORE (1U << 23) +#define CPUID_EXT3_PERFNB (1U << 24) -#define CPUID_SVM_NPT (1 << 0) -#define CPUID_SVM_LBRV (1 << 1) -#define CPUID_SVM_SVMLOCK (1 << 2) -#define CPUID_SVM_NRIPSAVE (1 << 3) -#define CPUID_SVM_TSCSCALE (1 << 4) -#define CPUID_SVM_VMCBCLEAN (1 << 5) -#define CPUID_SVM_FLUSHASID (1 << 6) -#define CPUID_SVM_DECODEASSIST (1 << 7) -#define CPUID_SVM_PAUSEFILTER (1 << 10) -#define CPUID_SVM_PFTHRESHOLD (1 << 12) +#define CPUID_SVM_NPT (1U << 0) +#define CPUID_SVM_LBRV (1U << 1) +#define CPUID_SVM_SVMLOCK (1U << 2) +#define CPUID_SVM_NRIPSAVE (1U << 3) +#define CPUID_SVM_TSCSCALE (1U << 4) +#define CPUID_SVM_VMCBCLEAN (1U << 5) +#define CPUID_SVM_FLUSHASID (1U << 6) +#define CPUID_SVM_DECODEASSIST (1U << 7) +#define CPUID_SVM_PAUSEFILTER (1U << 10) +#define CPUID_SVM_PFTHRESHOLD (1U << 12) -#define CPUID_7_0_EBX_FSGSBASE (1 << 0) -#define CPUID_7_0_EBX_BMI1 (1 << 3) -#define CPUID_7_0_EBX_HLE (1 << 4) -#define CPUID_7_0_EBX_AVX2 (1 << 5) -#define CPUID_7_0_EBX_SMEP (1 << 7) -#define CPUID_7_0_EBX_BMI2 (1 << 8) -#define CPUID_7_0_EBX_ERMS (1 << 9) -#define CPUID_7_0_EBX_INVPCID (1 << 10) -#define CPUID_7_0_EBX_RTM (1 << 11) -#define CPUID_7_0_EBX_RDSEED (1 << 18) -#define CPUID_7_0_EBX_ADX (1 << 19) -#define CPUID_7_0_EBX_SMAP (1 << 20) +#define CPUID_7_0_EBX_FSGSBASE (1U << 0) +#define CPUID_7_0_EBX_BMI1 (1U << 3) +#define CPUID_7_0_EBX_HLE (1U << 4) +#define CPUID_7_0_EBX_AVX2 (1U << 5) +#define CPUID_7_0_EBX_SMEP (1U << 7) +#define CPUID_7_0_EBX_BMI2 (1U << 8) +#define CPUID_7_0_EBX_ERMS (1U << 9) +#define CPUID_7_0_EBX_INVPCID (1U << 10) +#define CPUID_7_0_EBX_RTM (1U << 11) +#define CPUID_7_0_EBX_MPX (1U << 14) +#define CPUID_7_0_EBX_RDSEED (1U << 18) +#define CPUID_7_0_EBX_ADX (1U << 19) +#define CPUID_7_0_EBX_SMAP (1U << 20) #define CPUID_VENDOR_SZ 12 @@ -564,8 +573,8 @@ #define CPUID_VENDOR_VIA "CentaurHauls" -#define CPUID_MWAIT_IBE (1 << 1) /* Interrupts can exit capability */ -#define CPUID_MWAIT_EMX (1 << 0) /* enumeration supported */ +#define CPUID_MWAIT_IBE (1U << 1) /* Interrupts can exit capability */ +#define CPUID_MWAIT_EMX (1U << 0) /* enumeration supported */ #ifndef HYPERV_SPINLOCK_NEVER_RETRY #define HYPERV_SPINLOCK_NEVER_RETRY 0xFFFFFFFF @@ -685,7 +694,17 @@ uint64_t q; } MMXReg; -#ifdef WORDS_BIGENDIAN +typedef struct BNDReg { + uint64_t lb; + uint64_t ub; +} BNDReg; + +typedef struct BNDCSReg { + uint64_t cfgu; + uint64_t sts; +} BNDCSReg; + +#ifdef HOST_WORDS_BIGENDIAN #define XMM_B(n) _b[15 - (n)] #define XMM_W(n) _w[7 - (n)] #define XMM_L(n) _l[3 - (n)] @@ -731,8 +750,16 @@ #define CPU_NB_REGS CPU_NB_REGS32 #endif +#define MAX_FIXED_COUNTERS 3 +#define MAX_GP_COUNTERS (MSR_IA32_PERF_STATUS - MSR_P6_EVNTSEL0) + #define NB_MMU_MODES 2 +typedef enum TPRAccess { + TPR_ACCESS_READ, + TPR_ACCESS_WRITE, +} TPRAccess; + typedef struct CPUX86State { /* standard registers */ target_ulong regs[CPU_NB_REGS]; @@ -1028,31 +1055,16 @@ /* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel #define MMU_MODE1_SUFFIX _user +#define MMU_MODE2_SUFFIX _ksmap /* Kernel with SMAP override */ +#define MMU_KERNEL_IDX 0 #define MMU_USER_IDX 1 +#define MMU_KSMAP_IDX 2 static inline int cpu_mmu_index (CPUX86State *env) { - return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0; + return (env->hflags & HF_CPL_MASK) == 3 ? MMU_USER_IDX : + MMU_KERNEL_IDX; } -#undef EAX -#define EAX (env->regs[R_EAX]) -#undef ECX -#define ECX (env->regs[R_ECX]) -#undef EDX -#define EDX (env->regs[R_EDX]) -#undef EBX -#define EBX (env->regs[R_EBX]) -#undef ESP -#define ESP (env->regs[R_ESP]) -#undef EBP -#define EBP (env->regs[R_EBP]) -#undef ESI -#define ESI (env->regs[R_ESI]) -#undef EDI -#define EDI (env->regs[R_EDI]) -#undef EIP -#define EIP (env->eip) -#define DF (env->df) #define CC_SRC (env->cc_src) #define CC_DST (env->cc_dst) @@ -1061,10 +1073,11 @@ /* n must be a constant to be efficient */ static inline target_long lshift(target_long x, int n) { - if (n >= 0) + if (n >= 0) { return x << n; - else + } else { return x >> (-n); + } } /* float macros */ @@ -1138,34 +1151,31 @@ void do_interrupt(CPUArchState *env); void do_interrupt_x86_hardirq(CPUArchState *env, int intno, int is_hw); //void QEMU_NORETURN raise_exception_err(int exception_index, int error_code); -void QEMU_NORETURN raise_exception(CPUArchState *env, int exception_index); -void QEMU_NORETURN raise_exception_err(CPUX86State *env, - int exception_index, +void QEMU_NORETURN raise_exception(CPUX86State *env, int exception_index); +void QEMU_NORETURN raise_exception_err(CPUX86State *env, int exception_index, int error_code); - -void QEMU_NORETURN raise_interrupt(CPUX86State *env, - int intno, int is_int, int error_code, - int next_eip_addend); +void QEMU_NORETURN raise_interrupt(CPUX86State *nenv, int intno, int is_int, + int error_code, int next_eip_addend); void do_smm_enter(CPUArchState *env1); void svm_check_intercept(CPUArchState *env1, uint32_t type); /* cc_helper.c */ -const uint8_t parity_table[256]; -uint32_t cpu_cc_compute_all(CPUArchState *env1, int op); +extern const uint8_t parity_table[256]; +uint32_t cpu_cc_compute_all(CPUX86State *env1, int op); static inline uint32_t cpu_compute_eflags(CPUX86State *env) { - return env->eflags | cpu_cc_compute_all(env, CC_OP) | (DF & DF_MASK); + return env->eflags | cpu_cc_compute_all(env, CC_OP) | (env->df & DF_MASK); } /* NOTE: CC_OP must be modified manually to CC_OP_EFLAGS */ -static inline void cpu_load_eflags(CPUX86State *env, - int eflags, int update_mask) +static inline void cpu_load_eflags(CPUX86State *env, int eflags, + int update_mask) { CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); - DF = 1 - (2 * ((eflags >> 10) & 1)); + env->df = 1 - (2 * ((eflags >> 10) & 1)); env->eflags = (env->eflags & ~update_mask) | (eflags & update_mask) | 0x2; } @@ -1176,10 +1186,12 @@ { env->efer = val; env->hflags &= ~(HF_LMA_MASK | HF_SVME_MASK); - if (env->efer & MSR_EFER_LMA) + if (env->efer & MSR_EFER_LMA) { env->hflags |= HF_LMA_MASK; - if (env->efer & MSR_EFER_SVME) + } + if (env->efer & MSR_EFER_SVME) { env->hflags |= HF_SVME_MASK; + } }
diff --git a/target-i386/excp_helper.c b/target-i386/excp_helper.c index 5d973e6..3cd96a3 100644 --- a/target-i386/excp_helper.c +++ b/target-i386/excp_helper.c
@@ -23,10 +23,10 @@ #include "helper.h" #if 0 -#define raise_exception_err(a, b)\ +#define raise_exception_err(env, a, b) \ do {\ qemu_log("raise_exception line=%d\n", __LINE__);\ - (raise_exception_err)(a, b);\ + (raise_exception_err)(env, a, b); \ } while (0) #endif @@ -58,9 +58,9 @@ #if !defined(CONFIG_USER_ONLY) if (env->old_exception == EXCP08_DBLE) { - if (env->hflags & HF_SVMI_MASK) + if (env->hflags & HF_SVMI_MASK) { helper_vmexit(env, SVM_EXIT_SHUTDOWN, 0); /* does not return */ - + } qemu_log_mask(CPU_LOG_RESET, "Triple fault\n"); qemu_system_reset_request(); @@ -76,8 +76,9 @@ } if (second_contributory || (intno == EXCP0E_PAGE) || - (intno == EXCP08_DBLE)) + (intno == EXCP08_DBLE)) { env->old_exception = intno; + } return intno; } @@ -85,15 +86,16 @@ /* * Signal an interruption. It is executed in the main CPU loop. * is_int is TRUE if coming from the int instruction. next_eip is the - * EIP value AFTER the interrupt instruction. It is only relevant if + * env->eip value AFTER the interrupt instruction. It is only relevant if * is_int is TRUE. */ -void QEMU_NORETURN raise_interrupt(CPUX86State *env, - int intno, int is_int, int error_code, - int next_eip_addend) +void QEMU_NORETURN raise_interrupt(CPUX86State *env, int intno, + int is_int, int error_code, + int next_eip_addend) { if (!is_int) { - helper_svm_check_intercept_param(env, SVM_EXIT_EXCP_BASE + intno, error_code); + helper_svm_check_intercept_param(env, SVM_EXIT_EXCP_BASE + intno, + error_code); intno = check_exception(env, intno, &error_code); } else { helper_svm_check_intercept_param(env, SVM_EXIT_SWINT, 0); @@ -108,8 +110,8 @@ /* shortcuts to generate exceptions */ -void raise_exception_err(CPUX86State *env, - int exception_index, int error_code) +void raise_exception_err(CPUX86State *env, int exception_index, + int error_code) { raise_interrupt(env, exception_index, 0, error_code, 0); }
diff --git a/target-i386/fpu_helper.c b/target-i386/fpu_helper.c index b67f82b..ce7a9a5 100644 --- a/target-i386/fpu_helper.c +++ b/target-i386/fpu_helper.c
@@ -27,11 +27,11 @@ #include "exec/softmmu_exec.h" #endif /* !defined(CONFIG_USER_ONLY) */ -#define RC_MASK 0xc00 -#define RC_NEAR 0x000 -#define RC_DOWN 0x400 -#define RC_UP 0x800 -#define RC_CHOP 0xc00 +#define FPU_RC_MASK 0xc00 +#define FPU_RC_NEAR 0x000 +#define FPU_RC_DOWN 0x400 +#define FPU_RC_UP 0x800 +#define FPU_RC_CHOP 0xc00 #define MAXTAN 9223372036854775808.0 @@ -42,6 +42,17 @@ #define SIGND(fp) ((fp.l.upper) & 0x8000) #define MANTD(fp) (fp.l.lower) #define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS +#define FPUS_IE (1 << 0) +#define FPUS_DE (1 << 1) +#define FPUS_ZE (1 << 2) +#define FPUS_OE (1 << 3) +#define FPUS_UE (1 << 4) +#define FPUS_PE (1 << 5) +#define FPUS_SF (1 << 6) +#define FPUS_SE (1 << 7) +#define FPUS_B (1 << 15) + +#define FPUC_EM 0x3f #define floatx80_lg2 make_floatx80( 0x3ffd, 0x9a209a84fbcff799LL ) #define floatx80_l2e make_floatx80( 0x3fff, 0xb8aa3b295c17f0bcLL ) @@ -66,7 +77,7 @@ static inline void fpop(CPUX86State *env) { - env->fptags[env->fpstt] = 1; /* invvalidate stack entry */ + env->fptags[env->fpstt] = 1; /* invalidate stack entry */ env->fpstt = (env->fpstt + 1) & 7; } @@ -85,17 +96,6 @@ cpu_stw_data(env, ptr + 8, f.high); } -#define FPUS_IE (1 << 0) -#define FPUS_DE (1 << 1) -#define FPUS_ZE (1 << 2) -#define FPUS_OE (1 << 3) -#define FPUS_UE (1 << 4) -#define FPUS_PE (1 << 5) -#define FPUS_SF (1 << 6) -#define FPUS_SE (1 << 7) -#define FPUS_B (1 << 15) - -#define FPUC_EM 0x3f /* x87 FPU helpers */ @@ -124,8 +124,9 @@ static void fpu_set_exception(CPUX86State *env, int mask) { env->fpus |= mask; - if (env->fpus & (~env->fpuc & FPUC_EM)) + if (env->fpus & (~env->fpuc & FPUC_EM)) { env->fpus |= FPUS_SE | FPUS_B; + } } static inline floatx80 helper_fdiv(CPUX86State *env, floatx80 a, floatx80 b) @@ -243,8 +244,9 @@ { int32_t val; val = floatx80_to_int32(ST0, &env->fp_status); - if (val != (int16_t)val) + if (val != (int16_t)val) { val = -32768; + } return val; } @@ -266,8 +268,9 @@ { int32_t val; val = floatx80_to_int32_round_to_zero(ST0, &env->fp_status); - if (val != (int16_t)val) + if (val != (int16_t)val) { val = -32768; + } return val; } @@ -312,13 +315,13 @@ void helper_fdecstp(CPUX86State *env) { env->fpstt = (env->fpstt - 1) & 7; - env->fpus &= (~0x4700); + env->fpus &= ~0x4700; } void helper_fincstp(CPUX86State *env) { env->fpstt = (env->fpstt + 1) & 7; - env->fpus &= (~0x4700); + env->fpus &= ~0x4700; } /* FPU move */ @@ -449,9 +452,7 @@ void helper_fsubr_STN_ST0(CPUX86State *env, int st_index) { - floatx80 *p; - p = &ST(st_index); - *p = floatx80_sub(ST0, *p, &env->fp_status); + ST(st_index) = floatx80_sub(ST0, ST(st_index), &env->fp_status); } void helper_fdiv_STN_ST0(CPUX86State *env, int st_index) @@ -481,42 +482,42 @@ void helper_fld1_ST0(CPUX86State *env) { - ST0 = f15rk[1]; + ST0 = floatx80_one; } void helper_fldl2t_ST0(CPUX86State *env) { - ST0 = f15rk[6]; + ST0 = floatx80_l2t; } void helper_fldl2e_ST0(CPUX86State *env) { - ST0 = f15rk[5]; + ST0 = floatx80_l2e; } void helper_fldpi_ST0(CPUX86State *env) { - ST0 = f15rk[2]; + ST0 = floatx80_pi; } void helper_fldlg2_ST0(CPUX86State *env) { - ST0 = f15rk[3]; + ST0 = floatx80_lg2; } void helper_fldln2_ST0(CPUX86State *env) { - ST0 = f15rk[4]; + ST0 = floatx80_ln2; } void helper_fldz_ST0(CPUX86State *env) { - ST0 = f15rk[0]; + ST0 = floatx80_zero; } void helper_fldz_FT0(CPUX86State *env) { - FT0 = f15rk[0]; + FT0 = floatx80_zero; } uint32_t helper_fnstsw(CPUX86State *env) @@ -534,18 +535,18 @@ int rnd_type; /* set rounding mode */ - switch(env->fpuc & RC_MASK) { + switch (env->fpuc & FPU_RC_MASK) { default: - case RC_NEAR: + case FPU_RC_NEAR: rnd_type = float_round_nearest_even; break; - case RC_DOWN: + case FPU_RC_DOWN: rnd_type = float_round_down; break; - case RC_UP: + case FPU_RC_UP: rnd_type = float_round_up; break; - case RC_CHOP: + case FPU_RC_CHOP: rnd_type = float_round_to_zero; break; } @@ -578,8 +579,9 @@ void helper_fwait(CPUX86State *env) { - if (env->fpus & FPUS_SE) + if (env->fpus & FPUS_SE) { fpu_raise_exception(env); + } } void helper_fninit(CPUX86State *env) @@ -635,8 +637,9 @@ cpu_stb_data(env, mem_end, 0x00); } while (mem_ref < mem_end) { - if (val == 0) + if (val == 0) { break; + } v = val % 100; val = val / 100; v = ((v / 10) << 4) | (v % 10); @@ -664,7 +667,7 @@ ST1 = double_to_floatx80(env, fptemp); fpop(env); } else { - env->fpus &= (~0x4700); + env->fpus &= ~0x4700; env->fpus |= 0x400; } } @@ -680,7 +683,7 @@ ST0 = double_to_floatx80(env, fptemp); fpush(env); ST0 = floatx80_one; - env->fpus &= (~0x400); /* C2 <-- 0 */ + env->fpus &= ~0x400; /* C2 <-- 0 */ /* the above code is for |arg| < 2**52 only */ } } @@ -721,7 +724,7 @@ if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) { ST0 = double_to_floatx80(env, 0.0 / 0.0); /* NaN */ - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ + env->fpus &= ~0x4700; /* (C3,C2,C1,C0) <-- 0000 */ return; } @@ -733,7 +736,7 @@ if (expdif < 0) { /* optimisation? taken from the AMD docs */ - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ + env->fpus &= ~0x4700; /* (C3,C2,C1,C0) <-- 0000 */ /* ST0 is unchanged */ return; } @@ -745,12 +748,13 @@ st0 = fpsrcop - fptemp * dblq; /* convert dblq to q by truncating towards zero */ - if (dblq < 0.0) + if (dblq < 0.0) { q = (signed long long int)(-dblq); - else + } else { q = (signed long long int)dblq; + } - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ + env->fpus &= ~0x4700; /* (C3,C2,C1,C0) <-- 0000 */ /* (C0,C3,C1) <-- (q2,q1,q0) */ env->fpus |= (q & 0x4) << (8 - 2); /* (C0) <-- q2 */ env->fpus |= (q & 0x2) << (14 - 1); /* (C3) <-- q1 */ @@ -779,7 +783,7 @@ if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) { ST0 = double_to_floatx80(env, 0.0 / 0.0); /* NaN */ - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ + env->fpus &= ~0x4700; /* (C3,C2,C1,C0) <-- 0000 */ return; } @@ -797,7 +801,7 @@ } if (expdif < 53) { - dblq = fpsrcop / fptemp; /* ST0 / ST1*/; + dblq = fpsrcop / fptemp; /* ST0 / ST1 */ /* round dblq towards zero */ dblq = (dblq < 0.0) ? ceil(dblq) : floor(dblq); st0 = fpsrcop - fptemp * dblq; /* fpsrcop is ST0 */ @@ -837,7 +841,7 @@ ST1 = double_to_floatx80(env, fptemp); fpop(env); } else { - env->fpus &= (~0x4700); + env->fpus &= ~0x4700; env->fpus |= 0x400; } } @@ -863,7 +867,7 @@ ST0 = double_to_floatx80(env, sin(fptemp)); fpush(env); ST0 = double_to_floatx80(env, cos(fptemp)); - env->fpus &= (~0x400); /* C2 <-- 0 */ + env->fpus &= ~0x400; /* C2 <-- 0 */ /* the above code is for |arg| < 2**63 only */ } } @@ -889,7 +893,7 @@ env->fpus |= 0x400; } else { ST0 = double_to_floatx80(env, sin(fptemp)); - env->fpus &= (~0x400); /* C2 <-- 0 */ + env->fpus &= ~0x400; /* C2 <-- 0 */ /* the above code is for |arg| < 2**53 only */ } } @@ -902,8 +906,8 @@ env->fpus |= 0x400; } else { ST0 = double_to_floatx80(env, cos(fptemp)); - env->fpus &= (~0x400); /* C2 <-- 0 */ - /* the above code is for |arg5 < 2**63 only */ + env->fpus &= ~0x400; /* C2 <-- 0 */ + /* the above code is for |arg| < 2**63 only */ } } @@ -914,23 +918,24 @@ temp.d = ST0; - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ - if (SIGND(temp)) + env->fpus &= ~0x4700; /* (C3,C2,C1,C0) <-- 0000 */ + if (SIGND(temp)) { env->fpus |= 0x200; /* C1 <-- 1 */ + } /* XXX: test fptags too */ expdif = EXPD(temp); if (expdif == MAXEXPD) { if (MANTD(temp) == 0x8000000000000000ULL) { - env->fpus |= 0x500 /*Infinity*/; + env->fpus |= 0x500; /* Infinity */ } else { - env->fpus |= 0x100 /*NaN*/; + env->fpus |= 0x100; /* NaN */ } } else if (expdif == 0) { if (MANTD(temp) == 0) { - env->fpus |= 0x4000 /*Zero*/; + env->fpus |= 0x4000; /* Zero */ } else { - env->fpus |= 0x4400 /*Denormal*/; + env->fpus |= 0x4400; /* Denormal */ } } else { env->fpus |= 0x400; @@ -992,8 +997,7 @@ env->fpuc = cpu_lduw_data(env, ptr); fpus = cpu_lduw_data(env, ptr + 4); fptag = cpu_lduw_data(env, ptr + 8); - } - else { + } else { env->fpuc = cpu_lduw_data(env, ptr); fpus = cpu_lduw_data(env, ptr + 2); fptag = cpu_lduw_data(env, ptr + 4); @@ -1087,10 +1091,11 @@ /* XXX: finish it */ cpu_stl_data(env, ptr + 0x18, env->mxcsr); /* mxcsr */ cpu_stl_data(env, ptr + 0x1c, 0x0000ffff); /* mxcsr_mask */ - if (env->hflags & HF_CS64_MASK) + if (env->hflags & HF_CS64_MASK) { nb_xmm_regs = 16; - else + } else { nb_xmm_regs = 8; + } addr = ptr + 0xa0; /* Fast FXSAVE leaves out the XMM registers */ if (!(env->efer & MSR_EFER_FFXSR) @@ -1132,10 +1137,11 @@ /* XXX: finish it */ env->mxcsr = cpu_ldl_data(env, ptr + 0x18); //ldl(ptr + 0x1c); - if (env->hflags & HF_CS64_MASK) + if (env->hflags & HF_CS64_MASK) { nb_xmm_regs = 16; - else + } else { nb_xmm_regs = 8; + } addr = ptr + 0xa0; /* Fast FXRESTORE leaves out the XMM registers */ if (!(env->efer & MSR_EFER_FFXSR)
diff --git a/target-i386/helper.c b/target-i386/helper.c index 388f7a7..1999b73 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c
@@ -770,8 +770,9 @@ (uint32_t)env->cr[2], (uint32_t)env->cr[3], (uint32_t)env->cr[4]); - for(i = 0; i < 4; i++) + for(i = 0; i < 4; i++) { cpu_fprintf(f, "DR%d=%08x ", i, env->dr[i]); + } cpu_fprintf(f, "\nDR6=%08x DR7=%08x\n", env->dr[6], env->dr[7]); } if (flags & X86_DUMP_CCOP) { @@ -917,12 +918,14 @@ tlb_flush(env, 1); } /* SSE handling */ - if (!(env->cpuid_features & CPUID_SSE)) + if (!(env->cpuid_features & CPUID_SSE)) { new_cr4 &= ~CR4_OSFXSR_MASK; - if (new_cr4 & CR4_OSFXSR_MASK) + } + if (new_cr4 & CR4_OSFXSR_MASK) { env->hflags |= HF_OSFXSR_MASK; - else + } else { env->hflags &= ~HF_OSFXSR_MASK; + } env->cr[4] = new_cr4; } @@ -957,9 +960,9 @@ #endif /* return value: - -1 = cannot handle fault - 0 = nothing more to do - 1 = generate PF fault + * -1 = cannot handle fault + * 0 = nothing more to do + * 1 = generate PF fault */ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, int is_write1, int mmu_idx)
diff --git a/target-i386/int_helper.c b/target-i386/int_helper.c index 81159d1..a92f864 100644 --- a/target-i386/int_helper.c +++ b/target-i386/int_helper.c
@@ -23,13 +23,6 @@ //#define DEBUG_MULDIV -/* modulo 17 table */ -static const uint8_t rclw_table[32] = { - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9,10,11,12,13,14,15, - 16, 0, 1, 2, 3, 4, 5, 6, - 7, 8, 9,10,11,12,13,14, -}; /* modulo 9 table */ static const uint8_t rclb_table[32] = { @@ -39,76 +32,87 @@ 6, 7, 8, 0, 1, 2, 3, 4, }; +/* modulo 17 table */ +static const uint8_t rclw_table[32] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, +}; /* division, flags are undefined */ void helper_divb_AL(CPUX86State *env, target_ulong t0) { unsigned int num, den, q, r; - num = (EAX & 0xffff); + num = (env->regs[R_EAX] & 0xffff); den = (t0 & 0xff); if (den == 0) { raise_exception(env, EXCP00_DIVZ); } q = (num / den); - if (q > 0xff) + if (q > 0xff) { raise_exception(env, EXCP00_DIVZ); + } q &= 0xff; r = (num % den) & 0xff; - EAX = (EAX & ~0xffff) | (r << 8) | q; + env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | (r << 8) | q; } void helper_idivb_AL(CPUX86State *env, target_ulong t0) { int num, den, q, r; - num = (int16_t)EAX; + num = (int16_t)env->regs[R_EAX]; den = (int8_t)t0; if (den == 0) { raise_exception(env, EXCP00_DIVZ); } q = (num / den); - if (q != (int8_t)q) + if (q != (int8_t)q) { raise_exception(env, EXCP00_DIVZ); + } q &= 0xff; r = (num % den) & 0xff; - EAX = (EAX & ~0xffff) | (r << 8) | q; + env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | (r << 8) | q; } void helper_divw_AX(CPUX86State *env, target_ulong t0) { unsigned int num, den, q, r; - num = (EAX & 0xffff) | ((EDX & 0xffff) << 16); + num = (env->regs[R_EAX] & 0xffff) | ((env->regs[R_EDX] & 0xffff) << 16); den = (t0 & 0xffff); if (den == 0) { raise_exception(env, EXCP00_DIVZ); } q = (num / den); - if (q > 0xffff) + if (q > 0xffff) { raise_exception(env, EXCP00_DIVZ); + } q &= 0xffff; r = (num % den) & 0xffff; - EAX = (EAX & ~0xffff) | q; - EDX = (EDX & ~0xffff) | r; + env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | q; + env->regs[R_EDX] = (env->regs[R_EDX] & ~0xffff) | r; } void helper_idivw_AX(CPUX86State *env, target_ulong t0) { int num, den, q, r; - num = (EAX & 0xffff) | ((EDX & 0xffff) << 16); + num = (env->regs[R_EAX] & 0xffff) | ((env->regs[R_EDX] & 0xffff) << 16); den = (int16_t)t0; if (den == 0) { raise_exception(env, EXCP00_DIVZ); } q = (num / den); - if (q != (int16_t)q) + if (q != (int16_t)q) { raise_exception(env, EXCP00_DIVZ); + } q &= 0xffff; r = (num % den) & 0xffff; - EAX = (EAX & ~0xffff) | q; - EDX = (EDX & ~0xffff) | r; + env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | q; + env->regs[R_EDX] = (env->regs[R_EDX] & ~0xffff) | r; } void helper_divl_EAX(CPUX86State *env, target_ulong t0) @@ -116,17 +120,18 @@ unsigned int den, r; uint64_t num, q; - num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32); + num = ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32); den = t0; if (den == 0) { raise_exception(env, EXCP00_DIVZ); } q = (num / den); r = (num % den); - if (q > 0xffffffff) + if (q > 0xffffffff) { raise_exception(env, EXCP00_DIVZ); - EAX = (uint32_t)q; - EDX = (uint32_t)r; + } + env->regs[R_EAX] = (uint32_t)q; + env->regs[R_EDX] = (uint32_t)r; } void helper_idivl_EAX(CPUX86State *env, target_ulong t0) @@ -134,17 +139,18 @@ int den, r; int64_t num, q; - num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32); + num = ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32); den = t0; if (den == 0) { raise_exception(env, EXCP00_DIVZ); } q = (num / den); r = (num % den); - if (q != (int32_t)q) + if (q != (int32_t)q) { raise_exception(env, EXCP00_DIVZ); - EAX = (uint32_t)q; - EDX = (uint32_t)r; + } + env->regs[R_EAX] = (uint32_t)q; + env->regs[R_EDX] = (uint32_t)r; } /* bcd */ @@ -153,20 +159,20 @@ void helper_aam(CPUX86State *env, int base) { int al, ah; - al = EAX & 0xff; + al = env->regs[R_EAX] & 0xff; ah = al / base; al = al % base; - EAX = (EAX & ~0xffff) | al | (ah << 8); + env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | al | (ah << 8); CC_DST = al; } void helper_aad(CPUX86State *env, int base) { int al, ah; - al = EAX & 0xff; - ah = (EAX >> 8) & 0xff; + al = env->regs[R_EAX] & 0xff; + ah = (env->regs[R_EAX] >> 8) & 0xff; al = ((ah * base) + al) & 0xff; - EAX = (EAX & ~0xffff) | al; + env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | al; CC_DST = al; } @@ -178,8 +184,8 @@ eflags = helper_cc_compute_all(env, CC_OP); af = eflags & CC_A; - al = EAX & 0xff; - ah = (EAX >> 8) & 0xff; + al = env->regs[R_EAX] & 0xff; + ah = (env->regs[R_EAX] >> 8) & 0xff; icarry = (al > 0xf9); if (((al & 0x0f) > 9 ) || af) { @@ -190,7 +196,7 @@ eflags &= ~(CC_C | CC_A); al &= 0x0f; } - EAX = (EAX & ~0xffff) | al | (ah << 8); + env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | al | (ah << 8); CC_SRC = eflags; } @@ -202,8 +208,8 @@ eflags = helper_cc_compute_all(env, CC_OP); af = eflags & CC_A; - al = EAX & 0xff; - ah = (EAX >> 8) & 0xff; + al = env->regs[R_EAX] & 0xff; + ah = (env->regs[R_EAX] >> 8) & 0xff; icarry = (al < 6); if (((al & 0x0f) > 9 ) || af) { @@ -214,7 +220,7 @@ eflags &= ~(CC_C | CC_A); al &= 0x0f; } - EAX = (EAX & ~0xffff) | al | (ah << 8); + env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | al | (ah << 8); CC_SRC = eflags; } @@ -226,7 +232,7 @@ eflags = helper_cc_compute_all(env, CC_OP); cf = eflags & CC_C; af = eflags & CC_A; - al = EAX & 0xff; + al = env->regs[R_EAX] & 0xff; eflags = 0; if (((al & 0x0f) > 9 ) || af) { @@ -237,7 +243,7 @@ al = (al + 0x60) & 0xff; eflags |= CC_C; } - EAX = (EAX & ~0xff) | al; + env->regs[R_EAX] = (env->regs[R_EAX] & ~0xff) | al; /* well, speed is not an issue here, so we compute the flags by hand */ eflags |= (al == 0) << 6; /* zf */ eflags |= parity_table[al]; /* pf */ @@ -253,21 +259,22 @@ eflags = helper_cc_compute_all(env, CC_OP); cf = eflags & CC_C; af = eflags & CC_A; - al = EAX & 0xff; + al = env->regs[R_EAX] & 0xff; eflags = 0; al1 = al; if (((al & 0x0f) > 9 ) || af) { eflags |= CC_A; - if (al < 6 || cf) + if (al < 6 || cf) { eflags |= CC_C; + } al = (al - 6) & 0xff; } if ((al1 > 0x99) || cf) { al = (al - 0x60) & 0xff; eflags |= CC_C; } - EAX = (EAX & ~0xff) | al; + env->regs[R_EAX] = (env->regs[R_EAX] & ~0xff) | al; /* well, speed is not an issue here, so we compute the flags by hand */ eflags |= (al == 0) << 6; /* zf */ eflags |= parity_table[al]; /* pf */ @@ -281,8 +288,9 @@ { *plow += a; /* carry test */ - if (*plow < a) + if (*plow < a) { (*phigh)++; + } *phigh += b; } @@ -307,8 +315,9 @@ *plow = q; *phigh = r; } else { - if (a1 >= b) + if (a1 >= b) { return 1; + } /* XXX: use a better algorithm */ for(i = 0; i < 64; i++) { ab = a1 >> 63; @@ -322,7 +331,8 @@ a0 = (a0 << 1) | qb; } #if defined(DEBUG_MULDIV) - printf("div: 0x%016" PRIx64 "%016" PRIx64 " / 0x%016" PRIx64 ": q=0x%016" PRIx64 " r=0x%016" PRIx64 "\n", + printf("div: 0x%016" PRIx64 "%016" PRIx64 " / 0x%016" PRIx64 + ": q=0x%016" PRIx64 " r=0x%016" PRIx64 "\n", *phigh, *plow, b, a0, a1); #endif *plow = a0; @@ -336,23 +346,29 @@ { int sa, sb; sa = ((int64_t)*phigh < 0); - if (sa) + if (sa) { neg128(plow, phigh); + } sb = (b < 0); - if (sb) + if (sb) { b = -b; - if (div64(plow, phigh, b) != 0) + } + if (div64(plow, phigh, b) != 0) { return 1; + } if (sa ^ sb) { - if (*plow > (1ULL << 63)) + if (*plow > (1ULL << 63)) { return 1; + } *plow = - *plow; } else { - if (*plow >= (1ULL << 63)) + if (*plow >= (1ULL << 63)) { return 1; } - if (sa) + } + if (sa) { *phigh = - *phigh; + } return 0; } @@ -360,9 +376,9 @@ { uint64_t r0, r1; - mulu64(&r0, &r1, EAX, t0); - EAX = r0; - EDX = r1; + mulu64(&r0, &r1, env->regs[R_EAX], t0); + env->regs[R_EAX] = r0; + env->regs[R_EDX] = r1; CC_DST = r0; CC_SRC = r1; } @@ -371,9 +387,9 @@ { uint64_t r0, r1; - muls64(&r0, &r1, EAX, t0); - EAX = r0; - EDX = r1; + muls64(&r0, &r1, env->regs[R_EAX], t0); + env->regs[R_EAX] = r0; + env->regs[R_EDX] = r1; CC_DST = r0; CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63)); } @@ -394,12 +410,12 @@ if (t0 == 0) { raise_exception(env, EXCP00_DIVZ); } - r0 = EAX; - r1 = EDX; + r0 = env->regs[R_EAX]; + r1 = env->regs[R_EDX]; if (div64(&r0, &r1, t0)) raise_exception(env, EXCP00_DIVZ); - EAX = r0; - EDX = r1; + env->regs[R_EAX] = r0; + env->regs[R_EDX] = r1; } void helper_idivq_EAX(CPUX86State *env, target_ulong t0) @@ -408,12 +424,12 @@ if (t0 == 0) { raise_exception(env, EXCP00_DIVZ); } - r0 = EAX; - r1 = EDX; + r0 = env->regs[R_EAX]; + r1 = env->regs[R_EDX]; if (idiv64(&r0, &r1, t0)) raise_exception(env, EXCP00_DIVZ); - EAX = r0; - EDX = r1; + env->regs[R_EAX] = r0; + env->regs[R_EDX] = r1; } #endif
diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 465ae4e..38752a7 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c
@@ -174,12 +174,15 @@ c->index = j; cpu_x86_cpuid(env, i, j, &c->eax, &c->ebx, &c->ecx, &c->edx); - if (i == 4 && c->eax == 0) + if (i == 4 && c->eax == 0) { break; - if (i == 0xb && !(c->ecx & 0xff00)) + } + if (i == 0xb && !(c->ecx & 0xff00)) { break; - if (i == 0xd && c->eax == 0) + } + if (i == 0xd && c->eax == 0) { break; + } c = &cpuid_data.entries[cpuid_i++]; } @@ -310,23 +313,23 @@ lhs->selector = rhs->selector; lhs->base = rhs->base; lhs->limit = rhs->limit; - lhs->flags = - (rhs->type << DESC_TYPE_SHIFT) - | (rhs->present * DESC_P_MASK) - | (rhs->dpl << DESC_DPL_SHIFT) - | (rhs->db << DESC_B_SHIFT) - | (rhs->s * DESC_S_MASK) - | (rhs->l << DESC_L_SHIFT) - | (rhs->g * DESC_G_MASK) - | (rhs->avl * DESC_AVL_MASK); + lhs->flags = (rhs->type << DESC_TYPE_SHIFT) | + (rhs->present * DESC_P_MASK) | + (rhs->dpl << DESC_DPL_SHIFT) | + (rhs->db << DESC_B_SHIFT) | + (rhs->s * DESC_S_MASK) | + (rhs->l << DESC_L_SHIFT) | + (rhs->g * DESC_G_MASK) | + (rhs->avl * DESC_AVL_MASK); } static void kvm_getput_reg(__u64 *kvm_reg, target_ulong *qemu_reg, int set) { - if (set) + if (set) { *kvm_reg = *qemu_reg; - else + } else { *qemu_reg = *kvm_reg; + } } static int kvm_getput_regs(CPUX86State *env, int set) @@ -336,8 +339,9 @@ if (!set) { ret = kvm_vcpu_ioctl(ENV_GET_CPU(env), KVM_GET_REGS, ®s); - if (ret < 0) + if (ret < 0) { return ret; + } } kvm_getput_reg(®s.rax, &env->regs[R_EAX], set); @@ -362,8 +366,9 @@ kvm_getput_reg(®s.rflags, &env->eflags, set); kvm_getput_reg(®s.rip, &env->eip, set); - if (set) + if (set) { ret = kvm_vcpu_ioctl(ENV_GET_CPU(env), KVM_SET_REGS, ®s); + } return ret; } @@ -377,8 +382,9 @@ fpu.fsw = env->fpus & ~(7 << 11); fpu.fsw |= (env->fpstt & 7) << 11; fpu.fcw = env->fpuc; - for (i = 0; i < 8; ++i) - fpu.ftwx |= (!env->fptags[i]) << i; + for (i = 0; i < 8; ++i) { + fpu.ftwx |= (!env->fptags[i]) << i; + } memcpy(fpu.fpr, env->fpregs, sizeof env->fpregs); memcpy(fpu.xmm, env->xmm_regs, sizeof env->xmm_regs); fpu.mxcsr = env->mxcsr; @@ -457,8 +463,9 @@ kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_CS, env->sysenter_cs); kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_ESP, env->sysenter_esp); kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_EIP, env->sysenter_eip); - if (kvm_has_msr_star(env)) - kvm_msr_entry_set(&msrs[n++], MSR_STAR, env->star); + if (kvm_has_msr_star(env)) { + kvm_msr_entry_set(&msrs[n++], MSR_STAR, env->star); + } kvm_msr_entry_set(&msrs[n++], MSR_IA32_TSC, env->tsc); #ifdef TARGET_X86_64 /* FIXME if lm capable */ @@ -480,14 +487,16 @@ int i, ret; ret = kvm_vcpu_ioctl(ENV_GET_CPU(env), KVM_GET_FPU, &fpu); - if (ret < 0) + if (ret < 0) { return ret; + } env->fpstt = (fpu.fsw >> 11) & 7; env->fpus = fpu.fsw; env->fpuc = fpu.fcw; - for (i = 0; i < 8; ++i) - env->fptags[i] = !((fpu.ftwx >> i) & 1); + for (i = 0; i < 8; ++i) { + env->fptags[i] = !((fpu.ftwx >> i) & 1); + } memcpy(env->fpregs, fpu.fpr, sizeof env->fpregs); memcpy(env->xmm_regs, fpu.xmm, sizeof env->xmm_regs); env->mxcsr = fpu.mxcsr; @@ -503,8 +512,9 @@ int ret; ret = kvm_vcpu_ioctl(cpu, KVM_GET_SREGS, &sregs); - if (ret < 0) + if (ret < 0) { return ret; + } memcpy(env->interrupt_bitmap, sregs.interrupt_bitmap, @@ -535,8 +545,8 @@ env->efer = sregs.efer; //cpu_set_apic_tpr(env, sregs.cr8); -#define HFLAG_COPY_MASK ~( \ - HF_CPL_MASK | HF_PE_MASK | HF_MP_MASK | HF_EM_MASK | \ +#define HFLAG_COPY_MASK \ + ~( HF_CPL_MASK | HF_PE_MASK | HF_MP_MASK | HF_EM_MASK | \ HF_TS_MASK | HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK | \ HF_OSFXSR_MASK | HF_LMA_MASK | HF_CS32_MASK | \ HF_SS32_MASK | HF_CS64_MASK | HF_ADDSEG_MASK) @@ -562,15 +572,12 @@ (DESC_B_SHIFT - HF_CS32_SHIFT); hflags |= (env->segs[R_SS].flags & DESC_B_MASK) >> (DESC_B_SHIFT - HF_SS32_SHIFT); - if (!(env->cr[0] & CR0_PE_MASK) || - (env->eflags & VM_MASK) || + if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK) || !(hflags & HF_CS32_MASK)) { hflags |= HF_ADDSEG_MASK; } else { - hflags |= ((env->segs[R_DS].base | - env->segs[R_ES].base | - env->segs[R_SS].base) != 0) << - HF_ADDSEG_SHIFT; + hflags |= ((env->segs[R_DS].base | env->segs[R_ES].base | + env->segs[R_SS].base) != 0) << HF_ADDSEG_SHIFT; } } env->hflags = (env->hflags & HFLAG_COPY_MASK) | hflags; @@ -591,8 +598,9 @@ msrs[n++].index = MSR_IA32_SYSENTER_CS; msrs[n++].index = MSR_IA32_SYSENTER_ESP; msrs[n++].index = MSR_IA32_SYSENTER_EIP; - if (kvm_has_msr_star(env)) - msrs[n++].index = MSR_STAR; + if (kvm_has_msr_star(env)) { + msrs[n++].index = MSR_STAR; + } msrs[n++].index = MSR_IA32_TSC; #ifdef TARGET_X86_64 /* FIXME lm_capable_kernel */ @@ -603,8 +611,9 @@ #endif msr_data.info.nmsrs = n; ret = kvm_vcpu_ioctl(ENV_GET_CPU(env), KVM_GET_MSRS, &msr_data); - if (ret < 0) + if (ret < 0) { return ret; + } for (i = 0; i < ret; i++) { switch (msrs[i].index) { @@ -649,28 +658,29 @@ int ret; ret = kvm_getput_regs(env, 1); - if (ret < 0) + if (ret < 0) { return ret; - + } ret = kvm_put_fpu(env); - if (ret < 0) + if (ret < 0) { return ret; - + } ret = kvm_put_sregs(env); - if (ret < 0) + if (ret < 0) { return ret; - + } ret = kvm_put_msrs(env); - if (ret < 0) + if (ret < 0) { return ret; - + } ret = kvm_put_mp_state(cpu); - if (ret < 0) + if (ret < 0) { return ret; - + } ret = kvm_get_mp_state(cpu); - if (ret < 0) + if (ret < 0) { return ret; + } return 0; } @@ -681,30 +691,30 @@ CPUX86State *env = cpu->env_ptr; ret = kvm_getput_regs(env, 0); - if (ret < 0) + if (ret < 0) { return ret; - + } ret = kvm_get_fpu(env); - if (ret < 0) + if (ret < 0) { return ret; - + } ret = kvm_get_sregs(cpu); - if (ret < 0) + if (ret < 0) { return ret; - + } ret = kvm_get_msrs(env); - if (ret < 0) + if (ret < 0) { return ret; - + } return 0; } int kvm_arch_vcpu_run(CPUState *cpu) { #ifdef CONFIG_KVM_GS_RESTORE - if (gs_need_restore != KVM_GS_RESTORE_NO) + if (gs_need_restore != KVM_GS_RESTORE_NO) { return no_gs_ioctl(cpu->kvm_fd, KVM_RUN, 0); - else + } else #endif return kvm_vcpu_ioctl(cpu, KVM_RUN, 0); } @@ -734,10 +744,11 @@ * interrupt, request an interrupt window exit. This will * cause a return to userspace as soon as the guest is ready to * receive interrupts. */ - if ((cpu->interrupt_request & CPU_INTERRUPT_HARD)) + if ((cpu->interrupt_request & CPU_INTERRUPT_HARD)) { run->request_interrupt_window = 1; - else + } else { run->request_interrupt_window = 0; + } dprintf("setting tpr\n"); run->cr8 = cpu_get_apic_tpr(env); @@ -755,11 +766,11 @@ #ifdef CONFIG_KVM_GS_RESTORE gs_base_post_run(); #endif - if (run->if_flag) + if (run->if_flag) { env->eflags |= IF_MASK; - else + } else { env->eflags &= ~IF_MASK; - + } cpu_set_apic_tpr(env, run->cr8); cpu_set_apic_base(env, run->apic_base); @@ -801,8 +812,9 @@ const static uint8_t int3 = 0xcc; if (cpu_memory_rw_debug(cpu, bp->pc, (uint8_t *)&bp->saved_insn, 1, 0) || - cpu_memory_rw_debug(cpu, bp->pc, (uint8_t *)&int3, 1, 1)) + cpu_memory_rw_debug(cpu, bp->pc, (uint8_t *)&int3, 1, 1)) { return -EINVAL; + } return 0; } @@ -811,8 +823,9 @@ uint8_t int3; if (cpu_memory_rw_debug(cpu, bp->pc, &int3, 1, 0) || int3 != 0xcc || - cpu_memory_rw_debug(cpu, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) + cpu_memory_rw_debug(cpu, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) { return -EINVAL; + } return 0; } @@ -828,10 +841,12 @@ { int n; - for (n = 0; n < nb_hw_breakpoint; n++) + for (n = 0; n < nb_hw_breakpoint; n++) { if (hw_breakpoint[n].addr == addr && hw_breakpoint[n].type == type && - (hw_breakpoint[n].len == len || len == -1)) + (hw_breakpoint[n].len == len || len == -1)) { return n; + } + } return -1; } @@ -850,8 +865,9 @@ case 2: case 4: case 8: - if (addr & (len - 1)) + if (addr & (len - 1)) { return -EINVAL; + } break; default: return -EINVAL; @@ -861,12 +877,14 @@ return -ENOSYS; } - if (nb_hw_breakpoint == 4) + if (nb_hw_breakpoint == 4) { return -ENOBUFS; - if (find_hw_breakpoint(addr, len, type) >= 0) + } + if (find_hw_breakpoint(addr, len, type) >= 0) { return -EEXIST; + } hw_breakpoint[nb_hw_breakpoint].addr = addr; hw_breakpoint[nb_hw_breakpoint].len = len; hw_breakpoint[nb_hw_breakpoint].type = type; @@ -881,9 +899,10 @@ int n; n = find_hw_breakpoint(addr, (type == GDB_BREAKPOINT_HW) ? 1 : len, type); - if (n < 0) + if (n < 0) { return -ENOENT; + } nb_hw_breakpoint--; hw_breakpoint[n] = hw_breakpoint[nb_hw_breakpoint]; @@ -904,11 +923,12 @@ if (arch_info->exception == 1) { if (arch_info->dr6 & (1 << 14)) { - if (current_cpu->singlestep_enabled) + if (current_cpu->singlestep_enabled) { handle = 1; + } } else { - for (n = 0; n < 4; n++) - if (arch_info->dr6 & (1 << n)) + for (n = 0; n < 4; n++) { + if (arch_info->dr6 & (1 << n)) { switch ((arch_info->dr7 >> (16 + n*4)) & 0x3) { case 0x0: handle = 1; @@ -926,15 +946,17 @@ hw_watchpoint.flags = BP_MEM_ACCESS; break; } + } + } } - } else if (kvm_find_sw_breakpoint(current_cpu, arch_info->pc)) + } else if (kvm_find_sw_breakpoint(current_cpu, arch_info->pc)) { handle = 1; - - if (!handle) + } + if (!handle) { kvm_update_guest_debug(current_cpu, (arch_info->exception == 1) ? KVM_GUESTDBG_INJECT_DB : KVM_GUESTDBG_INJECT_BP); - + } return handle; } @@ -950,9 +972,9 @@ }; int n; - if (kvm_sw_breakpoints_active(cpu)) + if (kvm_sw_breakpoints_active(cpu)) { dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP; - + } if (nb_hw_breakpoint > 0) { dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP; dbg->arch.debugreg[7] = 0x0600;
diff --git a/target-i386/mem_helper.c b/target-i386/mem_helper.c index 9500bab..b4d3f9a 100644 --- a/target-i386/mem_helper.c +++ b/target-i386/mem_helper.c
@@ -45,14 +45,14 @@ eflags = helper_cc_compute_all(env, CC_OP); d = cpu_ldq_data(env, a0); - if (d == (((uint64_t)EDX << 32) | (uint32_t)EAX)) { - cpu_stq_data(env, a0, ((uint64_t)ECX << 32) | (uint32_t)EBX); + if (d == (((uint64_t)env->regs[R_EDX] << 32) | (uint32_t)env->regs[R_EAX])) { + cpu_stq_data(env, a0, ((uint64_t)env->regs[R_ECX] << 32) | (uint32_t)env->regs[R_EBX]); eflags |= CC_Z; } else { /* always do the store */ cpu_stq_data(env, a0, d); - EDX = (uint32_t)(d >> 32); - EAX = (uint32_t)d; + env->regs[R_EDX] = (uint32_t)(d >> 32); + env->regs[R_EAX] = (uint32_t)d; eflags &= ~CC_Z; } CC_SRC = eflags; @@ -64,21 +64,22 @@ uint64_t d0, d1; int eflags; - if ((a0 & 0xf) != 0) + if ((a0 & 0xf) != 0) { raise_exception(env, EXCP0D_GPF); - eflags = helper_cc_compute_all(env, CC_OP); + } + eflags = cpu_cc_compute_all(env, CC_OP); d0 = cpu_ldq_data(env, a0); d1 = cpu_ldq_data(env, a0 + 8); - if (d0 == EAX && d1 == EDX) { - cpu_stq_data(env, a0, EBX); - cpu_stq_data(env, a0 + 8, ECX); + if (d0 == env->regs[R_EAX] && d1 == env->regs[R_EDX]) { + cpu_stq_data(env, a0, env->regs[R_EBX]); + cpu_stq_data(env, a0 + 8, env->regs[R_ECX]); eflags |= CC_Z; } else { /* always do the store */ cpu_stq_data(env, a0, d0); cpu_stq_data(env, a0 + 8, d1); - EDX = d1; - EAX = d0; + env->regs[R_EDX] = d1; + env->regs[R_EAX] = d0; eflags &= ~CC_Z; } CC_SRC = eflags; @@ -126,8 +127,9 @@ #if !defined(CONFIG_USER_ONLY) /* try to fill the TLB and return an exception if error. If retaddr is - NULL, it means that the function was called in C code (i.e. not - from generated code or from helper.c) */ + * NULL, it means that the function was called in C code (i.e. not + * from generated code or from helper.c) + */ /* XXX: fix it to restore all registers */ void tlb_fill(CPUX86State* env, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr)
diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c index d8dc895..f4863dc 100644 --- a/target-i386/misc_helper.c +++ b/target-i386/misc_helper.c
@@ -33,13 +33,15 @@ /* TSS must be a valid 32 bit one */ if (!(env->tr.flags & DESC_P_MASK) || ((env->tr.flags >> DESC_TYPE_SHIFT) & 0xf) != 9 || - env->tr.limit < 103) + env->tr.limit < 103) { goto fail; + } 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) + if ((io_offset + 1) > env->tr.limit) { goto fail; + } val = cpu_lduw_kernel(env, env->tr.base + io_offset); val >>= (addr & 7); mask = (1 << size) - 1; @@ -119,11 +121,12 @@ helper_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) @@ -194,13 +197,16 @@ env->dr[reg] = t0; hw_breakpoint_insert(env, reg); } else if (reg == 7) { - for (i = 0; i < 4; i++) + for (i = 0; i < 4; i++) { hw_breakpoint_remove(env, i); + } env->dr[7] = t0; - for (i = 0; i < 4; i++) + for (i = 0; i < 4; i++) { hw_breakpoint_insert(env, i); - } else + } + } else { env->dr[reg] = t0; + } } #endif @@ -228,8 +234,8 @@ helper_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_rdpmc(CPUX86State *env) @@ -258,9 +264,10 @@ helper_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; @@ -277,18 +284,24 @@ { uint64_t update_mask; update_mask = 0; - if (env->cpuid_ext2_features & CPUID_EXT2_SYSCALL) + if (env->cpuid_ext2_features & CPUID_EXT2_SYSCALL) { update_mask |= MSR_EFER_SCE; - if (env->cpuid_ext2_features & CPUID_EXT2_LM) + } + if (env->cpuid_ext2_features & CPUID_EXT2_LM) { update_mask |= MSR_EFER_LME; - if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR) + } + if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR) { update_mask |= MSR_EFER_FFXSR; - if (env->cpuid_ext2_features & CPUID_EXT2_NX) + } + if (env->cpuid_ext2_features & CPUID_EXT2_NX) { update_mask |= MSR_EFER_NXE; - if (env->cpuid_ext3_features & CPUID_EXT3_SVM) + } + if (env->cpuid_ext3_features & CPUID_EXT3_SVM) { update_mask |= MSR_EFER_SVME; - if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR) + } + if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR) { update_mask |= MSR_EFER_FFXSR; + } cpu_load_efer(env, (env->efer & ~update_mask) | (val & update_mask)); } @@ -330,7 +343,8 @@ 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): @@ -340,14 +354,17 @@ 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: @@ -357,7 +374,8 @@ 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; @@ -367,16 +385,19 @@ break; case MSR_MCG_CTL: if ((env->mcg_cap & MCG_CTL_P) - && (val == 0 || val == ~(uint64_t)0)) + && (val == 0 || val == ~(uint64_t)0)) { env->mcg_ctl = 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)) + || (val == 0 || val == ~(uint64_t)0)) { env->mce_banks[offset] = val; + } break; } /* XXX: exception ? */ @@ -390,7 +411,7 @@ helper_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; @@ -449,7 +470,8 @@ 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): @@ -459,14 +481,16 @@ 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: @@ -476,34 +500,38 @@ 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->cpuid_features & CPUID_MTRR) { val = MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT | MSR_MTRRcap_WC_SUPPORTED; - else + } else { /* XXX: exception ? */ val = 0; + } break; case MSR_MCG_CAP: val = env->mcg_cap; break; case MSR_MCG_CTL: - if (env->mcg_cap & MCG_CTL_P) + if (env->mcg_cap & MCG_CTL_P) { val = env->mcg_ctl; - else + } else { val = 0; + } break; case MSR_MCG_STATUS: val = env->mcg_status; 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; } @@ -511,8 +539,8 @@ 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 @@ -527,25 +555,27 @@ void helper_hlt(CPUX86State *env, int next_eip_addend) { helper_svm_check_intercept_param(env, SVM_EXIT_HLT, 0); - EIP += next_eip_addend; + env->eip += next_eip_addend; do_hlt(env); } 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 ? */ helper_svm_check_intercept_param(env, SVM_EXIT_MONITOR, 0); } void helper_mwait(CPUX86State *env, int next_eip_addend) { - if ((uint32_t)ECX != 0) + if ((uint32_t)env->regs[R_ECX] != 0) { raise_exception(env, EXCP0D_GPF); + } helper_svm_check_intercept_param(env, SVM_EXIT_MWAIT, 0); - EIP += next_eip_addend; + env->eip += next_eip_addend; /* XXX: not complete but not completely erroneous */ CPUState *cpu = ENV_GET_CPU(env);
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c index 70ca829..1795e69 100644 --- a/target-i386/seg_helper.c +++ b/target-i386/seg_helper.c
@@ -22,11 +22,11 @@ #include "qemu/log.h" #include "helper.h" +//#define DEBUG_PCALL #if !defined(CONFIG_USER_ONLY) #include "exec/softmmu_exec.h" #endif /* !defined(CONFIG_USER_ONLY) */ -//#define DEBUG_PCALL #ifdef DEBUG_PCALL @@ -39,21 +39,22 @@ #endif /* return non zero if error */ -static inline int load_segment(CPUX86State *env, - uint32_t *e1_ptr, uint32_t *e2_ptr, - int selector) +static inline int load_segment(CPUX86State *env, uint32_t *e1_ptr, + uint32_t *e2_ptr, int selector) { SegmentCache *dt; int index; target_ulong ptr; - if (selector & 0x4) + if (selector & 0x4) { dt = &env->ldt; - else + } else { dt = &env->gdt; + } index = selector & ~7; - if ((index + 7) > dt->limit) + if ((index + 7) > dt->limit) { return -1; + } ptr = dt->base + index; *e1_ptr = cpu_ldl_kernel(env, ptr); *e2_ptr = cpu_ldl_kernel(env, ptr + 4); @@ -64,17 +65,19 @@ { unsigned int limit; limit = (e1 & 0xffff) | (e2 & 0x000f0000); - if (e2 & DESC_G_MASK) + if (e2 & DESC_G_MASK) { limit = (limit << 12) | 0xfff; + } return limit; } static inline uint32_t get_seg_base(uint32_t e1, uint32_t e2) { - return ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000)); + return (e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000); } -static inline void load_seg_cache_raw_dt(SegmentCache *sc, uint32_t e1, uint32_t e2) +static inline void load_seg_cache_raw_dt(SegmentCache *sc, uint32_t e1, + uint32_t e2) { sc->base = get_seg_base(e1, e2); sc->limit = get_seg_limit(e1, e2); @@ -89,8 +92,7 @@ (selector << 4), 0xffff, 0); } -static inline void get_ss_esp_from_tss(CPUX86State *env, - uint32_t *ss_ptr, +static inline void get_ss_esp_from_tss(CPUX86State *env, uint32_t *ss_ptr, uint32_t *esp_ptr, int dpl) { int type, index, shift; @@ -101,21 +103,26 @@ printf("TR: base=%p limit=%x\n", env->tr.base, env->tr.limit); for(i=0;i<env->tr.limit;i++) { printf("%02x ", env->tr.base[i]); - if ((i & 7) == 7) printf("\n"); + if ((i & 7) == 7) { + printf("\n"); + } } printf("\n"); } #endif - if (!(env->tr.flags & DESC_P_MASK)) + if (!(env->tr.flags & DESC_P_MASK)) { cpu_abort(env, "invalid tss"); + } type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf; - if ((type & 7) != 1) + if ((type & 7) != 1) { cpu_abort(env, "invalid tss type"); + } shift = type >> 3; index = (dpl * 4 + 2) << shift; - if (index + (4 << shift) - 1 > env->tr.limit) + if (index + (4 << shift) - 1 > env->tr.limit) { raise_exception_err(env, EXCP0A_TSS, env->tr.selector & 0xfffc); + } if (shift == 0) { *esp_ptr = cpu_lduw_kernel(env, env->tr.base + index); *ss_ptr = cpu_lduw_kernel(env, env->tr.base + index + 2); @@ -132,46 +139,57 @@ int rpl, dpl, cpl; if ((selector & 0xfffc) != 0) { - if (load_segment(env, &e1, &e2, selector) != 0) + if (load_segment(env, &e1, &e2, selector) != 0) { raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc); - if (!(e2 & DESC_S_MASK)) + } + if (!(e2 & DESC_S_MASK)) { raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc); + } rpl = selector & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3; cpl = env->hflags & HF_CPL_MASK; if (seg_reg == R_CS) { - if (!(e2 & DESC_CS_MASK)) + if (!(e2 & DESC_CS_MASK)) { raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc); + } /* XXX: is it correct ? */ - if (dpl != rpl) + if (dpl != rpl) { raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc); - if ((e2 & DESC_C_MASK) && dpl > rpl) + } + if ((e2 & DESC_C_MASK) && dpl > rpl) { raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc); + } } else if (seg_reg == R_SS) { /* SS must be writable data */ - if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK)) + if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK)) { raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc); - if (dpl != cpl || dpl != rpl) + } + if (dpl != cpl || dpl != rpl) { raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc); + } } else { /* not readable code */ - if ((e2 & DESC_CS_MASK) && !(e2 & DESC_R_MASK)) + if ((e2 & DESC_CS_MASK) && !(e2 & DESC_R_MASK)) { raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc); + } /* if data or non conforming code, checks the rights */ if (((e2 >> DESC_TYPE_SHIFT) & 0xf) < 12) { - if (dpl < cpl || dpl < rpl) + if (dpl < cpl || dpl < rpl) { raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc); } } - if (!(e2 & DESC_P_MASK)) + } + if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc); + } cpu_x86_load_seg_cache(env, seg_reg, selector, get_seg_base(e1, e2), get_seg_limit(e1, e2), e2); } else { - if (seg_reg == R_SS || seg_reg == R_CS) + if (seg_reg == R_SS || seg_reg == R_CS) { raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc); + } } } @@ -180,8 +198,7 @@ #define SWITCH_TSS_CALL 2 /* XXX: restore CPU state in registers (PowerPC case) */ -static void switch_tss(CPUX86State *env, - int tss_selector, +static void switch_tss(CPUX86State *env, int tss_selector, uint32_t e1, uint32_t e2, int source, uint32_t next_eip) { @@ -195,41 +212,51 @@ target_ulong ptr; type = (e2 >> DESC_TYPE_SHIFT) & 0xf; - LOG_PCALL("switch_tss: sel=0x%04x type=%d src=%d\n", tss_selector, type, source); + LOG_PCALL("switch_tss: sel=0x%04x type=%d src=%d\n", tss_selector, type, + source); /* if task gate, we read the TSS segment and we load it */ if (type == 5) { - if (!(e2 & DESC_P_MASK)) + if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, tss_selector & 0xfffc); + } tss_selector = e1 >> 16; - if (tss_selector & 4) + if (tss_selector & 4) { raise_exception_err(env, EXCP0A_TSS, tss_selector & 0xfffc); - if (load_segment(env, &e1, &e2, tss_selector) != 0) + } + if (load_segment(env, &e1, &e2, tss_selector) != 0) { raise_exception_err(env, EXCP0D_GPF, tss_selector & 0xfffc); - if (e2 & DESC_S_MASK) + } + if (e2 & DESC_S_MASK) { raise_exception_err(env, EXCP0D_GPF, tss_selector & 0xfffc); + } type = (e2 >> DESC_TYPE_SHIFT) & 0xf; - if ((type & 7) != 1) + if ((type & 7) != 1) { raise_exception_err(env, EXCP0D_GPF, tss_selector & 0xfffc); + } } - if (!(e2 & DESC_P_MASK)) + if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, tss_selector & 0xfffc); + } - if (type & 8) + if (type & 8) { tss_limit_max = 103; - else + } else { tss_limit_max = 43; + } tss_limit = get_seg_limit(e1, e2); tss_base = get_seg_base(e1, e2); if ((tss_selector & 4) != 0 || - tss_limit < tss_limit_max) + tss_limit < tss_limit_max) { raise_exception_err(env, EXCP0A_TSS, tss_selector & 0xfffc); + } old_type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf; - if (old_type & 8) + if (old_type & 8) { old_tss_limit_max = 103; - else + } else { old_tss_limit_max = 43; + } /* read all the registers from the new TSS */ if (type & 8) { @@ -237,10 +264,12 @@ new_cr3 = cpu_ldl_kernel(env, tss_base + 0x1c); new_eip = cpu_ldl_kernel(env, tss_base + 0x20); new_eflags = cpu_ldl_kernel(env, tss_base + 0x24); - for(i = 0; i < 8; i++) + for (i = 0; i < 8; i++) { new_regs[i] = cpu_ldl_kernel(env, tss_base + (0x28 + i * 4)); - for(i = 0; i < 6; i++) + } + for (i = 0; i < 6; i++) { new_segs[i] = cpu_lduw_kernel(env, tss_base + (0x48 + i * 4)); + } new_ldt = cpu_lduw_kernel(env, tss_base + 0x60); cpu_ldl_kernel(env, tss_base + 0x64); } else { @@ -248,10 +277,13 @@ new_cr3 = 0; new_eip = cpu_lduw_kernel(env, tss_base + 0x0e); new_eflags = cpu_lduw_kernel(env, tss_base + 0x10); - for(i = 0; i < 8; i++) - new_regs[i] = cpu_lduw_kernel(env, tss_base + (0x12 + i * 2)) | 0xffff0000; - for(i = 0; i < 4; i++) + for (i = 0; i < 8; i++) { + new_regs[i] = cpu_lduw_kernel(env, tss_base + (0x12 + i * 2)) | + 0xffff0000; + } + for (i = 0; i < 4; i++) { new_segs[i] = cpu_lduw_kernel(env, tss_base + (0x22 + i * 4)); + } new_ldt = cpu_lduw_kernel(env, tss_base + 0x2a); new_segs[R_FS] = 0; new_segs[R_GS] = 0; @@ -277,38 +309,43 @@ cpu_stl_kernel(env, ptr + 4, e2); } old_eflags = cpu_compute_eflags(env); - if (source == SWITCH_TSS_IRET) + if (source == SWITCH_TSS_IRET) { old_eflags &= ~NT_MASK; + } /* save the current state in the old TSS */ if (type & 8) { /* 32 bit */ cpu_stl_kernel(env, env->tr.base + 0x20, next_eip); cpu_stl_kernel(env, env->tr.base + 0x24, old_eflags); - cpu_stl_kernel(env, env->tr.base + (0x28 + 0 * 4), EAX); - cpu_stl_kernel(env, env->tr.base + (0x28 + 1 * 4), ECX); - cpu_stl_kernel(env, env->tr.base + (0x28 + 2 * 4), EDX); - cpu_stl_kernel(env, env->tr.base + (0x28 + 3 * 4), EBX); - cpu_stl_kernel(env, env->tr.base + (0x28 + 4 * 4), ESP); - cpu_stl_kernel(env, env->tr.base + (0x28 + 5 * 4), EBP); - cpu_stl_kernel(env, env->tr.base + (0x28 + 6 * 4), ESI); - cpu_stl_kernel(env, env->tr.base + (0x28 + 7 * 4), EDI); - for(i = 0; i < 6; i++) - cpu_stw_kernel(env, env->tr.base + (0x48 + i * 4), env->segs[i].selector); + cpu_stl_kernel(env, env->tr.base + (0x28 + 0 * 4), env->regs[R_EAX]); + cpu_stl_kernel(env, env->tr.base + (0x28 + 1 * 4), env->regs[R_ECX]); + cpu_stl_kernel(env, env->tr.base + (0x28 + 2 * 4), env->regs[R_EDX]); + cpu_stl_kernel(env, env->tr.base + (0x28 + 3 * 4), env->regs[R_EBX]); + cpu_stl_kernel(env, env->tr.base + (0x28 + 4 * 4), env->regs[R_ESP]); + cpu_stl_kernel(env, env->tr.base + (0x28 + 5 * 4), env->regs[R_EBP]); + cpu_stl_kernel(env, env->tr.base + (0x28 + 6 * 4), env->regs[R_ESI]); + cpu_stl_kernel(env, env->tr.base + (0x28 + 7 * 4), env->regs[R_EDI]); + for (i = 0; i < 6; i++) { + cpu_stw_kernel(env, env->tr.base + (0x48 + i * 4), + env->segs[i].selector); + } } else { /* 16 bit */ cpu_stw_kernel(env, env->tr.base + 0x0e, next_eip); cpu_stw_kernel(env, env->tr.base + 0x10, old_eflags); - cpu_stw_kernel(env, env->tr.base + (0x12 + 0 * 2), EAX); - cpu_stw_kernel(env, env->tr.base + (0x12 + 1 * 2), ECX); - cpu_stw_kernel(env, env->tr.base + (0x12 + 2 * 2), EDX); - cpu_stw_kernel(env, env->tr.base + (0x12 + 3 * 2), EBX); - cpu_stw_kernel(env, env->tr.base + (0x12 + 4 * 2), ESP); - cpu_stw_kernel(env, env->tr.base + (0x12 + 5 * 2), EBP); - cpu_stw_kernel(env, env->tr.base + (0x12 + 6 * 2), ESI); - cpu_stw_kernel(env, env->tr.base + (0x12 + 7 * 2), EDI); - for(i = 0; i < 4; i++) - cpu_stw_kernel(env, env->tr.base + (0x22 + i * 4), env->segs[i].selector); + cpu_stw_kernel(env, env->tr.base + (0x12 + 0 * 2), env->regs[R_EAX]); + cpu_stw_kernel(env, env->tr.base + (0x12 + 1 * 2), env->regs[R_ECX]); + cpu_stw_kernel(env, env->tr.base + (0x12 + 2 * 2), env->regs[R_EDX]); + cpu_stw_kernel(env, env->tr.base + (0x12 + 3 * 2), env->regs[R_EBX]); + cpu_stw_kernel(env, env->tr.base + (0x12 + 4 * 2), env->regs[R_ESP]); + cpu_stw_kernel(env, env->tr.base + (0x12 + 5 * 2), env->regs[R_EBP]); + cpu_stw_kernel(env, env->tr.base + (0x12 + 6 * 2), env->regs[R_ESI]); + cpu_stw_kernel(env, env->tr.base + (0x12 + 7 * 2), env->regs[R_EDI]); + for (i = 0; i < 4; i++) { + cpu_stw_kernel(env, env->tr.base + (0x22 + i * 4), + env->segs[i].selector); + } } /* now if an exception occurs, it will occurs in the next task @@ -347,29 +384,32 @@ env->eip = new_eip; eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK; - if (!(type & 8)) + if (!(type & 8)) { eflags_mask &= 0xffff; + } cpu_load_eflags(env, new_eflags, eflags_mask); /* XXX: what to do in 16 bit case ? */ - EAX = new_regs[0]; - ECX = new_regs[1]; - EDX = new_regs[2]; - EBX = new_regs[3]; - ESP = new_regs[4]; - EBP = new_regs[5]; - ESI = new_regs[6]; - EDI = new_regs[7]; + env->regs[R_EAX] = new_regs[0]; + env->regs[R_ECX] = new_regs[1]; + env->regs[R_EDX] = new_regs[2]; + env->regs[R_EBX] = new_regs[3]; + env->regs[R_ESP] = new_regs[4]; + env->regs[R_EBP] = new_regs[5]; + env->regs[R_ESI] = new_regs[6]; + env->regs[R_EDI] = new_regs[7]; if (new_eflags & VM_MASK) { - for(i = 0; i < 6; i++) + for (i = 0; i < 6; i++) { load_seg_vm(env, i, new_segs[i]); + } /* in vm86, CPL is always 3 */ cpu_x86_set_cpl(env, 3); } else { /* CPL is set the RPL of CS */ cpu_x86_set_cpl(env, new_segs[R_CS] & 3); /* first just selectors as the rest may trigger exceptions */ - for(i = 0; i < 6; i++) + for (i = 0; i < 6; i++) { cpu_x86_load_seg_cache(env, i, new_segs[i], 0, 0, 0); + } } env->ldt.selector = new_ldt & ~4; @@ -378,21 +418,25 @@ env->ldt.flags = 0; /* load the LDT */ - if (new_ldt & 4) + if (new_ldt & 4) { raise_exception_err(env, EXCP0A_TSS, new_ldt & 0xfffc); + } if ((new_ldt & 0xfffc) != 0) { dt = &env->gdt; index = new_ldt & ~7; - if ((index + 7) > dt->limit) + if ((index + 7) > dt->limit) { raise_exception_err(env, EXCP0A_TSS, new_ldt & 0xfffc); + } ptr = dt->base + index; e1 = cpu_ldl_kernel(env, ptr); e2 = cpu_ldl_kernel(env, ptr + 4); - if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2) + if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2) { raise_exception_err(env, EXCP0A_TSS, new_ldt & 0xfffc); - if (!(e2 & DESC_P_MASK)) + } + if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0A_TSS, new_ldt & 0xfffc); + } load_seg_cache_raw_dt(&env->ldt, e1, e2); } @@ -406,7 +450,7 @@ tss_load_seg(env, R_GS, new_segs[R_GS]); } - /* check that EIP is in the CS segment limits */ + /* check that env->eip is in the CS segment limits */ if (new_eip > env->segs[R_CS].limit) { /* XXX: different exception if CALL ? */ raise_exception_err(env, EXCP0D_GPF, 0); @@ -416,8 +460,9 @@ /* reset local breakpoints */ if (env->dr[7] & 0x55) { for (i = 0; i < 4; i++) { - if (hw_breakpoint_enabled(env->dr[7], i) == 0x1) + if (hw_breakpoint_enabled(env->dr[7], i) == 0x1) { hw_breakpoint_remove(env, i); + } } env->dr[7] &= ~0x55; } @@ -426,13 +471,14 @@ static inline unsigned int get_sp_mask(unsigned int e2) { - if (e2 & DESC_B_MASK) + if (e2 & DESC_B_MASK) { return 0xffffffff; - else + } else { return 0xffff; + } } -static int exeption_has_error_code(int intno) +static int exception_has_error_code(int intno) { switch(intno) { case 8: @@ -450,15 +496,21 @@ #ifdef TARGET_X86_64 #define SET_ESP(val, sp_mask)\ do {\ - if ((sp_mask) == 0xffff)\ - ESP = (ESP & ~0xffff) | ((val) & 0xffff);\ - else if ((sp_mask) == 0xffffffffLL)\ - ESP = (uint32_t)(val);\ - else\ - ESP = (val);\ + if ((sp_mask) == 0xffff) { \ + env->regs[R_ESP] = (env->regs[R_ESP] & ~0xffff) | \ + ((val) & 0xffff); \ + } else if ((sp_mask) == 0xffffffffLL) { \ + env->regs[R_ESP] = (uint32_t)(val); \ + } else { \ + env->regs[R_ESP] = (val); \ + } \ } while (0) #else -#define SET_ESP(val, sp_mask) ESP = (ESP & ~(sp_mask)) | ((val) & (sp_mask)) +#define SET_ESP(val, sp_mask) \ + do { \ + env->regs[R_ESP] = (env->regs[R_ESP] & ~(sp_mask)) | \ + ((val) & (sp_mask)); \ + } while (0) #endif /* in 64-bit machines, this can overflow. So this segment addition macro @@ -491,9 +543,9 @@ } /* protected mode interrupt */ -static void do_interrupt_protected(CPUX86State *env, - int intno, int is_int, int error_code, - unsigned int next_eip, int is_hw) +static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, + int error_code, unsigned int next_eip, + int is_hw) { SegmentCache *dt; target_ulong ptr, ssp; @@ -503,16 +555,19 @@ uint32_t old_eip, sp_mask; has_error_code = 0; - if (!is_int && !is_hw) - has_error_code = exeption_has_error_code(intno); - if (is_int) + if (!is_int && !is_hw) { + has_error_code = exception_has_error_code(intno); + } + if (is_int) { old_eip = next_eip; - else + } else { old_eip = env->eip; + } dt = &env->idt; - if (intno * 8 + 7 > dt->limit) + if (intno * 8 + 7 > dt->limit) { raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); + } ptr = dt->base + intno * 8; e1 = cpu_ldl_kernel(env, ptr); e2 = cpu_ldl_kernel(env, ptr + 4); @@ -521,8 +576,9 @@ switch(type) { case 5: /* task gate */ /* must do that check here to return the correct error code */ - if (!(e2 & DESC_P_MASK)) + if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, intno * 8 + 2); + } switch_tss(env, intno * 8, e1, e2, SWITCH_TSS_CALL, old_eip); if (has_error_code) { int type; @@ -530,16 +586,18 @@ /* push the error code */ type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf; shift = type >> 3; - if (env->segs[R_SS].flags & DESC_B_MASK) + if (env->segs[R_SS].flags & DESC_B_MASK) { mask = 0xffffffff; - else + } else { mask = 0xffff; - esp = (ESP - (2 << shift)) & mask; + } + esp = (env->regs[R_ESP] - (2 << shift)) & mask; ssp = env->segs[R_SS].base + esp; - if (shift) + if (shift) { cpu_stl_kernel(env, ssp, error_code); - else + } else { cpu_stw_kernel(env, ssp, error_code); + } SET_ESP(esp, mask); } return; @@ -555,54 +613,68 @@ dpl = (e2 >> DESC_DPL_SHIFT) & 3; cpl = env->hflags & HF_CPL_MASK; /* check privilege if software int */ - if (is_int && dpl < cpl) + if (is_int && dpl < cpl) { raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); + } /* check valid bit */ - if (!(e2 & DESC_P_MASK)) + if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, intno * 8 + 2); + } selector = e1 >> 16; offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff); - if ((selector & 0xfffc) == 0) + if ((selector & 0xfffc) == 0) { raise_exception_err(env, EXCP0D_GPF, 0); - if (load_segment(env, &e1, &e2, selector) != 0) + } + if (load_segment(env, &e1, &e2, selector) != 0) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); - if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) + } + if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); + } dpl = (e2 >> DESC_DPL_SHIFT) & 3; - if (dpl > cpl) + if (dpl > cpl) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); - if (!(e2 & DESC_P_MASK)) + } + if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc); + } if (!(e2 & DESC_C_MASK) && dpl < cpl) { /* to inner privilege */ get_ss_esp_from_tss(env, &ss, &esp, dpl); - if ((ss & 0xfffc) == 0) + if ((ss & 0xfffc) == 0) { raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); - if ((ss & 3) != dpl) + } + if ((ss & 3) != dpl) { raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); - if (load_segment(env, &ss_e1, &ss_e2, ss) != 0) + } + if (load_segment(env, &ss_e1, &ss_e2, ss) != 0) { raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); + } ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3; - if (ss_dpl != dpl) + if (ss_dpl != dpl) { raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); + } if (!(ss_e2 & DESC_S_MASK) || (ss_e2 & DESC_CS_MASK) || - !(ss_e2 & DESC_W_MASK)) + !(ss_e2 & DESC_W_MASK)) { raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); - if (!(ss_e2 & DESC_P_MASK)) + } + if (!(ss_e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); + } new_stack = 1; sp_mask = get_sp_mask(ss_e2); ssp = get_seg_base(ss_e1, ss_e2); } else if ((e2 & DESC_C_MASK) || dpl == cpl) { /* to same privilege */ - if (env->eflags & VM_MASK) + if (env->eflags & VM_MASK) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); + } new_stack = 0; sp_mask = get_sp_mask(env->segs[R_SS].flags); ssp = env->segs[R_SS].base; - esp = ESP; + esp = env->regs[R_ESP]; dpl = cpl; } else { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); @@ -617,8 +689,9 @@ #if 0 /* XXX: check that enough room is available */ push_size = 6 + (new_stack << 2) + (has_error_code << 1); - if (env->eflags & VM_MASK) + if (env->eflags & VM_MASK) { push_size += 8; + } push_size <<= shift; #endif if (shift == 1) { @@ -630,7 +703,7 @@ PUSHL(ssp, esp, sp_mask, env->segs[R_ES].selector); } PUSHL(ssp, esp, sp_mask, env->segs[R_SS].selector); - PUSHL(ssp, esp, sp_mask, ESP); + PUSHL(ssp, esp, sp_mask, env->regs[R_ESP]); } PUSHL(ssp, esp, sp_mask, cpu_compute_eflags(env)); PUSHL(ssp, esp, sp_mask, env->segs[R_CS].selector); @@ -647,7 +720,7 @@ PUSHW(ssp, esp, sp_mask, env->segs[R_ES].selector); } PUSHW(ssp, esp, sp_mask, env->segs[R_SS].selector); - PUSHW(ssp, esp, sp_mask, ESP); + PUSHW(ssp, esp, sp_mask, env->regs[R_ESP]); } PUSHW(ssp, esp, sp_mask, cpu_compute_eflags(env)); PUSHW(ssp, esp, sp_mask, env->segs[R_CS].selector); @@ -708,18 +781,19 @@ env->tr.base, env->tr.limit); #endif - if (!(env->tr.flags & DESC_P_MASK)) + if (!(env->tr.flags & DESC_P_MASK)) { cpu_abort(env, "invalid tss"); + } index = 8 * level + 4; - if ((index + 7) > env->tr.limit) + if ((index + 7) > env->tr.limit) { raise_exception_err(env, EXCP0A_TSS, env->tr.selector & 0xfffc); + } return cpu_ldq_kernel(env, env->tr.base + index); } /* 64 bit interrupt */ -static void do_interrupt64(CPUX86State *env, - int intno, int is_int, int error_code, - target_ulong next_eip, int is_hw) +static void do_interrupt64(CPUX86State *env, int intno, int is_int, + int error_code, target_ulong next_eip, int is_hw) { SegmentCache *dt; target_ulong ptr; @@ -729,16 +803,19 @@ target_ulong old_eip, esp, offset; has_error_code = 0; - if (!is_int && !is_hw) - has_error_code = exeption_has_error_code(intno); - if (is_int) + if (!is_int && !is_hw) { + has_error_code = exception_has_error_code(intno); + } + if (is_int) { old_eip = next_eip; - else + } else { old_eip = env->eip; + } dt = &env->idt; - if (intno * 16 + 15 > dt->limit) + if (intno * 16 + 15 > dt->limit) { raise_exception_err(env, EXCP0D_GPF, intno * 16 + 2); + } ptr = dt->base + intno * 16; e1 = cpu_ldl_kernel(env, ptr); e2 = cpu_ldl_kernel(env, ptr + 4); @@ -756,46 +833,57 @@ dpl = (e2 >> DESC_DPL_SHIFT) & 3; cpl = env->hflags & HF_CPL_MASK; /* check privilege if software int */ - if (is_int && dpl < cpl) + if (is_int && dpl < cpl) { raise_exception_err(env, EXCP0D_GPF, intno * 16 + 2); + } /* check valid bit */ - if (!(e2 & DESC_P_MASK)) + if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, intno * 16 + 2); + } selector = e1 >> 16; offset = ((target_ulong)e3 << 32) | (e2 & 0xffff0000) | (e1 & 0x0000ffff); ist = e2 & 7; - if ((selector & 0xfffc) == 0) + if ((selector & 0xfffc) == 0) { raise_exception_err(env, EXCP0D_GPF, 0); + } - if (load_segment(env, &e1, &e2, selector) != 0) + if (load_segment(env, &e1, &e2, selector) != 0) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); - if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) + } + if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); + } dpl = (e2 >> DESC_DPL_SHIFT) & 3; - if (dpl > cpl) + if (dpl > cpl) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); - if (!(e2 & DESC_P_MASK)) + } + if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc); - if (!(e2 & DESC_L_MASK) || (e2 & DESC_B_MASK)) + } + if (!(e2 & DESC_L_MASK) || (e2 & DESC_B_MASK)) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); + } if ((!(e2 & DESC_C_MASK) && dpl < cpl) || ist != 0) { /* to inner privilege */ - if (ist != 0) + if (ist != 0) { esp = get_rsp_from_tss(env, ist + 3); - else + } else { esp = get_rsp_from_tss(env, dpl); + } esp &= ~0xfLL; /* align stack */ ss = 0; new_stack = 1; } else if ((e2 & DESC_C_MASK) || dpl == cpl) { /* to same privilege */ - if (env->eflags & VM_MASK) + if (env->eflags & VM_MASK) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); + } new_stack = 0; - if (ist != 0) + if (ist != 0) { esp = get_rsp_from_tss(env, ist + 3); - else - esp = ESP; + } else { + esp = env->regs[R_ESP]; + } esp &= ~0xfLL; /* align stack */ dpl = cpl; } else { @@ -805,7 +893,7 @@ } PUSHQ(esp, env->segs[R_SS].selector); - PUSHQ(esp, ESP); + PUSHQ(esp, env->regs[R_ESP]); PUSHQ(esp, cpu_compute_eflags(env)); PUSHQ(esp, env->segs[R_CS].selector); PUSHQ(esp, old_eip); @@ -817,7 +905,7 @@ ss = 0 | dpl; cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0); } - ESP = esp; + env->regs[R_ESP] = esp; selector = (selector & ~3) | dpl; cpu_x86_load_seg_cache(env, R_CS, selector, @@ -855,7 +943,7 @@ if (env->hflags & HF_LMA_MASK) { int code64; - ECX = env->eip + next_eip_addend; + env->regs[R_ECX] = env->eip + next_eip_addend; env->regs[11] = cpu_compute_eflags(env); code64 = env->hflags & HF_CS64_MASK; @@ -865,7 +953,8 @@ 0, 0xffffffff, DESC_G_MASK | DESC_P_MASK | DESC_S_MASK | - DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK); + DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | + DESC_L_MASK); cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc, 0, 0xffffffff, DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | @@ -873,12 +962,13 @@ DESC_W_MASK | DESC_A_MASK); env->eflags &= ~env->fmask; cpu_load_eflags(env, env->eflags, 0); - if (code64) + if (code64) { env->eip = env->lstar; - else + } else { env->eip = env->cstar; + } } else { - ECX = (uint32_t)(env->eip + next_eip_addend); + env->regs[R_ECX] = (uint32_t)(env->eip + next_eip_addend); cpu_x86_set_cpl(env, 0); cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc, @@ -919,22 +1009,23 @@ DESC_S_MASK | (3 << DESC_DPL_SHIFT) | DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK); - env->eip = ECX; + env->eip = env->regs[R_ECX]; } else { cpu_x86_load_seg_cache(env, R_CS, selector | 3, 0, 0xffffffff, DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | (3 << DESC_DPL_SHIFT) | DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK); - env->eip = (uint32_t)ECX; + env->eip = (uint32_t)env->regs[R_ECX]; } cpu_x86_load_seg_cache(env, R_SS, selector + 8, 0, 0xffffffff, DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | (3 << DESC_DPL_SHIFT) | DESC_W_MASK | DESC_A_MASK); - cpu_load_eflags(env, (uint32_t)(env->regs[11]), TF_MASK | AC_MASK | ID_MASK | - IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK); + cpu_load_eflags(env, (uint32_t)(env->regs[11]), TF_MASK | AC_MASK + | ID_MASK | IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | + NT_MASK); cpu_x86_set_cpl(env, 3); } else { cpu_x86_load_seg_cache(env, R_CS, selector | 3, @@ -942,7 +1033,7 @@ DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | (3 << DESC_DPL_SHIFT) | DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK); - env->eip = (uint32_t)ECX; + env->eip = (uint32_t)env->regs[R_ECX]; cpu_x86_load_seg_cache(env, R_SS, selector + 8, 0, 0xffffffff, DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | @@ -955,9 +1046,8 @@ #endif /* real mode interrupt */ -static void do_interrupt_real(CPUX86State *env, - int intno, int is_int, int error_code, - unsigned int next_eip) +static void do_interrupt_real(CPUX86State *env, int intno, int is_int, + int error_code, unsigned int next_eip) { SegmentCache *dt; target_ulong ptr, ssp; @@ -967,17 +1057,19 @@ /* real mode (simpler !) */ dt = &env->idt; - if (intno * 4 + 3 > dt->limit) + if (intno * 4 + 3 > dt->limit) { raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); + } ptr = dt->base + intno * 4; offset = cpu_lduw_kernel(env, ptr); selector = cpu_lduw_kernel(env, ptr + 2); - esp = ESP; + esp = env->regs[R_ESP]; ssp = env->segs[R_SS].base; - if (is_int) + if (is_int) { old_eip = next_eip; - else + } else { old_eip = env->eip; + } old_cs = env->segs[R_CS].selector; /* XXX: use SS segment size ? */ PUSHW(ssp, esp, 0xffff, cpu_compute_eflags(env)); @@ -985,7 +1077,7 @@ PUSHW(ssp, esp, 0xffff, old_eip); /* update processor state */ - ESP = (ESP & ~0xffff) | (esp & 0xffff); + env->regs[R_ESP] = (env->regs[R_ESP] & ~0xffff) | (esp & 0xffff); env->eip = offset; env->segs[R_CS].selector = selector; env->segs[R_CS].base = (selector << 4); @@ -994,9 +1086,8 @@ #if defined(CONFIG_USER_ONLY) /* fake user mode interrupt */ -static void do_interrupt_user(CPUX86State *env, - int intno, int is_int, int error_code, - target_ulong next_eip) +static void do_interrupt_user(CPUX86State *env, int intno, int is_int, + int error_code, target_ulong next_eip) { SegmentCache *dt; target_ulong ptr; @@ -1015,68 +1106,73 @@ dpl = (e2 >> DESC_DPL_SHIFT) & 3; cpl = env->hflags & HF_CPL_MASK; /* check privilege if software int */ - if (is_int && dpl < cpl) + if (is_int && dpl < cpl) { raise_exception_err(env, EXCP0D_GPF, (intno << shift) + 2); + } /* Since we emulate only user space, we cannot do more than exiting the emulation with the suitable exception and error code */ - if (is_int) - EIP = next_eip; + if (is_int) { + env->eip = next_eip; + } } #else -static void handle_even_inj(CPUX86State *env, - int intno, int is_int, int error_code, - int is_hw, int rm) +static void handle_even_inj(CPUX86State *env, int intno, int is_int, + int error_code, int is_hw, int rm) { uint32_t event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj)); if (!(event_inj & SVM_EVTINJ_VALID)) { int type; - if (is_int) + if (is_int) { type = SVM_EVTINJ_TYPE_SOFT; - else + } else { type = SVM_EVTINJ_TYPE_EXEPT; + } event_inj = intno | type | SVM_EVTINJ_VALID; - if (!rm && exeption_has_error_code(intno)) { + if (!rm && exception_has_error_code(intno)) { event_inj |= SVM_EVTINJ_VALID_ERR; - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj_err), error_code); + stl_phys(env->vm_vmcb + offsetof(struct vmcb, + control.event_inj_err), + error_code); } - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), event_inj); + stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), + event_inj); } } #endif /* * Begin execution of an interruption. is_int is TRUE if coming from - * the int instruction. next_eip is the EIP value AFTER the interrupt + * the int instruction. next_eip is the env->eip value AFTER the interrupt * instruction. It is only relevant if is_int is TRUE. */ -static void do_interrupt_all(CPUX86State *env, - int intno, int is_int, int error_code, - target_ulong next_eip, int is_hw) +static void do_interrupt_all(CPUX86State *env, int intno, int is_int, + int error_code, target_ulong next_eip, int is_hw) { if (qemu_loglevel_mask(CPU_LOG_INT)) { if ((env->cr[0] & CR0_PE_MASK)) { static int count; - qemu_log("%6d: v=%02x e=%04x i=%d cpl=%d IP=%04x:" TARGET_FMT_lx " pc=" TARGET_FMT_lx " SP=%04x:" TARGET_FMT_lx, + qemu_log("%6d: v=%02x e=%04x i=%d cpl=%d IP=%04x:" TARGET_FMT_lx + " pc=" TARGET_FMT_lx " SP=%04x:" TARGET_FMT_lx, count, intno, error_code, is_int, env->hflags & HF_CPL_MASK, - env->segs[R_CS].selector, EIP, - (int)env->segs[R_CS].base + EIP, - env->segs[R_SS].selector, ESP); + env->segs[R_CS].selector, env->eip, + (int)env->segs[R_CS].base + env->eip, + env->segs[R_SS].selector, env->regs[R_ESP]); if (intno == 0x0e) { qemu_log(" CR2=" TARGET_FMT_lx, env->cr[2]); } else { - qemu_log(" EAX=" TARGET_FMT_lx, EAX); + qemu_log(" EAX=" TARGET_FMT_lx, env->regs[R_EAX]); } qemu_log("\n"); log_cpu_state(ENV_GET_CPU(env), X86_DUMP_CCOP); #if 0 { int i; - uint8_t *ptr; + target_ulong ptr; qemu_log(" code="); ptr = env->segs[R_CS].base + env->eip; for(i = 0; i < 16; i++) { @@ -1090,8 +1186,9 @@ } if (env->cr[0] & CR0_PE_MASK) { #if !defined(CONFIG_USER_ONLY) - if (env->hflags & HF_SVMI_MASK) + if (env->hflags & HF_SVMI_MASK) { handle_even_inj(env, intno, is_int, error_code, is_hw, 0); + } #endif #ifdef TARGET_X86_64 if (env->hflags & HF_LMA_MASK) { @@ -1099,12 +1196,14 @@ } else #endif { - do_interrupt_protected(env, intno, is_int, error_code, next_eip, is_hw); + do_interrupt_protected(env, intno, is_int, error_code, next_eip, + is_hw); } } else { #if !defined(CONFIG_USER_ONLY) - if (env->hflags & HF_SVMI_MASK) + if (env->hflags & HF_SVMI_MASK) { handle_even_inj(env, intno, is_int, error_code, is_hw, 1); + } #endif do_interrupt_real(env, intno, is_int, error_code, next_eip); } @@ -1152,16 +1251,16 @@ /* This should come from sysemu.h - if we could include it here... */ void qemu_system_reset_request(void); -void helper_enter_level(CPUX86State *env, - int level, int data32, target_ulong t1) +void helper_enter_level(CPUX86State *env, int level, int data32, + target_ulong t1) { target_ulong ssp; uint32_t esp_mask, esp, ebp; esp_mask = get_sp_mask(env->segs[R_SS].flags); ssp = env->segs[R_SS].base; - ebp = EBP; - esp = ESP; + ebp = env->regs[R_EBP]; + esp = env->regs[R_ESP]; if (data32) { /* 32 bit */ esp -= 4; @@ -1188,12 +1287,12 @@ } #ifdef TARGET_X86_64 -void helper_enter64_level(CPUX86State *env, - int level, int data64, target_ulong t1) +void helper_enter64_level(CPUX86State *env, int level, int data64, + target_ulong t1) { target_ulong esp, ebp; - ebp = EBP; - esp = ESP; + ebp = env->regs[R_EBP]; + esp = env->regs[R_ESP]; if (data64) { /* 64 bit */ @@ -1232,25 +1331,31 @@ env->ldt.base = 0; env->ldt.limit = 0; } else { - if (selector & 0x4) + if (selector & 0x4) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); + } dt = &env->gdt; index = selector & ~7; #ifdef TARGET_X86_64 - if (env->hflags & HF_LMA_MASK) + if (env->hflags & HF_LMA_MASK) { entry_limit = 15; - else + } else #endif + { entry_limit = 7; - if ((index + entry_limit) > dt->limit) + } + if ((index + entry_limit) > dt->limit) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); + } ptr = dt->base + index; e1 = cpu_ldl_kernel(env, ptr); e2 = cpu_ldl_kernel(env, ptr + 4); - if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2) + if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); - if (!(e2 & DESC_P_MASK)) + } + if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc); + } #ifdef TARGET_X86_64 if (env->hflags & HF_LMA_MASK) { uint32_t e3; @@ -1280,34 +1385,41 @@ env->tr.limit = 0; env->tr.flags = 0; } else { - if (selector & 0x4) + if (selector & 0x4) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); + } dt = &env->gdt; index = selector & ~7; #ifdef TARGET_X86_64 - if (env->hflags & HF_LMA_MASK) + if (env->hflags & HF_LMA_MASK) { entry_limit = 15; - else + } else #endif + { entry_limit = 7; - if ((index + entry_limit) > dt->limit) + } + if ((index + entry_limit) > dt->limit) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); + } ptr = dt->base + index; e1 = cpu_ldl_kernel(env, ptr); e2 = cpu_ldl_kernel(env, ptr + 4); type = (e2 >> DESC_TYPE_SHIFT) & 0xf; if ((e2 & DESC_S_MASK) || - (type != 1 && type != 9)) + (type != 1 && type != 9)) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); - if (!(e2 & DESC_P_MASK)) + } + if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc); + } #ifdef TARGET_X86_64 if (env->hflags & HF_LMA_MASK) { uint32_t e3, e4; e3 = cpu_ldl_kernel(env, ptr + 8); e4 = cpu_ldl_kernel(env, ptr + 12); - if ((e4 >> DESC_TYPE_SHIFT) & 0xf) + if ((e4 >> DESC_TYPE_SHIFT) & 0xf) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); + } load_seg_cache_raw_dt(&env->tr, e1, e2); env->tr.base |= (target_ulong)e3 << 32; } else @@ -1338,49 +1450,58 @@ #ifdef TARGET_X86_64 && (!(env->hflags & HF_CS64_MASK) || cpl == 3) #endif - ) + ) { raise_exception_err(env, EXCP0D_GPF, 0); + } cpu_x86_load_seg_cache(env, seg_reg, selector, 0, 0, 0); } else { - if (selector & 0x4) + if (selector & 0x4) { dt = &env->ldt; - else + } else { dt = &env->gdt; + } index = selector & ~7; - if ((index + 7) > dt->limit) + if ((index + 7) > dt->limit) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); + } ptr = dt->base + index; e1 = cpu_ldl_kernel(env, ptr); e2 = cpu_ldl_kernel(env, ptr + 4); - if (!(e2 & DESC_S_MASK)) + if (!(e2 & DESC_S_MASK)) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); + } rpl = selector & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3; if (seg_reg == R_SS) { /* must be writable segment */ - if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK)) + if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK)) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); - if (rpl != cpl || dpl != cpl) + } + if (rpl != cpl || dpl != cpl) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); + } } else { /* must be readable segment */ - if ((e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK) + if ((e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); + } if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) { /* if not conforming code, test rights */ - if (dpl < cpl || dpl < rpl) + if (dpl < cpl || dpl < rpl) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); + } } } if (!(e2 & DESC_P_MASK)) { - if (seg_reg == R_SS) + if (seg_reg == R_SS) { raise_exception_err(env, EXCP0C_STACK, selector & 0xfffc); - else + } else { raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc); + } } /* set the access bit if not already set */ @@ -1401,44 +1522,51 @@ } /* protected mode jump */ -void helper_ljmp_protected(CPUX86State *env, - int new_cs, target_ulong new_eip, +void helper_ljmp_protected(CPUX86State *env, int new_cs, target_ulong new_eip, int next_eip_addend) { int gate_cs, type; uint32_t e1, e2, cpl, dpl, rpl, limit; target_ulong next_eip; - if ((new_cs & 0xfffc) == 0) + if ((new_cs & 0xfffc) == 0) { raise_exception_err(env, EXCP0D_GPF, 0); - if (load_segment(env, &e1, &e2, new_cs) != 0) + } + if (load_segment(env, &e1, &e2, new_cs) != 0) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); + } cpl = env->hflags & HF_CPL_MASK; if (e2 & DESC_S_MASK) { - if (!(e2 & DESC_CS_MASK)) + if (!(e2 & DESC_CS_MASK)) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); + } dpl = (e2 >> DESC_DPL_SHIFT) & 3; if (e2 & DESC_C_MASK) { /* conforming code segment */ - if (dpl > cpl) + if (dpl > cpl) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); + } } else { /* non conforming code segment */ rpl = new_cs & 3; - if (rpl > cpl) + if (rpl > cpl) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); - if (dpl != cpl) + } + if (dpl != cpl) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); } - if (!(e2 & DESC_P_MASK)) + } + if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, new_cs & 0xfffc); + } limit = get_seg_limit(e1, e2); if (new_eip > limit && - !(env->hflags & HF_LMA_MASK) && !(e2 & DESC_L_MASK)) + !(env->hflags & HF_LMA_MASK) && !(e2 & DESC_L_MASK)) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); + } cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl, get_seg_base(e1, e2), limit, e2); - EIP = new_eip; + env->eip = new_eip; } else { /* jump to call or task gate */ dpl = (e2 >> DESC_DPL_SHIFT) & 3; @@ -1449,40 +1577,49 @@ case 1: /* 286 TSS */ case 9: /* 386 TSS */ case 5: /* task gate */ - if (dpl < cpl || dpl < rpl) + if (dpl < cpl || dpl < rpl) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); + } next_eip = env->eip + next_eip_addend; switch_tss(env, new_cs, e1, e2, SWITCH_TSS_JMP, next_eip); CC_OP = CC_OP_EFLAGS; break; case 4: /* 286 call gate */ case 12: /* 386 call gate */ - if ((dpl < cpl) || (dpl < rpl)) + if ((dpl < cpl) || (dpl < rpl)) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); - if (!(e2 & DESC_P_MASK)) + } + if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, new_cs & 0xfffc); + } gate_cs = e1 >> 16; new_eip = (e1 & 0xffff); - if (type == 12) + if (type == 12) { new_eip |= (e2 & 0xffff0000); - if (load_segment(env, &e1, &e2, gate_cs) != 0) + } + if (load_segment(env, &e1, &e2, gate_cs) != 0) { raise_exception_err(env, EXCP0D_GPF, gate_cs & 0xfffc); + } dpl = (e2 >> DESC_DPL_SHIFT) & 3; /* must be code segment */ if (((e2 & (DESC_S_MASK | DESC_CS_MASK)) != - (DESC_S_MASK | DESC_CS_MASK))) + (DESC_S_MASK | DESC_CS_MASK))) { raise_exception_err(env, EXCP0D_GPF, gate_cs & 0xfffc); + } if (((e2 & DESC_C_MASK) && (dpl > cpl)) || - (!(e2 & DESC_C_MASK) && (dpl != cpl))) + (!(e2 & DESC_C_MASK) && (dpl != cpl))) { raise_exception_err(env, EXCP0D_GPF, gate_cs & 0xfffc); - if (!(e2 & DESC_P_MASK)) + } + if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0D_GPF, gate_cs & 0xfffc); + } limit = get_seg_limit(e1, e2); - if (new_eip > limit) + if (new_eip > limit) { raise_exception_err(env, EXCP0D_GPF, 0); + } cpu_x86_load_seg_cache(env, R_CS, (gate_cs & 0xfffc) | cpl, get_seg_base(e1, e2), limit, e2); - EIP = new_eip; + env->eip = new_eip; break; default: raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); @@ -1492,8 +1629,7 @@ } /* real mode call */ -void helper_lcall_real(CPUX86State *env, - int new_cs, target_ulong new_eip1, +void helper_lcall_real(CPUX86State *env, int new_cs, target_ulong new_eip1, int shift, int next_eip) { int new_eip; @@ -1501,7 +1637,7 @@ target_ulong ssp; new_eip = new_eip1; - esp = ESP; + esp = env->regs[R_ESP]; esp_mask = get_sp_mask(env->segs[R_SS].flags); ssp = env->segs[R_SS].base; if (shift) { @@ -1519,8 +1655,7 @@ } /* protected mode call */ -void helper_lcall_protected(CPUX86State *env, - int new_cs, target_ulong new_eip, +void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip, int shift, int next_eip_addend) { int new_stack, i; @@ -1532,49 +1667,56 @@ next_eip = env->eip + next_eip_addend; LOG_PCALL("lcall %04x:%08x s=%d\n", new_cs, (uint32_t)new_eip, shift); LOG_PCALL_STATE(env); - if ((new_cs & 0xfffc) == 0) + if ((new_cs & 0xfffc) == 0) { raise_exception_err(env, EXCP0D_GPF, 0); - if (load_segment(env, &e1, &e2, new_cs) != 0) + } + if (load_segment(env, &e1, &e2, new_cs) != 0) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); + } cpl = env->hflags & HF_CPL_MASK; LOG_PCALL("desc=%08x:%08x\n", e1, e2); if (e2 & DESC_S_MASK) { - if (!(e2 & DESC_CS_MASK)) + if (!(e2 & DESC_CS_MASK)) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); + } dpl = (e2 >> DESC_DPL_SHIFT) & 3; if (e2 & DESC_C_MASK) { /* conforming code segment */ - if (dpl > cpl) + if (dpl > cpl) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); + } } else { /* non conforming code segment */ rpl = new_cs & 3; - if (rpl > cpl) + if (rpl > cpl) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); - if (dpl != cpl) + } + if (dpl != cpl) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); } - if (!(e2 & DESC_P_MASK)) + } + if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, new_cs & 0xfffc); + } #ifdef TARGET_X86_64 /* XXX: check 16/32 bit cases in long mode */ if (shift == 2) { target_ulong rsp; /* 64 bit case */ - rsp = ESP; + rsp = env->regs[R_ESP]; PUSHQ(rsp, env->segs[R_CS].selector); PUSHQ(rsp, next_eip); /* from this point, not restartable */ - ESP = rsp; + env->regs[R_ESP] = rsp; cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl, get_seg_base(e1, e2), get_seg_limit(e1, e2), e2); - EIP = new_eip; + env->eip = new_eip; } else #endif { - sp = ESP; + sp = env->regs[R_ESP]; sp_mask = get_sp_mask(env->segs[R_SS].flags); ssp = env->segs[R_SS].base; if (shift) { @@ -1586,13 +1728,14 @@ } limit = get_seg_limit(e1, e2); - if (new_eip > limit) + if (new_eip > limit) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); + } /* from this point, not restartable */ SET_ESP(sp, sp_mask); cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl, get_seg_base(e1, e2), limit, e2); - EIP = new_eip; + env->eip = new_eip; } } else { /* check gate type */ @@ -1603,8 +1746,9 @@ case 1: /* available 286 TSS */ case 9: /* available 386 TSS */ case 5: /* task gate */ - if (dpl < cpl || dpl < rpl) + if (dpl < cpl || dpl < rpl) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); + } switch_tss(env, new_cs, e1, e2, SWITCH_TSS_CALL, next_eip); CC_OP = CC_OP_EFLAGS; return; @@ -1617,49 +1761,63 @@ } shift = type >> 3; - if (dpl < cpl || dpl < rpl) + if (dpl < cpl || dpl < rpl) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); + } /* check valid bit */ - if (!(e2 & DESC_P_MASK)) + if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, new_cs & 0xfffc); + } selector = e1 >> 16; offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff); param_count = e2 & 0x1f; - if ((selector & 0xfffc) == 0) + if ((selector & 0xfffc) == 0) { raise_exception_err(env, EXCP0D_GPF, 0); + } - if (load_segment(env, &e1, &e2, selector) != 0) + if (load_segment(env, &e1, &e2, selector) != 0) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); - if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) + } + if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); + } dpl = (e2 >> DESC_DPL_SHIFT) & 3; - if (dpl > cpl) + if (dpl > cpl) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); - if (!(e2 & DESC_P_MASK)) + } + if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc); + } if (!(e2 & DESC_C_MASK) && dpl < cpl) { /* to inner privilege */ get_ss_esp_from_tss(env, &ss, &sp, dpl); - LOG_PCALL("new ss:esp=%04x:%08x param_count=%d ESP=" TARGET_FMT_lx "\n", - ss, sp, param_count, ESP); - if ((ss & 0xfffc) == 0) + LOG_PCALL("new ss:esp=%04x:%08x param_count=%d ESP=" + TARGET_FMT_lx "\n", ss, sp, param_count, + env->regs[R_ESP]); + if ((ss & 0xfffc) == 0) { raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); - if ((ss & 3) != dpl) + } + if ((ss & 3) != dpl) { raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); - if (load_segment(env, &ss_e1, &ss_e2, ss) != 0) + } + if (load_segment(env, &ss_e1, &ss_e2, ss) != 0) { raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); + } ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3; - if (ss_dpl != dpl) + if (ss_dpl != dpl) { raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); + } if (!(ss_e2 & DESC_S_MASK) || (ss_e2 & DESC_CS_MASK) || - !(ss_e2 & DESC_W_MASK)) + !(ss_e2 & DESC_W_MASK)) { raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); - if (!(ss_e2 & DESC_P_MASK)) + } + if (!(ss_e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); + } - // push_size = ((param_count * 2) + 8) << shift; + /* push_size = ((param_count * 2) + 8) << shift; */ old_sp_mask = get_sp_mask(env->segs[R_SS].flags); old_ssp = env->segs[R_SS].base; @@ -1668,26 +1826,30 @@ ssp = get_seg_base(ss_e1, ss_e2); if (shift) { PUSHL(ssp, sp, sp_mask, env->segs[R_SS].selector); - PUSHL(ssp, sp, sp_mask, ESP); + PUSHL(ssp, sp, sp_mask, env->regs[R_ESP]); for(i = param_count - 1; i >= 0; i--) { - val = cpu_ldl_kernel(env, old_ssp + ((ESP + i * 4) & old_sp_mask)); + val = cpu_ldl_kernel(env, old_ssp + + ((env->regs[R_ESP] + i * 4) & + old_sp_mask)); PUSHL(ssp, sp, sp_mask, val); } } else { PUSHW(ssp, sp, sp_mask, env->segs[R_SS].selector); - PUSHW(ssp, sp, sp_mask, ESP); + PUSHW(ssp, sp, sp_mask, env->regs[R_ESP]); for(i = param_count - 1; i >= 0; i--) { - val = cpu_lduw_kernel(env, old_ssp + ((ESP + i * 2) & old_sp_mask)); + val = cpu_lduw_kernel(env, old_ssp + + ((env->regs[R_ESP] + i * 2) & + old_sp_mask)); PUSHW(ssp, sp, sp_mask, val); } } new_stack = 1; } else { /* to same privilege */ - sp = ESP; + sp = env->regs[R_ESP]; sp_mask = get_sp_mask(env->segs[R_SS].flags); ssp = env->segs[R_SS].base; - // push_size = (4 << shift); + /* push_size = (4 << shift); */ new_stack = 0; } @@ -1716,7 +1878,7 @@ e2); cpu_x86_set_cpl(env, dpl); SET_ESP(sp, sp_mask); - EIP = offset; + env->eip = offset; } } @@ -1728,7 +1890,7 @@ int eflags_mask; sp_mask = 0xffff; /* XXXX: use SS segment size ? */ - sp = ESP; + sp = env->regs[R_ESP]; ssp = env->segs[R_SS].base; if (shift == 1) { /* 32 bits */ @@ -1742,16 +1904,20 @@ POPW(ssp, sp, sp_mask, new_cs); POPW(ssp, sp, sp_mask, new_eflags); } - ESP = (ESP & ~sp_mask) | (sp & sp_mask); + env->regs[R_ESP] = (env->regs[R_ESP] & ~sp_mask) | (sp & sp_mask); env->segs[R_CS].selector = new_cs; env->segs[R_CS].base = (new_cs << 4); env->eip = new_eip; - if (env->eflags & VM_MASK) - eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | RF_MASK | NT_MASK; - else - eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | IOPL_MASK | RF_MASK | NT_MASK; - if (shift == 0) + if (env->eflags & VM_MASK) { + eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | RF_MASK | + NT_MASK; + } else { + eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | IOPL_MASK | + RF_MASK | NT_MASK; + } + if (shift == 0) { eflags_mask &= 0xffff; + } cpu_load_eflags(env, new_eflags, eflags_mask); env->hflags2 &= ~HF2_NMI_MASK; } @@ -1765,8 +1931,9 @@ they may still contain a valid base. I would be interested to know how a real x86_64 CPU behaves */ if ((seg_reg == R_FS || seg_reg == R_GS) && - (env->segs[seg_reg].selector & 0xfffc) == 0) + (env->segs[seg_reg].selector & 0xfffc) == 0) { return; + } e2 = env->segs[seg_reg].flags; dpl = (e2 >> DESC_DPL_SHIFT) & 3; @@ -1779,8 +1946,8 @@ } /* protected mode iret */ -static inline void helper_ret_protected(CPUX86State *env, - int shift, int is_iret, int addend) +static inline void helper_ret_protected(CPUX86State *env, int shift, + int is_iret, int addend) { uint32_t new_cs, new_eflags, new_ss; uint32_t new_es, new_ds, new_fs, new_gs; @@ -1789,12 +1956,14 @@ target_ulong ssp, sp, new_eip, new_esp, sp_mask; #ifdef TARGET_X86_64 - if (shift == 2) + if (shift == 2) { sp_mask = -1; - else + } else #endif + { sp_mask = get_sp_mask(env->segs[R_SS].flags); - sp = ESP; + } + sp = env->regs[R_ESP]; ssp = env->segs[R_SS].base; new_eflags = 0; /* avoid warning */ #ifdef TARGET_X86_64 @@ -1807,6 +1976,7 @@ } } else #endif + { if (shift == 1) { /* 32 bits */ POPL(ssp, sp, sp_mask, new_eip); @@ -1814,40 +1984,50 @@ new_cs &= 0xffff; if (is_iret) { POPL(ssp, sp, sp_mask, new_eflags); - if (new_eflags & VM_MASK) + if (new_eflags & VM_MASK) { goto return_to_vm86; + } } } else { /* 16 bits */ POPW(ssp, sp, sp_mask, new_eip); POPW(ssp, sp, sp_mask, new_cs); - if (is_iret) + if (is_iret) { POPW(ssp, sp, sp_mask, new_eflags); + } + } } LOG_PCALL("lret new %04x:" TARGET_FMT_lx " s=%d addend=0x%x\n", new_cs, new_eip, shift, addend); LOG_PCALL_STATE(env); - if ((new_cs & 0xfffc) == 0) + if ((new_cs & 0xfffc) == 0) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); - if (load_segment(env, &e1, &e2, new_cs) != 0) + } + if (load_segment(env, &e1, &e2, new_cs) != 0) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); + } if (!(e2 & DESC_S_MASK) || - !(e2 & DESC_CS_MASK)) + !(e2 & DESC_CS_MASK)) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); + } cpl = env->hflags & HF_CPL_MASK; rpl = new_cs & 3; - if (rpl < cpl) + if (rpl < cpl) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); + } dpl = (e2 >> DESC_DPL_SHIFT) & 3; if (e2 & DESC_C_MASK) { - if (dpl > rpl) + if (dpl > rpl) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); + } } else { - if (dpl != rpl) + if (dpl != rpl) { raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc); } - if (!(e2 & DESC_P_MASK)) + } + if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, new_cs & 0xfffc); + } sp += addend; if (rpl == cpl && (!(env->hflags & HF_CS64_MASK) || @@ -1866,6 +2046,7 @@ new_ss &= 0xffff; } else #endif + { if (shift == 1) { /* 32 bits */ POPL(ssp, sp, sp_mask, new_esp); @@ -1876,6 +2057,7 @@ POPW(ssp, sp, sp_mask, new_esp); POPW(ssp, sp, sp_mask, new_ss); } + } LOG_PCALL("new ss:esp=%04x:" TARGET_FMT_lx "\n", new_ss, new_esp); if ((new_ss & 0xfffc) == 0) { @@ -1895,19 +2077,24 @@ raise_exception_err(env, EXCP0D_GPF, 0); } } else { - if ((new_ss & 3) != rpl) + if ((new_ss & 3) != rpl) { raise_exception_err(env, EXCP0D_GPF, new_ss & 0xfffc); - if (load_segment(env, &ss_e1, &ss_e2, new_ss) != 0) + } + if (load_segment(env, &ss_e1, &ss_e2, new_ss) != 0) { raise_exception_err(env, EXCP0D_GPF, new_ss & 0xfffc); + } if (!(ss_e2 & DESC_S_MASK) || (ss_e2 & DESC_CS_MASK) || - !(ss_e2 & DESC_W_MASK)) + !(ss_e2 & DESC_W_MASK)) { raise_exception_err(env, EXCP0D_GPF, new_ss & 0xfffc); + } dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3; - if (dpl != rpl) + if (dpl != rpl) { raise_exception_err(env, EXCP0D_GPF, new_ss & 0xfffc); - if (!(ss_e2 & DESC_P_MASK)) + } + if (!(ss_e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, new_ss & 0xfffc); + } cpu_x86_load_seg_cache(env, R_SS, new_ss, get_seg_base(ss_e1, ss_e2), get_seg_limit(ss_e1, ss_e2), @@ -1921,11 +2108,13 @@ cpu_x86_set_cpl(env, rpl); sp = new_esp; #ifdef TARGET_X86_64 - if (env->hflags & HF_CS64_MASK) + if (env->hflags & HF_CS64_MASK) { sp_mask = -1; - else + } else #endif + { sp_mask = get_sp_mask(ss_e2); + } /* validate data segments */ validate_seg(env, R_ES, rpl); @@ -1940,13 +2129,16 @@ if (is_iret) { /* NOTE: 'cpl' is the _old_ CPL */ eflags_mask = TF_MASK | AC_MASK | ID_MASK | RF_MASK | NT_MASK; - if (cpl == 0) + if (cpl == 0) { eflags_mask |= IOPL_MASK; + } iopl = (env->eflags >> IOPL_SHIFT) & 3; - if (cpl <= iopl) + if (cpl <= iopl) { eflags_mask |= IF_MASK; - if (shift == 0) + } + if (shift == 0) { eflags_mask &= 0xffff; + } cpu_load_eflags(env, new_eflags, eflags_mask); } return; @@ -1961,7 +2153,8 @@ /* modify processor state */ cpu_load_eflags(env, new_eflags, TF_MASK | AC_MASK | ID_MASK | - IF_MASK | IOPL_MASK | VM_MASK | NT_MASK | VIF_MASK | VIP_MASK); + IF_MASK | IOPL_MASK | VM_MASK | NT_MASK | VIF_MASK | + VIP_MASK); load_seg_vm(env, R_CS, new_cs & 0xffff); cpu_x86_set_cpl(env, 3); load_seg_vm(env, R_SS, new_ss & 0xffff); @@ -1971,7 +2164,7 @@ load_seg_vm(env, R_GS, new_gs & 0xffff); env->eip = new_eip & 0xffff; - ESP = new_esp; + env->regs[R_ESP] = new_esp; } void helper_iret_protected(CPUX86State *env, int shift, int next_eip) @@ -1982,18 +2175,22 @@ /* specific case for TSS */ if (env->eflags & NT_MASK) { #ifdef TARGET_X86_64 - if (env->hflags & HF_LMA_MASK) + if (env->hflags & HF_LMA_MASK) { raise_exception_err(env, EXCP0D_GPF, 0); + } #endif tss_selector = cpu_lduw_kernel(env, env->tr.base + 0); - if (tss_selector & 4) + if (tss_selector & 4) { raise_exception_err(env, EXCP0A_TSS, tss_selector & 0xfffc); - if (load_segment(env, &e1, &e2, tss_selector) != 0) + } + if (load_segment(env, &e1, &e2, tss_selector) != 0) { raise_exception_err(env, EXCP0A_TSS, tss_selector & 0xfffc); + } type = (e2 >> DESC_TYPE_SHIFT) & 0x17; /* NOTE: we check both segment and busy TSS */ - if (type != 3) + if (type != 3) { raise_exception_err(env, EXCP0A_TSS, tss_selector & 0xfffc); + } switch_tss(env, tss_selector, e1, e2, SWITCH_TSS_IRET, next_eip); } else { helper_ret_protected(env, shift, 1, 0); @@ -2020,7 +2217,8 @@ 0, 0xffffffff, DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | - DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK); + DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | + DESC_L_MASK); } else #endif { @@ -2035,8 +2233,8 @@ DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | DESC_W_MASK | DESC_A_MASK); - ESP = env->sysenter_esp; - EIP = env->sysenter_eip; + env->regs[R_ESP] = env->sysenter_esp; + env->eip = env->sysenter_eip; } void helper_sysexit(CPUX86State *env, int dflag) @@ -2050,32 +2248,33 @@ cpu_x86_set_cpl(env, 3); #ifdef TARGET_X86_64 if (dflag == 2) { - cpu_x86_load_seg_cache(env, R_CS, ((env->sysenter_cs + 32) & 0xfffc) | 3, - 0, 0xffffffff, + cpu_x86_load_seg_cache(env, R_CS, ((env->sysenter_cs + 32) & 0xfffc) | + 3, 0, 0xffffffff, DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | (3 << DESC_DPL_SHIFT) | - DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK); - cpu_x86_load_seg_cache(env, R_SS, ((env->sysenter_cs + 40) & 0xfffc) | 3, - 0, 0xffffffff, + DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | + DESC_L_MASK); + cpu_x86_load_seg_cache(env, R_SS, ((env->sysenter_cs + 40) & 0xfffc) | + 3, 0, 0xffffffff, DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | (3 << DESC_DPL_SHIFT) | DESC_W_MASK | DESC_A_MASK); } else #endif { - cpu_x86_load_seg_cache(env, R_CS, ((env->sysenter_cs + 16) & 0xfffc) | 3, - 0, 0xffffffff, + cpu_x86_load_seg_cache(env, R_CS, ((env->sysenter_cs + 16) & 0xfffc) | + 3, 0, 0xffffffff, DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | (3 << DESC_DPL_SHIFT) | DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK); - cpu_x86_load_seg_cache(env, R_SS, ((env->sysenter_cs + 24) & 0xfffc) | 3, - 0, 0xffffffff, + cpu_x86_load_seg_cache(env, R_SS, ((env->sysenter_cs + 24) & 0xfffc) | + 3, 0, 0xffffffff, DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | (3 << DESC_DPL_SHIFT) | DESC_W_MASK | DESC_A_MASK); } - ESP = ECX; - EIP = EDX; + env->regs[R_ESP] = env->regs[R_ECX]; + env->eip = env->regs[R_EDX]; } target_ulong helper_lsl(CPUX86State *env, target_ulong selector1) @@ -2086,10 +2285,12 @@ selector = selector1 & 0xffff; eflags = helper_cc_compute_all(env, CC_OP); - if ((selector & 0xfffc) == 0) + if ((selector & 0xfffc) == 0) { goto fail; - if (load_segment(env, &e1, &e2, selector) != 0) + } + if (load_segment(env, &e1, &e2, selector) != 0) { goto fail; + } rpl = selector & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3; cpl = env->hflags & HF_CPL_MASK; @@ -2097,8 +2298,9 @@ if ((e2 & DESC_CS_MASK) && (e2 & DESC_C_MASK)) { /* conforming */ } else { - if (dpl < cpl || dpl < rpl) + if (dpl < cpl || dpl < rpl) { goto fail; + } } } else { type = (e2 >> DESC_TYPE_SHIFT) & 0xf; @@ -2130,10 +2332,12 @@ selector = selector1 & 0xffff; eflags = helper_cc_compute_all(env, CC_OP); - if ((selector & 0xfffc) == 0) + if ((selector & 0xfffc) == 0) { goto fail; - if (load_segment(env, &e1, &e2, selector) != 0) + } + if (load_segment(env, &e1, &e2, selector) != 0) { goto fail; + } rpl = selector & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3; cpl = env->hflags & HF_CPL_MASK; @@ -2141,8 +2345,9 @@ if ((e2 & DESC_CS_MASK) && (e2 & DESC_C_MASK)) { /* conforming */ } else { - if (dpl < cpl || dpl < rpl) + if (dpl < cpl || dpl < rpl) { goto fail; + } } } else { type = (e2 >> DESC_TYPE_SHIFT) & 0xf; @@ -2176,21 +2381,26 @@ selector = selector1 & 0xffff; eflags = helper_cc_compute_all(env, CC_OP); - if ((selector & 0xfffc) == 0) + if ((selector & 0xfffc) == 0) { goto fail; - if (load_segment(env, &e1, &e2, selector) != 0) + } + if (load_segment(env, &e1, &e2, selector) != 0) { goto fail; - if (!(e2 & DESC_S_MASK)) + } + if (!(e2 & DESC_S_MASK)) { goto fail; + } rpl = selector & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3; cpl = env->hflags & HF_CPL_MASK; if (e2 & DESC_CS_MASK) { - if (!(e2 & DESC_R_MASK)) + if (!(e2 & DESC_R_MASK)) { goto fail; + } if (!(e2 & DESC_C_MASK)) { - if (dpl < cpl || dpl < rpl) + if (dpl < cpl || dpl < rpl) { goto fail; + } } } else { if (dpl < cpl || dpl < rpl) { @@ -2209,20 +2419,24 @@ selector = selector1 & 0xffff; eflags = helper_cc_compute_all(env, CC_OP); - if ((selector & 0xfffc) == 0) + if ((selector & 0xfffc) == 0) { goto fail; - if (load_segment(env, &e1, &e2, selector) != 0) + } + if (load_segment(env, &e1, &e2, selector) != 0) { goto fail; - if (!(e2 & DESC_S_MASK)) + } + if (!(e2 & DESC_S_MASK)) { goto fail; + } rpl = selector & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3; cpl = env->hflags & HF_CPL_MASK; if (e2 & DESC_CS_MASK) { goto fail; } else { - if (dpl < cpl || dpl < rpl) + if (dpl < cpl || dpl < rpl) { goto fail; + } if (!(e2 & DESC_W_MASK)) { fail: CC_SRC = eflags & ~CC_Z;
diff --git a/target-i386/shift_helper_template.h b/target-i386/shift_helper_template.h index cd06ab1..81953cb 100644 --- a/target-i386/shift_helper_template.h +++ b/target-i386/shift_helper_template.h
@@ -1,5 +1,5 @@ /* - * i386 helpers + * x86 shift helpers * * Copyright (c) 2008 Fabrice Bellard * @@ -14,12 +14,10 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA + * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ #define DATA_BITS (1 << (3 + SHIFT)) #define SHIFT_MASK (DATA_BITS - 1) -#define SIGN_MASK (((target_ulong)1) << (DATA_BITS - 1)) #if DATA_BITS <= 32 #define SHIFT1_MASK 0x1f #else @@ -28,32 +26,22 @@ #if DATA_BITS == 8 #define SUFFIX b -#define DATA_TYPE uint8_t -#define DATA_STYPE int8_t #define DATA_MASK 0xff #elif DATA_BITS == 16 #define SUFFIX w -#define DATA_TYPE uint16_t -#define DATA_STYPE int16_t #define DATA_MASK 0xffff #elif DATA_BITS == 32 #define SUFFIX l -#define DATA_TYPE uint32_t -#define DATA_STYPE int32_t #define DATA_MASK 0xffffffff #elif DATA_BITS == 64 #define SUFFIX q -#define DATA_TYPE uint64_t -#define DATA_STYPE int64_t #define DATA_MASK 0xffffffffffffffffULL #else #error unhandled operand size #endif -/* shifts */ - -target_ulong glue(helper_rcl, SUFFIX)(CPUX86State *env, - target_ulong t0, target_ulong t1) +target_ulong glue(helper_rcl, SUFFIX)(CPUX86State *env, target_ulong t0, + target_ulong t1) { int count, eflags; target_ulong src; @@ -70,8 +58,9 @@ t0 &= DATA_MASK; src = t0; res = (t0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1)); - if (count > 1) + if (count > 1) { res |= t0 >> (DATA_BITS + 1 - count); + } t0 = res; env->cc_src = (eflags & ~(CC_C | CC_O)) | (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) | @@ -80,8 +69,8 @@ return t0; } -target_ulong glue(helper_rcr, SUFFIX)(CPUX86State *env, - target_ulong t0, target_ulong t1) +target_ulong glue(helper_rcr, SUFFIX)(CPUX86State *env, target_ulong t0, + target_ulong t1) { int count, eflags; target_ulong src; @@ -97,9 +86,11 @@ eflags = env->cc_src; t0 &= DATA_MASK; src = t0; - res = (t0 >> count) | ((target_ulong)(eflags & CC_C) << (DATA_BITS - count)); - if (count > 1) + res = (t0 >> count) | + ((target_ulong)(eflags & CC_C) << (DATA_BITS - count)); + if (count > 1) { res |= t0 << (DATA_BITS + 1 - count); + } t0 = res; env->cc_src = (eflags & ~(CC_C | CC_O)) | (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) | @@ -111,8 +102,6 @@ #undef DATA_BITS #undef SHIFT_MASK #undef SHIFT1_MASK -#undef SIGN_MASK #undef DATA_TYPE -#undef DATA_STYPE #undef DATA_MASK #undef SUFFIX
diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c index c432277..1cd64e2 100644 --- a/target-i386/smm_helper.c +++ b/target-i386/smm_helper.c
@@ -82,14 +82,14 @@ stq_phys(sm_state + 0x7ed0, env->efer); - stq_phys(sm_state + 0x7ff8, EAX); - stq_phys(sm_state + 0x7ff0, ECX); - stq_phys(sm_state + 0x7fe8, EDX); - stq_phys(sm_state + 0x7fe0, EBX); - stq_phys(sm_state + 0x7fd8, ESP); - stq_phys(sm_state + 0x7fd0, EBP); - stq_phys(sm_state + 0x7fc8, ESI); - stq_phys(sm_state + 0x7fc0, EDI); + stq_phys(sm_state + 0x7ff8, env->regs[R_EAX]); + stq_phys(sm_state + 0x7ff0, env->regs[R_ECX]); + stq_phys(sm_state + 0x7fe8, env->regs[R_EDX]); + stq_phys(sm_state + 0x7fe0, env->regs[R_EBX]); + stq_phys(sm_state + 0x7fd8, env->regs[R_ESP]); + stq_phys(sm_state + 0x7fd0, env->regs[R_EBP]); + stq_phys(sm_state + 0x7fc8, env->regs[R_ESI]); + stq_phys(sm_state + 0x7fc0, env->regs[R_EDI]); for(i = 8; i < 16; i++) stq_phys(sm_state + 0x7ff8 - i * 8, env->regs[i]); stq_phys(sm_state + 0x7f78, env->eip); @@ -108,13 +108,13 @@ stl_phys(sm_state + 0x7ff8, env->cr[3]); stl_phys(sm_state + 0x7ff4, cpu_compute_eflags(env)); stl_phys(sm_state + 0x7ff0, env->eip); - stl_phys(sm_state + 0x7fec, EDI); - stl_phys(sm_state + 0x7fe8, ESI); - stl_phys(sm_state + 0x7fe4, EBP); - stl_phys(sm_state + 0x7fe0, ESP); - stl_phys(sm_state + 0x7fdc, EBX); - stl_phys(sm_state + 0x7fd8, EDX); - stl_phys(sm_state + 0x7fd4, ECX); + stl_phys(sm_state + 0x7fec, env->regs[R_EDI]); + stl_phys(sm_state + 0x7fe8, env->regs[R_ESI]); + stl_phys(sm_state + 0x7fe4, env->regs[R_EBP]); + stl_phys(sm_state + 0x7fe0, env->regs[R_ESP]); + stl_phys(sm_state + 0x7fdc, env->regs[R_EBX]); + stl_phys(sm_state + 0x7fd8, env->regs[R_EDX]); + stl_phys(sm_state + 0x7fd4, env->regs[R_ECX]); stl_phys(sm_state + 0x7fd0, EAX); stl_phys(sm_state + 0x7fcc, env->dr[6]); stl_phys(sm_state + 0x7fc8, env->dr[7]); @@ -137,10 +137,11 @@ for(i = 0; i < 6; i++) { dt = &env->segs[i]; - if (i < 3) + if (i < 3) { offset = 0x7f84 + i * 12; - else + } else { offset = 0x7f2c + (i - 3) * 12; + } stl_phys(sm_state + 0x7fa8 + i * 4, dt->selector); stl_phys(sm_state + offset + 8, dt->base); stl_phys(sm_state + offset + 4, dt->limit); @@ -156,7 +157,8 @@ #ifdef TARGET_X86_64 cpu_load_efer(env, 0); #endif - cpu_load_eflags(env, 0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); + cpu_load_eflags(env, 0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | + DF_MASK)); env->eip = 0x00008000; cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase, 0xffffffff, 0); @@ -167,7 +169,8 @@ cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff, 0); cpu_x86_update_cr0(env, - env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK | CR0_PG_MASK)); + env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK | + CR0_PG_MASK)); cpu_x86_update_cr4(env, 0); env->dr[7] = 0x00000400; CC_OP = CC_OP_EFLAGS; @@ -189,7 +192,8 @@ lduw_phys(sm_state + offset), ldq_phys(sm_state + offset + 8), ldl_phys(sm_state + offset + 4), - (lduw_phys(sm_state + offset + 2) & 0xf0ff) << 8); + (lduw_phys(sm_state + offset + 2) & + 0xf0ff) << 8); } env->gdt.base = ldq_phys(sm_state + 0x7e68); @@ -208,14 +212,14 @@ env->tr.limit = ldl_phys(sm_state + 0x7e94); env->tr.flags = (lduw_phys(sm_state + 0x7e92) & 0xf0ff) << 8; - EAX = ldq_phys(sm_state + 0x7ff8); - ECX = ldq_phys(sm_state + 0x7ff0); - EDX = ldq_phys(sm_state + 0x7fe8); - EBX = ldq_phys(sm_state + 0x7fe0); - ESP = ldq_phys(sm_state + 0x7fd8); - EBP = ldq_phys(sm_state + 0x7fd0); - ESI = ldq_phys(sm_state + 0x7fc8); - EDI = ldq_phys(sm_state + 0x7fc0); + env->regs[R_EAX] = ldq_phys(sm_state + 0x7ff8); + env->regs[R_ECX] = ldq_phys(sm_state + 0x7ff0); + env->regs[R_EDX] = ldq_phys(sm_state + 0x7fe8); + env->regs[R_EBX] = ldq_phys(sm_state + 0x7fe0); + env->regs[R_ESP] = ldq_phys(sm_state + 0x7fd8); + env->regs[R_EBP] = ldq_phys(sm_state + 0x7fd0); + env->regs[R_ESI] = ldq_phys(sm_state + 0x7fc8); + env->regs[R_EDI] = ldq_phys(sm_state + 0x7fc0); for(i = 8; i < 16; i++) env->regs[i] = ldq_phys(sm_state + 0x7ff8 - i * 8); env->eip = ldq_phys(sm_state + 0x7f78); @@ -238,13 +242,13 @@ cpu_load_eflags(env, ldl_phys(sm_state + 0x7ff4), ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); env->eip = ldl_phys(sm_state + 0x7ff0); - EDI = ldl_phys(sm_state + 0x7fec); - ESI = ldl_phys(sm_state + 0x7fe8); - EBP = ldl_phys(sm_state + 0x7fe4); - ESP = ldl_phys(sm_state + 0x7fe0); - EBX = ldl_phys(sm_state + 0x7fdc); - EDX = ldl_phys(sm_state + 0x7fd8); - ECX = ldl_phys(sm_state + 0x7fd4); + env->regs[R_EDI] = ldl_phys(sm_state + 0x7fec); + env->regs[R_ESI] = ldl_phys(sm_state + 0x7fe8); + env->regs[R_EBP] = ldl_phys(sm_state + 0x7fe4); + env->regs[R_ESP] = ldl_phys(sm_state + 0x7fe0); + env->regs[R_EBX] = ldl_phys(sm_state + 0x7fdc); + env->regs[R_EDX] = ldl_phys(sm_state + 0x7fd8); + env->regs[R_ECX] = ldl_phys(sm_state + 0x7fd4); EAX = ldl_phys(sm_state + 0x7fd0); env->dr[6] = ldl_phys(sm_state + 0x7fcc); env->dr[7] = ldl_phys(sm_state + 0x7fc8); @@ -266,10 +270,11 @@ env->idt.limit = ldl_phys(sm_state + 0x7f54); for(i = 0; i < 6; i++) { - if (i < 3) + if (i < 3) { offset = 0x7f84 + i * 12; - else + } else { offset = 0x7f2c + (i - 3) * 12; + } cpu_x86_load_seg_cache(env, i, ldl_phys(sm_state + 0x7fa8 + i * 4) & 0xffff, ldl_phys(sm_state + offset + 8),
diff --git a/target-i386/svm_helper.c b/target-i386/svm_helper.c index e3b2501..5b2a83b 100644 --- a/target-i386/svm_helper.c +++ b/target-i386/svm_helper.c
@@ -53,8 +53,7 @@ void helper_invlpga(CPUX86State *env, int aflag) { } -void helper_vmexit(CPUX86State *env, - uint32_t exit_code, uint64_t exit_info_1) +void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1) { } void helper_svm_check_intercept_param(CPUX86State *env, @@ -114,10 +113,11 @@ helper_svm_check_intercept_param(env, SVM_EXIT_VMRUN, 0); - if (aflag == 2) - addr = EAX; - else - addr = (uint32_t)EAX; + if (aflag == 2) { + addr = env->regs[R_EAX]; + } else { + addr = (uint32_t)env->regs[R_EAX]; + } qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmrun! " TARGET_FMT_lx "\n", addr); @@ -150,9 +150,9 @@ &env->segs[R_DS]); stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip), - EIP + next_eip_addend); - stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp), ESP); - stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax), EAX); + env->eip + next_eip_addend); + stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp), env->regs[R_ESP]); + stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax), env->regs[R_EAX]); /* load the interception bitmaps so we do not need to access the vmcb in svm mode */ @@ -186,8 +186,9 @@ if (int_ctl & V_INTR_MASKING_MASK) { env->v_tpr = int_ctl & V_TPR_MASK; env->hflags2 |= HF2_VINTR_MASK; - if (env->eflags & IF_MASK) + if (env->eflags & IF_MASK) { env->hflags2 |= HF2_HIF_MASK; + } } cpu_load_efer(env, @@ -206,10 +207,10 @@ svm_load_seg_cache(env->vm_vmcb + offsetof(struct vmcb, save.ds), env, R_DS); - EIP = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip)); - env->eip = EIP; - ESP = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rsp)); - EAX = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rax)); + env->eip = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip)); + env->eip = env->eip; + env->regs[R_ESP] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rsp)); + env->regs[R_EAX] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rax)); env->dr[7] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr7)); env->dr[6] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr6)); cpu_x86_set_cpl(env, ldub_phys(env->vm_vmcb + offsetof(struct vmcb, save.cpl))); @@ -254,7 +255,7 @@ env->exception_index = EXCP02_NMI; env->error_code = event_inj_err; env->exception_is_int = 0; - env->exception_next_eip = EIP; + env->exception_next_eip = env->eip; qemu_log_mask(CPU_LOG_TB_IN_ASM, "NMI"); cpu_loop_exit(env); break; @@ -270,7 +271,7 @@ env->exception_index = vector; env->error_code = event_inj_err; env->exception_is_int = 1; - env->exception_next_eip = EIP; + env->exception_next_eip = env->eip; qemu_log_mask(CPU_LOG_TB_IN_ASM, "SOFT"); cpu_loop_exit(env); break; @@ -290,10 +291,11 @@ target_ulong addr; helper_svm_check_intercept_param(env, SVM_EXIT_VMLOAD, 0); - if (aflag == 2) - addr = EAX; - else - addr = (uint32_t)EAX; + if (aflag == 2) { + addr = env->regs[R_EAX]; + } else { + addr = (uint32_t)env->regs[R_EAX]; + } qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmload! " TARGET_FMT_lx "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n", addr, ldq_phys(addr + offsetof(struct vmcb, save.fs.base)), @@ -325,10 +327,11 @@ target_ulong addr; helper_svm_check_intercept_param(env, SVM_EXIT_VMSAVE, 0); - if (aflag == 2) - addr = EAX; - else - addr = (uint32_t)EAX; + if (aflag == 2) { + addr = env->regs[R_EAX]; + } else { + addr = (uint32_t)env->regs[R_EAX]; + } qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmsave! " TARGET_FMT_lx "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n", addr, ldq_phys(addr + offsetof(struct vmcb, save.fs.base)), @@ -379,10 +382,11 @@ target_ulong addr; helper_svm_check_intercept_param(env, SVM_EXIT_INVLPGA, 0); - if (aflag == 2) - addr = EAX; - else - addr = (uint32_t)EAX; + if (aflag == 2) { + addr = env->regs[R_EAX]; + } else { + addr = (uint32_t)env->regs[R_EAX]; + } /* XXX: could use the ASID to see if it is needed to do the flush */ @@ -392,8 +396,9 @@ void helper_svm_check_intercept_param(CPUX86State *env, uint32_t type, uint64_t param) { - if (likely(!(env->hflags & HF_SVMI_MASK))) + if (likely(!(env->hflags & HF_SVMI_MASK))) { return; + } switch(type) { case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR0 + 8: if (env->intercept_cr_read & (1 << (type - SVM_EXIT_READ_CR0))) { @@ -425,18 +430,18 @@ /* FIXME: this should be read in at vmrun (faster this way?) */ uint64_t addr = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.msrpm_base_pa)); uint32_t t0, t1; - switch((uint32_t)ECX) { + switch ((uint32_t)env->regs[R_ECX]) { case 0 ... 0x1fff: - t0 = (ECX * 2) % 8; - t1 = ECX / 8; + t0 = (env->regs[R_ECX] * 2) % 8; + t1 = env->regs[R_ECX] / 8; break; case 0xc0000000 ... 0xc0001fff: - t0 = (8192 + ECX - 0xc0000000) * 2; + t0 = (8192 + env->regs[R_ECX] - 0xc0000000) * 2; t1 = (t0 / 8); t0 %= 8; break; case 0xc0010000 ... 0xc0011fff: - t0 = (16384 + ECX - 0xc0010000) * 2; + t0 = (16384 + env->regs[R_ECX] - 0xc0010000) * 2; t1 = (t0 / 8); t0 %= 8; break; @@ -446,8 +451,9 @@ t1 = 0; break; } - if (ldub_phys(addr + t1) & ((1 << param) << t0)) + if (ldub_phys(addr + t1) & ((1 << param) << t0)) { helper_vmexit(env, type, param); + } } break; default: @@ -472,7 +478,7 @@ uint64_t addr = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.iopm_base_pa)); uint16_t mask = (1 << ((param >> 4) & 7)) - 1; if(lduw_phys(addr + port / 8) & (mask << (port & 7))) { - /* next EIP */ + /* next env->eip */ stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), env->eip + next_eip_addend); helper_vmexit(env, SVM_EXIT_IOIO, param | (port << 16)); @@ -489,7 +495,7 @@ qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmexit(%08x, %016" PRIx64 ", %016" PRIx64 ", " TARGET_FMT_lx ")!\n", exit_code, exit_info_1, ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2)), - EIP); + env->eip); if(env->hflags & HF_INHIBIT_IRQ_MASK) { stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_state), SVM_INTERRUPT_SHADOW_MASK); @@ -523,14 +529,15 @@ int_ctl = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)); int_ctl &= ~(V_TPR_MASK | V_IRQ_MASK); int_ctl |= env->v_tpr & V_TPR_MASK; - if (ENV_GET_CPU(env)->interrupt_request & CPU_INTERRUPT_VIRQ) + if (ENV_GET_CPU(env)->interrupt_request & CPU_INTERRUPT_VIRQ) { int_ctl |= V_IRQ_MASK; + } stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), int_ctl); stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rflags), cpu_compute_eflags(env)); stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip), env->eip); - stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rsp), ESP); - stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rax), EAX); + stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rsp), env->regs[R_ESP]); + stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rax), env->regs[R_EAX]); stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr7), env->dr[7]); stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr6), env->dr[6]); stb_phys(env->vm_vmcb + offsetof(struct vmcb, save.cpl), env->hflags & HF_CPL_MASK); @@ -570,9 +577,9 @@ svm_load_seg_cache(env->vm_hsave + offsetof(struct vmcb, save.ds), env, R_DS); - EIP = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip)); - ESP = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp)); - EAX = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax)); + env->eip = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip)); + env->regs[R_ESP] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp)); + env->regs[R_EAX] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax)); env->dr[6] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr6)); env->dr[7] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr7));
diff --git a/target-i386/translate.c b/target-i386/translate.c index 9ae45a5..f125877 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c
@@ -324,7 +324,7 @@ #endif /* !TARGET_X86_64 */ -#if defined(WORDS_BIGENDIAN) +#if defined(HOST_WORDS_BIGENDIAN) #define REG_B_OFFSET (sizeof(target_ulong) - 1) #define REG_H_OFFSET (sizeof(target_ulong) - 2) #define REG_W_OFFSET (sizeof(target_ulong) - 2)