1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include "qemu/osdep.h"
21#include "cpu.h"
22#include "helper-tcg.h"
23#include "qemu/accel.h"
24#include "hw/core/accel-cpu.h"
25
26#include "tcg-cpu.h"
27
28
29
30static void x86_cpu_exec_enter(CPUState *cs)
31{
32 X86CPU *cpu = X86_CPU(cs);
33 CPUX86State *env = &cpu->env;
34
35 CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
36 env->df = 1 - (2 * ((env->eflags >> 10) & 1));
37 CC_OP = CC_OP_EFLAGS;
38 env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
39}
40
41static void x86_cpu_exec_exit(CPUState *cs)
42{
43 X86CPU *cpu = X86_CPU(cs);
44 CPUX86State *env = &cpu->env;
45
46 env->eflags = cpu_compute_eflags(env);
47}
48
49static void x86_cpu_synchronize_from_tb(CPUState *cs,
50 const TranslationBlock *tb)
51{
52 X86CPU *cpu = X86_CPU(cs);
53
54 cpu->env.eip = tb->pc - tb->cs_base;
55}
56
57#ifndef CONFIG_USER_ONLY
58static bool x86_debug_check_breakpoint(CPUState *cs)
59{
60 X86CPU *cpu = X86_CPU(cs);
61 CPUX86State *env = &cpu->env;
62
63
64 return !(env->eflags & RF_MASK);
65}
66#endif
67
68#include "hw/core/tcg-cpu-ops.h"
69
70static const struct TCGCPUOps x86_tcg_ops = {
71 .initialize = tcg_x86_init,
72 .synchronize_from_tb = x86_cpu_synchronize_from_tb,
73 .cpu_exec_enter = x86_cpu_exec_enter,
74 .cpu_exec_exit = x86_cpu_exec_exit,
75#ifdef CONFIG_USER_ONLY
76 .fake_user_interrupt = x86_cpu_do_interrupt,
77 .record_sigsegv = x86_cpu_record_sigsegv,
78#else
79 .tlb_fill = x86_cpu_tlb_fill,
80 .do_interrupt = x86_cpu_do_interrupt,
81 .cpu_exec_interrupt = x86_cpu_exec_interrupt,
82 .debug_excp_handler = breakpoint_handler,
83 .debug_check_breakpoint = x86_debug_check_breakpoint,
84#endif
85};
86
87static void tcg_cpu_init_ops(AccelCPUClass *accel_cpu, CPUClass *cc)
88{
89
90 cc->tcg_ops = &x86_tcg_ops;
91}
92
93static void tcg_cpu_class_init(CPUClass *cc)
94{
95 cc->init_accel_cpu = tcg_cpu_init_ops;
96}
97
98static void tcg_cpu_xsave_init(void)
99{
100#define XO(bit, field) \
101 x86_ext_save_areas[bit].offset = offsetof(X86XSaveArea, field);
102
103 XO(XSTATE_FP_BIT, legacy);
104 XO(XSTATE_SSE_BIT, legacy);
105 XO(XSTATE_YMM_BIT, avx_state);
106 XO(XSTATE_BNDREGS_BIT, bndreg_state);
107 XO(XSTATE_BNDCSR_BIT, bndcsr_state);
108 XO(XSTATE_OPMASK_BIT, opmask_state);
109 XO(XSTATE_ZMM_Hi256_BIT, zmm_hi256_state);
110 XO(XSTATE_Hi16_ZMM_BIT, hi16_zmm_state);
111 XO(XSTATE_PKRU_BIT, pkru_state);
112
113#undef XO
114}
115
116
117
118
119
120static PropValue tcg_default_props[] = {
121 { "vme", "off" },
122 { NULL, NULL },
123};
124
125static void tcg_cpu_instance_init(CPUState *cs)
126{
127 X86CPU *cpu = X86_CPU(cs);
128 X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
129
130 if (xcc->model) {
131
132 x86_cpu_apply_props(cpu, tcg_default_props);
133 }
134
135 tcg_cpu_xsave_init();
136}
137
138static void tcg_cpu_accel_class_init(ObjectClass *oc, void *data)
139{
140 AccelCPUClass *acc = ACCEL_CPU_CLASS(oc);
141
142#ifndef CONFIG_USER_ONLY
143 acc->cpu_realizefn = tcg_cpu_realizefn;
144#endif
145
146 acc->cpu_class_init = tcg_cpu_class_init;
147 acc->cpu_instance_init = tcg_cpu_instance_init;
148}
149static const TypeInfo tcg_cpu_accel_type_info = {
150 .name = ACCEL_CPU_NAME("tcg"),
151
152 .parent = TYPE_ACCEL_CPU,
153 .class_init = tcg_cpu_accel_class_init,
154 .abstract = true,
155};
156static void tcg_cpu_accel_register_types(void)
157{
158 type_register_static(&tcg_cpu_accel_type_info);
159}
160type_init(tcg_cpu_accel_register_types);
161