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/cpu.h"
11 #include "sysemu/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
fpu_needed(void * opaque)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 const VMStateDescription vmstate_lsxh_reg = {
49 .name = "lsxh_reg",
50 .version_id = 1,
51 .minimum_version_id = 1,
52 .fields = (const VMStateField[]) {
53 VMSTATE_UINT64(UD(1), VReg),
54 VMSTATE_END_OF_LIST()
55 }
56 };
57
58 #define VMSTATE_LSXH_REGS(_field, _state, _start) \
59 VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, 32, 0, \
60 vmstate_lsxh_reg, fpr_t)
61
lsx_needed(void * opaque)62 static bool lsx_needed(void *opaque)
63 {
64 LoongArchCPU *cpu = opaque;
65
66 return FIELD_EX64(cpu->env.cpucfg[2], CPUCFG2, LSX);
67 }
68
69 static const VMStateDescription vmstate_lsx = {
70 .name = "cpu/lsx",
71 .version_id = 1,
72 .minimum_version_id = 1,
73 .needed = lsx_needed,
74 .fields = (const VMStateField[]) {
75 VMSTATE_LSXH_REGS(env.fpr, LoongArchCPU, 0),
76 VMSTATE_END_OF_LIST()
77 },
78 };
79
80 static const VMStateDescription vmstate_lasxh_reg = {
81 .name = "lasxh_reg",
82 .version_id = 1,
83 .minimum_version_id = 1,
84 .fields = (const VMStateField[]) {
85 VMSTATE_UINT64(UD(2), VReg),
86 VMSTATE_UINT64(UD(3), VReg),
87 VMSTATE_END_OF_LIST()
88 }
89 };
90
91 #define VMSTATE_LASXH_REGS(_field, _state, _start) \
92 VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, 32, 0, \
93 vmstate_lasxh_reg, fpr_t)
94
lasx_needed(void * opaque)95 static bool lasx_needed(void *opaque)
96 {
97 LoongArchCPU *cpu = opaque;
98
99 return FIELD_EX64(cpu->env.cpucfg[2], CPUCFG2, LASX);
100 }
101
102 static const VMStateDescription vmstate_lasx = {
103 .name = "cpu/lasx",
104 .version_id = 1,
105 .minimum_version_id = 1,
106 .needed = lasx_needed,
107 .fields = (const VMStateField[]) {
108 VMSTATE_LASXH_REGS(env.fpr, LoongArchCPU, 0),
109 VMSTATE_END_OF_LIST()
110 },
111 };
112
113 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
tlb_needed(void * opaque)114 static bool tlb_needed(void *opaque)
115 {
116 return tcg_enabled();
117 }
118
119 /* TLB state */
120 static const VMStateDescription vmstate_tlb_entry = {
121 .name = "cpu/tlb_entry",
122 .version_id = 0,
123 .minimum_version_id = 0,
124 .fields = (const VMStateField[]) {
125 VMSTATE_UINT64(tlb_misc, LoongArchTLB),
126 VMSTATE_UINT64(tlb_entry0, LoongArchTLB),
127 VMSTATE_UINT64(tlb_entry1, LoongArchTLB),
128 VMSTATE_END_OF_LIST()
129 }
130 };
131
132 static const VMStateDescription vmstate_tlb = {
133 .name = "cpu/tlb",
134 .version_id = 0,
135 .minimum_version_id = 0,
136 .needed = tlb_needed,
137 .fields = (const VMStateField[]) {
138 VMSTATE_STRUCT_ARRAY(env.tlb, LoongArchCPU, LOONGARCH_TLB_MAX,
139 0, vmstate_tlb_entry, LoongArchTLB),
140 VMSTATE_END_OF_LIST()
141 }
142 };
143 #endif
144
145 /* LoongArch CPU state */
146 const VMStateDescription vmstate_loongarch_cpu = {
147 .name = "cpu",
148 .version_id = 2,
149 .minimum_version_id = 2,
150 .fields = (const VMStateField[]) {
151 VMSTATE_UINTTL_ARRAY(env.gpr, LoongArchCPU, 32),
152 VMSTATE_UINTTL(env.pc, LoongArchCPU),
153
154 /* Remaining CSRs */
155 VMSTATE_UINT64(env.CSR_CRMD, LoongArchCPU),
156 VMSTATE_UINT64(env.CSR_PRMD, LoongArchCPU),
157 VMSTATE_UINT64(env.CSR_EUEN, LoongArchCPU),
158 VMSTATE_UINT64(env.CSR_MISC, LoongArchCPU),
159 VMSTATE_UINT64(env.CSR_ECFG, LoongArchCPU),
160 VMSTATE_UINT64(env.CSR_ESTAT, LoongArchCPU),
161 VMSTATE_UINT64(env.CSR_ERA, LoongArchCPU),
162 VMSTATE_UINT64(env.CSR_BADV, LoongArchCPU),
163 VMSTATE_UINT64(env.CSR_BADI, LoongArchCPU),
164 VMSTATE_UINT64(env.CSR_EENTRY, LoongArchCPU),
165 VMSTATE_UINT64(env.CSR_TLBIDX, LoongArchCPU),
166 VMSTATE_UINT64(env.CSR_TLBEHI, LoongArchCPU),
167 VMSTATE_UINT64(env.CSR_TLBELO0, LoongArchCPU),
168 VMSTATE_UINT64(env.CSR_TLBELO1, LoongArchCPU),
169 VMSTATE_UINT64(env.CSR_ASID, LoongArchCPU),
170 VMSTATE_UINT64(env.CSR_PGDL, LoongArchCPU),
171 VMSTATE_UINT64(env.CSR_PGDH, LoongArchCPU),
172 VMSTATE_UINT64(env.CSR_PGD, LoongArchCPU),
173 VMSTATE_UINT64(env.CSR_PWCL, LoongArchCPU),
174 VMSTATE_UINT64(env.CSR_PWCH, LoongArchCPU),
175 VMSTATE_UINT64(env.CSR_STLBPS, LoongArchCPU),
176 VMSTATE_UINT64(env.CSR_RVACFG, LoongArchCPU),
177 VMSTATE_UINT64(env.CSR_PRCFG1, LoongArchCPU),
178 VMSTATE_UINT64(env.CSR_PRCFG2, LoongArchCPU),
179 VMSTATE_UINT64(env.CSR_PRCFG3, LoongArchCPU),
180 VMSTATE_UINT64_ARRAY(env.CSR_SAVE, LoongArchCPU, 16),
181 VMSTATE_UINT64(env.CSR_TID, LoongArchCPU),
182 VMSTATE_UINT64(env.CSR_TCFG, LoongArchCPU),
183 VMSTATE_UINT64(env.CSR_TVAL, LoongArchCPU),
184 VMSTATE_UINT64(env.CSR_CNTC, LoongArchCPU),
185 VMSTATE_UINT64(env.CSR_TICLR, LoongArchCPU),
186 VMSTATE_UINT64(env.CSR_LLBCTL, LoongArchCPU),
187 VMSTATE_UINT64(env.CSR_IMPCTL1, LoongArchCPU),
188 VMSTATE_UINT64(env.CSR_IMPCTL2, LoongArchCPU),
189 VMSTATE_UINT64(env.CSR_TLBRENTRY, LoongArchCPU),
190 VMSTATE_UINT64(env.CSR_TLBRBADV, LoongArchCPU),
191 VMSTATE_UINT64(env.CSR_TLBRERA, LoongArchCPU),
192 VMSTATE_UINT64(env.CSR_TLBRSAVE, LoongArchCPU),
193 VMSTATE_UINT64(env.CSR_TLBRELO0, LoongArchCPU),
194 VMSTATE_UINT64(env.CSR_TLBRELO1, LoongArchCPU),
195 VMSTATE_UINT64(env.CSR_TLBREHI, LoongArchCPU),
196 VMSTATE_UINT64(env.CSR_TLBRPRMD, LoongArchCPU),
197 VMSTATE_UINT64(env.CSR_MERRCTL, LoongArchCPU),
198 VMSTATE_UINT64(env.CSR_MERRINFO1, LoongArchCPU),
199 VMSTATE_UINT64(env.CSR_MERRINFO2, LoongArchCPU),
200 VMSTATE_UINT64(env.CSR_MERRENTRY, LoongArchCPU),
201 VMSTATE_UINT64(env.CSR_MERRERA, LoongArchCPU),
202 VMSTATE_UINT64(env.CSR_MERRSAVE, LoongArchCPU),
203 VMSTATE_UINT64(env.CSR_CTAG, LoongArchCPU),
204 VMSTATE_UINT64_ARRAY(env.CSR_DMW, LoongArchCPU, 4),
205
206 /* Debug CSRs */
207 VMSTATE_UINT64(env.CSR_DBG, LoongArchCPU),
208 VMSTATE_UINT64(env.CSR_DERA, LoongArchCPU),
209 VMSTATE_UINT64(env.CSR_DSAVE, LoongArchCPU),
210
211 VMSTATE_UINT64(kvm_state_counter, LoongArchCPU),
212
213 VMSTATE_END_OF_LIST()
214 },
215 .subsections = (const VMStateDescription * const []) {
216 &vmstate_fpu,
217 &vmstate_lsx,
218 &vmstate_lasx,
219 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
220 &vmstate_tlb,
221 #endif
222 NULL
223 }
224 };
225