diff --git a/arch/arm/src/common/up_initialstate.c b/arch/arm/src/common/up_initialstate.c index a945b4c518..9c683a9508 100644 --- a/arch/arm/src/common/up_initialstate.c +++ b/arch/arm/src/common/up_initialstate.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/common/up_initialstate.c * - * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -40,10 +40,16 @@ #include #include #include + #include + #include "up_internal.h" #include "up_arch.h" +#ifdef __thumb2__ +# include "cortexm3_psr.h" +#endif + /**************************************************************************** * Private Definitions ****************************************************************************/ @@ -81,18 +87,36 @@ void up_initial_state(_TCB *tcb) /* Initialize the initial exception register context structure */ memset(xcp, 0, sizeof(struct xcptcontext)); + + /* Save the initial stack point */ + xcp->regs[REG_SP] = (uint32)tcb->adj_stack_ptr; - xcp->regs[REG_PC] = (uint32)tcb->start; #ifdef __thumb2__ + /* Save the task entry point (stripping off the thumb bit) */ + + xcp->regs[REG_PC] = (uint32)tcb->start & ~1; + + /* Specify thumb mode */ + + xcp->regs[REG_XPSR] = CORTEXM3_XPSR_T; + + /* Enable or disable interrupts, based on user configuration */ + # ifdef CONFIG_SUPPRESS_INTERRUPTS xcp->regs[REG_PRIMASK] = 1; # endif -#else +#else /* __thumb2__ */ + /* Save the task entry point */ + + xcp->regs[REG_PC] = (uint32)tcb->start; + + /* Enable or disable interrupts, based on user configuration */ + # ifdef CONFIG_SUPPRESS_INTERRUPTS xcp->regs[REG_CPSR] = SVC_MODE | PSR_I_BIT | PSR_F_BIT; # else xcp->regs[REG_CPSR] = SVC_MODE | PSR_F_BIT; # endif -#endif +#endif /* __thumb2__ */ } diff --git a/arch/arm/src/lm3s/lm3s_vectors.S b/arch/arm/src/lm3s/lm3s_vectors.S index 5be36a90e6..70774c464b 100644 --- a/arch/arm/src/lm3s/lm3s_vectors.S +++ b/arch/arm/src/lm3s/lm3s_vectors.S @@ -298,7 +298,7 @@ lm3s_irqcommon: * as current stack pointer, then things are relatively easy. */ - cmp r0, r1 + cmp r0, r1 /* Context switch? */ beq 1f /* Branch if no context switch */ /* We are returning with a pending context switch. This case is different @@ -307,11 +307,11 @@ lm3s_irqcommon: * values to the stack. */ - add r1, r0, #SW_XCPT_REGS /* r2=offset HW save area */ - ldmia r1, {r4-r11} /* Eight registers in HW save area */ + add r1, r0, #SW_XCPT_SIZE /* R1=Address of HW save area in reg array */ + ldmia r1, {r4-r11} /* Fetch eight registers in HW save area */ ldr r1, [r0, #(4*REG_SP)] /* R1=Value of SP before interrupt */ - stmdb r1!, {r4-r11} /* Eight registers in HW save area */ - ldmia r0!, {r2-r11} /* Recover R4-R11 + 2 temp values */ + stmdb r1!, {r4-r11} /* Store eight registers in HW save area */ + ldmia r0, {r2-r11} /* Recover R4-R11 + 2 temp values */ b 2f /* Re-join common logic */ /* We are returning with no context switch. We simply need to "unwind"