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.2 retrieving revision 1.25.2.2 diff -u -p -r1.2 -r1.25.2.2 --- src/sys/arch/i386/i386/locore.S 2002/12/11 12:02:07 1.2 +++ src/sys/arch/i386/i386/locore.S 2004/09/20 05:57:11 1.25.2.2 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.S,v 1.2 2002/12/11 12:02:07 fvdl Exp $ */ +/* $NetBSD: locore.S,v 1.25.2.2 2004/09/20 05:57:11 tron Exp $ */ /*- * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. @@ -51,11 +51,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -74,22 +70,23 @@ * @(#)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" #include "apm.h" #include "lapic.h" #include "ioapic.h" +#include "ksyms.h" #include #include @@ -114,21 +111,21 @@ #if defined(MULTIPROCESSOR) -#define SET_CURPROC(proc,cpu) \ +#define SET_CURLWP(lwp,cpu) \ movl CPUVAR(SELF),cpu ; \ - movl proc,CPUVAR(CURPROC) ; \ - movl cpu,P_CPU(proc) + movl lwp,CPUVAR(CURLWP) ; \ + movl cpu,L_CPU(lwp) #else -#define SET_CURPROC(proc,tcpu) movl proc,CPUVAR(CURPROC) -#define GET_CURPROC(reg) movl CPUVAR(CURPROC),reg +#define SET_CURLWP(lwp,tcpu) movl lwp,CPUVAR(CURLWP) +#define GET_CURLWP(reg) movl CPUVAR(CURLWP),reg #endif #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 */ @@ -163,7 +160,7 @@ * XXX 4 == sizeof pde */ .set _C_LABEL(PTmap),(PDSLOT_PTE << PDSHIFT) - .set _C_LABEL(PTD),(_C_LABEL(PTmap) + PDSLOT_PTE * NBPG) + .set _C_LABEL(PTD),(_C_LABEL(PTmap) + PDSLOT_PTE * PAGE_SIZE) .set _C_LABEL(PTDpde),(_C_LABEL(PTD) + PDSLOT_PTE * 4) /* @@ -173,7 +170,7 @@ * XXX 4 == sizeof pde */ .set _C_LABEL(APTmap),(PDSLOT_APTE << PDSHIFT) - .set _C_LABEL(APTD),(_C_LABEL(APTmap) + PDSLOT_APTE * NBPG) + .set _C_LABEL(APTD),(_C_LABEL(APTmap) + PDSLOT_APTE * PAGE_SIZE) .set _C_LABEL(APTDpde),(_C_LABEL(PTD) + PDSLOT_APTE * 4) @@ -183,7 +180,6 @@ .data .globl _C_LABEL(cpu) - .globl _C_LABEL(cpu_feature) .globl _C_LABEL(esym),_C_LABEL(boothowto) .globl _C_LABEL(bootinfo),_C_LABEL(atdevbase) #ifdef COMPAT_OLDBOOT @@ -199,7 +195,7 @@ #if NLAPIC > 0 #ifdef __ELF__ - .align NBPG + .align PAGE_SIZE #else .align 12 #endif @@ -214,7 +210,7 @@ _C_LABEL(lapic_tpr): _C_LABEL(lapic_ppr): .space LAPIC_ISR-LAPIC_PPRI _C_LABEL(lapic_isr): - .space NBPG-LAPIC_ISR + .space PAGE_SIZE-LAPIC_ISR #else _C_LABEL(lapic_tpr): .long 0 @@ -223,8 +219,6 @@ _C_LABEL(lapic_tpr): _C_LABEL(cpu): .long 0 # are we 386, 386sx, or 486, # or Pentium, or.. -_C_LABEL(cpu_feature): .long 0 # feature flags from 'cpuid' - # instruction _C_LABEL(esym): .long 0 # ptr to end of syms _C_LABEL(atdevbase): .long 0 # location of start of iomem in virtual _C_LABEL(proc0paddr): .long 0 @@ -244,7 +238,7 @@ _C_LABEL(biosextmem): .long REALEXTMEM tmpstk: -#define _RELOC(x) ((x) - KERNBASE) +#define _RELOC(x) ((x) - KERNBASE_LOCORE) #define RELOC(x) _RELOC(_C_LABEL(x)) .text @@ -298,7 +292,7 @@ start: movw $0x1234,0x472 # warm boot movl 16(%esp),%eax testl %eax,%eax jz 1f - addl $KERNBASE,%eax + addl $KERNBASE_LOCORE,%eax 1: movl %eax,RELOC(esym) movl RELOC(biosextmem),%eax @@ -506,19 +500,19 @@ try586: /* Use the `cpuid' instruction. * text | data | bss | [syms] | page dir | proc0 kstack * 0 1 2 3 */ -#define PROC0PDIR ((0) * NBPG) -#define PROC0STACK ((1) * NBPG) -#define SYSMAP ((1+UPAGES) * NBPG) -#define TABLESIZE ((1+UPAGES) * NBPG) /* + nkpde * NBPG */ +#define PROC0PDIR ((0) * PAGE_SIZE) +#define PROC0STACK ((1) * PAGE_SIZE) +#define SYSMAP ((1+UPAGES) * PAGE_SIZE) +#define TABLESIZE ((1+UPAGES) * PAGE_SIZE) /* + nkpde * PAGE_SIZE */ /* Find end of kernel image. */ movl $RELOC(end),%edi -#if defined(DDB) && !defined(SYMTAB_SPACE) +#if (NKSYMS || defined(DDB) || defined(LKM)) && !defined(SYMTAB_SPACE) /* Save the symbols (if loaded). */ movl RELOC(esym),%eax testl %eax,%eax jz 1f - subl $KERNBASE,%eax + subl $KERNBASE_LOCORE,%eax movl %eax,%edi 1: #endif @@ -530,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 @@ -561,7 +562,7 @@ try586: /* Use the `cpuid' instruction. */ #define fillkpt \ 1: movl %eax,(%ebx) ; \ - addl $NBPG,%eax ; /* increment physical address */ \ + addl $PAGE_SIZE,%eax ; /* increment physical address */ \ addl $4,%ebx ; /* next pte */ \ loop 1b ; @@ -634,10 +635,10 @@ try586: /* Use the `cpuid' instruction. ret begin: - /* Now running relocated at KERNBASE. Remove double mapping. */ + /* Now running relocated at KERNBASE_LOCORE. Remove double mapping. */ movl _C_LABEL(nkpde),%ecx # for this many pde s, leal (PROC0PDIR+0*4)(%esi),%ebx # which is where temp maps! - addl $(KERNBASE), %ebx # now use relocated address + addl $(KERNBASE_LOCORE), %ebx # now use relocated address 1: movl $0,(%ebx) addl $4,%ebx # next pde loop 1b @@ -645,12 +646,12 @@ begin: /* Relocate atdevbase. */ movl _C_LABEL(nkpde),%edx shll $PGSHIFT,%edx - addl $(TABLESIZE+KERNBASE),%edx + addl $(TABLESIZE+KERNBASE_LOCORE),%edx addl %esi,%edx movl %edx,_C_LABEL(atdevbase) /* Set up bootstrap stack. */ - leal (PROC0STACK+KERNBASE)(%esi),%eax + leal (PROC0STACK+KERNBASE_LOCORE)(%esi),%eax movl %eax,_C_LABEL(proc0paddr) leal (USPACE-FRAMESIZE)(%eax),%esp movl %esi,PCB_CR3(%eax) # pcb->pcb_cr3 @@ -707,11 +708,12 @@ NENTRY(proc_trampoline) pushl %ebx call *%esi addl $4,%esp + DO_DEFERRED_SWITCH(%eax) INTRFASTEXIT /* NOTREACHED */ /*****************************************************************************/ - +#ifdef COMPAT_16 /* * Signal trampoline; copied to top of user stack. */ @@ -724,12 +726,13 @@ 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 .globl _C_LABEL(esigcode) _C_LABEL(esigcode): +#endif /*****************************************************************************/ @@ -777,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 @@ -870,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) @@ -1011,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) || \ @@ -1061,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) @@ -1082,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 @@ -1095,8 +1115,8 @@ ENTRY(copyoutstr) /* Compute number of bytes in first page. */ movl %edi,%eax andl $PGOFSET,%eax - movl $NBPG,%ecx - subl %eax,%ecx # ecx = NBPG - (src % NBPG) + movl $PAGE_SIZE,%ecx + subl %eax,%ecx # ecx = PAGE_SIZE - (src % PAGE_SIZE) GET_CURPCB(%eax) movl $6f,PCB_ONFAULT(%eax) @@ -1143,7 +1163,7 @@ ENTRY(copyoutstr) jmp copystr_return 4: /* Go to next page, if any. */ - movl $NBPG,%ecx + movl $PAGE_SIZE,%ecx testl %edx,%edx jnz 1b @@ -1199,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) @@ -1310,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) @@ -1326,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) @@ -1343,11 +1368,13 @@ 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) - movl CPUVAR(CURPROC),%ecx - movl P_ADDR(%ecx),%ecx + movl CPUVAR(CURLWP),%ecx + movl L_ADDR(%ecx),%ecx movl $_C_LABEL(fusubail),PCB_ONFAULT(%ecx) movzwl (%edx),%eax movl $0,PCB_ONFAULT(%ecx) @@ -1360,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) @@ -1404,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) @@ -1451,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) @@ -1499,11 +1529,13 @@ 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) - movl CPUVAR(CURPROC),%ecx - movl P_ADDR(%ecx),%ecx + movl CPUVAR(CURLWP),%ecx + movl L_ADDR(%ecx),%ecx movl $_C_LABEL(fusubail),PCB_ONFAULT(%ecx) #if defined(I386_CPU) @@ -1536,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) @@ -1647,84 +1680,9 @@ ENTRY(longjmp) /*****************************************************************************/ -/* - * The following primitives manipulate the run queues. - * _whichqs tells which of the 32 queues _qs - * have processes in them. Setrq puts processes into queues, Remrq - * removes them from queues. The running process is on no queue, - * other processes are on a queue related to p->p_pri, divided by 4 - * actually to shrink the 0-127 range of priorities into the 32 available - * queues. - */ .globl _C_LABEL(sched_whichqs),_C_LABEL(sched_qs) .globl _C_LABEL(uvmexp),_C_LABEL(panic) -/* - * void setrunqueue(struct proc *p); - * Insert a process on the appropriate queue. Should be called at splclock(). - * See setrunqueue(9) for more details. - */ -/* LINTSTUB: Func: void setrunqueue(struct proc *p) */ -NENTRY(setrunqueue) - movl 4(%esp),%eax -#ifdef DIAGNOSTIC - cmpl $0,P_BACK(%eax) # should not be on q already - jne 1f - cmpl $0,P_WCHAN(%eax) - jne 1f - cmpb $SRUN,P_STAT(%eax) - jne 1f -#endif /* DIAGNOSTIC */ - movzbl P_PRIORITY(%eax),%edx - shrl $2,%edx - btsl %edx,_C_LABEL(sched_whichqs) # set q full bit - leal _C_LABEL(sched_qs)(,%edx,8),%edx # locate q hdr - movl P_BACK(%edx),%ecx - movl %edx,P_FORW(%eax) # link process on tail of q - movl %eax,P_BACK(%edx) - movl %eax,P_FORW(%ecx) - movl %ecx,P_BACK(%eax) - ret -#ifdef DIAGNOSTIC -1: pushl $2f - call _C_LABEL(panic) - /* NOTREACHED */ -2: .asciz "setrunqueue" -#endif /* DIAGNOSTIC */ - -/* - * void remrunqueue(struct proc *p); - * Remove a process from its queue. Should be called at splclock(). - * See remrunqueue(9) for more details. - */ -/* LINTSTUB: Func: void remrunqueue(struct proc *p) */ -NENTRY(remrunqueue) - movl 4(%esp),%ecx - movzbl P_PRIORITY(%ecx),%eax -#ifdef DIAGNOSTIC - shrl $2,%eax - btl %eax,_C_LABEL(sched_whichqs) - jnc 1f -#endif /* DIAGNOSTIC */ - movl P_BACK(%ecx),%edx # unlink process - movl $0,P_BACK(%ecx) # zap reverse link to indicate off list - movl P_FORW(%ecx),%ecx - movl %ecx,P_FORW(%edx) - movl %edx,P_BACK(%ecx) - cmpl %ecx,%edx # q still has something? - jne 2f -#ifndef DIAGNOSTIC - shrl $2,%eax -#endif - btrl %eax,_C_LABEL(sched_whichqs) # no; clear bit -2: ret -#ifdef DIAGNOSTIC -1: pushl $3f - call _C_LABEL(panic) - /* NOTREACHED */ -3: .asciz "remrunqueue" -#endif /* DIAGNOSTIC */ - #ifdef DIAGNOSTIC NENTRY(switch_error) pushl $1f @@ -1734,14 +1692,14 @@ NENTRY(switch_error) #endif /* DIAGNOSTIC */ /* - * void cpu_switch(struct proc *) + * void cpu_switch(struct lwp *) * Find a runnable process and switch to it. Wait if necessary. If the new * process is the same as the old one, we short-circuit the context save and * restore. * * Note that the stack frame layout is known to "struct switchframe" * in and to the code in cpu_fork() which initializes - * it for a new process. + * it for a new lwp. */ ENTRY(cpu_switch) pushl %ebx @@ -1751,37 +1709,36 @@ ENTRY(cpu_switch) #ifdef DEBUG cmpl $IPL_SCHED,CPUVAR(ILEVEL) jae 1f - pushl 2f + pushl $2f call _C_LABEL(panic) /* NOTREACHED */ -2: .asciz "not splhigh() in cpu_switch!" - +2: .asciz "not splsched() in cpu_switch!" 1: #endif /* DEBUG */ - movl CPUVAR(CURPROC),%esi + movl 16(%esp),%esi # current /* - * Clear curproc so that we don't accumulate system time while idle. - * This also insures that schedcpu() will move the old process to + * Clear curlwp so that we don't accumulate system time while idle. + * This also insures that schedcpu() will move the old lwp to * the correct queue if it happens to get called from the spllower() * below and changes the priority. (See corresponding comment in * userret()). */ - movl $0,CPUVAR(CURPROC) + movl $0,CPUVAR(CURLWP) /* - * First phase: find new process. + * First phase: find new lwp. * * Registers: * %eax - queue head, scratch, then zero * %ebx - queue number * %ecx - cached value of whichqs - * %edx - next process in queue - * %esi - old process - * %edi - new process + * %edx - next lwp in queue + * %esi - old lwp + * %edi - new lwp */ - /* Look for new process. */ + /* Look for new lwp. */ cli # splhigh doesn't do a cli movl _C_LABEL(sched_whichqs),%ecx bsfl %ecx,%ebx # find a full q @@ -1792,15 +1749,15 @@ ENTRY(cpu_switch) * * Registers: * %eax, %ecx - scratch - * %esi - old process, then old pcb + * %esi - old lwp, then old pcb * %edi - idle pcb */ pushl %esi - call _C_LABEL(pmap_deactivate) # pmap_deactivate(oldproc) + call _C_LABEL(pmap_deactivate2) # pmap_deactivate(oldproc) addl $4,%esp - movl P_ADDR(%esi),%esi + movl L_ADDR(%esi),%esi /* Save stack pointers. */ movl %esp,PCB_ESP(%esi) @@ -1808,14 +1765,14 @@ ENTRY(cpu_switch) /* Find idle PCB for this CPU */ #ifndef MULTIPROCESSOR - movl $_C_LABEL(proc0),%ebx - movl P_ADDR(%ebx),%edi - movl P_MD_TSS_SEL(%ebx),%edx + movl $_C_LABEL(lwp0),%ebx + movl L_ADDR(%ebx),%edi + movl L_MD_TSS_SEL(%ebx),%edx #else movl CPUVAR(IDLE_PCB),%edi movl CPUVAR(IDLE_TSS_SEL),%edx #endif - movl $0,CPUVAR(CURPROC) /* In case we fault... */ + movl $0,CPUVAR(CURLWP) /* In case we fault... */ /* Restore the idle context (avoid interrupts) */ cli @@ -1824,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 @@ -1878,6 +1832,7 @@ idle_start: jz idle_loop idle_exit: movl $IPL_HIGH,CPUVAR(ILEVEL) # splhigh + sti #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) call _C_LABEL(sched_lock_idle) #endif @@ -1893,14 +1848,14 @@ switch_dequeue: sti leal _C_LABEL(sched_qs)(,%ebx,8),%eax # select q - movl P_FORW(%eax),%edi # unlink from front of process q + movl L_FORW(%eax),%edi # unlink from front of process q #ifdef DIAGNOSTIC cmpl %edi,%eax # linked to self (i.e. nothing queued)? je _C_LABEL(switch_error) # not possible #endif /* DIAGNOSTIC */ - movl P_FORW(%edi),%edx - movl %edx,P_FORW(%eax) - movl %eax,P_BACK(%edx) + movl L_FORW(%edi),%edx + movl %edx,L_FORW(%eax) + movl %eax,L_BACK(%edx) cmpl %edx,%eax # q empty? jne 3f @@ -1912,25 +1867,27 @@ switch_dequeue: xorl %eax,%eax CLEAR_RESCHED(%eax) +switch_resume: #ifdef DIAGNOSTIC - cmpl %eax,P_WCHAN(%edi) # Waiting for something? + cmpl %eax,L_WCHAN(%edi) # Waiting for something? jne _C_LABEL(switch_error) # Yes; shouldn't be queued. - cmpb $SRUN,P_STAT(%edi) # In run state? + cmpb $LSRUN,L_STAT(%edi) # In run state? jne _C_LABEL(switch_error) # No; shouldn't be queued. #endif /* DIAGNOSTIC */ - /* Isolate process. XXX Is this necessary? */ - movl %eax,P_BACK(%edi) + /* Isolate lwp. XXX Is this necessary? */ + movl %eax,L_BACK(%edi) - /* Record new process. */ - movb $SONPROC,P_STAT(%edi) # p->p_stat = SONPROC - SET_CURPROC(%edi,%ecx) + /* Record new lwp. */ + movb $LSONPROC,L_STAT(%edi) # l->l_stat = LSONPROC + SET_CURLWP(%edi,%ecx) - /* Skip context switch if same process. */ + /* Skip context switch if same lwp. */ + xorl %ebx,%ebx cmpl %edi,%esi je switch_return - /* If old process exited, don't bother. */ + /* If old lwp exited, don't bother. */ testl %esi,%esi jz switch_exited @@ -1939,15 +1896,15 @@ switch_dequeue: * * Registers: * %eax, %ecx - scratch - * %esi - old process, then old pcb - * %edi - new process + * %esi - old lwp, then old pcb + * %edi - new lwp */ pushl %esi - call _C_LABEL(pmap_deactivate) # pmap_deactivate(oldproc) + call _C_LABEL(pmap_deactivate2) # pmap_deactivate(oldproc) addl $4,%esp - movl P_ADDR(%esi),%esi + movl L_ADDR(%esi),%esi /* Save stack pointers. */ movl %esp,PCB_ESP(%esi) @@ -1960,12 +1917,12 @@ switch_exited: * Registers: * %eax, %ebx, %ecx, %edx - scratch * %esi - new pcb - * %edi - new process + * %edi - new lwp */ /* No interrupts while loading new state. */ cli - movl P_ADDR(%edi),%esi + movl L_ADDR(%edi),%esi /* Restore stack pointers. */ movl PCB_ESP(%esi),%esp @@ -1973,19 +1930,21 @@ switch_exited: #if 0 /* Don't bother with the rest if switching to a system process. */ - testl $P_SYSTEM,P_FLAG(%edi) + testl $P_SYSTEM,L_FLAG(%edi); XXX NJWLWP lwp's don't have P_SYSTEM! 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 /* Load TSS info. */ movl _C_LABEL(gdt),%eax #endif - movl P_MD_TSS_SEL(%edi),%edx + movl L_MD_TSS_SEL(%edi),%edx - /* Switch TSS. Reset "task busy" flag before loading. */ andl $~0x0200,4(%eax,%edx, 1) ltr %dx @@ -2000,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 @@ -2019,23 +1978,13 @@ switch_restored: /* * Check for restartable atomic sequences (RAS) - * XXX %edi reloads are not necessary here as %edi is callee-saved! */ - movl CPUVAR(CURPROC),%edi - cmpl $0,P_NRAS(%edi) - je 1f - movl P_MD_REGS(%edi),%edx - movl TF_EIP(%edx),%eax - pushl %eax - pushl %edi - call _C_LABEL(ras_lookup) - addl $8,%esp - cmpl $-1,%eax - je 1f - movl CPUVAR(CURPROC),%edi - movl P_MD_REGS(%edi),%edx - movl %eax,TF_EIP(%edx) + movl CPUVAR(CURLWP),%edi + movl L_PROC(%edi),%esi + cmpl $0,P_RASLIST(%esi) + jne 2f 1: + movl $1,%ebx switch_return: #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) @@ -2045,38 +1994,93 @@ switch_return: call _C_LABEL(Xspllower) # process pending interrupts addl $4,%esp movl $IPL_HIGH,CPUVAR(ILEVEL) # splhigh() + + movl %ebx,%eax - movl %edi,%eax # return (p); popl %edi popl %esi 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. + */ +ENTRY(cpu_switchto) + pushl %ebx + pushl %esi + pushl %edi + +#ifdef DEBUG + cmpl $IPL_SCHED,CPUVAR(ILEVEL) + jae 1f + pushl $2f + call _C_LABEL(panic) + /* NOTREACHED */ +2: .asciz "not splsched() in cpu_switchto!" +1: +#endif /* DEBUG */ + + movl 16(%esp),%esi # current + movl 20(%esp),%edi # next + + /* + * Clear curlwp so that we don't accumulate system time while idle. + * This also insures that schedcpu() will move the old process to + * the correct queue if it happens to get called from the spllower() + * below and changes the priority. (See corresponding comment in + * usrret()). + * + * XXX Is this necessary? We know we won't go idle. + */ + movl $0,CPUVAR(CURLWP) + + /* + * We're running at splhigh(), but it's otherwise okay to take + * interrupts here. + */ + sti + + /* Jump into the middle of cpu_switch */ + xorl %eax,%eax + jmp switch_resume + /* - * void switch_exit(struct proc *p); - * switch_exit(struct proc *p); - * Switch to the appropriate idle context (proc0'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. */ #ifndef MULTIPROCESSOR - .globl _C_LABEL(proc0) + .globl _C_LABEL(lwp0) #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 proc *p) */ -ENTRY(switch_exit) +/* LINTSTUB: Func: void cpu_exit(struct lwp *l) */ +ENTRY(cpu_exit) movl 4(%esp),%edi # old process #ifndef MULTIPROCESSOR - movl $_C_LABEL(proc0),%ebx - movl P_ADDR(%ebx),%esi - movl P_MD_TSS_SEL(%ebx),%edx + movl $_C_LABEL(lwp0),%ebx + movl L_ADDR(%ebx),%esi + movl L_MD_TSS_SEL(%ebx),%edx #else movl CPUVAR(IDLE_PCB),%esi movl CPUVAR(IDLE_TSS_SEL),%edx #endif /* In case we fault... */ - movl $0,CPUVAR(CURPROC) + movl $0,CPUVAR(CURLWP) /* Restore the idle context. */ cli @@ -2085,7 +2089,9 @@ ENTRY(switch_exit) movl PCB_ESP(%esi),%esp movl PCB_EBP(%esi),%ebp - /* 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 @@ -2093,11 +2099,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 @@ -2114,15 +2115,15 @@ ENTRY(switch_exit) sti /* - * Schedule the dead process's vmspace and stack to be freed. + * Schedule the dead LWP's stack to be freed. */ - pushl %edi /* exit2(p) */ - call _C_LABEL(exit2) + pushl %edi + call _C_LABEL(lwp_exit2) addl $4,%esp /* Jump into cpu_switch() with the right state. */ xorl %esi,%esi - movl %esi,CPUVAR(CURPROC) + movl %esi,CPUVAR(CURLWP) jmp idle_start /* @@ -2161,6 +2162,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 @@ -2172,23 +2179,31 @@ syscall1: #endif 1: #endif /* DIAGNOSTIC */ - movl CPUVAR(CURPROC),%edx - movl %esp,P_MD_REGS(%edx) # save pointer to frame + movl CPUVAR(CURLWP),%edx + movl %esp,L_MD_REGS(%edx) # save pointer to frame + movl L_PROC(%edx),%edx + pushl %esp call *P_MD_SYSCALL(%edx) # get pointer to syscall() function -2: /* Check for ASTs on exit to user mode. */ + addl $4,%esp +syscall_checkast: + /* Check for ASTs on exit to user mode. */ cli - CHECK_ASTPENDING() + CHECK_ASTPENDING(%eax) je 1f /* Always returning to user mode here. */ - CLEAR_ASTPENDING() + CLEAR_ASTPENDING(%eax) sti /* Pushed T_ASTFLT into tf_trapno on entry. */ + pushl %esp call _C_LABEL(trap) - jmp 2b + addl $4,%esp + jmp syscall_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 @@ -2202,7 +2217,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 syscall_checkast /* re-check ASTs */ #if NNPX > 0 /*