:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / ntoskrnl / ke / i386 / tskswitch.S
1 /*
2  *  ReactOS kernel
3  *  Copyright (C) 2000 David Welch <welch@cwcom.net>
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /*
20  * FILE:            ntoskrnl/ke/i386/tskswitch.S
21  * PURPOSE:         Microkernel thread support
22  * PROGRAMMER:      David Welch (welch@cwcom.net)
23  * UPDATE HISTORY:
24  *                  Created 09/10/00
25  */
26
27 /* INCLUDES ******************************************************************/
28
29 #include <internal/i386/segment.h>
30 #include <internal/ps.h>
31 #include <ddk/i386/tss.h>
32 #include <internal/ntoskrnl.h>
33                 
34 /* FUNCTIONS ****************************************************************/
35         
36 .globl _Ki386ContextSwitch
37 _Ki386ContextSwitch:
38 /* 
39  * FUNCTIONS: Switches to another thread's context
40  * ARGUMENTS:
41  *        Thread = Thread to switch to
42  *        OldThread = Thread to switch from
43  */
44         pushl   %ebp
45         movl    %esp, %ebp
46
47         /*
48          * Save callee save registers.
49          */
50         pushl   %ebx
51         pushl   %esi
52         pushl   %edi
53
54         /*
55          * This is a critical section for this processor.
56          */
57         cli
58
59         /*
60          * Get the pointer to the new thread.
61          */
62         movl    8(%ebp), %ebx
63                 
64         /*
65          * Set the base of the TEB selector to the base of the TEB for
66          * this thread.
67          */
68         pushl   %ebx
69         pushl   KTHREAD_TEB(%ebx)
70         pushl   $TEB_SELECTOR
71         call    _KeSetBaseGdtSelector
72         addl    $8, %esp
73         popl    %ebx
74
75         /*
76          * Load the PCR selector.
77          */
78         movl    $PCR_SELECTOR, %eax
79         movl    %eax, %fs
80
81         /*
82          * Set the current thread information in the PCR.
83          */
84         movl    %ebx, %fs:KPCR_CURRENT_THREAD
85
86         /*
87          * FIXME: Save debugging state.
88          */
89
90         /*
91          * FIXME: Save floating point state.
92          */
93
94         /*
95          * Switch stacks
96          */
97         movl    12(%ebp), %ebx
98         movl    %esp, KTHREAD_KERNEL_STACK(%ebx)        
99         movl    8(%ebp), %ebx
100         movl    KTHREAD_KERNEL_STACK(%ebx), %esp
101         movl    KTHREAD_STACK_LIMIT(%ebx), %edi
102
103         /*
104          * Set the stack pointer in this processors TSS
105          */
106         movl    KTHREAD_INITIAL_STACK(%ebx), %eax
107         movl    %fs:KPCR_TSS, %esi
108         movl    %eax, KTSS_ESP0(%esi)
109
110         /*
111          * Change the address space
112          */
113         movl    ETHREAD_THREADS_PROCESS(%ebx), %ebx
114         movl    KPROCESS_DIRECTORY_TABLE_BASE(%ebx), %eax
115         movl    %eax, %cr3
116
117         /*
118          * Set up the PDE for the top of the new stack.
119          */
120         movl    $0, %ebx
121 .L2:    movl    %edi, %esi
122         shr     $22, %esi
123         movl    0xF03C0000(,%esi, 4), %eax
124         cmpl    $0, %eax
125         jne     .L1
126         movl    _MmGlobalKernelPageDirectory(,%esi, 4), %eax
127         movl    %eax, 0xF03C0000(,%esi, 4)
128 .L1:
129         addl    $4096, %edi
130         incl    %ebx
131         cmp     $(MM_STACK_SIZE / 4096), %ebx
132         jl      .L2
133                 
134         /*
135          * FIXME: Restore floating point state
136          */
137
138         /*
139          * FIXME: Restore debugging state
140          */
141
142         /*
143          * Exit the critical section
144          */
145         sti
146         
147         /*
148          * Restore the saved register and exit
149          */
150         popl    %edi
151         popl    %esi
152         popl    %ebx
153         
154         popl    %ebp
155         ret