summaryrefslogtreecommitdiff
path: root/nuttx/arch/pjrc-8051/src/up_restorecontext.c
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/arch/pjrc-8051/src/up_restorecontext.c')
-rw-r--r--nuttx/arch/pjrc-8051/src/up_restorecontext.c199
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);
-}
-