1#include "cpu.h" 2#include "hw/hw.h" 3#include "hw/boards.h" 4 5void cpu_save(QEMUFile *f, void *opaque) 6{ 7 int i; 8 CPUARMState *env = (CPUARMState *)opaque; 9 10 for (i = 0; i < 16; i++) { 11 qemu_put_be32(f, env->regs[i]); 12 } 13 qemu_put_be32(f, cpsr_read(env)); 14 qemu_put_be32(f, env->spsr); 15 for (i = 0; i < 6; i++) { 16 qemu_put_be32(f, env->banked_spsr[i]); 17 qemu_put_be32(f, env->banked_r13[i]); 18 qemu_put_be32(f, env->banked_r14[i]); 19 } 20 for (i = 0; i < 5; i++) { 21 qemu_put_be32(f, env->usr_regs[i]); 22 qemu_put_be32(f, env->fiq_regs[i]); 23 } 24 qemu_put_be32(f, env->cp15.c0_cpuid); 25 qemu_put_be32(f, env->cp15.c0_cachetype); 26 qemu_put_be32(f, env->cp15.c0_cssel); 27 qemu_put_be32(f, env->cp15.c1_sys); 28 qemu_put_be32(f, env->cp15.c1_coproc); 29 qemu_put_be32(f, env->cp15.c1_xscaleauxcr); 30 qemu_put_be32(f, env->cp15.c1_secfg); 31 qemu_put_be32(f, env->cp15.c1_sedbg); 32 qemu_put_be32(f, env->cp15.c1_nseac); 33 qemu_put_be32(f, env->cp15.c2_base0); 34 qemu_put_be32(f, env->cp15.c2_base1); 35 qemu_put_be32(f, env->cp15.c2_control); 36 qemu_put_be32(f, env->cp15.c2_mask); 37 qemu_put_be32(f, env->cp15.c2_base_mask); 38 qemu_put_be32(f, env->cp15.c2_data); 39 qemu_put_be32(f, env->cp15.c2_insn); 40 qemu_put_be32(f, env->cp15.c3); 41 qemu_put_be32(f, env->cp15.c5_insn); 42 qemu_put_be32(f, env->cp15.c5_data); 43 for (i = 0; i < 8; i++) { 44 qemu_put_be32(f, env->cp15.c6_region[i]); 45 } 46 qemu_put_be32(f, env->cp15.c6_insn); 47 qemu_put_be32(f, env->cp15.c6_data); 48 qemu_put_be32(f, env->cp15.c7_par); 49 qemu_put_be32(f, env->cp15.c9_insn); 50 qemu_put_be32(f, env->cp15.c9_data); 51 qemu_put_be32(f, env->cp15.c9_pmcr); 52 qemu_put_be32(f, env->cp15.c9_pmcnten); 53 qemu_put_be32(f, env->cp15.c9_pmovsr); 54 qemu_put_be32(f, env->cp15.c9_pmxevtyper); 55 qemu_put_be32(f, env->cp15.c9_pmuserenr); 56 qemu_put_be32(f, env->cp15.c9_pminten); 57 qemu_put_be32(f, env->cp15.c13_fcse); 58 qemu_put_be32(f, env->cp15.c13_context); 59 qemu_put_be32(f, env->cp15.c13_tls1); 60 qemu_put_be32(f, env->cp15.c13_tls2); 61 qemu_put_be32(f, env->cp15.c13_tls3); 62 qemu_put_be32(f, env->cp15.c15_cpar); 63 64 qemu_put_be32(f, env->cp14_dbgdidr); 65 66 qemu_put_be32(f, env->features); 67 68 if (arm_feature(env, ARM_FEATURE_VFP)) { 69 for (i = 0; i < 16; i++) { 70 CPU_DoubleU u; 71 u.d = env->vfp.regs[i]; 72 qemu_put_be32(f, u.l.upper); 73 qemu_put_be32(f, u.l.lower); 74 } 75 for (i = 0; i < 16; i++) { 76 qemu_put_be32(f, env->vfp.xregs[i]); 77 } 78 79 /* TODO: Should use proper FPSCR access functions. */ 80 qemu_put_be32(f, env->vfp.vec_len); 81 qemu_put_be32(f, env->vfp.vec_stride); 82 83 if (arm_feature(env, ARM_FEATURE_VFP3)) { 84 for (i = 16; i < 32; i++) { 85 CPU_DoubleU u; 86 u.d = env->vfp.regs[i]; 87 qemu_put_be32(f, u.l.upper); 88 qemu_put_be32(f, u.l.lower); 89 } 90 } 91 } 92 93 if (arm_feature(env, ARM_FEATURE_IWMMXT)) { 94 for (i = 0; i < 16; i++) { 95 qemu_put_be64(f, env->iwmmxt.regs[i]); 96 } 97 for (i = 0; i < 16; i++) { 98 qemu_put_be32(f, env->iwmmxt.cregs[i]); 99 } 100 } 101 102 if (arm_feature(env, ARM_FEATURE_M)) { 103 qemu_put_be32(f, env->v7m.other_sp); 104 qemu_put_be32(f, env->v7m.vecbase); 105 qemu_put_be32(f, env->v7m.basepri); 106 qemu_put_be32(f, env->v7m.control); 107 qemu_put_be32(f, env->v7m.current_sp); 108 qemu_put_be32(f, env->v7m.exception); 109 } 110 111 if (arm_feature(env, ARM_FEATURE_THUMB2EE)) { 112 qemu_put_be32(f, env->teecr); 113 qemu_put_be32(f, env->teehbr); 114 } 115} 116 117#define CPU_SAVE_VERSION_LEGACY 3 118 119int cpu_load(QEMUFile *f, void *opaque, int version_id) 120{ 121 CPUARMState *env = (CPUARMState *)opaque; 122 int i; 123 uint32_t val; 124 125 if (version_id != CPU_SAVE_VERSION && version_id != CPU_SAVE_VERSION_LEGACY) 126 return -EINVAL; 127 128 for (i = 0; i < 16; i++) { 129 env->regs[i] = qemu_get_be32(f); 130 } 131 val = qemu_get_be32(f); 132 /* Avoid mode switch when restoring CPSR. */ 133 env->uncached_cpsr = val & CPSR_M; 134 cpsr_write(env, val, 0xffffffff); 135 env->spsr = qemu_get_be32(f); 136 for (i = 0; i < 6; i++) { 137 env->banked_spsr[i] = qemu_get_be32(f); 138 env->banked_r13[i] = qemu_get_be32(f); 139 env->banked_r14[i] = qemu_get_be32(f); 140 } 141 for (i = 0; i < 5; i++) { 142 env->usr_regs[i] = qemu_get_be32(f); 143 env->fiq_regs[i] = qemu_get_be32(f); 144 } 145 env->cp15.c0_cpuid = qemu_get_be32(f); 146 env->cp15.c0_cachetype = qemu_get_be32(f); 147 env->cp15.c0_cssel = qemu_get_be32(f); 148 env->cp15.c1_sys = qemu_get_be32(f); 149 env->cp15.c1_coproc = qemu_get_be32(f); 150 env->cp15.c1_xscaleauxcr = qemu_get_be32(f); 151 env->cp15.c1_secfg = qemu_get_be32(f); 152 env->cp15.c1_sedbg = qemu_get_be32(f); 153 env->cp15.c1_nseac = qemu_get_be32(f); 154 env->cp15.c2_base0 = qemu_get_be32(f); 155 env->cp15.c2_base1 = qemu_get_be32(f); 156 env->cp15.c2_control = qemu_get_be32(f); 157 env->cp15.c2_mask = qemu_get_be32(f); 158 env->cp15.c2_base_mask = qemu_get_be32(f); 159 env->cp15.c2_data = qemu_get_be32(f); 160 env->cp15.c2_insn = qemu_get_be32(f); 161 env->cp15.c3 = qemu_get_be32(f); 162 env->cp15.c5_insn = qemu_get_be32(f); 163 env->cp15.c5_data = qemu_get_be32(f); 164 for (i = 0; i < 8; i++) { 165 env->cp15.c6_region[i] = qemu_get_be32(f); 166 } 167 env->cp15.c6_insn = qemu_get_be32(f); 168 env->cp15.c6_data = qemu_get_be32(f); 169 env->cp15.c7_par = qemu_get_be32(f); 170 env->cp15.c9_insn = qemu_get_be32(f); 171 env->cp15.c9_data = qemu_get_be32(f); 172 if (version_id == CPU_SAVE_VERSION_LEGACY) { 173 (void)qemu_get_be32(f); 174 (void)qemu_get_be32(f); 175 (void)qemu_get_be32(f); 176 } else { 177 env->cp15.c9_pmcr = qemu_get_be32(f); 178 env->cp15.c9_pmcnten = qemu_get_be32(f); 179 env->cp15.c9_pmovsr = qemu_get_be32(f); 180 env->cp15.c9_pmxevtyper = qemu_get_be32(f); 181 env->cp15.c9_pmuserenr = qemu_get_be32(f); 182 env->cp15.c9_pminten = qemu_get_be32(f); 183 } 184 env->cp15.c13_fcse = qemu_get_be32(f); 185 env->cp15.c13_context = qemu_get_be32(f); 186 env->cp15.c13_tls1 = qemu_get_be32(f); 187 env->cp15.c13_tls2 = qemu_get_be32(f); 188 env->cp15.c13_tls3 = qemu_get_be32(f); 189 env->cp15.c15_cpar = qemu_get_be32(f); 190 191 env->cp14_dbgdidr = qemu_get_be32(f); 192 193 env->features = qemu_get_be32(f); 194 195 if (arm_feature(env, ARM_FEATURE_VFP)) { 196 for (i = 0; i < 16; i++) { 197 CPU_DoubleU u; 198 u.l.upper = qemu_get_be32(f); 199 u.l.lower = qemu_get_be32(f); 200 env->vfp.regs[i] = u.d; 201 } 202 for (i = 0; i < 16; i++) { 203 env->vfp.xregs[i] = qemu_get_be32(f); 204 } 205 206 /* TODO: Should use proper FPSCR access functions. */ 207 env->vfp.vec_len = qemu_get_be32(f); 208 env->vfp.vec_stride = qemu_get_be32(f); 209 210 if (arm_feature(env, ARM_FEATURE_VFP3)) { 211 for (i = 0; i < 16; i++) { 212 CPU_DoubleU u; 213 u.l.upper = qemu_get_be32(f); 214 u.l.lower = qemu_get_be32(f); 215 env->vfp.regs[i] = u.d; 216 } 217 } 218 } 219 220 if (arm_feature(env, ARM_FEATURE_IWMMXT)) { 221 for (i = 0; i < 16; i++) { 222 env->iwmmxt.regs[i] = qemu_get_be64(f); 223 } 224 for (i = 0; i < 16; i++) { 225 env->iwmmxt.cregs[i] = qemu_get_be32(f); 226 } 227 } 228 229 if (arm_feature(env, ARM_FEATURE_M)) { 230 env->v7m.other_sp = qemu_get_be32(f); 231 env->v7m.vecbase = qemu_get_be32(f); 232 env->v7m.basepri = qemu_get_be32(f); 233 env->v7m.control = qemu_get_be32(f); 234 env->v7m.current_sp = qemu_get_be32(f); 235 env->v7m.exception = qemu_get_be32(f); 236 } 237 238 if (arm_feature(env, ARM_FEATURE_THUMB2EE)) { 239 env->teecr = qemu_get_be32(f); 240 env->teehbr = qemu_get_be32(f); 241 } 242 243 return 0; 244} 245