xref: /openbmc/qemu/target/loongarch/machine.c (revision b2580720)
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 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
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