Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/arch/i386/i386/locore.S,v rcsdiff: /ftp/cvs/cvsroot/src/sys/arch/i386/i386/locore.S,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.16 retrieving revision 1.29 diff -u -p -r1.16 -r1.29 --- src/sys/arch/i386/i386/locore.S 2003/09/10 16:46:59 1.16 +++ src/sys/arch/i386/i386/locore.S 2004/08/05 15:25:29 1.29 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.16 2003/09/10 16:46:59 christos Exp $ */ +/* $NetBSD: locore.S,v 1.29 2004/08/05 15:25:29 mycroft Exp $ */ /*- * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. @@ -70,16 +70,16 @@ * @(#)locore.s 7.3 (Berkeley) 5/13/91 */ +#include "opt_compat_netbsd.h" +#include "opt_compat_oldboot.h" #include "opt_cputype.h" #include "opt_ddb.h" #include "opt_ipkdb.h" -#include "opt_vm86.h" -#include "opt_user_ldt.h" -#include "opt_dummy_nops.h" -#include "opt_compat_oldboot.h" -#include "opt_multiprocessor.h" #include "opt_lockdebug.h" +#include "opt_multiprocessor.h" #include "opt_realmem.h" +#include "opt_user_ldt.h" +#include "opt_vm86.h" #include "npx.h" #include "assym.h" @@ -125,7 +125,7 @@ #define GET_CURPCB(reg) movl CPUVAR(CURPCB),reg #define SET_CURPCB(reg) movl reg,CPUVAR(CURPCB) - + #define CLEAR_RESCHED(reg) movl reg,CPUVAR(RESCHED) /* XXX temporary kluge; these should not be here */ @@ -524,17 +524,24 @@ try586: /* Use the `cpuid' instruction. /* * Calculate the size of the kernel page table directory, and - * how many entries it will have. + * how many entries it will have. Adjust nkpde to the actual + * kernel size automatically. Account for the bootstrap tables, + * round up, and add an extra 4MB. */ + leal TABLESIZE+NBPD+PDOFSET(%edi),%eax + shrl $PDSHIFT,%eax movl RELOC(nkpde),%ecx # get nkpde - cmpl $NKPTP_MIN,%ecx # larger than min? + cmpl %ecx,%eax + jb 1f + movl %eax,%ecx +1: cmpl $NKPTP_MIN,%ecx # larger than min? jge 1f movl $NKPTP_MIN,%ecx # set at min jmp 2f 1: cmpl $NKPTP_MAX,%ecx # larger than max? jle 2f movl $NKPTP_MAX,%ecx -2: +2: movl %ecx,RELOC(nkpde) /* Clear memory for bootstrap tables. */ shll $PGSHIFT,%ecx @@ -701,6 +708,7 @@ NENTRY(proc_trampoline) pushl %ebx call *%esi addl $4,%esp + DO_DEFERRED_SWITCH(%eax) INTRFASTEXIT /* NOTREACHED */ @@ -718,7 +726,7 @@ NENTRY(sigcode) leal 12(%esp),%eax # get pointer to sigcontext movl %eax,4(%esp) # put it in the argument slot # fake return address already there - movl $SYS___sigreturn14,%eax + movl $SYS_compat_16___sigreturn14,%eax int $0x80 # enter kernel with args on stack movl $SYS_exit,%eax int $0x80 # exit if sigreturn fails @@ -772,7 +780,7 @@ ENTRY(kcopy) pushl %edi GET_CURPCB(%eax) # load curpcb into eax and set on-fault pushl PCB_ONFAULT(%eax) - movl $_C_LABEL(copy_fault), PCB_ONFAULT(%eax) + movl $_C_LABEL(kcopy_fault), PCB_ONFAULT(%eax) movl 16(%esp),%esi movl 20(%esp),%edi @@ -865,6 +873,7 @@ _C_LABEL(copyin_func): */ /* LINTSTUB: Func: int copyout(const void *kaddr, void *uaddr, size_t len) */ ENTRY(copyout) + DO_DEFERRED_SWITCH(%eax) jmp *_C_LABEL(copyout_func) #if defined(I386_CPU) @@ -1006,6 +1015,7 @@ ENTRY(i486_copyout) */ /* LINTSTUB: Func: int copyin(const void *uaddr, void *kaddr, size_t len) */ ENTRY(copyin) + DO_DEFERRED_SWITCH(%eax) jmp *_C_LABEL(copyin_func) #if defined(I386_CPU) || defined(I486_CPU) || defined(I586_CPU) || \ @@ -1056,6 +1066,19 @@ ENTRY(i386_copyin) NENTRY(copy_efault) movl $EFAULT,%eax +/* + * kcopy_fault is used by kcopy and copy_fault is used by copyin/out. + * + * they're distinguished for lazy pmap switching. see trap(). + */ +/* LINTSTUB: Ignore */ +NENTRY(kcopy_fault) + GET_CURPCB(%edx) + popl PCB_ONFAULT(%edx) + popl %edi + popl %esi + ret + /* LINTSTUB: Ignore */ NENTRY(copy_fault) GET_CURPCB(%edx) @@ -1077,6 +1100,8 @@ ENTRY(copyoutstr) pushl %esi pushl %edi + DO_DEFERRED_SWITCH(%eax) + movl 12(%esp),%esi # esi = from movl 16(%esp),%edi # edi = to movl 20(%esp),%edx # edx = maxlen @@ -1194,6 +1219,9 @@ ENTRY(copyoutstr) ENTRY(copyinstr) pushl %esi pushl %edi + + DO_DEFERRED_SWITCH(%eax) + GET_CURPCB(%ecx) movl $_C_LABEL(copystr_fault),PCB_ONFAULT(%ecx) @@ -1305,6 +1333,7 @@ ENTRY(copystr) */ /* LINTSTUB: Func: long fuword(const void *base) */ ENTRY(fuword) + DO_DEFERRED_SWITCH(%eax) movl 4(%esp),%edx cmpl $VM_MAXUSER_ADDRESS-4,%edx ja _C_LABEL(fusuaddrfault) @@ -1321,6 +1350,7 @@ ENTRY(fuword) */ /* LINTSTUB: Func: int fusword(const void *base) */ ENTRY(fusword) + DO_DEFERRED_SWITCH(%eax) movl 4(%esp),%edx cmpl $VM_MAXUSER_ADDRESS-2,%edx ja _C_LABEL(fusuaddrfault) @@ -1338,6 +1368,8 @@ ENTRY(fusword) */ /* LINTSTUB: Func: int fuswintr(const void *base) */ ENTRY(fuswintr) + cmpl $TLBSTATE_VALID, CPUVAR(TLBSTATE) + jnz _C_LABEL(fusuaddrfault) movl 4(%esp),%edx cmpl $VM_MAXUSER_ADDRESS-2,%edx ja _C_LABEL(fusuaddrfault) @@ -1355,6 +1387,7 @@ ENTRY(fuswintr) */ /* LINTSTUB: Func: int fubyte(const void *base) */ ENTRY(fubyte) + DO_DEFERRED_SWITCH(%eax) movl 4(%esp),%edx cmpl $VM_MAXUSER_ADDRESS-1,%edx ja _C_LABEL(fusuaddrfault) @@ -1399,6 +1432,7 @@ NENTRY(fusuaddrfault) */ /* LINTSTUB: Func: int suword(void *base, long c) */ ENTRY(suword) + DO_DEFERRED_SWITCH(%eax) movl 4(%esp),%edx cmpl $VM_MAXUSER_ADDRESS-4,%edx ja _C_LABEL(fusuaddrfault) @@ -1446,6 +1480,7 @@ ENTRY(suword) */ /* LINTSTUB: Func: int susword(void *base, short c) */ ENTRY(susword) + DO_DEFERRED_SWITCH(%eax) movl 4(%esp),%edx cmpl $VM_MAXUSER_ADDRESS-2,%edx ja _C_LABEL(fusuaddrfault) @@ -1494,6 +1529,8 @@ ENTRY(susword) */ /* LINTSTUB: Func: int suswintr(void *base, short c) */ ENTRY(suswintr) + cmpl $TLBSTATE_VALID, CPUVAR(TLBSTATE) + jnz _C_LABEL(fusuaddrfault) movl 4(%esp),%edx cmpl $VM_MAXUSER_ADDRESS-2,%edx ja _C_LABEL(fusuaddrfault) @@ -1531,6 +1568,7 @@ ENTRY(suswintr) */ /* LINTSTUB: Func: int subyte(void *base, int c) */ ENTRY(subyte) + DO_DEFERRED_SWITCH(%eax) movl 4(%esp),%edx cmpl $VM_MAXUSER_ADDRESS-1,%edx ja _C_LABEL(fusuaddrfault) @@ -1716,7 +1754,7 @@ ENTRY(cpu_switch) */ pushl %esi - call _C_LABEL(pmap_deactivate) # pmap_deactivate(oldproc) + call _C_LABEL(pmap_deactivate2) # pmap_deactivate(oldproc) addl $4,%esp movl L_ADDR(%esi),%esi @@ -1743,12 +1781,9 @@ ENTRY(cpu_switch) movl PCB_ESP(%edi),%esp movl PCB_EBP(%edi),%ebp - - /* Switch address space. */ - movl PCB_CR3(%edi),%ecx - movl %ecx,%cr3 - /* Switch TSS. Reset "task busy" flag before loading. */ + movl %cr3,%eax + movl %eax,PCB_CR3(%edi) #ifdef MULTIPROCESSOR movl CPUVAR(GDT),%eax #else @@ -1866,7 +1901,7 @@ switch_resume: */ pushl %esi - call _C_LABEL(pmap_deactivate) # pmap_deactivate(oldproc) + call _C_LABEL(pmap_deactivate2) # pmap_deactivate(oldproc) addl $4,%esp movl L_ADDR(%esi),%esi @@ -1899,6 +1934,9 @@ switch_exited: jnz switch_restored #endif + /* Switch TSS. Reset "task busy" flag before loading. */ + movl %cr3,%eax + movl %eax,PCB_CR3(%esi) /* XXX should be done by pmap_activate? */ #ifdef MULTIPROCESSOR movl CPUVAR(GDT),%eax #else @@ -1907,7 +1945,6 @@ switch_exited: #endif movl L_MD_TSS_SEL(%edi),%edx - /* Switch TSS. Reset "task busy" flag before loading. */ andl $~0x0200,4(%eax,%edx, 1) ltr %dx @@ -1922,7 +1959,7 @@ switch_restored: movl PCB_CR0(%esi),%ecx #ifdef MULTIPROCESSOR /* - * If our floating point registers are on a different cpu, + * If our floating point registers are on a different CPU, * clear CR0_TS so we'll trap rather than reuse bogus state. */ movl PCB_FPCPU(%esi),%ebx @@ -1944,17 +1981,8 @@ switch_restored: */ movl CPUVAR(CURLWP),%edi movl L_PROC(%edi),%esi - cmpl $0,P_NRAS(%esi) - je 1f - movl L_MD_REGS(%edi),%ebx - movl TF_EIP(%ebx),%eax - pushl %eax - pushl %esi - call _C_LABEL(ras_lookup) - addl $8,%esp - cmpl $-1,%eax - je 1f - movl %eax,TF_EIP(%ebx) + cmpl $0,P_RASLIST(%esi) + jne 2f 1: movl $1,%ebx @@ -1962,9 +1990,12 @@ switch_return: #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) call _C_LABEL(sched_unlock_idle) #endif + cmpl $0,CPUVAR(IPENDING) + jz 3f pushl $IPL_NONE # spl0() call _C_LABEL(Xspllower) # process pending interrupts addl $4,%esp +3: movl $IPL_HIGH,CPUVAR(ILEVEL) # splhigh() movl %ebx,%eax @@ -1974,6 +2005,18 @@ switch_return: popl %ebx ret +2: # check RAS list + movl L_MD_REGS(%edi),%ebx + movl TF_EIP(%ebx),%eax + pushl %eax + pushl %esi + call _C_LABEL(ras_lookup) + addl $8,%esp + cmpl $-1,%eax + je 1b + movl %eax,TF_EIP(%ebx) + jmp 1b + /* * void cpu_switchto(struct lwp *current, struct lwp *next) * Switch to the specified next LWP. @@ -2018,8 +2061,8 @@ ENTRY(cpu_switchto) jmp switch_resume /* - * void switch_exit(struct lwp *l, void (*exit)(struct lwp *)); - * Switch to the appropriate idle context (lwp0's if uniprocessor; the cpu's + * void cpu_exit(struct lwp *l) + * Switch to the appropriate idle context (lwp0's if uniprocessor; the CPU's * if multiprocessor) and deallocate the address space and kernel stack for p. * Then jump into cpu_switch(), as if we were in the idle proc all along. */ @@ -2028,10 +2071,9 @@ ENTRY(cpu_switchto) #endif .globl _C_LABEL(uvmspace_free),_C_LABEL(kernel_map) .globl _C_LABEL(uvm_km_free),_C_LABEL(tss_free) -/* LINTSTUB: Func: void switch_exit(struct lwp *l, void (*exit)(struct lwp *)) */ -ENTRY(switch_exit) +/* LINTSTUB: Func: void cpu_exit(struct lwp *l) */ +ENTRY(cpu_exit) movl 4(%esp),%edi # old process - movl 8(%esp),%eax # exit func #ifndef MULTIPROCESSOR movl $_C_LABEL(lwp0),%ebx movl L_ADDR(%ebx),%esi @@ -2050,10 +2092,9 @@ ENTRY(switch_exit) movl PCB_ESP(%esi),%esp movl PCB_EBP(%esi),%ebp - /* Save exit func. */ - pushl %eax - - /* Load TSS info. */ + /* Switch TSS. Reset "task busy" flag before loading. */ + movl %cr3,%eax + movl %eax,PCB_CR3(%esi) #ifdef MULTIPROCESSOR movl CPUVAR(GDT),%eax #else @@ -2061,11 +2102,6 @@ ENTRY(switch_exit) movl _C_LABEL(gdt),%eax #endif - /* Switch address space. */ - movl PCB_CR3(%esi),%ecx - movl %ecx,%cr3 - - /* Switch TSS. */ andl $~0x0200,4-SEL_KPL(%eax,%edx,1) ltr %dx @@ -2082,11 +2118,10 @@ ENTRY(switch_exit) sti /* - * Schedule the dead process's vmspace and stack to be freed. + * Schedule the dead LWP's stack to be freed. */ - movl 0(%esp),%eax /* %eax = exit func */ - movl %edi,0(%esp) /* {lwp_}exit2(l) */ - call *%eax + pushl %edi + call _C_LABEL(lwp_exit2) addl $4,%esp /* Jump into cpu_switch() with the right state. */ @@ -2130,6 +2165,12 @@ syscall1: INTRENTRY #ifdef DIAGNOSTIC + cmpl $0, CPUVAR(WANT_PMAPLOAD) + jz 1f + pushl $6f + call _C_LABEL(printf) + addl $4, %esp +1: movl CPUVAR(ILEVEL),%ebx testl %ebx,%ebx jz 1f @@ -2147,7 +2188,8 @@ syscall1: pushl %esp call *P_MD_SYSCALL(%edx) # get pointer to syscall() function addl $4,%esp -2: /* Check for ASTs on exit to user mode. */ +.Lsyscall_checkast: + /* Check for ASTs on exit to user mode. */ cli CHECK_ASTPENDING(%eax) je 1f @@ -2158,11 +2200,13 @@ syscall1: pushl %esp call _C_LABEL(trap) addl $4,%esp - jmp 2b + jmp .Lsyscall_checkast /* re-check ASTs */ +1: CHECK_DEFERRED_SWITCH(%eax) + jnz 9f #ifndef DIAGNOSTIC -1: INTRFASTEXIT + INTRFASTEXIT #else /* DIAGNOSTIC */ -1: cmpl $IPL_NONE,CPUVAR(ILEVEL) + cmpl $IPL_NONE,CPUVAR(ILEVEL) jne 3f INTRFASTEXIT 3: sti @@ -2176,7 +2220,11 @@ syscall1: jmp 2b 4: .asciz "WARNING: SPL NOT LOWERED ON SYSCALL EXIT\n" 5: .asciz "WARNING: SPL NOT ZERO ON SYSCALL ENTRY\n" +6: .asciz "WARNING: WANT PMAPLOAD ON SYSCALL ENTRY\n" #endif /* DIAGNOSTIC */ +9: sti + call _C_LABEL(pmap_load) + jmp .Lsyscall_checkast /* re-check ASTs */ #if NNPX > 0 /*