2 * Copyright (c) 1990 The Regents of the University of California.
4 * LWKT threads Copyright (c) 2003 Matthew Dillon
6 * This code is derived from software contributed to Berkeley by
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * $FreeBSD: src/sys/i386/i386/swtch.s,v 1.89.2.10 2003/01/23 03:36:24 ps Exp $
38 * $DragonFly: src/lib/libcaps/i386/td_switch_asm.S,v 1.2 2003/12/07 04:21:54 dillon Exp $
49 * The switch function is changed to this when a thread is going away
50 * for good. We have to ensure that the MMU state is not cached, and
51 * we don't bother saving the existing thread state before switching.
53 * At this point we are in a critical section and this cpu owns the
54 * thread's token, which serves as an interlock until the switchout is
57 NON_GPROF_ENTRY(cpu_exit_switch)
59 * Get us out of the vmspace
61 movl PCPU(curthread),%ebx
63 * Switch to the next thread. RET into the restore function, which
64 * expects the new thread in EAX and the old in EBX.
66 * There is a one-instruction window where curthread is the new
67 * thread but %esp still points to the old thread's stack, but
68 * we are protected by a critical section so it is ok.
71 movl %eax,PCPU(curthread)
76 * cpu_kthread_start() (current thread is %eax on entry) (one-time execution)
78 * Run only on first function
80 NON_GPROF_ENTRY(cpu_kthread_start)
81 andl $~TDF_RUNNING,TD_FLAGS(%ebx)
82 orl $TDF_RUNNING,TD_FLAGS(%eax)
83 subl $TDPRI_CRIT,TD_PRI(%eax)
95 * cpu_rfork_start(). The current thread is the idlethread. We restore the
96 * idle thread which generally causes us to jump to cpu_kthraed_start.
98 NON_GPROF_ENTRY(cpu_rfork_start)
99 movl PCPU(curthread),%eax
101 movl TD_SP(%eax),%esp
107 * Standard LWKT switching function. Only non-scratch registers are
108 * saved and we don't bother with the MMU state or anything else.
110 * This function is always called while in a critical section.
112 * There is a one-instruction window where curthread is the new
113 * thread but %esp still points to the old thread's stack, but
114 * we are protected by a critical section so it is ok.
118 NON_GPROF_ENTRY(cpu_lwkt_switch)
125 movl PCPU(curthread),%ebx
126 pushl $cpu_lwkt_restore
127 movl %esp,TD_SP(%ebx)
128 movl %eax,PCPU(curthread)
129 movl TD_SP(%eax),%esp
132 * eax contains new thread, ebx contains old thread.
137 * cpu_lwkt_restore() (current thread in %eax on entry)
138 * (old thread %ebx on entry)
140 * Standard LWKT restore function. This function is always called
141 * while in a critical section.
143 * Warning: due to preemption the restore function can be used to
144 * 'return' to the original thread. Interrupt disablement must be
145 * protected through the switch so we cannot run splz here.
147 * YYY we theoretically do not need to load IdlePTD into cr3, but if
148 * so we need a way to detect when the PTD we are using is being
149 * deleted due to a process exiting.
151 NON_GPROF_ENTRY(cpu_lwkt_restore)
152 andl $~TDF_RUNNING,TD_FLAGS(%ebx)
153 orl $TDF_RUNNING,TD_FLAGS(%eax)
164 * Standard USER switching function. FP and non-scratch registers
167 * This function is always called while in a critical section.
169 * There is a one-instruction window where curthread is the new
170 * thread but %esp still points to the old thread's stack, but
171 * we are protected by a critical section so it is ok.
175 NON_GPROF_ENTRY(cpu_user_switch)
184 movl PCPU(curthread),%ebx
185 pushl $cpu_user_restore
186 movl %esp,TD_SP(%ebx)
187 movl %eax,PCPU(curthread)
188 movl TD_SP(%eax),%esp
191 * eax contains new thread, ebx contains old thread.
196 * cpu_user_restore() (current thread in %eax on entry)
198 * Standard LWKT restore function. This function is always called
199 * while in a critical section.
201 * Warning: due to preemption the restore function can be used to
202 * 'return' to the original thread. Interrupt disablement must be
203 * protected through the switch so we cannot run splz here.
205 * YYY we theoretically do not need to load IdlePTD into cr3, but if
206 * so we need a way to detect when the PTD we are using is being
207 * deleted due to a process exiting.
209 NON_GPROF_ENTRY(cpu_user_restore)
210 andl $~TDF_RUNNING,TD_FLAGS(%ebx)
211 orl $TDF_RUNNING,TD_FLAGS(%eax)