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. */
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
+
#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) \