]>
Commit | Line | Data |
---|---|---|
db5ebe5f | 1 | #include "qemu/osdep.h" |
33c11879 | 2 | #include "cpu.h" |
63c91552 | 3 | #include "exec/exec-all.h" |
1de7afc9 | 4 | #include "qemu/timer.h" |
8dd3dca3 | 5 | |
1e00b8d5 | 6 | #include "migration/cpu.h" |
8dd3dca3 | 7 | |
df32c8d4 JQ |
8 | #ifdef TARGET_SPARC64 |
9 | static const VMStateDescription vmstate_cpu_timer = { | |
10 | .name = "cpu_timer", | |
11 | .version_id = 1, | |
12 | .minimum_version_id = 1, | |
dd9729b3 | 13 | .fields = (const VMStateField[]) { |
df32c8d4 JQ |
14 | VMSTATE_UINT32(frequency, CPUTimer), |
15 | VMSTATE_UINT32(disabled, CPUTimer), | |
16 | VMSTATE_UINT64(disabled_mask, CPUTimer), | |
17 | VMSTATE_UINT32(npt, CPUTimer), | |
18 | VMSTATE_UINT64(npt_mask, CPUTimer), | |
19 | VMSTATE_INT64(clock_offset, CPUTimer), | |
20 | VMSTATE_TIMER_PTR(qtimer, CPUTimer), | |
21 | VMSTATE_END_OF_LIST() | |
22 | } | |
23 | }; | |
a7a044f2 | 24 | |
df32c8d4 JQ |
25 | #define VMSTATE_CPU_TIMER(_f, _s) \ |
26 | VMSTATE_STRUCT_POINTER(_f, _s, vmstate_cpu_timer, CPUTimer) | |
8dd3dca3 | 27 | |
df32c8d4 JQ |
28 | static const VMStateDescription vmstate_trap_state = { |
29 | .name = "trap_state", | |
30 | .version_id = 1, | |
31 | .minimum_version_id = 1, | |
dd9729b3 | 32 | .fields = (const VMStateField[]) { |
df32c8d4 JQ |
33 | VMSTATE_UINT64(tpc, trap_state), |
34 | VMSTATE_UINT64(tnpc, trap_state), | |
35 | VMSTATE_UINT64(tstate, trap_state), | |
36 | VMSTATE_UINT32(tt, trap_state), | |
37 | VMSTATE_END_OF_LIST() | |
8dd3dca3 | 38 | } |
df32c8d4 | 39 | }; |
8dd3dca3 | 40 | |
df32c8d4 JQ |
41 | static const VMStateDescription vmstate_tlb_entry = { |
42 | .name = "tlb_entry", | |
43 | .version_id = 1, | |
44 | .minimum_version_id = 1, | |
dd9729b3 | 45 | .fields = (const VMStateField[]) { |
df32c8d4 JQ |
46 | VMSTATE_UINT64(tag, SparcTLBEntry), |
47 | VMSTATE_UINT64(tte, SparcTLBEntry), | |
48 | VMSTATE_END_OF_LIST() | |
0b8f1b10 | 49 | } |
df32c8d4 | 50 | }; |
8dd3dca3 | 51 | #endif |
df32c8d4 | 52 | |
03fee66f MAL |
53 | static int get_psr(QEMUFile *f, void *opaque, size_t size, |
54 | const VMStateField *field) | |
df32c8d4 JQ |
55 | { |
56 | SPARCCPU *cpu = opaque; | |
57 | CPUSPARCState *env = &cpu->env; | |
58 | uint32_t val = qemu_get_be32(f); | |
59 | ||
60 | /* needed to ensure that the wrapping registers are correctly updated */ | |
61 | env->cwp = 0; | |
62 | cpu_put_psr_raw(env, val); | |
63 | ||
64 | return 0; | |
8dd3dca3 AJ |
65 | } |
66 | ||
03fee66f | 67 | static int put_psr(QEMUFile *f, void *opaque, size_t size, |
3ddba9a9 | 68 | const VMStateField *field, JSONWriter *vmdesc) |
8dd3dca3 | 69 | { |
df32c8d4 JQ |
70 | SPARCCPU *cpu = opaque; |
71 | CPUSPARCState *env = &cpu->env; | |
72 | uint32_t val; | |
73 | ||
74 | val = cpu_get_psr(env); | |
8dd3dca3 | 75 | |
df32c8d4 | 76 | qemu_put_be32(f, val); |
2c21ee76 | 77 | return 0; |
df32c8d4 JQ |
78 | } |
79 | ||
80 | static const VMStateInfo vmstate_psr = { | |
81 | .name = "psr", | |
82 | .get = get_psr, | |
83 | .put = put_psr, | |
84 | }; | |
85 | ||
1ccd6e13 RH |
86 | static int get_fsr(QEMUFile *f, void *opaque, size_t size, |
87 | const VMStateField *field) | |
88 | { | |
89 | SPARCCPU *cpu = opaque; | |
90 | target_ulong val = qemu_get_betl(f); | |
91 | ||
92 | cpu_put_fsr(&cpu->env, val); | |
93 | return 0; | |
94 | } | |
95 | ||
96 | static int put_fsr(QEMUFile *f, void *opaque, size_t size, | |
97 | const VMStateField *field, JSONWriter *vmdesc) | |
98 | { | |
99 | SPARCCPU *cpu = opaque; | |
100 | target_ulong val = cpu_get_fsr(&cpu->env); | |
101 | ||
102 | qemu_put_betl(f, val); | |
103 | return 0; | |
104 | } | |
105 | ||
106 | static const VMStateInfo vmstate_fsr = { | |
107 | .name = "fsr", | |
108 | .get = get_fsr, | |
109 | .put = put_fsr, | |
110 | }; | |
111 | ||
2a1905c7 RH |
112 | #ifdef TARGET_SPARC64 |
113 | static int get_xcc(QEMUFile *f, void *opaque, size_t size, | |
114 | const VMStateField *field) | |
115 | { | |
116 | SPARCCPU *cpu = opaque; | |
117 | CPUSPARCState *env = &cpu->env; | |
118 | uint32_t val = qemu_get_be32(f); | |
119 | ||
120 | /* Do not clobber icc.[NV] */ | |
121 | env->cc_N = deposit64(env->cc_N, 32, 32, -(val & PSR_NEG)); | |
122 | env->cc_V = deposit64(env->cc_V, 32, 32, -(val & PSR_OVF)); | |
123 | env->xcc_Z = ~val & PSR_ZERO; | |
124 | env->xcc_C = (val >> PSR_CARRY_SHIFT) & 1; | |
125 | ||
126 | return 0; | |
127 | } | |
128 | ||
129 | static int put_xcc(QEMUFile *f, void *opaque, size_t size, | |
130 | const VMStateField *field, JSONWriter *vmdesc) | |
131 | { | |
132 | SPARCCPU *cpu = opaque; | |
133 | CPUSPARCState *env = &cpu->env; | |
134 | uint32_t val = cpu_get_ccr(env); | |
135 | ||
136 | /* Extract just xcc out of ccr and shift into legacy position. */ | |
137 | qemu_put_be32(f, (val & 0xf0) << (20 - 4)); | |
138 | return 0; | |
139 | } | |
140 | ||
141 | static const VMStateInfo vmstate_xcc = { | |
142 | .name = "xcc", | |
143 | .get = get_xcc, | |
144 | .put = put_xcc, | |
145 | }; | |
146 | #endif | |
147 | ||
44b1ff31 | 148 | static int cpu_pre_save(void *opaque) |
df32c8d4 JQ |
149 | { |
150 | SPARCCPU *cpu = opaque; | |
151 | CPUSPARCState *env = &cpu->env; | |
152 | ||
153 | /* if env->cwp == env->nwindows - 1, this will set the ins of the last | |
154 | * window as the outs of the first window | |
155 | */ | |
156 | cpu_set_cwp(env, env->cwp); | |
44b1ff31 DDAG |
157 | |
158 | return 0; | |
df32c8d4 JQ |
159 | } |
160 | ||
0e88d45a PM |
161 | /* 32-bit SPARC retains migration compatibility with older versions |
162 | * of QEMU; 64-bit SPARC has had a migration break since then, so the | |
163 | * versions are different. | |
164 | */ | |
165 | #ifndef TARGET_SPARC64 | |
166 | #define SPARC_VMSTATE_VER 7 | |
167 | #else | |
6d532244 | 168 | #define SPARC_VMSTATE_VER 9 |
0e88d45a PM |
169 | #endif |
170 | ||
df32c8d4 JQ |
171 | const VMStateDescription vmstate_sparc_cpu = { |
172 | .name = "cpu", | |
0e88d45a PM |
173 | .version_id = SPARC_VMSTATE_VER, |
174 | .minimum_version_id = SPARC_VMSTATE_VER, | |
df32c8d4 | 175 | .pre_save = cpu_pre_save, |
dd9729b3 | 176 | .fields = (const VMStateField[]) { |
df32c8d4 JQ |
177 | VMSTATE_UINTTL_ARRAY(env.gregs, SPARCCPU, 8), |
178 | VMSTATE_UINT32(env.nwindows, SPARCCPU), | |
179 | VMSTATE_VARRAY_MULTIPLY(env.regbase, SPARCCPU, env.nwindows, 16, | |
180 | vmstate_info_uinttl, target_ulong), | |
181 | VMSTATE_CPUDOUBLE_ARRAY(env.fpr, SPARCCPU, TARGET_DPREGS), | |
182 | VMSTATE_UINTTL(env.pc, SPARCCPU), | |
183 | VMSTATE_UINTTL(env.npc, SPARCCPU), | |
184 | VMSTATE_UINTTL(env.y, SPARCCPU), | |
185 | { | |
df32c8d4 JQ |
186 | .name = "psr", |
187 | .version_id = 0, | |
188 | .size = sizeof(uint32_t), | |
189 | .info = &vmstate_psr, | |
190 | .flags = VMS_SINGLE, | |
191 | .offset = 0, | |
192 | }, | |
1ccd6e13 RH |
193 | { |
194 | .name = "fsr", | |
195 | .version_id = 0, | |
196 | .size = sizeof(target_ulong), | |
197 | .info = &vmstate_fsr, | |
198 | .flags = VMS_SINGLE, | |
199 | .offset = 0, | |
200 | }, | |
df32c8d4 JQ |
201 | VMSTATE_UINTTL(env.tbr, SPARCCPU), |
202 | VMSTATE_INT32(env.interrupt_index, SPARCCPU), | |
203 | VMSTATE_UINT32(env.pil_in, SPARCCPU), | |
8dd3dca3 | 204 | #ifndef TARGET_SPARC64 |
df32c8d4 JQ |
205 | /* MMU */ |
206 | VMSTATE_UINT32(env.wim, SPARCCPU), | |
207 | VMSTATE_UINT32_ARRAY(env.mmuregs, SPARCCPU, 32), | |
208 | VMSTATE_UINT64_ARRAY(env.mxccdata, SPARCCPU, 4), | |
209 | VMSTATE_UINT64_ARRAY(env.mxccregs, SPARCCPU, 8), | |
210 | VMSTATE_UINT32(env.mmubpctrv, SPARCCPU), | |
211 | VMSTATE_UINT32(env.mmubpctrc, SPARCCPU), | |
212 | VMSTATE_UINT32(env.mmubpctrs, SPARCCPU), | |
213 | VMSTATE_UINT64(env.mmubpaction, SPARCCPU), | |
214 | VMSTATE_UINT64_ARRAY(env.mmubpregs, SPARCCPU, 4), | |
0b8f1b10 | 215 | #else |
df32c8d4 | 216 | VMSTATE_UINT64(env.lsu, SPARCCPU), |
96df2bc9 AT |
217 | VMSTATE_UINT64_ARRAY(env.immu.mmuregs, SPARCCPU, 16), |
218 | VMSTATE_UINT64_ARRAY(env.dmmu.mmuregs, SPARCCPU, 16), | |
0e88d45a PM |
219 | VMSTATE_STRUCT_ARRAY(env.itlb, SPARCCPU, 64, 0, |
220 | vmstate_tlb_entry, SparcTLBEntry), | |
221 | VMSTATE_STRUCT_ARRAY(env.dtlb, SPARCCPU, 64, 0, | |
222 | vmstate_tlb_entry, SparcTLBEntry), | |
df32c8d4 JQ |
223 | VMSTATE_UINT32(env.mmu_version, SPARCCPU), |
224 | VMSTATE_STRUCT_ARRAY(env.ts, SPARCCPU, MAXTL_MAX, 0, | |
225 | vmstate_trap_state, trap_state), | |
2a1905c7 RH |
226 | { |
227 | .name = "xcc", | |
228 | .version_id = 0, | |
229 | .size = sizeof(uint32_t), | |
230 | .info = &vmstate_xcc, | |
231 | .flags = VMS_SINGLE, | |
232 | .offset = 0, | |
233 | }, | |
df32c8d4 JQ |
234 | VMSTATE_UINT32(env.asi, SPARCCPU), |
235 | VMSTATE_UINT32(env.pstate, SPARCCPU), | |
236 | VMSTATE_UINT32(env.tl, SPARCCPU), | |
237 | VMSTATE_UINT32(env.cansave, SPARCCPU), | |
238 | VMSTATE_UINT32(env.canrestore, SPARCCPU), | |
239 | VMSTATE_UINT32(env.otherwin, SPARCCPU), | |
240 | VMSTATE_UINT32(env.wstate, SPARCCPU), | |
241 | VMSTATE_UINT32(env.cleanwin, SPARCCPU), | |
242 | VMSTATE_UINT64_ARRAY(env.agregs, SPARCCPU, 8), | |
243 | VMSTATE_UINT64_ARRAY(env.bgregs, SPARCCPU, 8), | |
244 | VMSTATE_UINT64_ARRAY(env.igregs, SPARCCPU, 8), | |
245 | VMSTATE_UINT64_ARRAY(env.mgregs, SPARCCPU, 8), | |
ca4d5d86 PM |
246 | VMSTATE_UNUSED(4), /* was unused high half of uint64_t fprs */ |
247 | VMSTATE_UINT32(env.fprs, SPARCCPU), | |
df32c8d4 JQ |
248 | VMSTATE_UINT64(env.tick_cmpr, SPARCCPU), |
249 | VMSTATE_UINT64(env.stick_cmpr, SPARCCPU), | |
250 | VMSTATE_CPU_TIMER(env.tick, SPARCCPU), | |
251 | VMSTATE_CPU_TIMER(env.stick, SPARCCPU), | |
252 | VMSTATE_UINT64(env.gsr, SPARCCPU), | |
253 | VMSTATE_UINT32(env.gl, SPARCCPU), | |
254 | VMSTATE_UINT64(env.hpstate, SPARCCPU), | |
255 | VMSTATE_UINT64_ARRAY(env.htstate, SPARCCPU, MAXTL_MAX), | |
256 | VMSTATE_UINT64(env.hintp, SPARCCPU), | |
257 | VMSTATE_UINT64(env.htba, SPARCCPU), | |
258 | VMSTATE_UINT64(env.hver, SPARCCPU), | |
259 | VMSTATE_UINT64(env.hstick_cmpr, SPARCCPU), | |
260 | VMSTATE_UINT64(env.ssr, SPARCCPU), | |
261 | VMSTATE_CPU_TIMER(env.hstick, SPARCCPU), | |
6d532244 PM |
262 | /* On SPARC32 env.psrpil and env.cwp are migrated as part of the PSR */ |
263 | VMSTATE_UINT32(env.psrpil, SPARCCPU), | |
264 | VMSTATE_UINT32(env.cwp, SPARCCPU), | |
8dd3dca3 | 265 | #endif |
df32c8d4 JQ |
266 | VMSTATE_END_OF_LIST() |
267 | }, | |
268 | }; |