version 1.53, 2007/10/18 15:28:35 |
version 1.53.2.3, 2007/12/27 00:43:07 |
|
|
* @(#)locore.s 7.3 (Berkeley) 5/13/91 |
* @(#)locore.s 7.3 (Berkeley) 5/13/91 |
*/ |
*/ |
|
|
|
#include <machine/asm.h> |
|
__KERNEL_RCSID(0, "$NetBSD$"); |
|
|
#include "opt_compat_oldboot.h" |
#include "opt_compat_oldboot.h" |
#include "opt_cputype.h" |
|
#include "opt_ddb.h" |
#include "opt_ddb.h" |
#include "opt_realmem.h" |
#include "opt_realmem.h" |
#include "opt_vm86.h" |
#include "opt_vm86.h" |
|
|
#include <machine/trap.h> |
#include <machine/trap.h> |
#include <machine/i82489reg.h> |
#include <machine/i82489reg.h> |
#include <machine/multiboot.h> |
#include <machine/multiboot.h> |
#include <machine/asm.h> |
|
#include <machine/frameasm.h> |
#include <machine/frameasm.h> |
#include <machine/i82489reg.h> |
#include <machine/i82489reg.h> |
|
|
|
|
ret |
ret |
|
|
/* |
/* |
* struct lwp *cpu_switchto(struct lwp *oldlwp, struct newlwp) |
* struct lwp *cpu_switchto(struct lwp *oldlwp, struct newlwp, |
|
* bool returning) |
* |
* |
* 1. if (oldlwp != NULL), save its context. |
* 1. if (oldlwp != NULL), save its context. |
* 2. then, restore context of newlwp. |
* 2. then, restore context of newlwp. |
Line 739 ENTRY(cpu_switchto) |
|
Line 741 ENTRY(cpu_switchto) |
|
|
|
movl 16(%esp),%esi # oldlwp |
movl 16(%esp),%esi # oldlwp |
movl 20(%esp),%edi # newlwp |
movl 20(%esp),%edi # newlwp |
|
movl 24(%esp),%edx # returning |
testl %esi,%esi |
testl %esi,%esi |
jz 1f |
jz 1f |
|
|
Line 752 ENTRY(cpu_switchto) |
|
Line 755 ENTRY(cpu_switchto) |
|
movl PCB_EBP(%ebx),%ebp |
movl PCB_EBP(%ebx),%ebp |
movl PCB_ESP(%ebx),%esp |
movl PCB_ESP(%ebx),%esp |
|
|
|
/* Set curlwp. */ |
|
movl %edi,CPUVAR(CURLWP) |
|
|
|
/* Skip the rest if returning to a pinned LWP. */ |
|
testl %edx,%edx |
|
jnz 4f |
|
|
/* Switch TSS. Reset "task busy" flag before loading. */ |
/* Switch TSS. Reset "task busy" flag before loading. */ |
movl %cr3,%eax |
movl %cr3,%eax |
movl %eax,PCB_CR3(%ebx) # for TSS gates |
movl %eax,PCB_CR3(%ebx) # for TSS gates |
movl CPUVAR(GDT),%eax |
movl CPUVAR(GDT),%ecx |
movl L_MD_TSS_SEL(%edi),%edx |
movl L_MD_TSS_SEL(%edi),%edx |
andl $~0x0200,4(%eax,%edx, 1) |
andl $~0x0200,4(%ecx,%edx, 1) |
ltr %dx |
ltr %dx |
|
|
/* Set curlwp. */ |
|
movl %edi,CPUVAR(CURLWP) |
|
|
|
/* Don't bother with the rest if switching to a system process. */ |
/* Don't bother with the rest if switching to a system process. */ |
testl $LW_SYSTEM,L_FLAG(%edi) |
testl $LW_SYSTEM,L_FLAG(%edi) |
jnz 4f |
jnz 4f |
|
|
|
/* Restore thread-private %fs/%gs descriptors. */ |
|
movl PCB_FSD(%ebx), %eax |
|
movl PCB_FSD+4(%ebx), %edx |
|
movl %eax, (GUFS_SEL*8)(%ecx) |
|
movl %edx, (GUFS_SEL*8+4)(%ecx) |
|
movl PCB_GSD(%ebx), %eax |
|
movl PCB_GSD+4(%ebx), %edx |
|
movl %eax, (GUGS_SEL*8)(%ecx) |
|
movl %edx, (GUGS_SEL*8+4)(%ecx) |
|
|
/* Is this process using RAS (restartable atomic sequences)? */ |
/* Is this process using RAS (restartable atomic sequences)? */ |
movl L_PROC(%edi),%eax |
movl L_PROC(%edi),%eax |
cmpl $0,P_RASLIST(%eax) |
cmpl $0,P_RASLIST(%eax) |
|
|
pushl $4f |
pushl $4f |
call _C_LABEL(printf) |
call _C_LABEL(printf) |
addl $4,%esp |
addl $4,%esp |
#ifdef DDB |
pushl $IPL_NONE |
int $3 |
call _C_LABEL(spllower) |
#endif /* DDB */ |
addl $4,%esp |
movl $IPL_NONE,CPUVAR(ILEVEL) |
|
jmp .Lsyscall_checkast |
jmp .Lsyscall_checkast |
4: .asciz "WARNING: SPL NOT LOWERED ON SYSCALL EXIT\n" |
4: .asciz "WARNING: SPL NOT LOWERED ON SYSCALL EXIT\n" |
5: .asciz "WARNING: SPL NOT ZERO ON SYSCALL ENTRY\n" |
5: .asciz "WARNING: SPL NOT ZERO ON SYSCALL ENTRY\n" |