xref: /openbmc/qemu/target/loongarch/machine.c (revision b278b60d)
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 
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 
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 
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 static bool lbt_needed(void *opaque)
114 {
115     LoongArchCPU *cpu = opaque;
116 
117     return !!FIELD_EX64(cpu->env.cpucfg[2], CPUCFG2, LBT_ALL);
118 }
119 
120 static const VMStateDescription vmstate_lbt = {
121     .name = "cpu/lbt",
122     .version_id = 0,
123     .minimum_version_id = 0,
124     .needed = lbt_needed,
125     .fields = (const VMStateField[]) {
126         VMSTATE_UINT64(env.lbt.scr0,   LoongArchCPU),
127         VMSTATE_UINT64(env.lbt.scr1,   LoongArchCPU),
128         VMSTATE_UINT64(env.lbt.scr2,   LoongArchCPU),
129         VMSTATE_UINT64(env.lbt.scr3,   LoongArchCPU),
130         VMSTATE_UINT32(env.lbt.eflags, LoongArchCPU),
131         VMSTATE_UINT32(env.lbt.ftop,   LoongArchCPU),
132         VMSTATE_END_OF_LIST()
133     },
134 };
135 
136 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
137 static bool tlb_needed(void *opaque)
138 {
139     return tcg_enabled();
140 }
141 
142 /* TLB state */
143 static const VMStateDescription vmstate_tlb_entry = {
144     .name = "cpu/tlb_entry",
145     .version_id = 0,
146     .minimum_version_id = 0,
147     .fields = (const VMStateField[]) {
148         VMSTATE_UINT64(tlb_misc, LoongArchTLB),
149         VMSTATE_UINT64(tlb_entry0, LoongArchTLB),
150         VMSTATE_UINT64(tlb_entry1, LoongArchTLB),
151         VMSTATE_END_OF_LIST()
152     }
153 };
154 
155 static const VMStateDescription vmstate_tlb = {
156     .name = "cpu/tlb",
157     .version_id = 0,
158     .minimum_version_id = 0,
159     .needed = tlb_needed,
160     .fields = (const VMStateField[]) {
161         VMSTATE_STRUCT_ARRAY(env.tlb, LoongArchCPU, LOONGARCH_TLB_MAX,
162                              0, vmstate_tlb_entry, LoongArchTLB),
163         VMSTATE_END_OF_LIST()
164     }
165 };
166 #endif
167 
168 /* LoongArch CPU state */
169 const VMStateDescription vmstate_loongarch_cpu = {
170     .name = "cpu",
171     .version_id = 3,
172     .minimum_version_id = 3,
173     .fields = (const VMStateField[]) {
174         VMSTATE_UINTTL_ARRAY(env.gpr, LoongArchCPU, 32),
175         VMSTATE_UINTTL(env.pc, LoongArchCPU),
176 
177         /* Remaining CSRs */
178         VMSTATE_UINT64(env.CSR_CRMD, LoongArchCPU),
179         VMSTATE_UINT64(env.CSR_PRMD, LoongArchCPU),
180         VMSTATE_UINT64(env.CSR_EUEN, LoongArchCPU),
181         VMSTATE_UINT64(env.CSR_MISC, LoongArchCPU),
182         VMSTATE_UINT64(env.CSR_ECFG, LoongArchCPU),
183         VMSTATE_UINT64(env.CSR_ESTAT, LoongArchCPU),
184         VMSTATE_UINT64(env.CSR_ERA, LoongArchCPU),
185         VMSTATE_UINT64(env.CSR_BADV, LoongArchCPU),
186         VMSTATE_UINT64(env.CSR_BADI, LoongArchCPU),
187         VMSTATE_UINT64(env.CSR_EENTRY, LoongArchCPU),
188         VMSTATE_UINT64(env.CSR_TLBIDX, LoongArchCPU),
189         VMSTATE_UINT64(env.CSR_TLBEHI, LoongArchCPU),
190         VMSTATE_UINT64(env.CSR_TLBELO0, LoongArchCPU),
191         VMSTATE_UINT64(env.CSR_TLBELO1, LoongArchCPU),
192         VMSTATE_UINT64(env.CSR_ASID, LoongArchCPU),
193         VMSTATE_UINT64(env.CSR_PGDL, LoongArchCPU),
194         VMSTATE_UINT64(env.CSR_PGDH, LoongArchCPU),
195         VMSTATE_UINT64(env.CSR_PGD, LoongArchCPU),
196         VMSTATE_UINT64(env.CSR_PWCL, LoongArchCPU),
197         VMSTATE_UINT64(env.CSR_PWCH, LoongArchCPU),
198         VMSTATE_UINT64(env.CSR_STLBPS, LoongArchCPU),
199         VMSTATE_UINT64(env.CSR_RVACFG, LoongArchCPU),
200         VMSTATE_UINT64(env.CSR_PRCFG1, LoongArchCPU),
201         VMSTATE_UINT64(env.CSR_PRCFG2, LoongArchCPU),
202         VMSTATE_UINT64(env.CSR_PRCFG3, LoongArchCPU),
203         VMSTATE_UINT64_ARRAY(env.CSR_SAVE, LoongArchCPU, 16),
204         VMSTATE_UINT64(env.CSR_TID, LoongArchCPU),
205         VMSTATE_UINT64(env.CSR_TCFG, LoongArchCPU),
206         VMSTATE_UINT64(env.CSR_TVAL, LoongArchCPU),
207         VMSTATE_UINT64(env.CSR_CNTC, LoongArchCPU),
208         VMSTATE_UINT64(env.CSR_TICLR, LoongArchCPU),
209         VMSTATE_UINT64(env.CSR_LLBCTL, LoongArchCPU),
210         VMSTATE_UINT64(env.CSR_IMPCTL1, LoongArchCPU),
211         VMSTATE_UINT64(env.CSR_IMPCTL2, LoongArchCPU),
212         VMSTATE_UINT64(env.CSR_TLBRENTRY, LoongArchCPU),
213         VMSTATE_UINT64(env.CSR_TLBRBADV, LoongArchCPU),
214         VMSTATE_UINT64(env.CSR_TLBRERA, LoongArchCPU),
215         VMSTATE_UINT64(env.CSR_TLBRSAVE, LoongArchCPU),
216         VMSTATE_UINT64(env.CSR_TLBRELO0, LoongArchCPU),
217         VMSTATE_UINT64(env.CSR_TLBRELO1, LoongArchCPU),
218         VMSTATE_UINT64(env.CSR_TLBREHI, LoongArchCPU),
219         VMSTATE_UINT64(env.CSR_TLBRPRMD, LoongArchCPU),
220         VMSTATE_UINT64(env.CSR_MERRCTL, LoongArchCPU),
221         VMSTATE_UINT64(env.CSR_MERRINFO1, LoongArchCPU),
222         VMSTATE_UINT64(env.CSR_MERRINFO2, LoongArchCPU),
223         VMSTATE_UINT64(env.CSR_MERRENTRY, LoongArchCPU),
224         VMSTATE_UINT64(env.CSR_MERRERA, LoongArchCPU),
225         VMSTATE_UINT64(env.CSR_MERRSAVE, LoongArchCPU),
226         VMSTATE_UINT64(env.CSR_CTAG, LoongArchCPU),
227         VMSTATE_UINT64_ARRAY(env.CSR_DMW, LoongArchCPU, 4),
228 
229         /* Debug CSRs */
230         VMSTATE_UINT64(env.CSR_DBG, LoongArchCPU),
231         VMSTATE_UINT64(env.CSR_DERA, LoongArchCPU),
232         VMSTATE_UINT64(env.CSR_DSAVE, LoongArchCPU),
233 
234         VMSTATE_UINT64(kvm_state_counter, LoongArchCPU),
235         /* PV steal time */
236         VMSTATE_UINT64(env.stealtime.guest_addr, LoongArchCPU),
237 
238         VMSTATE_END_OF_LIST()
239     },
240     .subsections = (const VMStateDescription * const []) {
241         &vmstate_fpu,
242         &vmstate_lsx,
243         &vmstate_lasx,
244 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
245         &vmstate_tlb,
246 #endif
247         &vmstate_lbt,
248         NULL
249     }
250 };
251