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