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,7 +405,7 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum, | ||
405 | #define cpu_signal_handler cpu_arm_signal_handler | 405 | #define cpu_signal_handler cpu_arm_signal_handler |
406 | #define cpu_list arm_cpu_list | 406 | #define cpu_list arm_cpu_list |
407 | 407 | ||
408 | -#define CPU_SAVE_VERSION 1 | 408 | +#define CPU_SAVE_VERSION 2 |
409 | 409 | ||
410 | /* MMU modes definitions */ | 410 | /* MMU modes definitions */ |
411 | #define MMU_MODE0_SUFFIX _kernel | 411 | #define MMU_MODE0_SUFFIX _kernel |
target-arm/machine.c
@@ -22,12 +22,15 @@ void cpu_save(QEMUFile *f, void *opaque) | @@ -22,12 +22,15 @@ void cpu_save(QEMUFile *f, void *opaque) | ||
22 | } | 22 | } |
23 | qemu_put_be32(f, env->cp15.c0_cpuid); | 23 | qemu_put_be32(f, env->cp15.c0_cpuid); |
24 | qemu_put_be32(f, env->cp15.c0_cachetype); | 24 | qemu_put_be32(f, env->cp15.c0_cachetype); |
25 | + qemu_put_be32(f, env->cp15.c0_cssel); | ||
25 | qemu_put_be32(f, env->cp15.c1_sys); | 26 | qemu_put_be32(f, env->cp15.c1_sys); |
26 | qemu_put_be32(f, env->cp15.c1_coproc); | 27 | qemu_put_be32(f, env->cp15.c1_coproc); |
27 | qemu_put_be32(f, env->cp15.c1_xscaleauxcr); | 28 | qemu_put_be32(f, env->cp15.c1_xscaleauxcr); |
28 | qemu_put_be32(f, env->cp15.c2_base0); | 29 | qemu_put_be32(f, env->cp15.c2_base0); |
29 | qemu_put_be32(f, env->cp15.c2_base1); | 30 | qemu_put_be32(f, env->cp15.c2_base1); |
31 | + qemu_put_be32(f, env->cp15.c2_control); | ||
30 | qemu_put_be32(f, env->cp15.c2_mask); | 32 | qemu_put_be32(f, env->cp15.c2_mask); |
33 | + qemu_put_be32(f, env->cp15.c2_base_mask); | ||
31 | qemu_put_be32(f, env->cp15.c2_data); | 34 | qemu_put_be32(f, env->cp15.c2_data); |
32 | qemu_put_be32(f, env->cp15.c2_insn); | 35 | qemu_put_be32(f, env->cp15.c2_insn); |
33 | qemu_put_be32(f, env->cp15.c3); | 36 | qemu_put_be32(f, env->cp15.c3); |
@@ -91,12 +94,18 @@ void cpu_save(QEMUFile *f, void *opaque) | @@ -91,12 +94,18 @@ void cpu_save(QEMUFile *f, void *opaque) | ||
91 | qemu_put_be32(f, env->v7m.current_sp); | 94 | qemu_put_be32(f, env->v7m.current_sp); |
92 | qemu_put_be32(f, env->v7m.exception); | 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 | int cpu_load(QEMUFile *f, void *opaque, int version_id) | 104 | int cpu_load(QEMUFile *f, void *opaque, int version_id) |
97 | { | 105 | { |
98 | CPUARMState *env = (CPUARMState *)opaque; | 106 | CPUARMState *env = (CPUARMState *)opaque; |
99 | int i; | 107 | int i; |
108 | + uint32_t val; | ||
100 | 109 | ||
101 | if (version_id != CPU_SAVE_VERSION) | 110 | if (version_id != CPU_SAVE_VERSION) |
102 | return -EINVAL; | 111 | return -EINVAL; |
@@ -104,7 +113,10 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) | @@ -104,7 +113,10 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) | ||
104 | for (i = 0; i < 16; i++) { | 113 | for (i = 0; i < 16; i++) { |
105 | env->regs[i] = qemu_get_be32(f); | 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 | env->spsr = qemu_get_be32(f); | 120 | env->spsr = qemu_get_be32(f); |
109 | for (i = 0; i < 6; i++) { | 121 | for (i = 0; i < 6; i++) { |
110 | env->banked_spsr[i] = qemu_get_be32(f); | 122 | env->banked_spsr[i] = qemu_get_be32(f); |
@@ -117,12 +129,15 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) | @@ -117,12 +129,15 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) | ||
117 | } | 129 | } |
118 | env->cp15.c0_cpuid = qemu_get_be32(f); | 130 | env->cp15.c0_cpuid = qemu_get_be32(f); |
119 | env->cp15.c0_cachetype = qemu_get_be32(f); | 131 | env->cp15.c0_cachetype = qemu_get_be32(f); |
132 | + env->cp15.c0_cssel = qemu_get_be32(f); | ||
120 | env->cp15.c1_sys = qemu_get_be32(f); | 133 | env->cp15.c1_sys = qemu_get_be32(f); |
121 | env->cp15.c1_coproc = qemu_get_be32(f); | 134 | env->cp15.c1_coproc = qemu_get_be32(f); |
122 | env->cp15.c1_xscaleauxcr = qemu_get_be32(f); | 135 | env->cp15.c1_xscaleauxcr = qemu_get_be32(f); |
123 | env->cp15.c2_base0 = qemu_get_be32(f); | 136 | env->cp15.c2_base0 = qemu_get_be32(f); |
124 | env->cp15.c2_base1 = qemu_get_be32(f); | 137 | env->cp15.c2_base1 = qemu_get_be32(f); |
138 | + env->cp15.c2_control = qemu_get_be32(f); | ||
125 | env->cp15.c2_mask = qemu_get_be32(f); | 139 | env->cp15.c2_mask = qemu_get_be32(f); |
140 | + env->cp15.c2_base_mask = qemu_get_be32(f); | ||
126 | env->cp15.c2_data = qemu_get_be32(f); | 141 | env->cp15.c2_data = qemu_get_be32(f); |
127 | env->cp15.c2_insn = qemu_get_be32(f); | 142 | env->cp15.c2_insn = qemu_get_be32(f); |
128 | env->cp15.c3 = qemu_get_be32(f); | 143 | env->cp15.c3 = qemu_get_be32(f); |
@@ -187,5 +202,10 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) | @@ -187,5 +202,10 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) | ||
187 | env->v7m.exception = qemu_get_be32(f); | 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 | return 0; | 210 | return 0; |
191 | } | 211 | } |