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 .cpu_exec_interrupt = x86_cpu_exec_interrupt,
76 .do_interrupt = x86_cpu_do_interrupt,
77 .tlb_fill = x86_cpu_tlb_fill,
78#ifndef CONFIG_USER_ONLY
79 .debug_excp_handler = breakpoint_handler,
80 .debug_check_breakpoint = x86_debug_check_breakpoint,
81#endif
82};
83
84static void tcg_cpu_init_ops(AccelCPUClass *accel_cpu, CPUClass *cc)
85{
86
87 cc->tcg_ops = &x86_tcg_ops;
88}
89
90static void tcg_cpu_class_init(CPUClass *cc)
91{
92 cc->init_accel_cpu = tcg_cpu_init_ops;
93}
94
95static void tcg_cpu_xsave_init(void)
96{
97#define XO(bit, field) \
98 x86_ext_save_areas[bit].offset = offsetof(X86XSaveArea, field);
99
100 XO(XSTATE_FP_BIT, legacy);
101 XO(XSTATE_SSE_BIT, legacy);
102 XO(XSTATE_YMM_BIT, avx_state);
103 XO(XSTATE_BNDREGS_BIT, bndreg_state);
104 XO(XSTATE_BNDCSR_BIT, bndcsr_state);
105 XO(XSTATE_OPMASK_BIT, opmask_state);
106 XO(XSTATE_ZMM_Hi256_BIT, zmm_hi256_state);
107 XO(XSTATE_Hi16_ZMM_BIT, hi16_zmm_state);
108 XO(XSTATE_PKRU_BIT, pkru_state);
109
110#undef XO
111}
112
113
114
115
116
117static PropValue tcg_default_props[] = {
118 { "vme", "off" },
119 { NULL, NULL },
120};
121
122static void tcg_cpu_instance_init(CPUState *cs)
123{
124 X86CPU *cpu = X86_CPU(cs);
125 X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
126
127 if (xcc->model) {
128
129 x86_cpu_apply_props(cpu, tcg_default_props);
130 }
131
132 tcg_cpu_xsave_init();
133}
134
135static void tcg_cpu_accel_class_init(ObjectClass *oc, void *data)
136{
137 AccelCPUClass *acc = ACCEL_CPU_CLASS(oc);
138
139#ifndef CONFIG_USER_ONLY
140 acc->cpu_realizefn = tcg_cpu_realizefn;
141#endif
142
143 acc->cpu_class_init = tcg_cpu_class_init;
144 acc->cpu_instance_init = tcg_cpu_instance_init;
145}
146static const TypeInfo tcg_cpu_accel_type_info = {
147 .name = ACCEL_CPU_NAME("tcg"),
148
149 .parent = TYPE_ACCEL_CPU,
150 .class_init = tcg_cpu_accel_class_init,
151 .abstract = true,
152};
153static void tcg_cpu_accel_register_types(void)
154{
155 type_register_static(&tcg_cpu_accel_type_info);
156}
157type_init(tcg_cpu_accel_register_types);
158