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