]>
Commit | Line | Data |
---|---|---|
8dd3dca3 AJ |
1 | #include "hw/hw.h" |
2 | #include "hw/boards.h" | |
3 | ||
3cc1d208 | 4 | static bool vfp_needed(void *opaque) |
8dd3dca3 | 5 | { |
3cc1d208 JQ |
6 | ARMCPU *cpu = opaque; |
7 | CPUARMState *env = &cpu->env; | |
8dd3dca3 | 8 | |
3cc1d208 JQ |
9 | return arm_feature(env, ARM_FEATURE_VFP); |
10 | } | |
8dd3dca3 | 11 | |
e91f229a PM |
12 | static int get_fpscr(QEMUFile *f, void *opaque, size_t size) |
13 | { | |
14 | ARMCPU *cpu = opaque; | |
15 | CPUARMState *env = &cpu->env; | |
16 | uint32_t val = qemu_get_be32(f); | |
17 | ||
18 | vfp_set_fpscr(env, val); | |
19 | return 0; | |
20 | } | |
21 | ||
22 | static void put_fpscr(QEMUFile *f, void *opaque, size_t size) | |
23 | { | |
24 | ARMCPU *cpu = opaque; | |
25 | CPUARMState *env = &cpu->env; | |
26 | ||
27 | qemu_put_be32(f, vfp_get_fpscr(env)); | |
28 | } | |
29 | ||
30 | static const VMStateInfo vmstate_fpscr = { | |
31 | .name = "fpscr", | |
32 | .get = get_fpscr, | |
33 | .put = put_fpscr, | |
34 | }; | |
35 | ||
3cc1d208 JQ |
36 | static const VMStateDescription vmstate_vfp = { |
37 | .name = "cpu/vfp", | |
e91f229a PM |
38 | .version_id = 2, |
39 | .minimum_version_id = 2, | |
40 | .minimum_version_id_old = 2, | |
3cc1d208 JQ |
41 | .fields = (VMStateField[]) { |
42 | VMSTATE_FLOAT64_ARRAY(env.vfp.regs, ARMCPU, 32), | |
e91f229a PM |
43 | /* The xregs array is a little awkward because element 1 (FPSCR) |
44 | * requires a specific accessor, so we have to split it up in | |
45 | * the vmstate: | |
46 | */ | |
47 | VMSTATE_UINT32(env.vfp.xregs[0], ARMCPU), | |
48 | VMSTATE_UINT32_SUB_ARRAY(env.vfp.xregs, ARMCPU, 2, 14), | |
49 | { | |
50 | .name = "fpscr", | |
51 | .version_id = 0, | |
52 | .size = sizeof(uint32_t), | |
53 | .info = &vmstate_fpscr, | |
54 | .flags = VMS_SINGLE, | |
55 | .offset = 0, | |
56 | }, | |
3cc1d208 | 57 | VMSTATE_END_OF_LIST() |
8dd3dca3 | 58 | } |
3cc1d208 | 59 | }; |
8dd3dca3 | 60 | |
3cc1d208 JQ |
61 | static bool iwmmxt_needed(void *opaque) |
62 | { | |
63 | ARMCPU *cpu = opaque; | |
64 | CPUARMState *env = &cpu->env; | |
8dd3dca3 | 65 | |
3cc1d208 JQ |
66 | return arm_feature(env, ARM_FEATURE_IWMMXT); |
67 | } | |
ffe47d33 | 68 | |
3cc1d208 JQ |
69 | static const VMStateDescription vmstate_iwmmxt = { |
70 | .name = "cpu/iwmmxt", | |
71 | .version_id = 1, | |
72 | .minimum_version_id = 1, | |
73 | .minimum_version_id_old = 1, | |
74 | .fields = (VMStateField[]) { | |
75 | VMSTATE_UINT64_ARRAY(env.iwmmxt.regs, ARMCPU, 16), | |
76 | VMSTATE_UINT32_ARRAY(env.iwmmxt.cregs, ARMCPU, 16), | |
77 | VMSTATE_END_OF_LIST() | |
ffe47d33 | 78 | } |
3cc1d208 JQ |
79 | }; |
80 | ||
81 | static bool m_needed(void *opaque) | |
82 | { | |
83 | ARMCPU *cpu = opaque; | |
84 | CPUARMState *env = &cpu->env; | |
85 | ||
86 | return arm_feature(env, ARM_FEATURE_M); | |
8dd3dca3 AJ |
87 | } |
88 | ||
3cc1d208 JQ |
89 | const VMStateDescription vmstate_m = { |
90 | .name = "cpu/m", | |
91 | .version_id = 1, | |
92 | .minimum_version_id = 1, | |
93 | .minimum_version_id_old = 1, | |
94 | .fields = (VMStateField[]) { | |
95 | VMSTATE_UINT32(env.v7m.other_sp, ARMCPU), | |
96 | VMSTATE_UINT32(env.v7m.vecbase, ARMCPU), | |
97 | VMSTATE_UINT32(env.v7m.basepri, ARMCPU), | |
98 | VMSTATE_UINT32(env.v7m.control, ARMCPU), | |
99 | VMSTATE_INT32(env.v7m.current_sp, ARMCPU), | |
100 | VMSTATE_INT32(env.v7m.exception, ARMCPU), | |
101 | VMSTATE_END_OF_LIST() | |
102 | } | |
103 | }; | |
104 | ||
105 | static bool thumb2ee_needed(void *opaque) | |
8dd3dca3 | 106 | { |
3cc1d208 JQ |
107 | ARMCPU *cpu = opaque; |
108 | CPUARMState *env = &cpu->env; | |
8dd3dca3 | 109 | |
3cc1d208 JQ |
110 | return arm_feature(env, ARM_FEATURE_THUMB2EE); |
111 | } | |
8dd3dca3 | 112 | |
3cc1d208 JQ |
113 | static const VMStateDescription vmstate_thumb2ee = { |
114 | .name = "cpu/thumb2ee", | |
115 | .version_id = 1, | |
116 | .minimum_version_id = 1, | |
117 | .minimum_version_id_old = 1, | |
118 | .fields = (VMStateField[]) { | |
119 | VMSTATE_UINT32(env.teecr, ARMCPU), | |
120 | VMSTATE_UINT32(env.teehbr, ARMCPU), | |
121 | VMSTATE_END_OF_LIST() | |
8dd3dca3 | 122 | } |
3cc1d208 JQ |
123 | }; |
124 | ||
125 | static int get_cpsr(QEMUFile *f, void *opaque, size_t size) | |
126 | { | |
127 | ARMCPU *cpu = opaque; | |
128 | CPUARMState *env = &cpu->env; | |
129 | uint32_t val = qemu_get_be32(f); | |
130 | ||
131 | /* Avoid mode switch when restoring CPSR */ | |
ffe47d33 PB |
132 | env->uncached_cpsr = val & CPSR_M; |
133 | cpsr_write(env, val, 0xffffffff); | |
3cc1d208 JQ |
134 | return 0; |
135 | } | |
8dd3dca3 | 136 | |
3cc1d208 JQ |
137 | static void put_cpsr(QEMUFile *f, void *opaque, size_t size) |
138 | { | |
139 | ARMCPU *cpu = opaque; | |
140 | CPUARMState *env = &cpu->env; | |
8dd3dca3 | 141 | |
3cc1d208 JQ |
142 | qemu_put_be32(f, cpsr_read(env)); |
143 | } | |
8dd3dca3 | 144 | |
3cc1d208 JQ |
145 | static const VMStateInfo vmstate_cpsr = { |
146 | .name = "cpsr", | |
147 | .get = get_cpsr, | |
148 | .put = put_cpsr, | |
149 | }; | |
150 | ||
151 | const VMStateDescription vmstate_arm_cpu = { | |
152 | .name = "cpu", | |
602131e9 PM |
153 | .version_id = 11, |
154 | .minimum_version_id = 11, | |
155 | .minimum_version_id_old = 11, | |
3cc1d208 JQ |
156 | .fields = (VMStateField[]) { |
157 | VMSTATE_UINT32_ARRAY(env.regs, ARMCPU, 16), | |
158 | { | |
159 | .name = "cpsr", | |
160 | .version_id = 0, | |
161 | .size = sizeof(uint32_t), | |
162 | .info = &vmstate_cpsr, | |
163 | .flags = VMS_SINGLE, | |
164 | .offset = 0, | |
165 | }, | |
166 | VMSTATE_UINT32(env.spsr, ARMCPU), | |
167 | VMSTATE_UINT32_ARRAY(env.banked_spsr, ARMCPU, 6), | |
168 | VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 6), | |
169 | VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 6), | |
170 | VMSTATE_UINT32_ARRAY(env.usr_regs, ARMCPU, 5), | |
171 | VMSTATE_UINT32_ARRAY(env.fiq_regs, ARMCPU, 5), | |
172 | VMSTATE_UINT32(env.cp15.c0_cpuid, ARMCPU), | |
173 | VMSTATE_UINT32(env.cp15.c0_cssel, ARMCPU), | |
174 | VMSTATE_UINT32(env.cp15.c1_sys, ARMCPU), | |
175 | VMSTATE_UINT32(env.cp15.c1_coproc, ARMCPU), | |
176 | VMSTATE_UINT32(env.cp15.c1_xscaleauxcr, ARMCPU), | |
177 | VMSTATE_UINT32(env.cp15.c1_scr, ARMCPU), | |
178 | VMSTATE_UINT32(env.cp15.c2_base0, ARMCPU), | |
179 | VMSTATE_UINT32(env.cp15.c2_base0_hi, ARMCPU), | |
180 | VMSTATE_UINT32(env.cp15.c2_base1, ARMCPU), | |
181 | VMSTATE_UINT32(env.cp15.c2_base1_hi, ARMCPU), | |
182 | VMSTATE_UINT32(env.cp15.c2_control, ARMCPU), | |
183 | VMSTATE_UINT32(env.cp15.c2_mask, ARMCPU), | |
184 | VMSTATE_UINT32(env.cp15.c2_base_mask, ARMCPU), | |
185 | VMSTATE_UINT32(env.cp15.c2_data, ARMCPU), | |
186 | VMSTATE_UINT32(env.cp15.c2_insn, ARMCPU), | |
187 | VMSTATE_UINT32(env.cp15.c3, ARMCPU), | |
188 | VMSTATE_UINT32(env.cp15.c5_insn, ARMCPU), | |
189 | VMSTATE_UINT32(env.cp15.c5_data, ARMCPU), | |
190 | VMSTATE_UINT32_ARRAY(env.cp15.c6_region, ARMCPU, 8), | |
191 | VMSTATE_UINT32(env.cp15.c6_insn, ARMCPU), | |
192 | VMSTATE_UINT32(env.cp15.c6_data, ARMCPU), | |
193 | VMSTATE_UINT32(env.cp15.c7_par, ARMCPU), | |
194 | VMSTATE_UINT32(env.cp15.c7_par_hi, ARMCPU), | |
195 | VMSTATE_UINT32(env.cp15.c9_insn, ARMCPU), | |
196 | VMSTATE_UINT32(env.cp15.c9_data, ARMCPU), | |
197 | VMSTATE_UINT32(env.cp15.c9_pmcr, ARMCPU), | |
198 | VMSTATE_UINT32(env.cp15.c9_pmcnten, ARMCPU), | |
199 | VMSTATE_UINT32(env.cp15.c9_pmovsr, ARMCPU), | |
200 | VMSTATE_UINT32(env.cp15.c9_pmxevtyper, ARMCPU), | |
201 | VMSTATE_UINT32(env.cp15.c9_pmuserenr, ARMCPU), | |
202 | VMSTATE_UINT32(env.cp15.c9_pminten, ARMCPU), | |
203 | VMSTATE_UINT32(env.cp15.c13_fcse, ARMCPU), | |
204 | VMSTATE_UINT32(env.cp15.c13_context, ARMCPU), | |
205 | VMSTATE_UINT32(env.cp15.c13_tls1, ARMCPU), | |
206 | VMSTATE_UINT32(env.cp15.c13_tls2, ARMCPU), | |
207 | VMSTATE_UINT32(env.cp15.c13_tls3, ARMCPU), | |
208 | VMSTATE_UINT32(env.cp15.c15_cpar, ARMCPU), | |
602131e9 PM |
209 | VMSTATE_UINT32(env.cp15.c15_ticonfig, ARMCPU), |
210 | VMSTATE_UINT32(env.cp15.c15_i_max, ARMCPU), | |
211 | VMSTATE_UINT32(env.cp15.c15_i_min, ARMCPU), | |
212 | VMSTATE_UINT32(env.cp15.c15_threadid, ARMCPU), | |
3cc1d208 JQ |
213 | VMSTATE_UINT32(env.cp15.c15_power_control, ARMCPU), |
214 | VMSTATE_UINT32(env.cp15.c15_diagnostic, ARMCPU), | |
215 | VMSTATE_UINT32(env.cp15.c15_power_diagnostic, ARMCPU), | |
602131e9 PM |
216 | VMSTATE_UINT32(env.exclusive_addr, ARMCPU), |
217 | VMSTATE_UINT32(env.exclusive_val, ARMCPU), | |
218 | VMSTATE_UINT32(env.exclusive_high, ARMCPU), | |
3cc1d208 JQ |
219 | VMSTATE_UINT64(env.features, ARMCPU), |
220 | VMSTATE_END_OF_LIST() | |
221 | }, | |
222 | .subsections = (VMStateSubsection[]) { | |
223 | { | |
224 | .vmsd = &vmstate_vfp, | |
225 | .needed = vfp_needed, | |
226 | } , { | |
227 | .vmsd = &vmstate_iwmmxt, | |
228 | .needed = iwmmxt_needed, | |
229 | } , { | |
230 | .vmsd = &vmstate_m, | |
231 | .needed = m_needed, | |
232 | } , { | |
233 | .vmsd = &vmstate_thumb2ee, | |
234 | .needed = thumb2ee_needed, | |
235 | } , { | |
236 | /* empty */ | |
237 | } | |
ffe47d33 | 238 | } |
3cc1d208 | 239 | }; |