master
c 294 lines 9.9 KB
Raw
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * QEMU LoongArch Machine State
4 *
5 * Copyright (c) 2021 Loongson Technology Corporation Limited
6 */
7
8 #include "qemu/osdep.h"
9 #include "cpu.h"
10 #include "migration/vmstate.h"
11 #include "system/tcg.h"
12 #include "vec.h"
13
14 static const VMStateDescription vmstate_fpu_reg = {
15 .name = "fpu_reg",
16 .version_id = 1,
17 .minimum_version_id = 1,
18 .fields = (const VMStateField[]) {
19 VMSTATE_UINT64(UD(0), VReg),
20 VMSTATE_END_OF_LIST()
21 }
22 };
23
24 #define VMSTATE_FPU_REGS(_field, _state, _start) \
25 VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, 32, 0, \
26 vmstate_fpu_reg, fpr_t)
27
28 static bool fpu_needed(void *opaque)
29 {
30 LoongArchCPU *cpu = opaque;
31
32 return FIELD_EX64(cpu->env.cpucfg[2], CPUCFG2, FP);
33 }
34
35 static const VMStateDescription vmstate_fpu = {
36 .name = "cpu/fpu",
37 .version_id = 1,
38 .minimum_version_id = 1,
39 .needed = fpu_needed,
40 .fields = (const VMStateField[]) {
41 VMSTATE_FPU_REGS(env.fpr, LoongArchCPU, 0),
42 VMSTATE_UINT32(env.fcsr0, LoongArchCPU),
43 VMSTATE_BOOL_ARRAY(env.cf, LoongArchCPU, 8),
44 VMSTATE_END_OF_LIST()
45 },
46 };
47
48 static bool msgint_needed(void *opaque)
49 {
50 LoongArchCPU *cpu = opaque;
51
52 return FIELD_EX64(cpu->env.cpucfg[1], CPUCFG1, MSG_INT);
53 }
54
55 static const VMStateDescription vmstate_msgint = {
56 .name = "cpu/msgint",
57 .version_id = 1,
58 .minimum_version_id = 1,
59 .needed = msgint_needed,
60 .fields = (const VMStateField[]) {
61 VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_MSGIS, LoongArchCPU, N_MSGIS),
62 VMSTATE_UINT64(env.sys_states[0].CSR_MSGIR, LoongArchCPU),
63 VMSTATE_UINT64(env.sys_states[0].CSR_MSGIE, LoongArchCPU),
64 VMSTATE_END_OF_LIST()
65 },
66 };
67
68 static const VMStateDescription vmstate_lsxh_reg = {
69 .name = "lsxh_reg",
70 .version_id = 1,
71 .minimum_version_id = 1,
72 .fields = (const VMStateField[]) {
73 VMSTATE_UINT64(UD(1), VReg),
74 VMSTATE_END_OF_LIST()
75 }
76 };
77
78 #define VMSTATE_LSXH_REGS(_field, _state, _start) \
79 VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, 32, 0, \
80 vmstate_lsxh_reg, fpr_t)
81
82 static bool lsx_needed(void *opaque)
83 {
84 LoongArchCPU *cpu = opaque;
85
86 return FIELD_EX64(cpu->env.cpucfg[2], CPUCFG2, LSX);
87 }
88
89 static const VMStateDescription vmstate_lsx = {
90 .name = "cpu/lsx",
91 .version_id = 1,
92 .minimum_version_id = 1,
93 .needed = lsx_needed,
94 .fields = (const VMStateField[]) {
95 VMSTATE_LSXH_REGS(env.fpr, LoongArchCPU, 0),
96 VMSTATE_END_OF_LIST()
97 },
98 };
99
100 static const VMStateDescription vmstate_lasxh_reg = {
101 .name = "lasxh_reg",
102 .version_id = 1,
103 .minimum_version_id = 1,
104 .fields = (const VMStateField[]) {
105 VMSTATE_UINT64(UD(2), VReg),
106 VMSTATE_UINT64(UD(3), VReg),
107 VMSTATE_END_OF_LIST()
108 }
109 };
110
111 #define VMSTATE_LASXH_REGS(_field, _state, _start) \
112 VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, 32, 0, \
113 vmstate_lasxh_reg, fpr_t)
114
115 static bool lasx_needed(void *opaque)
116 {
117 LoongArchCPU *cpu = opaque;
118
119 return FIELD_EX64(cpu->env.cpucfg[2], CPUCFG2, LASX);
120 }
121
122 static const VMStateDescription vmstate_lasx = {
123 .name = "cpu/lasx",
124 .version_id = 1,
125 .minimum_version_id = 1,
126 .needed = lasx_needed,
127 .fields = (const VMStateField[]) {
128 VMSTATE_LASXH_REGS(env.fpr, LoongArchCPU, 0),
129 VMSTATE_END_OF_LIST()
130 },
131 };
132
133 static bool lbt_needed(void *opaque)
134 {
135 LoongArchCPU *cpu = opaque;
136
137 return !!FIELD_EX64(cpu->env.cpucfg[2], CPUCFG2, LBT_ALL);
138 }
139
140 static const VMStateDescription vmstate_lbt = {
141 .name = "cpu/lbt",
142 .version_id = 0,
143 .minimum_version_id = 0,
144 .needed = lbt_needed,
145 .fields = (const VMStateField[]) {
146 VMSTATE_UINT64(env.lbt.scr0, LoongArchCPU),
147 VMSTATE_UINT64(env.lbt.scr1, LoongArchCPU),
148 VMSTATE_UINT64(env.lbt.scr2, LoongArchCPU),
149 VMSTATE_UINT64(env.lbt.scr3, LoongArchCPU),
150 VMSTATE_UINT32(env.lbt.eflags, LoongArchCPU),
151 VMSTATE_UINT32(env.lbt.ftop, LoongArchCPU),
152 VMSTATE_END_OF_LIST()
153 },
154 };
155
156 static bool pmu_needed(void *opaque)
157 {
158 LoongArchCPU *cpu = opaque;
159
160 return cpu->pmu == ON_OFF_AUTO_ON;
161 }
162
163 static const VMStateDescription vmstate_pmu = {
164 .name = "cpu/pmu",
165 .version_id = 0,
166 .minimum_version_id = 0,
167 .needed = pmu_needed,
168 .fields = (const VMStateField[]) {
169 VMSTATE_UINT32(env.perf_event_num, LoongArchCPU),
170 VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_PERFCTRL, LoongArchCPU,\
171 MAX_PERF_EVENTS),
172 VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_PERFCNTR, LoongArchCPU, \
173 MAX_PERF_EVENTS),
174 VMSTATE_END_OF_LIST()
175 },
176 };
177
178 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
179 static bool tlb_needed(void *opaque)
180 {
181 return tcg_enabled();
182 }
183
184 /* TLB state */
185 static const VMStateDescription vmstate_tlb_entry = {
186 .name = "cpu/tlb_entry",
187 .version_id = 0,
188 .minimum_version_id = 0,
189 .fields = (const VMStateField[]) {
190 VMSTATE_UINT64(tlb_misc, LoongArchTLB),
191 VMSTATE_UINT64(tlb_entry0, LoongArchTLB),
192 VMSTATE_UINT64(tlb_entry1, LoongArchTLB),
193 VMSTATE_END_OF_LIST()
194 }
195 };
196
197 static const VMStateDescription vmstate_tlb = {
198 .name = "cpu/tlb",
199 .version_id = 0,
200 .minimum_version_id = 0,
201 .needed = tlb_needed,
202 .fields = (const VMStateField[]) {
203 VMSTATE_STRUCT_ARRAY(env.tlb, LoongArchCPU, LOONGARCH_TLB_MAX,
204 0, vmstate_tlb_entry, LoongArchTLB),
205 VMSTATE_END_OF_LIST()
206 }
207 };
208 #endif
209
210 /* LoongArch CPU state */
211 const VMStateDescription vmstate_loongarch_cpu = {
212 .name = "cpu",
213 .version_id = 4,
214 .minimum_version_id = 4,
215 .fields = (const VMStateField[]) {
216 VMSTATE_UINT64_ARRAY(env.gpr, LoongArchCPU, 32),
217 VMSTATE_UINT64(env.pc, LoongArchCPU),
218
219 /* Remaining CSRs */
220 VMSTATE_UINT64(env.sys_states[0].CSR_CRMD, LoongArchCPU),
221 VMSTATE_UINT64(env.sys_states[0].CSR_PRMD, LoongArchCPU),
222 VMSTATE_UINT64(env.sys_states[0].CSR_EUEN, LoongArchCPU),
223 VMSTATE_UINT64(env.sys_states[0].CSR_MISC, LoongArchCPU),
224 VMSTATE_UINT64(env.sys_states[0].CSR_ECFG, LoongArchCPU),
225 VMSTATE_UINT64(env.sys_states[0].CSR_ESTAT, LoongArchCPU),
226 VMSTATE_UINT64(env.sys_states[0].CSR_ERA, LoongArchCPU),
227 VMSTATE_UINT64(env.sys_states[0].CSR_BADV, LoongArchCPU),
228 VMSTATE_UINT64(env.sys_states[0].CSR_BADI, LoongArchCPU),
229 VMSTATE_UINT64(env.sys_states[0].CSR_EENTRY, LoongArchCPU),
230 VMSTATE_UINT64(env.sys_states[0].CSR_TLBIDX, LoongArchCPU),
231 VMSTATE_UINT64(env.sys_states[0].CSR_TLBEHI, LoongArchCPU),
232 VMSTATE_UINT64(env.sys_states[0].CSR_TLBELO0, LoongArchCPU),
233 VMSTATE_UINT64(env.sys_states[0].CSR_TLBELO1, LoongArchCPU),
234 VMSTATE_UINT64(env.sys_states[0].CSR_ASID, LoongArchCPU),
235 VMSTATE_UINT64(env.sys_states[0].CSR_PGDL, LoongArchCPU),
236 VMSTATE_UINT64(env.sys_states[0].CSR_PGDH, LoongArchCPU),
237 VMSTATE_UINT64(env.sys_states[0].CSR_PGD, LoongArchCPU),
238 VMSTATE_UINT64(env.sys_states[0].CSR_PWCL, LoongArchCPU),
239 VMSTATE_UINT64(env.sys_states[0].CSR_PWCH, LoongArchCPU),
240 VMSTATE_UINT64(env.sys_states[0].CSR_STLBPS, LoongArchCPU),
241 VMSTATE_UINT64(env.sys_states[0].CSR_RVACFG, LoongArchCPU),
242 VMSTATE_UINT64(env.sys_states[0].CSR_PRCFG1, LoongArchCPU),
243 VMSTATE_UINT64(env.sys_states[0].CSR_PRCFG2, LoongArchCPU),
244 VMSTATE_UINT64(env.sys_states[0].CSR_PRCFG3, LoongArchCPU),
245 VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_SAVE, LoongArchCPU, 16),
246 VMSTATE_UINT64(env.sys_states[0].CSR_TID, LoongArchCPU),
247 VMSTATE_UINT64(env.sys_states[0].CSR_TCFG, LoongArchCPU),
248 VMSTATE_UINT64(env.sys_states[0].CSR_TVAL, LoongArchCPU),
249 VMSTATE_UINT64(env.sys_states[0].CSR_CNTC, LoongArchCPU),
250 VMSTATE_UINT64(env.sys_states[0].CSR_TICLR, LoongArchCPU),
251 VMSTATE_UINT64(env.sys_states[0].CSR_LLBCTL, LoongArchCPU),
252 VMSTATE_UINT64(env.sys_states[0].CSR_IMPCTL1, LoongArchCPU),
253 VMSTATE_UINT64(env.sys_states[0].CSR_IMPCTL2, LoongArchCPU),
254 VMSTATE_UINT64(env.sys_states[0].CSR_TLBRENTRY, LoongArchCPU),
255 VMSTATE_UINT64(env.sys_states[0].CSR_TLBRBADV, LoongArchCPU),
256 VMSTATE_UINT64(env.sys_states[0].CSR_TLBRERA, LoongArchCPU),
257 VMSTATE_UINT64(env.sys_states[0].CSR_TLBRSAVE, LoongArchCPU),
258 VMSTATE_UINT64(env.sys_states[0].CSR_TLBRELO0, LoongArchCPU),
259 VMSTATE_UINT64(env.sys_states[0].CSR_TLBRELO1, LoongArchCPU),
260 VMSTATE_UINT64(env.sys_states[0].CSR_TLBREHI, LoongArchCPU),
261 VMSTATE_UINT64(env.sys_states[0].CSR_TLBRPRMD, LoongArchCPU),
262 VMSTATE_UINT64(env.sys_states[0].CSR_MERRCTL, LoongArchCPU),
263 VMSTATE_UINT64(env.sys_states[0].CSR_MERRINFO1, LoongArchCPU),
264 VMSTATE_UINT64(env.sys_states[0].CSR_MERRINFO2, LoongArchCPU),
265 VMSTATE_UINT64(env.sys_states[0].CSR_MERRENTRY, LoongArchCPU),
266 VMSTATE_UINT64(env.sys_states[0].CSR_MERRERA, LoongArchCPU),
267 VMSTATE_UINT64(env.sys_states[0].CSR_MERRSAVE, LoongArchCPU),
268 VMSTATE_UINT64(env.sys_states[0].CSR_CTAG, LoongArchCPU),
269 VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_DMW, LoongArchCPU, 4),
270
271 /* Debug CSRs */
272 VMSTATE_UINT64(env.sys_states[0].CSR_DBG, LoongArchCPU),
273 VMSTATE_UINT64(env.sys_states[0].CSR_DERA, LoongArchCPU),
274 VMSTATE_UINT64(env.sys_states[0].CSR_DSAVE, LoongArchCPU),
275
276 VMSTATE_UINT64(kvm_state_counter, LoongArchCPU),
277 /* PV steal time */
278 VMSTATE_UINT64(env.stealtime.guest_addr, LoongArchCPU),
279
280 VMSTATE_END_OF_LIST()
281 },
282 .subsections = (const VMStateDescription * const []) {
283 &vmstate_fpu,
284 &vmstate_lsx,
285 &vmstate_lasx,
286 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
287 &vmstate_tlb,
288 #endif
289 &vmstate_lbt,
290 &vmstate_msgint,
291 &vmstate_pmu,
292 NULL
293 }
294 };