167ebd42aSXiaojuan Yang /* SPDX-License-Identifier: GPL-2.0-or-later */
267ebd42aSXiaojuan Yang /*
367ebd42aSXiaojuan Yang * QEMU LoongArch Machine State
467ebd42aSXiaojuan Yang *
567ebd42aSXiaojuan Yang * Copyright (c) 2021 Loongson Technology Corporation Limited
667ebd42aSXiaojuan Yang */
767ebd42aSXiaojuan Yang
867ebd42aSXiaojuan Yang #include "qemu/osdep.h"
967ebd42aSXiaojuan Yang #include "cpu.h"
1067ebd42aSXiaojuan Yang #include "migration/cpu.h"
11*32cad1ffSPhilippe Mathieu-Daudé #include "system/tcg.h"
12008a3b16SSong Gao #include "vec.h"
137e1c521eSXiaojuan Yang
1416f5396cSSong Gao static const VMStateDescription vmstate_fpu_reg = {
1516f5396cSSong Gao .name = "fpu_reg",
1616f5396cSSong Gao .version_id = 1,
1716f5396cSSong Gao .minimum_version_id = 1,
182d23bb1aSRichard Henderson .fields = (const VMStateField[]) {
1916f5396cSSong Gao VMSTATE_UINT64(UD(0), VReg),
2016f5396cSSong Gao VMSTATE_END_OF_LIST()
2116f5396cSSong Gao }
2216f5396cSSong Gao };
2316f5396cSSong Gao
2416f5396cSSong Gao #define VMSTATE_FPU_REGS(_field, _state, _start) \
2516f5396cSSong Gao VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, 32, 0, \
2616f5396cSSong Gao vmstate_fpu_reg, fpr_t)
2716f5396cSSong Gao
fpu_needed(void * opaque)2816f5396cSSong Gao static bool fpu_needed(void *opaque)
2916f5396cSSong Gao {
3016f5396cSSong Gao LoongArchCPU *cpu = opaque;
3116f5396cSSong Gao
3216f5396cSSong Gao return FIELD_EX64(cpu->env.cpucfg[2], CPUCFG2, FP);
3316f5396cSSong Gao }
3416f5396cSSong Gao
3516f5396cSSong Gao static const VMStateDescription vmstate_fpu = {
3616f5396cSSong Gao .name = "cpu/fpu",
3716f5396cSSong Gao .version_id = 1,
3816f5396cSSong Gao .minimum_version_id = 1,
3916f5396cSSong Gao .needed = fpu_needed,
402d23bb1aSRichard Henderson .fields = (const VMStateField[]) {
4116f5396cSSong Gao VMSTATE_FPU_REGS(env.fpr, LoongArchCPU, 0),
4216f5396cSSong Gao VMSTATE_UINT32(env.fcsr0, LoongArchCPU),
4316f5396cSSong Gao VMSTATE_BOOL_ARRAY(env.cf, LoongArchCPU, 8),
4416f5396cSSong Gao VMSTATE_END_OF_LIST()
4516f5396cSSong Gao },
4616f5396cSSong Gao };
4716f5396cSSong Gao
4816f5396cSSong Gao static const VMStateDescription vmstate_lsxh_reg = {
4916f5396cSSong Gao .name = "lsxh_reg",
5016f5396cSSong Gao .version_id = 1,
5116f5396cSSong Gao .minimum_version_id = 1,
522d23bb1aSRichard Henderson .fields = (const VMStateField[]) {
5316f5396cSSong Gao VMSTATE_UINT64(UD(1), VReg),
5416f5396cSSong Gao VMSTATE_END_OF_LIST()
5516f5396cSSong Gao }
5616f5396cSSong Gao };
5716f5396cSSong Gao
5816f5396cSSong Gao #define VMSTATE_LSXH_REGS(_field, _state, _start) \
5916f5396cSSong Gao VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, 32, 0, \
6016f5396cSSong Gao vmstate_lsxh_reg, fpr_t)
6116f5396cSSong Gao
lsx_needed(void * opaque)6216f5396cSSong Gao static bool lsx_needed(void *opaque)
6316f5396cSSong Gao {
6416f5396cSSong Gao LoongArchCPU *cpu = opaque;
6516f5396cSSong Gao
6616f5396cSSong Gao return FIELD_EX64(cpu->env.cpucfg[2], CPUCFG2, LSX);
6716f5396cSSong Gao }
6816f5396cSSong Gao
6916f5396cSSong Gao static const VMStateDescription vmstate_lsx = {
7016f5396cSSong Gao .name = "cpu/lsx",
7116f5396cSSong Gao .version_id = 1,
7216f5396cSSong Gao .minimum_version_id = 1,
7316f5396cSSong Gao .needed = lsx_needed,
742d23bb1aSRichard Henderson .fields = (const VMStateField[]) {
7516f5396cSSong Gao VMSTATE_LSXH_REGS(env.fpr, LoongArchCPU, 0),
7616f5396cSSong Gao VMSTATE_END_OF_LIST()
7716f5396cSSong Gao },
7816f5396cSSong Gao };
7916f5396cSSong Gao
80008a3b16SSong Gao static const VMStateDescription vmstate_lasxh_reg = {
81008a3b16SSong Gao .name = "lasxh_reg",
82008a3b16SSong Gao .version_id = 1,
83008a3b16SSong Gao .minimum_version_id = 1,
842d23bb1aSRichard Henderson .fields = (const VMStateField[]) {
85008a3b16SSong Gao VMSTATE_UINT64(UD(2), VReg),
86008a3b16SSong Gao VMSTATE_UINT64(UD(3), VReg),
87008a3b16SSong Gao VMSTATE_END_OF_LIST()
88008a3b16SSong Gao }
89008a3b16SSong Gao };
90008a3b16SSong Gao
91008a3b16SSong Gao #define VMSTATE_LASXH_REGS(_field, _state, _start) \
92008a3b16SSong Gao VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, 32, 0, \
93008a3b16SSong Gao vmstate_lasxh_reg, fpr_t)
94008a3b16SSong Gao
lasx_needed(void * opaque)95008a3b16SSong Gao static bool lasx_needed(void *opaque)
96008a3b16SSong Gao {
97008a3b16SSong Gao LoongArchCPU *cpu = opaque;
98008a3b16SSong Gao
99008a3b16SSong Gao return FIELD_EX64(cpu->env.cpucfg[2], CPUCFG2, LASX);
100008a3b16SSong Gao }
101008a3b16SSong Gao
102008a3b16SSong Gao static const VMStateDescription vmstate_lasx = {
103008a3b16SSong Gao .name = "cpu/lasx",
104008a3b16SSong Gao .version_id = 1,
105008a3b16SSong Gao .minimum_version_id = 1,
106008a3b16SSong Gao .needed = lasx_needed,
1072d23bb1aSRichard Henderson .fields = (const VMStateField[]) {
108008a3b16SSong Gao VMSTATE_LASXH_REGS(env.fpr, LoongArchCPU, 0),
109008a3b16SSong Gao VMSTATE_END_OF_LIST()
110008a3b16SSong Gao },
111008a3b16SSong Gao };
112008a3b16SSong Gao
lbt_needed(void * opaque)113a45df286SBibo Mao static bool lbt_needed(void *opaque)
114a45df286SBibo Mao {
115a45df286SBibo Mao LoongArchCPU *cpu = opaque;
116a45df286SBibo Mao
117a45df286SBibo Mao return !!FIELD_EX64(cpu->env.cpucfg[2], CPUCFG2, LBT_ALL);
118a45df286SBibo Mao }
119a45df286SBibo Mao
120a45df286SBibo Mao static const VMStateDescription vmstate_lbt = {
121a45df286SBibo Mao .name = "cpu/lbt",
122a45df286SBibo Mao .version_id = 0,
123a45df286SBibo Mao .minimum_version_id = 0,
124a45df286SBibo Mao .needed = lbt_needed,
125a45df286SBibo Mao .fields = (const VMStateField[]) {
126a45df286SBibo Mao VMSTATE_UINT64(env.lbt.scr0, LoongArchCPU),
127a45df286SBibo Mao VMSTATE_UINT64(env.lbt.scr1, LoongArchCPU),
128a45df286SBibo Mao VMSTATE_UINT64(env.lbt.scr2, LoongArchCPU),
129a45df286SBibo Mao VMSTATE_UINT64(env.lbt.scr3, LoongArchCPU),
130a45df286SBibo Mao VMSTATE_UINT32(env.lbt.eflags, LoongArchCPU),
131a45df286SBibo Mao VMSTATE_UINT32(env.lbt.ftop, LoongArchCPU),
132a45df286SBibo Mao VMSTATE_END_OF_LIST()
133a45df286SBibo Mao },
134a45df286SBibo Mao };
135a45df286SBibo Mao
1366f703a48SBibo Mao #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
tlb_needed(void * opaque)1376f703a48SBibo Mao static bool tlb_needed(void *opaque)
1386f703a48SBibo Mao {
1396f703a48SBibo Mao return tcg_enabled();
1406f703a48SBibo Mao }
1416f703a48SBibo Mao
1427e1c521eSXiaojuan Yang /* TLB state */
1436f703a48SBibo Mao static const VMStateDescription vmstate_tlb_entry = {
1446f703a48SBibo Mao .name = "cpu/tlb_entry",
1457e1c521eSXiaojuan Yang .version_id = 0,
1467e1c521eSXiaojuan Yang .minimum_version_id = 0,
1472d23bb1aSRichard Henderson .fields = (const VMStateField[]) {
1487e1c521eSXiaojuan Yang VMSTATE_UINT64(tlb_misc, LoongArchTLB),
1497e1c521eSXiaojuan Yang VMSTATE_UINT64(tlb_entry0, LoongArchTLB),
1507e1c521eSXiaojuan Yang VMSTATE_UINT64(tlb_entry1, LoongArchTLB),
1517e1c521eSXiaojuan Yang VMSTATE_END_OF_LIST()
1527e1c521eSXiaojuan Yang }
1537e1c521eSXiaojuan Yang };
15467ebd42aSXiaojuan Yang
1556f703a48SBibo Mao static const VMStateDescription vmstate_tlb = {
1566f703a48SBibo Mao .name = "cpu/tlb",
1576f703a48SBibo Mao .version_id = 0,
1586f703a48SBibo Mao .minimum_version_id = 0,
1596f703a48SBibo Mao .needed = tlb_needed,
1606f703a48SBibo Mao .fields = (const VMStateField[]) {
1616f703a48SBibo Mao VMSTATE_STRUCT_ARRAY(env.tlb, LoongArchCPU, LOONGARCH_TLB_MAX,
1626f703a48SBibo Mao 0, vmstate_tlb_entry, LoongArchTLB),
1636f703a48SBibo Mao VMSTATE_END_OF_LIST()
1646f703a48SBibo Mao }
1656f703a48SBibo Mao };
1666f703a48SBibo Mao #endif
1676f703a48SBibo Mao
16867ebd42aSXiaojuan Yang /* LoongArch CPU state */
16967ebd42aSXiaojuan Yang const VMStateDescription vmstate_loongarch_cpu = {
17067ebd42aSXiaojuan Yang .name = "cpu",
17147b54e15SBibo Mao .version_id = 3,
17247b54e15SBibo Mao .minimum_version_id = 3,
1732d23bb1aSRichard Henderson .fields = (const VMStateField[]) {
17467ebd42aSXiaojuan Yang VMSTATE_UINTTL_ARRAY(env.gpr, LoongArchCPU, 32),
17567ebd42aSXiaojuan Yang VMSTATE_UINTTL(env.pc, LoongArchCPU),
17667ebd42aSXiaojuan Yang
17767ebd42aSXiaojuan Yang /* Remaining CSRs */
17867ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_CRMD, LoongArchCPU),
17967ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_PRMD, LoongArchCPU),
18067ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_EUEN, LoongArchCPU),
18167ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_MISC, LoongArchCPU),
18267ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_ECFG, LoongArchCPU),
18367ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_ESTAT, LoongArchCPU),
18467ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_ERA, LoongArchCPU),
18567ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_BADV, LoongArchCPU),
18667ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_BADI, LoongArchCPU),
18767ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_EENTRY, LoongArchCPU),
18867ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_TLBIDX, LoongArchCPU),
18967ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_TLBEHI, LoongArchCPU),
19067ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_TLBELO0, LoongArchCPU),
19167ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_TLBELO1, LoongArchCPU),
19267ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_ASID, LoongArchCPU),
19367ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_PGDL, LoongArchCPU),
19467ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_PGDH, LoongArchCPU),
19567ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_PGD, LoongArchCPU),
19667ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_PWCL, LoongArchCPU),
19767ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_PWCH, LoongArchCPU),
19867ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_STLBPS, LoongArchCPU),
19967ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_RVACFG, LoongArchCPU),
20067ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_PRCFG1, LoongArchCPU),
20167ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_PRCFG2, LoongArchCPU),
20267ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_PRCFG3, LoongArchCPU),
20367ebd42aSXiaojuan Yang VMSTATE_UINT64_ARRAY(env.CSR_SAVE, LoongArchCPU, 16),
20467ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_TID, LoongArchCPU),
20567ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_TCFG, LoongArchCPU),
20667ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_TVAL, LoongArchCPU),
20767ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_CNTC, LoongArchCPU),
20867ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_TICLR, LoongArchCPU),
20967ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_LLBCTL, LoongArchCPU),
21067ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_IMPCTL1, LoongArchCPU),
21167ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_IMPCTL2, LoongArchCPU),
21267ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_TLBRENTRY, LoongArchCPU),
21367ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_TLBRBADV, LoongArchCPU),
21467ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_TLBRERA, LoongArchCPU),
21567ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_TLBRSAVE, LoongArchCPU),
21667ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_TLBRELO0, LoongArchCPU),
21767ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_TLBRELO1, LoongArchCPU),
21867ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_TLBREHI, LoongArchCPU),
21967ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_TLBRPRMD, LoongArchCPU),
22067ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_MERRCTL, LoongArchCPU),
22167ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_MERRINFO1, LoongArchCPU),
22267ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_MERRINFO2, LoongArchCPU),
22367ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_MERRENTRY, LoongArchCPU),
22467ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_MERRERA, LoongArchCPU),
22567ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_MERRSAVE, LoongArchCPU),
22667ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_CTAG, LoongArchCPU),
22767ebd42aSXiaojuan Yang VMSTATE_UINT64_ARRAY(env.CSR_DMW, LoongArchCPU, 4),
22867ebd42aSXiaojuan Yang
22967ebd42aSXiaojuan Yang /* Debug CSRs */
23067ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_DBG, LoongArchCPU),
23167ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_DERA, LoongArchCPU),
23267ebd42aSXiaojuan Yang VMSTATE_UINT64(env.CSR_DSAVE, LoongArchCPU),
23367ebd42aSXiaojuan Yang
2340eb285c3SSong Gao VMSTATE_UINT64(kvm_state_counter, LoongArchCPU),
23547b54e15SBibo Mao /* PV steal time */
23647b54e15SBibo Mao VMSTATE_UINT64(env.stealtime.guest_addr, LoongArchCPU),
2370eb285c3SSong Gao
23867ebd42aSXiaojuan Yang VMSTATE_END_OF_LIST()
23967ebd42aSXiaojuan Yang },
2402d23bb1aSRichard Henderson .subsections = (const VMStateDescription * const []) {
24116f5396cSSong Gao &vmstate_fpu,
24216f5396cSSong Gao &vmstate_lsx,
243008a3b16SSong Gao &vmstate_lasx,
2446f703a48SBibo Mao #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
2456f703a48SBibo Mao &vmstate_tlb,
2466f703a48SBibo Mao #endif
247a45df286SBibo Mao &vmstate_lbt,
2487534695bSRichard Henderson NULL
24916f5396cSSong Gao }
25067ebd42aSXiaojuan Yang };
251