Updated PCI IDs to latest snapshot.
[tangerine.git] / arch / i386-pc / exec / stackswap.S
blob0c3ec2b388295e61e417ab030868805e3a69ac22
1 /*
2     Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3     $Id$
4 */
6 /*****************************************************************************
7  
8     NAME
9  
10         AROS_LH1(void, StackSwap,
12     SYNOPSIS
13         AROS_LHA(struct StackSwapStruct *, newStack, A0),
15     LOCATION
16         struct ExecBase *, SysBase, 122, Exec)
18     FUNCTION
19         This function switches to the new stack given by the parameters in the
20         stackswapstruct structure. The old stack parameters are returned in
21         the same structure so that the stack can be restored later
23     INPUTS
24         newStack - parameters for the new stack
26     RESULT
28     NOTES
30     EXAMPLE
32     BUGS
34     SEE ALSO
36     INTERNALS
38     HISTORY
40 ******************************************************************************/
41 #include "aros/i386/asm.h"
42 #include <aros/config.h>
44         .text
45         .globl  AROS_SLIB_ENTRY(StackSwap,Exec)
46         _FUNCTION(AROS_SLIB_ENTRY(StackSwap,Exec))
47 AROS_SLIB_ENTRY(StackSwap,Exec):
48         /* Save %ebx content */
49         pushl   %ebx
50         
51         /* Take the function's parameters */
52         movl    8(%esp),  %ebx  //newStack
53         movl    12(%esp), %eax  //SysBase
55         /* Disable interrupts, to be sure they always find a good stackframe */
56         pushl   %eax
57         call    *Disable(%eax)
58         popl    %eax
60         /* FindTask(NULL) in %edx */
61         movl    ThisTask(%eax), %edx
62         
63         /* Swap Lower boundaries, %ecx is used as temp register */
64         movl    tc_SPLower(%edx), %ecx
65         xchgl   %ecx,             stk_Lower(%ebx)
66         movl    %ecx,             tc_SPLower(%edx)
68         /* Swap Upper boundaries, %ecx is used as temp register */
69         movl    tc_SPUpper(%edx), %ecx
70         xchgl   %ecx,             stk_Upper(%ebx)
71         movl    %ecx,             tc_SPUpper(%edx)
72         
73 #if AROS_STACK_DEBUG
74         /* Fill [stk_Lower .. stk_Pointer - 16] with 0xE1 */
75         
76         pushl   %edi
77         pushl   %eax
78         
79         /* Destination register = %edi = NEW SPLower.
80            Which was already swapped above, so to be found
81            in task->tc_SPLower */
82         movl    tc_SPLower(%edx), %edi
84         /* %ecx = count register = NEW SP register - NEW SP_Lower - 16 */
85         movl    stk_Pointer(%ebx), %ecx
86         subl    $16, %ecx
87         subl    %edi, %ecx
88         
89         /* byte value to store */
90         movb    $0xE1, %al
91         
92         /* direction to store: forward */
93         cld
94         
95         /* do the store operation: put %ecx times %al into memory starting at %edi. */
96         rep
97         stosb
98         
99         popl    %eax
100         popl    %edi
101 #endif  
103         /* We need to restore %ebx before swapping stack pointers, so
104            put its content in a register whose content doesn't matter
105            anymore to us, like %edx.  */
106         movl    %ebx, %edx  // newStack, ThisTask is lost
108         /* Now restore %ebx */
109         popl    %ebx        
110         
111         /* And take the function's return address, before we
112            swap stacks.  */
113         popl    %ecx    // return address    
114         
115         /* Swap stack pointers */
116         xchgl   %esp, stk_Pointer(%edx) 
118         /* Reenable interrupts. */
119         pushl   %eax
120         call    *Enable(%eax)
121         popl    %eax
122         
123         /* Return. %ecx contains the return address, and the stack is already
124            adjusted, we don't need, or even can, use ret here.  */
125         jmp     *%ecx