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