Optimization: Use a trampoline to start ARM processes instead of wasting one stack...
authorbatt <batt@38d2e660-2303-0410-9eaa-f027e97ec537>
Thu, 14 Jan 2010 14:21:26 +0000 (14:21 +0000)
committerbatt <batt@38d2e660-2303-0410-9eaa-f027e97ec537>
Thu, 14 Jan 2010 14:21:26 +0000 (14:21 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@3134 38d2e660-2303-0410-9eaa-f027e97ec537

bertos/cpu/arm/hw/switch_ctx_arm.S
bertos/cpu/frame.h

index 39e9f46a2dabb58b88475203acf095dacd9a1155..e610ac97c535073bb3cbbcc798299c792aaced57 100644 (file)
 asm_switch_context:
        mrs     r2, cpsr               /* Save status. */
 
-       /*
-        * To work correctly the lr should point to proc_exit, so when process finish
-        * could be return
-        */
-       push {lr}                  /* Add one element on stack, for next switching */
-
        stmfd   sp!, {r2, r4-r11, lr}  /* Save registers. */
 
        str     sp, [r1]               /* Save old stack pointer. */
@@ -57,5 +51,15 @@ asm_switch_context:
        ldmfd   sp!, {r2, r4-r11, lr}  /* Load new registers. */
        msr     cpsr, r2               /* restore flags reg. */
 
-       pop {r0}                  /* pop on stack address of the process that we want to jump */
-       mov     pc, r0
+       mov     pc, lr
+
+
+/* proc_entry trampoline needed because ARM does not pop return addresses
+from the stack, but uses lr instead.*/
+.globl asm_proc_entry
+asm_proc_entry:
+       mov     lr, pc
+       /* In r11 we have the real process entry point as set up by CPU_CREATE_NEW_STACK */
+       bx      r11
+       bl      proc_exit
+
index 2244b3b1bf85a243ca1d1f407a365fd1bc99cf24..8cb7a813d5a2192c9afe1c47dda4616042008ed4 100644 (file)
@@ -62,6 +62,8 @@
        #define CPU_STACK_GROWS_UPWARD 0
        #define CPU_SP_ON_EMPTY_SLOT   0
 
+
+       EXTERN_C void asm_proc_entry(void);
        /**
         * Initialization value for registers in stack frame.
         * For the CPSR register, the initial value is set to:
         */
        #define CPU_CREATE_NEW_STACK(stack, entry, exit) \
        do { \
-               /* Process entry point */ \
+               /* LR (asm proc_entry trampoline) */ \
+               CPU_PUSH_CALL_FRAME(stack, asm_proc_entry); \
+               /* R11 (Process entry point) DO NOT CHANGE: asm_proc_entry expects \
+                * to find the actual process entry point in R11 */ \
                CPU_PUSH_CALL_FRAME(stack, entry); \
-               /* LR (proc_exit) */ \
-               CPU_PUSH_CALL_FRAME(stack, exit); \
-               /* R11 */ \
-               CPU_PUSH_WORD(stack, 0x11111111); \
                /* R10 */ \
                CPU_PUSH_WORD(stack, 0x10101010); \
                /* R9 */ \
 
 /**
  * Default macro for creating a new Process stack
- */ 
+ */
 #ifndef CPU_CREATE_NEW_STACK
 
        #define CPU_CREATE_NEW_STACK(stack, entry, exit) \