X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/88e6c60671df4c8b1b6c1eb8f76950ab1bea0ec2..6bada5e80ee5941a3b7ab118b738a4097dd76e37:/target-i386/cpu.h diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 196b0c5c40..f257c972fb 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -42,7 +42,7 @@ #define ELF_MACHINE EM_386 #endif -#define CPUState struct CPUX86State +#define CPUArchState struct CPUX86State #include "cpu-defs.h" @@ -241,6 +241,7 @@ #define PG_DIRTY_MASK (1 << PG_DIRTY_BIT) #define PG_PSE_MASK (1 << PG_PSE_BIT) #define PG_GLOBAL_MASK (1 << PG_GLOBAL_BIT) +#define PG_HI_USER_MASK 0x7ff0000000000000LL #define PG_NX_MASK (1LL << PG_NX_BIT) #define PG_ERROR_W_BIT 1 @@ -740,6 +741,8 @@ typedef struct CPUX86State { /* Store the results of Centaur's CPUID instructions */ uint32_t cpuid_xlevel2; uint32_t cpuid_ext4_features; + /* Flags from CPUID[EAX=7,ECX=0].EBX */ + uint32_t cpuid_7_0_ebx; /* MTRRs */ uint64_t mtrr_fixed[11]; @@ -782,12 +785,13 @@ typedef struct CPUX86State { TPRAccess tpr_access_type; } CPUX86State; -CPUX86State *cpu_x86_init(const char *cpu_model); +#include "cpu-qom.h" + +X86CPU *cpu_x86_init(const char *cpu_model); int cpu_x86_exec(CPUX86State *s); -void cpu_x86_close(CPUX86State *s); void x86_cpu_list (FILE *f, fprintf_function cpu_fprintf, const char *optarg); void x86_cpudef_setup(void); -int cpu_x86_support_mca_broadcast(CPUState *env); +int cpu_x86_support_mca_broadcast(CPUX86State *env); int cpu_get_pic_interrupt(CPUX86State *s); /* MSDOS compatibility mode FPU exception support */ @@ -899,7 +903,7 @@ int cpu_x86_signal_handler(int host_signum, void *pinfo, void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx); -int cpu_x86_register (CPUX86State *env, const char *cpu_model); +int cpu_x86_register(X86CPU *cpu, const char *cpu_model); void cpu_clear_apic_feature(CPUX86State *env); void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx); @@ -956,7 +960,15 @@ uint64_t cpu_get_tsc(CPUX86State *env); #define TARGET_VIRT_ADDR_SPACE_BITS 32 #endif -#define cpu_init cpu_x86_init +static inline CPUX86State *cpu_init(const char *cpu_model) +{ + X86CPU *cpu = cpu_x86_init(cpu_model); + if (cpu == NULL) { + return NULL; + } + return &cpu->env; +} + #define cpu_exec cpu_x86_exec #define cpu_gen_code cpu_x86_gen_code #define cpu_signal_handler cpu_x86_signal_handler @@ -969,7 +981,7 @@ uint64_t cpu_get_tsc(CPUX86State *env); #define MMU_MODE0_SUFFIX _kernel #define MMU_MODE1_SUFFIX _user #define MMU_USER_IDX 1 -static inline int cpu_mmu_index (CPUState *env) +static inline int cpu_mmu_index (CPUX86State *env) { return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0; } @@ -998,6 +1010,16 @@ static inline int cpu_mmu_index (CPUState *env) #define CC_DST (env->cc_dst) #define CC_OP (env->cc_op) +/* n must be a constant to be efficient */ +static inline target_long lshift(target_long x, int n) +{ + if (n >= 0) { + return x << n; + } else { + return x >> (-n); + } +} + /* float macros */ #define FT0 (env->ft0) #define ST0 (env->fpregs[env->fpstt].d) @@ -1008,7 +1030,7 @@ static inline int cpu_mmu_index (CPUState *env) void optimize_flags_init(void); #if defined(CONFIG_USER_ONLY) -static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) +static inline void cpu_clone_regs(CPUX86State *env, target_ulong newsp) { if (newsp) env->regs[R_ESP] = newsp; @@ -1023,7 +1045,7 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) #include "hw/apic.h" #endif -static inline bool cpu_has_work(CPUState *env) +static inline bool cpu_has_work(CPUX86State *env) { return ((env->interrupt_request & CPU_INTERRUPT_HARD) && (env->eflags & IF_MASK)) || @@ -1035,12 +1057,12 @@ static inline bool cpu_has_work(CPUState *env) #include "exec-all.h" -static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) +static inline void cpu_pc_from_tb(CPUX86State *env, TranslationBlock *tb) { env->eip = tb->pc - tb->cs_base; } -static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, +static inline void cpu_get_tb_cpu_state(CPUX86State *env, target_ulong *pc, target_ulong *cs_base, int *flags) { *cs_base = env->segs[R_CS].base; @@ -1049,29 +1071,67 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, (env->eflags & (IOPL_MASK | TF_MASK | RF_MASK | VM_MASK)); } -void do_cpu_init(CPUState *env); -void do_cpu_sipi(CPUState *env); +void do_cpu_init(X86CPU *cpu); +void do_cpu_sipi(X86CPU *cpu); #define MCE_INJECT_BROADCAST 1 #define MCE_INJECT_UNCOND_AO 2 -void cpu_x86_inject_mce(Monitor *mon, CPUState *cenv, int bank, +void cpu_x86_inject_mce(Monitor *mon, CPUX86State *cenv, int bank, uint64_t status, uint64_t mcg_status, uint64_t addr, uint64_t misc, int flags); -/* op_helper.c */ -void do_interrupt(CPUState *env); -void do_interrupt_x86_hardirq(CPUState *env, int intno, int is_hw); -void QEMU_NORETURN raise_exception_env(int exception_index, CPUState *nenv); -void QEMU_NORETURN raise_exception_err_env(CPUState *nenv, int exception_index, - int error_code); +/* excp_helper.c */ +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 *nenv, int intno, int is_int, + int error_code, int next_eip_addend); -void do_smm_enter(CPUState *env1); +/* cc_helper.c */ +extern const uint8_t parity_table[256]; +uint32_t cpu_cc_compute_all(CPUX86State *env1, int op); -void svm_check_intercept(CPUState *env1, uint32_t type); +static inline uint32_t cpu_compute_eflags(CPUX86State *env) +{ + return env->eflags | cpu_cc_compute_all(env, CC_OP) | (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) +{ + CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); + DF = 1 - (2 * ((eflags >> 10) & 1)); + env->eflags = (env->eflags & ~update_mask) | + (eflags & update_mask) | 0x2; +} + +/* load efer and update the corresponding hflags. XXX: do consistency + checks with cpuid bits? */ +static inline void cpu_load_efer(CPUX86State *env, uint64_t val) +{ + env->efer = val; + env->hflags &= ~(HF_LMA_MASK | HF_SVME_MASK); + if (env->efer & MSR_EFER_LMA) { + env->hflags |= HF_LMA_MASK; + } + if (env->efer & MSR_EFER_SVME) { + env->hflags |= HF_SVME_MASK; + } +} + +/* svm_helper.c */ +void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type, + uint64_t param); +void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_1); + +/* op_helper.c */ +void do_interrupt(CPUX86State *env); +void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw); -uint32_t cpu_cc_compute_all(CPUState *env1, int op); +void do_smm_enter(CPUX86State *env1); -void cpu_report_tpr_access(CPUState *env, TPRAccess access); +void cpu_report_tpr_access(CPUX86State *env, TPRAccess access); #endif /* CPU_I386_H */