18bc5d4f181807f82561dfae7408b6ad60fa024f
[reactos.git] / reactos / 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 <ntos/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 * Set the current LDT
88 */
89 xorl %eax, %eax
90 movl KTHREAD_APCSTATE_PROCESS(%ebx), %edi
91 testw $0xFFFF, KPROCESS_LDT_DESCRIPTOR0(%edi)
92 jz .L4
93
94 pushl KPROCESS_LDT_DESCRIPTOR1(%edi)
95 pushl KPROCESS_LDT_DESCRIPTOR0(%edi)
96 pushl $LDT_SELECTOR
97 call _KeSetGdtSelector
98 addl $12, %esp
99
100 movl $LDT_SELECTOR, %eax
101
102 .L4:
103 lldtw %ax
104
105 /*
106 * Load up the iomap offset for this thread in
107 * preparation for setting it below.
108 */
109 movl KPROCESS_IOPM_OFFSET(%edi), %eax
110
111 /*
112 * FIXME: Save debugging state.
113 */
114
115 /*
116 * FIXME: Save floating point state.
117 */
118
119 /*
120 * Switch stacks
121 */
122 movl 12(%ebp), %ebx
123 movl %esp, KTHREAD_KERNEL_STACK(%ebx)
124 movl 8(%ebp), %ebx
125 movl KTHREAD_KERNEL_STACK(%ebx), %esp
126 movl KTHREAD_STACK_LIMIT(%ebx), %edi
127
128 /*
129 * Set the stack pointer in this processors TSS
130 */
131 movl %fs:KPCR_TSS, %esi
132
133 /*
134 * Set current IOPM offset in the TSS
135 */
136 movw %ax, KTSS_IOMAPBASE(%esi)
137
138 movl KTHREAD_INITIAL_STACK(%ebx), %eax
139 movl %eax, KTSS_ESP0(%esi)
140
141 /*
142 * Change the address space
143 */
144 movl KTHREAD_APCSTATE_PROCESS(%ebx), %ebx
145 movl KPROCESS_DIRECTORY_TABLE_BASE(%ebx), %eax
146 movl %eax, %cr3
147
148 /*
149 * FIXME: Restore floating point state
150 */
151
152 /*
153 * FIXME: Restore debugging state
154 */
155
156 /*
157 * Exit the critical section
158 */
159 sti
160
161 push $_PiThreadLock
162 call _KeReleaseSpinLockFromDpcLevel@4
163
164 cmpl $0, _PiNrThreadsAwaitingReaping
165 je .L3
166 call _PiWakeupReaperThread@0
167 .L3:
168
169 /*
170 * Restore the saved register and exit
171 */
172 popl %edi
173 popl %esi
174 popl %ebx
175
176 popl %ebp
177 ret