qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] target-arm: Fix resetting issues on ARMv7-M CPU


From: Martin Galvan
Subject: Re: [Qemu-devel] [PATCH] target-arm: Fix resetting issues on ARMv7-M CPUs
Date: Tue, 19 Aug 2014 00:54:55 -0300

Ping http://patchwork.ozlabs.org/patch/379134/


On Mon, Aug 11, 2014 at 1:50 PM, Martin Galvan <address@hidden> wrote:
When calling qemu_system_reset after startup on a Cortex-M CPU, the initial values of PC, MSP and the Thumb bit weren't set correctly. In particular, since Thumb was 0, an Usage Fault would arise immediately after trying to excecute any instruction on a Cortex-M.

Signed-off-by: Martin Galvan <address@hidden>
---
 target-arm/cpu.c | 19 ++++++++++++++-----
 target-arm/cpu.h |  4 ++++
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 7cebb76..d436b59 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -131,7 +131,6 @@ static void arm_cpu_reset(CPUState *s)
     /* 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.  */
     if (IS_M(env)) {
-        uint32_t pc;
         uint8_t *rom;
         env->daif &= ~PSTATE_I;
         rom = rom_ptr(0);
@@ -140,11 +139,21 @@ static void arm_cpu_reset(CPUState *s)
                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;
+            env->initial_MSP = ldl_p(rom) & 0xFFFFFFFC;
+            env->initial_PC = ldl_p(rom + 4);
+            env->initial_PC &= ~1;
         }
+
+        /* If we do a system reset, rom will be NULL since its data
+            was zeroed when calling cpu_flush_icache_range at startup. Set
+            the initial registers here using the values we loaded from ROM
+            at startup. */
+        env->regs[13] = env->initial_MSP;
+        env->regs[15] = env->initial_PC;
+
+        /* ARMv7-M only supports Thumb instructions. If this isn't
+           set we'll get an Usage Fault. */
+        env->thumb = 1;
     }
 
     if (env->cp15.c1_sys & SCTLR_V) {
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 79205ba..a56aebd 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -330,6 +330,10 @@ typedef struct CPUARMState {
 
     void *nvic;
     const struct arm_boot_info *boot_info;
+
+    /* Initial MSP and PC for ARMv7-M CPUs */
+    uint32_t initial_MSP; /* Stored in 0x0 inside the guest ROM */
+    uint32_t initial_PC; /* Stored in 0x4 inside the guest ROM */
 } CPUARMState;
 
 #include "cpu-qom.h"
--
1.9.1



--

http://www.tallertechnologies.com


Martín Galván

Software Engineer

Taller Technologies Argentina


San Lorenzo 47, 3rd Floor, Office 5

Córdoba, Argentina

Phone: 54 351 4217888 / +54 351 4218211

http://www.linkedin.com/company/taller-technologieshttps://www.facebook.com/tallertechnologies

reply via email to

[Prev in Thread] Current Thread [Next in Thread]