Revision d9957a8b
b/target-i386/cpu.h | ||
---|---|---|
720 | 720 |
#endif |
721 | 721 |
} |
722 | 722 |
|
723 |
/* op_helper.c */ |
|
723 | 724 |
/* used for debug or cpu save/restore */ |
724 | 725 |
void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, CPU86_LDouble f); |
725 | 726 |
CPU86_LDouble cpu_set_fp80(uint64_t mant, uint16_t upper); |
726 | 727 |
|
728 |
/* cpu-exec.c */ |
|
727 | 729 |
/* the following helpers are only usable in user mode simulation as |
728 | 730 |
they can trigger unexpected exceptions */ |
729 | 731 |
void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector); |
... | ... | |
735 | 737 |
is returned if the signal was handled by the virtual CPU. */ |
736 | 738 |
int cpu_x86_signal_handler(int host_signum, void *pinfo, |
737 | 739 |
void *puc); |
740 |
|
|
741 |
/* helper.c */ |
|
742 |
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, |
|
743 |
int is_write, int mmu_idx, int is_softmmu); |
|
738 | 744 |
void cpu_x86_set_a20(CPUX86State *env, int a20_state); |
745 |
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, |
|
746 |
uint32_t *eax, uint32_t *ebx, |
|
747 |
uint32_t *ecx, uint32_t *edx); |
|
739 | 748 |
|
740 |
uint64_t cpu_get_tsc(CPUX86State *env); |
|
749 |
static inline int hw_breakpoint_enabled(unsigned long dr7, int index) |
|
750 |
{ |
|
751 |
return (dr7 >> (index * 2)) & 3; |
|
752 |
} |
|
741 | 753 |
|
754 |
static inline int hw_breakpoint_type(unsigned long dr7, int index) |
|
755 |
{ |
|
756 |
return (dr7 >> (DR7_TYPE_SHIFT + (index * 2))) & 3; |
|
757 |
} |
|
758 |
|
|
759 |
static inline int hw_breakpoint_len(unsigned long dr7, int index) |
|
760 |
{ |
|
761 |
int len = ((dr7 >> (DR7_LEN_SHIFT + (index * 2))) & 3); |
|
762 |
return (len == 2) ? 8 : len + 1; |
|
763 |
} |
|
764 |
|
|
765 |
void hw_breakpoint_insert(CPUX86State *env, int index); |
|
766 |
void hw_breakpoint_remove(CPUX86State *env, int index); |
|
767 |
int check_hw_breakpoints(CPUX86State *env, int force_dr6_update); |
|
768 |
|
|
769 |
/* will be suppressed */ |
|
770 |
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0); |
|
771 |
void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3); |
|
772 |
void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4); |
|
773 |
|
|
774 |
/* hw/apic.c */ |
|
742 | 775 |
void cpu_set_apic_base(CPUX86State *env, uint64_t val); |
743 | 776 |
uint64_t cpu_get_apic_base(CPUX86State *env); |
744 | 777 |
void cpu_set_apic_tpr(CPUX86State *env, uint8_t val); |
745 | 778 |
#ifndef NO_CPU_IO_DEFS |
746 | 779 |
uint8_t cpu_get_apic_tpr(CPUX86State *env); |
747 | 780 |
#endif |
748 |
void cpu_smm_update(CPUX86State *env); |
|
749 | 781 |
|
750 |
/* will be suppressed */ |
|
751 |
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0); |
|
752 |
|
|
753 |
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, |
|
754 |
uint32_t *eax, uint32_t *ebx, |
|
755 |
uint32_t *ecx, uint32_t *edx); |
|
782 |
/* hw/pc.c */ |
|
783 |
void cpu_smm_update(CPUX86State *env); |
|
784 |
uint64_t cpu_get_tsc(CPUX86State *env); |
|
756 | 785 |
|
757 | 786 |
/* used to debug */ |
758 | 787 |
#define X86_DUMP_FPU 0x0001 /* dump FPU state too */ |
... | ... | |
787 | 816 |
return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0; |
788 | 817 |
} |
789 | 818 |
|
819 |
/* translate.c */ |
|
790 | 820 |
void optimize_flags_init(void); |
791 | 821 |
|
792 | 822 |
typedef struct CCTable { |
... | ... | |
803 | 833 |
} |
804 | 834 |
#endif |
805 | 835 |
|
806 |
static inline int hw_breakpoint_enabled(unsigned long dr7, int index) |
|
807 |
{ |
|
808 |
return (dr7 >> (index * 2)) & 3; |
|
809 |
} |
|
810 |
|
|
811 |
static inline int hw_breakpoint_type(unsigned long dr7, int index) |
|
812 |
{ |
|
813 |
return (dr7 >> (DR7_TYPE_SHIFT + (index * 2))) & 3; |
|
814 |
} |
|
815 |
|
|
816 |
static inline int hw_breakpoint_len(unsigned long dr7, int index) |
|
817 |
{ |
|
818 |
int len = ((dr7 >> (DR7_LEN_SHIFT + (index * 2))) & 3); |
|
819 |
return (len == 2) ? 8 : len + 1; |
|
820 |
} |
|
821 |
|
|
822 |
void hw_breakpoint_insert(CPUState *env, int index); |
|
823 |
void hw_breakpoint_remove(CPUState *env, int index); |
|
824 |
int check_hw_breakpoints(CPUState *env, int force_dr6_update); |
|
825 |
|
|
826 | 836 |
#include "cpu-all.h" |
827 | 837 |
#include "exec-all.h" |
828 | 838 |
|
b/target-i386/exec.h | ||
---|---|---|
57 | 57 |
#include "cpu.h" |
58 | 58 |
#include "exec-all.h" |
59 | 59 |
|
60 |
void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3); |
|
61 |
void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4); |
|
62 |
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, |
|
63 |
int is_write, int mmu_idx, int is_softmmu); |
|
64 |
void __hidden cpu_lock(void); |
|
65 |
void __hidden cpu_unlock(void); |
|
60 |
/* op_helper.c */ |
|
66 | 61 |
void do_interrupt(int intno, int is_int, int error_code, |
67 | 62 |
target_ulong next_eip, int is_hw); |
68 | 63 |
void do_interrupt_user(int intno, int is_int, int error_code, |
69 | 64 |
target_ulong next_eip); |
70 |
void raise_interrupt(int intno, int is_int, int error_code, |
|
71 |
int next_eip_addend); |
|
72 | 65 |
void raise_exception_err(int exception_index, int error_code); |
73 | 66 |
void raise_exception(int exception_index); |
74 | 67 |
void do_smm_enter(void); |
... | ... | |
274 | 267 |
|
275 | 268 |
#define FPUC_EM 0x3f |
276 | 269 |
|
277 |
extern const CPU86_LDouble f15rk[7]; |
|
278 |
|
|
279 |
void fpu_raise_exception(void); |
|
280 |
void restore_native_fp_state(CPUState *env); |
|
281 |
void save_native_fp_state(CPUState *env); |
|
282 |
|
|
283 |
extern const uint8_t parity_table[256]; |
|
284 |
extern const uint8_t rclw_table[32]; |
|
285 |
extern const uint8_t rclb_table[32]; |
|
286 |
|
|
287 | 270 |
static inline uint32_t compute_eflags(void) |
288 | 271 |
{ |
289 | 272 |
return env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK); |
b/target-i386/helper.c | ||
---|---|---|
27 | 27 |
|
28 | 28 |
#include "cpu.h" |
29 | 29 |
#include "exec-all.h" |
30 |
#include "svm.h" |
|
31 | 30 |
#include "qemu-common.h" |
32 | 31 |
#include "kvm.h" |
33 |
#include "helper.h" |
|
34 | 32 |
|
35 | 33 |
//#define DEBUG_MMU |
36 | 34 |
|
... | ... | |
849 | 847 |
env->cr[4] = new_cr4; |
850 | 848 |
} |
851 | 849 |
|
852 |
/* XXX: also flush 4MB pages */ |
|
853 |
void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr) |
|
854 |
{ |
|
855 |
tlb_flush_page(env, addr); |
|
856 |
} |
|
857 |
|
|
858 | 850 |
#if defined(CONFIG_USER_ONLY) |
859 | 851 |
|
860 | 852 |
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, |
b/target-i386/op_helper.c | ||
---|---|---|
19 | 19 |
*/ |
20 | 20 |
#define CPU_NO_GLOBAL_REGS |
21 | 21 |
#include "exec.h" |
22 |
#include "exec-all.h" |
|
22 | 23 |
#include "host-utils.h" |
23 | 24 |
|
24 | 25 |
//#define DEBUG_PCALL |
... | ... | |
32 | 33 |
} while (0) |
33 | 34 |
#endif |
34 | 35 |
|
35 |
const uint8_t parity_table[256] = { |
|
36 |
static const uint8_t parity_table[256] = {
|
|
36 | 37 |
CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, |
37 | 38 |
0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, |
38 | 39 |
0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, |
... | ... | |
68 | 69 |
}; |
69 | 70 |
|
70 | 71 |
/* modulo 17 table */ |
71 |
const uint8_t rclw_table[32] = { |
|
72 |
static const uint8_t rclw_table[32] = {
|
|
72 | 73 |
0, 1, 2, 3, 4, 5, 6, 7, |
73 | 74 |
8, 9,10,11,12,13,14,15, |
74 | 75 |
16, 0, 1, 2, 3, 4, 5, 6, |
... | ... | |
76 | 77 |
}; |
77 | 78 |
|
78 | 79 |
/* modulo 9 table */ |
79 |
const uint8_t rclb_table[32] = { |
|
80 |
static const uint8_t rclb_table[32] = {
|
|
80 | 81 |
0, 1, 2, 3, 4, 5, 6, 7, |
81 | 82 |
8, 0, 1, 2, 3, 4, 5, 6, |
82 | 83 |
7, 8, 0, 1, 2, 3, 4, 5, |
83 | 84 |
6, 7, 8, 0, 1, 2, 3, 4, |
84 | 85 |
}; |
85 | 86 |
|
86 |
const CPU86_LDouble f15rk[7] = |
|
87 |
static const CPU86_LDouble f15rk[7] =
|
|
87 | 88 |
{ |
88 | 89 |
0.00000000000000000000L, |
89 | 90 |
1.00000000000000000000L, |
... | ... | |
995 | 996 |
} |
996 | 997 |
#endif |
997 | 998 |
|
999 |
#ifdef TARGET_X86_64 |
|
998 | 1000 |
#if defined(CONFIG_USER_ONLY) |
999 | 1001 |
void helper_syscall(int next_eip_addend) |
1000 | 1002 |
{ |
... | ... | |
1011 | 1013 |
raise_exception_err(EXCP06_ILLOP, 0); |
1012 | 1014 |
} |
1013 | 1015 |
selector = (env->star >> 32) & 0xffff; |
1014 |
#ifdef TARGET_X86_64 |
|
1015 | 1016 |
if (env->hflags & HF_LMA_MASK) { |
1016 | 1017 |
int code64; |
1017 | 1018 |
|
... | ... | |
1037 | 1038 |
env->eip = env->lstar; |
1038 | 1039 |
else |
1039 | 1040 |
env->eip = env->cstar; |
1040 |
} else |
|
1041 |
#endif |
|
1042 |
{ |
|
1041 |
} else { |
|
1043 | 1042 |
ECX = (uint32_t)(env->eip + next_eip_addend); |
1044 | 1043 |
|
1045 | 1044 |
cpu_x86_set_cpl(env, 0); |
... | ... | |
1058 | 1057 |
} |
1059 | 1058 |
} |
1060 | 1059 |
#endif |
1060 |
#endif |
|
1061 | 1061 |
|
1062 |
#ifdef TARGET_X86_64 |
|
1062 | 1063 |
void helper_sysret(int dflag) |
1063 | 1064 |
{ |
1064 | 1065 |
int cpl, selector; |
... | ... | |
1071 | 1072 |
raise_exception_err(EXCP0D_GPF, 0); |
1072 | 1073 |
} |
1073 | 1074 |
selector = (env->star >> 48) & 0xffff; |
1074 |
#ifdef TARGET_X86_64 |
|
1075 | 1075 |
if (env->hflags & HF_LMA_MASK) { |
1076 | 1076 |
if (dflag == 2) { |
1077 | 1077 |
cpu_x86_load_seg_cache(env, R_CS, (selector + 16) | 3, |
... | ... | |
1097 | 1097 |
load_eflags((uint32_t)(env->regs[11]), TF_MASK | AC_MASK | ID_MASK | |
1098 | 1098 |
IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK); |
1099 | 1099 |
cpu_x86_set_cpl(env, 3); |
1100 |
} else |
|
1101 |
#endif |
|
1102 |
{ |
|
1100 |
} else { |
|
1103 | 1101 |
cpu_x86_load_seg_cache(env, R_CS, selector | 3, |
1104 | 1102 |
0, 0xffffffff, |
1105 | 1103 |
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | |
... | ... | |
1123 | 1121 |
} |
1124 | 1122 |
#endif |
1125 | 1123 |
} |
1124 |
#endif |
|
1126 | 1125 |
|
1127 | 1126 |
/* real mode interrupt */ |
1128 | 1127 |
static void do_interrupt_real(int intno, int is_int, int error_code, |
... | ... | |
1285 | 1284 |
* EIP value AFTER the interrupt instruction. It is only relevant if |
1286 | 1285 |
* is_int is TRUE. |
1287 | 1286 |
*/ |
1288 |
void raise_interrupt(int intno, int is_int, int error_code, |
|
1289 |
int next_eip_addend) |
|
1287 |
static void raise_interrupt(int intno, int is_int, int error_code,
|
|
1288 |
int next_eip_addend)
|
|
1290 | 1289 |
{ |
1291 | 1290 |
if (!is_int) { |
1292 | 1291 |
helper_svm_check_intercept_param(SVM_EXIT_EXCP_BASE + intno, error_code); |
... | ... | |
1304 | 1303 |
|
1305 | 1304 |
/* shortcuts to generate exceptions */ |
1306 | 1305 |
|
1307 |
void (raise_exception_err)(int exception_index, int error_code)
|
|
1306 |
void raise_exception_err(int exception_index, int error_code)
|
|
1308 | 1307 |
{ |
1309 | 1308 |
raise_interrupt(exception_index, 0, error_code, 0); |
1310 | 1309 |
} |
... | ... | |
3319 | 3318 |
return a / b; |
3320 | 3319 |
} |
3321 | 3320 |
|
3322 |
void fpu_raise_exception(void) |
|
3321 |
static void fpu_raise_exception(void)
|
|
3323 | 3322 |
{ |
3324 | 3323 |
if (env->cr[0] & CR0_NE_MASK) { |
3325 | 3324 |
raise_exception(EXCP10_COPR); |
... | ... | |
4660 | 4659 |
|
4661 | 4660 |
#endif |
4662 | 4661 |
|
4662 |
#if !defined(CONFIG_USER_ONLY) |
|
4663 | 4663 |
/* try to fill the TLB and return an exception if error. If retaddr is |
4664 | 4664 |
NULL, it means that the function was called in C code (i.e. not |
4665 | 4665 |
from generated code or from helper.c) */ |
... | ... | |
4692 | 4692 |
} |
4693 | 4693 |
env = saved_env; |
4694 | 4694 |
} |
4695 |
|
|
4695 |
#endif |
|
4696 | 4696 |
|
4697 | 4697 |
/* Secure Virtual Machine helpers */ |
4698 | 4698 |
|
Also available in: Unified diff