Commit ffe47d331d4f725567e83375ffc19a36dbdce7f5
1 parent
2814df28
Save/restore ARMv6 MMU state
Correctly save/restore ARMV6 MMU state. Signed-off-by: Paul Brook <paul@codesourcery.com>
Showing
2 changed files
with
22 additions
and
2 deletions
target-arm/cpu.h
... | ... | @@ -405,7 +405,7 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum, |
405 | 405 | #define cpu_signal_handler cpu_arm_signal_handler |
406 | 406 | #define cpu_list arm_cpu_list |
407 | 407 | |
408 | -#define CPU_SAVE_VERSION 1 | |
408 | +#define CPU_SAVE_VERSION 2 | |
409 | 409 | |
410 | 410 | /* MMU modes definitions */ |
411 | 411 | #define MMU_MODE0_SUFFIX _kernel | ... | ... |
target-arm/machine.c
... | ... | @@ -22,12 +22,15 @@ void cpu_save(QEMUFile *f, void *opaque) |
22 | 22 | } |
23 | 23 | qemu_put_be32(f, env->cp15.c0_cpuid); |
24 | 24 | qemu_put_be32(f, env->cp15.c0_cachetype); |
25 | + qemu_put_be32(f, env->cp15.c0_cssel); | |
25 | 26 | qemu_put_be32(f, env->cp15.c1_sys); |
26 | 27 | qemu_put_be32(f, env->cp15.c1_coproc); |
27 | 28 | qemu_put_be32(f, env->cp15.c1_xscaleauxcr); |
28 | 29 | qemu_put_be32(f, env->cp15.c2_base0); |
29 | 30 | qemu_put_be32(f, env->cp15.c2_base1); |
31 | + qemu_put_be32(f, env->cp15.c2_control); | |
30 | 32 | qemu_put_be32(f, env->cp15.c2_mask); |
33 | + qemu_put_be32(f, env->cp15.c2_base_mask); | |
31 | 34 | qemu_put_be32(f, env->cp15.c2_data); |
32 | 35 | qemu_put_be32(f, env->cp15.c2_insn); |
33 | 36 | qemu_put_be32(f, env->cp15.c3); |
... | ... | @@ -91,12 +94,18 @@ void cpu_save(QEMUFile *f, void *opaque) |
91 | 94 | qemu_put_be32(f, env->v7m.current_sp); |
92 | 95 | qemu_put_be32(f, env->v7m.exception); |
93 | 96 | } |
97 | + | |
98 | + if (arm_feature(env, ARM_FEATURE_THUMB2EE)) { | |
99 | + qemu_put_be32(f, env->teecr); | |
100 | + qemu_put_be32(f, env->teehbr); | |
101 | + } | |
94 | 102 | } |
95 | 103 | |
96 | 104 | int cpu_load(QEMUFile *f, void *opaque, int version_id) |
97 | 105 | { |
98 | 106 | CPUARMState *env = (CPUARMState *)opaque; |
99 | 107 | int i; |
108 | + uint32_t val; | |
100 | 109 | |
101 | 110 | if (version_id != CPU_SAVE_VERSION) |
102 | 111 | return -EINVAL; |
... | ... | @@ -104,7 +113,10 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) |
104 | 113 | for (i = 0; i < 16; i++) { |
105 | 114 | env->regs[i] = qemu_get_be32(f); |
106 | 115 | } |
107 | - cpsr_write(env, qemu_get_be32(f), 0xffffffff); | |
116 | + val = qemu_get_be32(f); | |
117 | + /* Avoid mode switch when restoring CPSR. */ | |
118 | + env->uncached_cpsr = val & CPSR_M; | |
119 | + cpsr_write(env, val, 0xffffffff); | |
108 | 120 | env->spsr = qemu_get_be32(f); |
109 | 121 | for (i = 0; i < 6; i++) { |
110 | 122 | env->banked_spsr[i] = qemu_get_be32(f); |
... | ... | @@ -117,12 +129,15 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) |
117 | 129 | } |
118 | 130 | env->cp15.c0_cpuid = qemu_get_be32(f); |
119 | 131 | env->cp15.c0_cachetype = qemu_get_be32(f); |
132 | + env->cp15.c0_cssel = qemu_get_be32(f); | |
120 | 133 | env->cp15.c1_sys = qemu_get_be32(f); |
121 | 134 | env->cp15.c1_coproc = qemu_get_be32(f); |
122 | 135 | env->cp15.c1_xscaleauxcr = qemu_get_be32(f); |
123 | 136 | env->cp15.c2_base0 = qemu_get_be32(f); |
124 | 137 | env->cp15.c2_base1 = qemu_get_be32(f); |
138 | + env->cp15.c2_control = qemu_get_be32(f); | |
125 | 139 | env->cp15.c2_mask = qemu_get_be32(f); |
140 | + env->cp15.c2_base_mask = qemu_get_be32(f); | |
126 | 141 | env->cp15.c2_data = qemu_get_be32(f); |
127 | 142 | env->cp15.c2_insn = qemu_get_be32(f); |
128 | 143 | env->cp15.c3 = qemu_get_be32(f); |
... | ... | @@ -187,5 +202,10 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) |
187 | 202 | env->v7m.exception = qemu_get_be32(f); |
188 | 203 | } |
189 | 204 | |
205 | + if (arm_feature(env, ARM_FEATURE_THUMB2EE)) { | |
206 | + env->teecr = qemu_get_be32(f); | |
207 | + env->teehbr = qemu_get_be32(f); | |
208 | + } | |
209 | + | |
190 | 210 | return 0; |
191 | 211 | } | ... | ... |