]> git.proxmox.com Git - qemu.git/blob - target-arm/machine.c
target-arm: port ARM CPU save/load to use VMState
[qemu.git] / target-arm / machine.c
1 #include "hw/hw.h"
2 #include "hw/boards.h"
3
4 static bool vfp_needed(void *opaque)
5 {
6 ARMCPU *cpu = opaque;
7 CPUARMState *env = &cpu->env;
8
9 return arm_feature(env, ARM_FEATURE_VFP);
10 }
11
12 static const VMStateDescription vmstate_vfp = {
13 .name = "cpu/vfp",
14 .version_id = 1,
15 .minimum_version_id = 1,
16 .minimum_version_id_old = 1,
17 .fields = (VMStateField[]) {
18 VMSTATE_FLOAT64_ARRAY(env.vfp.regs, ARMCPU, 32),
19 VMSTATE_UINT32_ARRAY(env.vfp.xregs, ARMCPU, 16),
20 /* TODO: Should use proper FPSCR access functions. */
21 VMSTATE_INT32(env.vfp.vec_len, ARMCPU),
22 VMSTATE_INT32(env.vfp.vec_stride, ARMCPU),
23 VMSTATE_END_OF_LIST()
24 }
25 };
26
27 static bool iwmmxt_needed(void *opaque)
28 {
29 ARMCPU *cpu = opaque;
30 CPUARMState *env = &cpu->env;
31
32 return arm_feature(env, ARM_FEATURE_IWMMXT);
33 }
34
35 static const VMStateDescription vmstate_iwmmxt = {
36 .name = "cpu/iwmmxt",
37 .version_id = 1,
38 .minimum_version_id = 1,
39 .minimum_version_id_old = 1,
40 .fields = (VMStateField[]) {
41 VMSTATE_UINT64_ARRAY(env.iwmmxt.regs, ARMCPU, 16),
42 VMSTATE_UINT32_ARRAY(env.iwmmxt.cregs, ARMCPU, 16),
43 VMSTATE_END_OF_LIST()
44 }
45 };
46
47 static bool m_needed(void *opaque)
48 {
49 ARMCPU *cpu = opaque;
50 CPUARMState *env = &cpu->env;
51
52 return arm_feature(env, ARM_FEATURE_M);
53 }
54
55 const VMStateDescription vmstate_m = {
56 .name = "cpu/m",
57 .version_id = 1,
58 .minimum_version_id = 1,
59 .minimum_version_id_old = 1,
60 .fields = (VMStateField[]) {
61 VMSTATE_UINT32(env.v7m.other_sp, ARMCPU),
62 VMSTATE_UINT32(env.v7m.vecbase, ARMCPU),
63 VMSTATE_UINT32(env.v7m.basepri, ARMCPU),
64 VMSTATE_UINT32(env.v7m.control, ARMCPU),
65 VMSTATE_INT32(env.v7m.current_sp, ARMCPU),
66 VMSTATE_INT32(env.v7m.exception, ARMCPU),
67 VMSTATE_END_OF_LIST()
68 }
69 };
70
71 static bool thumb2ee_needed(void *opaque)
72 {
73 ARMCPU *cpu = opaque;
74 CPUARMState *env = &cpu->env;
75
76 return arm_feature(env, ARM_FEATURE_THUMB2EE);
77 }
78
79 static const VMStateDescription vmstate_thumb2ee = {
80 .name = "cpu/thumb2ee",
81 .version_id = 1,
82 .minimum_version_id = 1,
83 .minimum_version_id_old = 1,
84 .fields = (VMStateField[]) {
85 VMSTATE_UINT32(env.teecr, ARMCPU),
86 VMSTATE_UINT32(env.teehbr, ARMCPU),
87 VMSTATE_END_OF_LIST()
88 }
89 };
90
91 static int get_cpsr(QEMUFile *f, void *opaque, size_t size)
92 {
93 ARMCPU *cpu = opaque;
94 CPUARMState *env = &cpu->env;
95 uint32_t val = qemu_get_be32(f);
96
97 /* Avoid mode switch when restoring CPSR */
98 env->uncached_cpsr = val & CPSR_M;
99 cpsr_write(env, val, 0xffffffff);
100 return 0;
101 }
102
103 static void put_cpsr(QEMUFile *f, void *opaque, size_t size)
104 {
105 ARMCPU *cpu = opaque;
106 CPUARMState *env = &cpu->env;
107
108 qemu_put_be32(f, cpsr_read(env));
109 }
110
111 static const VMStateInfo vmstate_cpsr = {
112 .name = "cpsr",
113 .get = get_cpsr,
114 .put = put_cpsr,
115 };
116
117 const VMStateDescription vmstate_arm_cpu = {
118 .name = "cpu",
119 .version_id = 10,
120 .minimum_version_id = 10,
121 .minimum_version_id_old = 10,
122 .fields = (VMStateField[]) {
123 VMSTATE_UINT32_ARRAY(env.regs, ARMCPU, 16),
124 {
125 .name = "cpsr",
126 .version_id = 0,
127 .size = sizeof(uint32_t),
128 .info = &vmstate_cpsr,
129 .flags = VMS_SINGLE,
130 .offset = 0,
131 },
132 VMSTATE_UINT32(env.spsr, ARMCPU),
133 VMSTATE_UINT32_ARRAY(env.banked_spsr, ARMCPU, 6),
134 VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 6),
135 VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 6),
136 VMSTATE_UINT32_ARRAY(env.usr_regs, ARMCPU, 5),
137 VMSTATE_UINT32_ARRAY(env.fiq_regs, ARMCPU, 5),
138 VMSTATE_UINT32(env.cp15.c0_cpuid, ARMCPU),
139 VMSTATE_UINT32(env.cp15.c0_cssel, ARMCPU),
140 VMSTATE_UINT32(env.cp15.c1_sys, ARMCPU),
141 VMSTATE_UINT32(env.cp15.c1_coproc, ARMCPU),
142 VMSTATE_UINT32(env.cp15.c1_xscaleauxcr, ARMCPU),
143 VMSTATE_UINT32(env.cp15.c1_scr, ARMCPU),
144 VMSTATE_UINT32(env.cp15.c2_base0, ARMCPU),
145 VMSTATE_UINT32(env.cp15.c2_base0_hi, ARMCPU),
146 VMSTATE_UINT32(env.cp15.c2_base1, ARMCPU),
147 VMSTATE_UINT32(env.cp15.c2_base1_hi, ARMCPU),
148 VMSTATE_UINT32(env.cp15.c2_control, ARMCPU),
149 VMSTATE_UINT32(env.cp15.c2_mask, ARMCPU),
150 VMSTATE_UINT32(env.cp15.c2_base_mask, ARMCPU),
151 VMSTATE_UINT32(env.cp15.c2_data, ARMCPU),
152 VMSTATE_UINT32(env.cp15.c2_insn, ARMCPU),
153 VMSTATE_UINT32(env.cp15.c3, ARMCPU),
154 VMSTATE_UINT32(env.cp15.c5_insn, ARMCPU),
155 VMSTATE_UINT32(env.cp15.c5_data, ARMCPU),
156 VMSTATE_UINT32_ARRAY(env.cp15.c6_region, ARMCPU, 8),
157 VMSTATE_UINT32(env.cp15.c6_insn, ARMCPU),
158 VMSTATE_UINT32(env.cp15.c6_data, ARMCPU),
159 VMSTATE_UINT32(env.cp15.c7_par, ARMCPU),
160 VMSTATE_UINT32(env.cp15.c7_par_hi, ARMCPU),
161 VMSTATE_UINT32(env.cp15.c9_insn, ARMCPU),
162 VMSTATE_UINT32(env.cp15.c9_data, ARMCPU),
163 VMSTATE_UINT32(env.cp15.c9_pmcr, ARMCPU),
164 VMSTATE_UINT32(env.cp15.c9_pmcnten, ARMCPU),
165 VMSTATE_UINT32(env.cp15.c9_pmovsr, ARMCPU),
166 VMSTATE_UINT32(env.cp15.c9_pmxevtyper, ARMCPU),
167 VMSTATE_UINT32(env.cp15.c9_pmuserenr, ARMCPU),
168 VMSTATE_UINT32(env.cp15.c9_pminten, ARMCPU),
169 VMSTATE_UINT32(env.cp15.c13_fcse, ARMCPU),
170 VMSTATE_UINT32(env.cp15.c13_context, ARMCPU),
171 VMSTATE_UINT32(env.cp15.c13_tls1, ARMCPU),
172 VMSTATE_UINT32(env.cp15.c13_tls2, ARMCPU),
173 VMSTATE_UINT32(env.cp15.c13_tls3, ARMCPU),
174 VMSTATE_UINT32(env.cp15.c15_cpar, ARMCPU),
175 VMSTATE_UINT32(env.cp15.c15_power_control, ARMCPU),
176 VMSTATE_UINT32(env.cp15.c15_diagnostic, ARMCPU),
177 VMSTATE_UINT32(env.cp15.c15_power_diagnostic, ARMCPU),
178 VMSTATE_UINT64(env.features, ARMCPU),
179 VMSTATE_END_OF_LIST()
180 },
181 .subsections = (VMStateSubsection[]) {
182 {
183 .vmsd = &vmstate_vfp,
184 .needed = vfp_needed,
185 } , {
186 .vmsd = &vmstate_iwmmxt,
187 .needed = iwmmxt_needed,
188 } , {
189 .vmsd = &vmstate_m,
190 .needed = m_needed,
191 } , {
192 .vmsd = &vmstate_thumb2ee,
193 .needed = thumb2ee_needed,
194 } , {
195 /* empty */
196 }
197 }
198 };