qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] ARM Cortex-M3 Resets


From: Christopher Johnson
Subject: [Qemu-devel] ARM Cortex-M3 Resets
Date: Mon, 14 Jun 2010 12:17:25 -0400

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.

--- 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]);
+    }
         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



reply via email to

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