/************************************************************************** * arch/z80/src/z8/z8_saveusercontext.S * Save the state of the current user thread * * Copyright (C) 2008 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. Neither the name NuttX nor the names of its contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS or IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER or CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, or CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS or SERVICES; LOSS * OF USE, DATA, or PROFITS; or BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, or TORT (INCLUDING NEGLIGENCE or OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * **************************************************************************/ /************************************************************************** * Included Files **************************************************************************/ #include #include #include /************************************************************************** * Definitions **************************************************************************/ xdef _z8_restorecontext /************************************************************************** * Code **************************************************************************/ segment CODE /**************************************************************************** * Name: _z8_restorecontext * * Description: * Restore the task context that was previously saved via * _z8_saveusercontext() or by interrupt handling. Unlike the * _z8_saveusercontext() counterpart, we do not know the context of the * restored task and, hence, we must handle the worst case -- restore * everythihng. * * Parameters: * On entry, the following stack organization is assumed: * * Pointer to the context save structure * TOS -> Return address (2) * * Assumptions: * Large model, dynamic frames * **************************************************************************/ _z8_restorecontext: /* Disable all interrupts because we are going to be using * the IRQ register set. */ di /* Switch to IRQ register set */ srp #%f0 /* Get the rr0 = the current value of the stack pointer */ ldx r0, sph /* rr0 = stack pointer */ ldx r1, spl /* Get rr6 = the pointer to the context save structure */ ldx r6, 2(rr0) /* rr6 = pointer to context structure */ ldx r7, 3(rr0) /* Copy all registers into the user register area. NOTE: we * use the saved RP value to determine the destination adress. */ clr r0 /* rr0 = destination address */ ldx r1, XCPT_RP_OFFS(rr6) ld r2, r6 /* rr2 = source address */ ld r3, r7 ld r4, #16 /* r4 = number of bytes to copy */ _z8_restore: ldx r5, @rr2 ldx @rr0, r5 incw rr0 incw rr2 djnz r4, _z8_restore /* Set the new stack pointer */ ldx r0, XCPT_SPH_OFFS(rr6) ldx r1, XCPT_SPL_OFFS(rr6) ldx sph, r0 ldx spl, r1 /* Push the return address onto the stack */ ldx r0, XCPT_PCH_OFFS(rr6) ldx r1, XCPT_PCL_OFFS(rr6) push r1 push r0 /* Recover the flags and RP settings.. but don't restore them yet */ ldx r1, XCPT_FLAGS_OFFS(rr6) ldx r2, XCPT_RP_OFFS(rr6) /* Determine whether interrupts must be enabled on return. This * would be nicer to do below, but later we will need to preserve * the condition codes in the flags. */ ldx r0, XCPT_IRQCTL_OFFS(rr6) tm r0, #%80 jr nz, _z8_returnenabled /* Restore the flag settings */ ldx flags, r1 /* Restore the user register page and return with interrupts disabled */ ldx rp, r2 /* Does not effect flags */ ret /* Does not effect flags */ _z8_returnenabled: /* Restore the flag settings */ ldx flags, r1 /* Restore the user register page, re-enable interrupts and return */ ldx rp, r2 /* Does not effect flags */ ei /* Does not effect flags */ ret /* Does not effect flags */ end