diff options
Diffstat (limited to 'nuttx/arch/pjrc-8051/src/up_restorecontext.c')
-rw-r--r-- | nuttx/arch/pjrc-8051/src/up_restorecontext.c | 199 |
1 files changed, 104 insertions, 95 deletions
diff --git a/nuttx/arch/pjrc-8051/src/up_restorecontext.c b/nuttx/arch/pjrc-8051/src/up_restorecontext.c index 98b4d0bb4..ce5735db9 100644 --- a/nuttx/arch/pjrc-8051/src/up_restorecontext.c +++ b/nuttx/arch/pjrc-8051/src/up_restorecontext.c @@ -65,25 +65,116 @@ **************************************************************************/ /************************************************************************** - * Name: up_popcontext + * Public Functions + **************************************************************************/ + +/************************************************************************** + * Name: up_restorecontext * * Description: - * Pop the current execution context from the stack and return to the - * execution context. Similar operations are executed from the interrupt - * state restore + * Restore the stack specified in the context structure and return to + * that context * * Inputs: - * None + * context - Holds the stack content of the context to return to * * Return: - * This function does not return + * This function does not return. * **************************************************************************/ -static void up_popcontext(ubyte newsp) __naked - +void up_restorecontext(FAR struct xcptcontext *context) __naked { - _asm + _asm + ar2 = 0x02 + ar3 = 0x03 + ar4 = 0x04 + ar5 = 0x05 + ar6 = 0x06 + ar7 = 0x07 + ar0 = 0x00 + ar1 = 0x01 + +#ifdef CONFIG_SWITCH_FRAME_DUMP + push dpl + push dph + lcall _up_dumpframe + pop dph + pop dpl +#endif + + /* Interrupts should be disabled for the following. up_popcontext() will + * set the new interrupt state correctly. + */ + + clr ea + + /* Register usage in the following: + * + * R0 - Holds working the 8-bit IRAM pointer + * R1 - Not used + * R2-3 - Holds the working 16-bit XRAM pointer + * R4 - Holds the working byte count + * R5 - Holds the new stack pointer + * R6-7 - Not used + */ + + /* Fetch r4 = context->nbytes */ + + movx a, @dptr + mov r4, a + + /* Save the new stack pointer in r5 */ + + add a, #(STACK_BASE-1) + mov r5, a + + /* Save r2-3 = &context->stack */ + + inc dptr + mov r2, dpl + mov r3, dph + + /* Set r0 = stack base address */ + + mov r0, #STACK_BASE + + /* Top of the copy loop */ +00001$: + dec r4 + jz 00002$ + + /* Fetch the next byte from context->stack */ + + mov dpl, r2 + mov dph, r3 + movx a,@dptr + + /* Increment the XRAM pointer */ + + inc dptr + mov r2, dpl + mov r3, dph + + /* Save the next byte into IRAM */ + + mov @r0, a + + /* Increment the IRAM pointer */ + + inc r0 + sjmp 00001$ +00002$: + + /* Set the new stack pointer */ + + mov sp, r5 + +#ifdef CONFIG_SWITCH_FRAME_DUMP + lcall _up_dumpstack +#endif + /* Then restore the context from the stack */ + pop _bp pop psw pop ar1 @@ -101,98 +192,16 @@ static void up_popcontext(ubyte newsp) __naked /* Restore the interrupt state per the stored IE value */ pop acc - jb acc.7,00001$ + jb acc.7,00003$ clr ie.7 - sjmp 00002$ - 00001$: + sjmp 00004$ + 00003$: setb ie.7 - 00002$: + 00004$: pop acc ret _endasm; } -/************************************************************************** - * Public Functions - **************************************************************************/ - -/************************************************************************** - * Name: up_restorecontext - * - * Description: - * Restore the stack specified in the context structure and return to - * that context - * - * Inputs: - * context - Holds the stack content of the context to return to - * - * Return: - * This function does not return. - * - **************************************************************************/ - -void up_restorecontext(FAR struct xcptcontext *context) -{ - int nbytes = context->nbytes; - FAR ubyte *src = context->stack; - NEAR ubyte *dest = (NEAR ubyte*)STACK_BASE; - - /* Interrupts should be disabled for the following. up_popcontext() will - * set the new interrupt state correctly. - */ - - (void)irqsave(); - - while (nbytes--) - { - *src++ = *dest++; - } - - /* Then return to the restored context (probably restoring interrupts) */ - - up_popcontext(context->nbytes + (STACK_BASE-1)); -} - -/************************************************************************** - * Name: up_restorestack - * - * Description: - * Restore the entire interrupt stack contents in the provided context - * structure. - * - * Inputs: - * context - the context structure from which to restore the stack info - * - * Return: - * None - * - * Assumptions: - * - We are in an interrupt handler with g_irqtos set - * - Interrupts are disabled - * - **************************************************************************/ - -void up_restorestack(FAR struct xcptcontext *context) -{ - /* Now copy the current stack frame (including the saved execution - * context) from internal RAM to XRAM. - */ - - ubyte nbytes = context->nbytes; - FAR ubyte *src = context->stack; - NEAR ubyte *dest = (NEAR ubyte*)STACK_BASE; - - while (nbytes--) - { - *dest++ = *src++; - } - - /* We are still in the interrupt context, but the size of the interrupt - * stack has changed. - */ - - g_irqtos = context->nbytes + (STACK_BASE-1); -} - |