From f709a37e5659fd591b5a61d80b45257105ac1850 Mon Sep 17 00:00:00 2001 From: batt Date: Thu, 10 Sep 2009 13:53:01 +0000 Subject: [PATCH] New macro to fill a new process stack: in this way the stack is always aligned. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@2928 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/cpu/frame.h | 56 +++++++++++++++++++++++++++++++++++----------- bertos/kern/proc.c | 14 +++--------- 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/bertos/cpu/frame.h b/bertos/cpu/frame.h index 1a80fa1d..2244b3b1 100644 --- a/bertos/cpu/frame.h +++ b/bertos/cpu/frame.h @@ -64,24 +64,37 @@ /** * Initialization value for registers in stack frame. - * The register index is not directly corrispondent to CPU - * register numbers, but is related to how are pushed to - * stack (\see asm_switch_context). - * Index (CPU_SAVED_REGS_CNT - 1) is the CPSR register, - * the initial value is set to: + * For the CPSR register, the initial value is set to: * - All flags (N, Z, C, V) set to 0. * - IRQ and FIQ enabled. * - ARM state. * - CPU in Supervisor Mode (SVC). */ - #define CPU_REG_INIT_VALUE(reg) \ - ({ int a = 0; \ - if(reg == 0) \ - a = (int)proc_exit; \ - else if(reg == (CPU_SAVED_REGS_CNT - 1)) \ - a = 0x13; \ - a; \ - }) + #define CPU_CREATE_NEW_STACK(stack, entry, exit) \ + do { \ + /* Process entry point */ \ + 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 */ \ + CPU_PUSH_WORD(stack, 0x09090909); \ + /* R8 */ \ + CPU_PUSH_WORD(stack, 0x08080808); \ + /* R7 */ \ + CPU_PUSH_WORD(stack, 0x07070707); \ + /* R6 */ \ + CPU_PUSH_WORD(stack, 0x06060606); \ + /* R5 */ \ + CPU_PUSH_WORD(stack, 0x05050505); \ + /* R4 */ \ + CPU_PUSH_WORD(stack, 0x04040404); \ + /* CPSR */ \ + CPU_PUSH_WORD(stack, 0x00000013); \ + } while (0) #elif CPU_PPC @@ -244,4 +257,21 @@ #endif /* !ARCH_EMUL */ #endif /* !CPU_IDLE */ +/** + * Default macro for creating a new Process stack + */ +#ifndef CPU_CREATE_NEW_STACK + + #define CPU_CREATE_NEW_STACK(stack, entry, exit) \ + do { \ + size_t i; \ + /* Initialize process stack frame */ \ + CPU_PUSH_CALL_FRAME(stack, exit); \ + CPU_PUSH_CALL_FRAME(stack, entry); \ + /* Push a clean set of CPU registers for asm_switch_context() */ \ + for (i = 0; i < CPU_SAVED_REGS_CNT; i++) \ + CPU_PUSH_WORD(stack, CPU_REG_INIT_VALUE(i)); \ + } while (0) +#endif + #endif /* CPU_ATTR_H */ diff --git a/bertos/kern/proc.c b/bertos/kern/proc.c index 267ace6c..15fe5b7f 100644 --- a/bertos/kern/proc.c +++ b/bertos/kern/proc.c @@ -240,17 +240,9 @@ struct Process *proc_new_with_name(UNUSED_ARG(const char *, name), void (*entry) makecontext(&proc->context, (void (*)(void))proc_entry, 1, entry); #else // !CONFIG_KERN_PREEMPT - { - size_t i; - - /* Initialize process stack frame */ - CPU_PUSH_CALL_FRAME(proc->stack, proc_exit); - CPU_PUSH_CALL_FRAME(proc->stack, entry); - - /* Push a clean set of CPU registers for asm_switch_context() */ - for (i = 0; i < CPU_SAVED_REGS_CNT; i++) - CPU_PUSH_WORD(proc->stack, CPU_REG_INIT_VALUE(i)); - } + + CPU_CREATE_NEW_STACK(proc->stack, entry, proc_exit); + #endif // CONFIG_KERN_PREEMPT #if CONFIG_KERN_MONITOR -- 2.25.1