Patchwork ARM Cortex-M3 Resets

login
register
mail settings
Submitter Christopher Johnson
Date June 14, 2010, 4:17 p.m.
Message ID <AANLkTimkEqmgWXhQ33GM0NaFC276wlfe4Y_Jv118pk3J@mail.gmail.com>
Download mbox | patch
Permalink /patch/55564/
State New
Headers show

Comments

Christopher Johnson - June 14, 2010, 4:17 p.m.
I am attempting to run FreeRTOS under qemu-system-arm 0.12.  I am compiling
from source.  At the current time arm-test works fine.  It uses a boot
loader with the expectation that the PC=0 after Reset is de-asserted.

The CORTEXT-M3 reference states:
NVIC resets, holds core in reset NVIC clears most of its registers. The
processor is in Thread mode, priority is
                                 privileged, and the stack is set to Main.
NVIC releases core from reset    NVIC releases core from reset.
Core sets stack                  Core reads the start SP, SP_main, from
vector-table offset 0.
Core sets PC and LR              Core reads the start PC from vector-table
offset. LR is set to 0xFFFFFFFF.
Reset routine runs               NVIC has interrupts disabled, and NMI and
Hard Fault are not disabled.

My translation of this is that the NVIC vector table is located at 0x0.
Therefore SP=Word at location 0 of physical memory.  LR=0xFFFFFFFF, and
PC=Word at location 4 of physical memory.

This matches what I see in the LM3S811 example code from TI, it also matches
what I see in the FreeRTOS code.

In looking at target-arm/helper.c I did not see anything that seemed to set
the PC, SP or LR.  I added some code to the reset functions and moved what I
think is the PC set.

+    }
         break;
     case ARM_CPUID_ANY: /* For userspace emulation.  */
         set_feature(env, ARM_FEATURE_V6);
@@ -193,11 +202,13 @@
         qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
         log_cpu_state(env, 0);
     }
+    fprintf(stderr,"CPU Reset (CPU %d)\n", env->cpu_index);

     id = env->cp15.c0_cpuid;
     memset(env, 0, offsetof(CPUARMState, breakpoints));
     if (id)
         cpu_reset_model_id(env, id);
+    env->regs[15] = 0;
 #if defined (CONFIG_USER_ONLY)
     env->uncached_cpsr = ARM_CPU_MODE_USR;
     env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30;
@@ -211,7 +222,6 @@
     env->vfp.xregs[ARM_VFP_FPEXC] = 0;
     env->cp15.c2_base_mask = 0xffffc000u;
 #endif
-    env->regs[15] = 0;
     tlb_flush(env, 1);
 }

The problem is that It does not seem to load from the NVIC vector and even
when I do a monitor command: system_reset, the arm does not reset.

I'm looking for help in accessing rom memory to set SP and PC on reset.  Of
implementing system_reset for the ARM processor(s).

Thank you,
-Chris

Patch

--- helper.c.ORG    2010-05-04 11:27:48.000000000 -0400
+++ helper.c    2010-06-13 19:46:58.000000000 -0400
@@ -134,6 +134,15 @@ 
         set_feature(env, ARM_FEATURE_V7);
         set_feature(env, ARM_FEATURE_M);
         set_feature(env, ARM_FEATURE_DIV);
+    /* R13 = SP, R14=LR, R15=PC */
+    {
+        uint8_t buf[8];
+        cpu_physical_memory_read(0x0, buf, sizeof(buf));
+        env->regs[13]=(buf[0]<<24) | (buf[1] << 16) | (buf[2] << 8) | bu
f[3];
+        env->regs[14]=0xFFFFFFFF;
+        env->regs[15]=(buf[4]<<24) | (buf[5] << 16) | (buf[6] << 8) | bu
f[7];
+fprintf(stderr,"cpu_reset_model_id: SP=0x%X, LR=0x%X, PC=0x%X\n",
env->regs[13]
, env->regs[14], env->regs[15]);