summaryrefslogblamecommitdiff
path: root/nuttx/arch/x86/src/qemu/qemu_fullcontextrestore.S
blob: 7d25e9072ed56825aec054000a144cd998afc2ed (plain) (tree)
1
2
3
4


                                                                           
                                                          










































                                                                            
                                           

                                                                           
                            





                                                                            


                                                                              
 








                                                                    




                                                                            

             







                                                                            


                                                
                                                                  
 




                                                                                
 

           



                                                                              
                                      
 







                                                              
           
 


                                              
                    
                                          
                    






                                                    
                                       
                    
 
                                                 
 
                                       
                                       
                                       
                                       

                                       
 





                                                                                  
 
                                             
 
                                                              
 
                    
            
                                                              
        
 
/**************************************************************************
 * arch/x86/src/qemu/qemu_fullcontextrestore.S
 *
 *   Copyright (C) 2011 Gregory Nutt. All rights reserved.
 *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
 *
 * 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.
 *
 **************************************************************************/

/**************************************************************************
 * Conditional Compilation Options
 **************************************************************************/

/**************************************************************************
 * Included Files
 **************************************************************************/

#include <nuttx/config.h>
#include <arch/irq.h>
#include "up_internal.h"

	.file	"qemu_fullcontextrestore.S"

/**************************************************************************
 * Pre-processor Definitions
 **************************************************************************/

/**************************************************************************
 * Global Variables
 **************************************************************************/

/****************************************************************************
 * Macros
 ****************************************************************************/

/* Trace macros, use like trace 'i' to print char to serial port. */

	.macro	trace, ch
#ifdef CONFIG_DEBUG
	mov		$0x3f8, %dx
	mov		$\ch, %al
	out		%al, %dx
#endif
	.endm

/**************************************************************************
 * Public Functions
 **************************************************************************/

	.text

/**************************************************************************
 * Name: up_fullcontextrestore
 *
 * Full C prototype:
 *  void up_fullcontextrestore(uint32_t *regs) __attribute__ ((noreturn));
 *
 **************************************************************************/

	.globl	up_fullcontextrestore
	.type	up_fullcontextrestore, @function
up_fullcontextrestore:
	/* Fetch the pointer to the register save array in EAX. */

	movl	4(%esp), %eax

	/* Disable interrupts now (the correct EFLAGS will be restored before we
	 * return
	 */

	cli

	/* We now have everything we need from the old stack.  Now get the new
	 * stack pointer.
	 */

	movl	(4*REG_SP)(%eax), %esp

	/* Create an interrupt stack frame for the final iret.
	 *
	 * SP Before -> 
	 *              SS
	 *              ESP
	 *              EFLAGS
	 *              CS
	 * SP After  -> EIP
	 */

	mov		(4*REG_SS)(%eax), %ebx
	push	%ebx
	movl	(4*REG_SP)(%eax), %ebx
	push	%ebx
	movl	(4*REG_EFLAGS)(%eax), %ebx
	push	%ebx
	mov		(4*REG_CS)(%eax), %ebx
	push	%ebx
	movl	(4*REG_EIP)(%eax), %ebx
	push	%ebx

	/* Save the value of EAX on the stack too */

	movl	(4*REG_EAX)(%eax), %ebx
	push	%ebx

	/* Now restore the remaining registers */

	movl	(4*REG_ESI)(%eax), %esi
	movl	(4*REG_EDI)(%eax), %edi
	movl	(4*REG_EBP)(%eax), %ebp
	movl	(4*REG_EBX)(%eax), %ebx
	movl	(4*REG_EDX)(%eax), %edx
	movl	(4*REG_ECX)(%eax), %ecx

	/* Restore the data segment register.  I think there is an issue that will
	 * need to be address here at some time:  If the register save area is in
	 * one data segment and the stack is in another, then the above would not
	 * work (and, conversely, if they are in the same data segment, the
	 * following is unnecessary and redundant).
	 */

	mov		(4*REG_DS)(%eax), %ds

	/* Restore the correct value of EAX and then return */

	popl	%eax
	iret
	.size up_fullcontextrestore, . - up_fullcontextrestore
    .end