提交 6e3cf5df 编写于 作者: M Martin Galvan 提交者: Peter Maydell

target-arm: Fix resetting issues on ARMv7-M CPUs

When calling qemu_system_reset after startup on a Cortex-M
CPU, the initial values of PC, MSP and the Thumb bit weren't being set
correctly if the vector table was in ROM. In particular, since Thumb was 0, a
Usage Fault would arise immediately after trying to execute any instruction
on a Cortex-M.
Signed-off-by: NMartin Galvan <martin.galvan@tallertechnologies.com>
Message-id: CAOKbPbaLt-LJsAKkQdOE0cs9Xx4OWrUfpDhATXPSdtuNw2xu_A@mail.gmail.com
[PMM: removed an incorrect comment]
Reviewed-by: NPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
上级 bfb27e60
......@@ -129,22 +129,34 @@ static void arm_cpu_reset(CPUState *s)
env->uncached_cpsr = ARM_CPU_MODE_SVC;
env->daif = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F;
/* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is
clear at reset. Initial SP and PC are loaded from ROM. */
* clear at reset. Initial SP and PC are loaded from ROM.
*/
if (IS_M(env)) {
uint32_t pc;
uint32_t initial_msp; /* Loaded from 0x0 */
uint32_t initial_pc; /* Loaded from 0x4 */
uint8_t *rom;
env->daif &= ~PSTATE_I;
rom = rom_ptr(0);
if (rom) {
/* We should really use ldl_phys here, in case the guest
modified flash and reset itself. However images
loaded via -kernel have not been copied yet, so load the
values directly from there. */
env->regs[13] = ldl_p(rom) & 0xFFFFFFFC;
pc = ldl_p(rom + 4);
env->thumb = pc & 1;
env->regs[15] = pc & ~1;
/* Address zero is covered by ROM which hasn't yet been
* copied into physical memory.
*/
initial_msp = ldl_p(rom);
initial_pc = ldl_p(rom + 4);
} else {
/* Address zero not covered by a ROM blob, or the ROM blob
* is in non-modifiable memory and this is a second reset after
* it got copied into memory. In the latter case, rom_ptr
* will return a NULL pointer and we should use ldl_phys instead.
*/
initial_msp = ldl_phys(s->as, 0);
initial_pc = ldl_phys(s->as, 4);
}
env->regs[13] = initial_msp & 0xFFFFFFFC;
env->regs[15] = initial_pc & ~1;
env->thumb = initial_pc & 1;
}
if (env->cp15.c1_sys & SCTLR_V) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册