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.7 retrieving revision 1.31.6.2 diff -u -p -r1.7 -r1.31.6.2 --- src/sys/arch/i386/i386/locore.S 2003/04/08 23:48:48 1.7 +++ src/sys/arch/i386/i386/locore.S 2005/03/19 08:33:02 1.31.6.2 @@ -1,7 +1,7 @@ -/* $NetBSD: locore.S,v 1.7 2003/04/08 23:48:48 thorpej Exp $ */ +/* $NetBSD: locore.S,v 1.31.6.2 2005/03/19 08:33:02 yamt Exp $ */ /*- - * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. + * Copyright (c) 1998, 2000, 2004 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -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 @@ -113,12 +110,12 @@ #include #if defined(MULTIPROCESSOR) - + #define SET_CURLWP(lwp,cpu) \ movl CPUVAR(SELF),cpu ; \ movl lwp,CPUVAR(CURLWP) ; \ movl cpu,L_CPU(lwp) - + #else #define SET_CURLWP(lwp,tcpu) movl lwp,CPUVAR(CURLWP) @@ -126,9 +123,9 @@ #endif -#define GET_CURPCB(reg) movl CPUVAR(CURPCB),reg +#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 */ @@ -155,27 +152,9 @@ #ifdef MULTIPROCESSOR #include #endif - -/* - * PTmap is recursive pagemap at top of virtual address space. - * Within PTmap, the page directory can be found (third indirection). - * - * XXX 4 == sizeof pde - */ - .set _C_LABEL(PTmap),(PDSLOT_PTE << PDSHIFT) - .set _C_LABEL(PTD),(_C_LABEL(PTmap) + PDSLOT_PTE * PAGE_SIZE) - .set _C_LABEL(PTDpde),(_C_LABEL(PTD) + PDSLOT_PTE * 4) - -/* - * APTmap, APTD is the alternate recursive pagemap. - * It's used when modifying another process's page tables. - * - * XXX 4 == sizeof pde - */ - .set _C_LABEL(APTmap),(PDSLOT_APTE << PDSHIFT) - .set _C_LABEL(APTD),(_C_LABEL(APTmap) + PDSLOT_APTE * PAGE_SIZE) - .set _C_LABEL(APTDpde),(_C_LABEL(PTD) + PDSLOT_APTE * 4) +/* This shouldn't conflict with a macro of the same name defined in pmap.h */ +#define PTE_BASE (PDSLOT_PTE << PDSHIFT) /* * Initialization @@ -183,20 +162,19 @@ .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 .globl _C_LABEL(bootdev) #endif - .globl _C_LABEL(proc0paddr),_C_LABEL(PTDpaddr) + .globl _C_LABEL(proc0paddr),_C_LABEL(PDPpaddr) .globl _C_LABEL(biosbasemem),_C_LABEL(biosextmem) .globl _C_LABEL(gdt) #ifdef I586_CPU .globl _C_LABEL(idt) #endif - .globl _C_LABEL(lapic_tpr) - + .globl _C_LABEL(lapic_tpr) + #if NLAPIC > 0 #ifdef __ELF__ .align PAGE_SIZE @@ -206,29 +184,27 @@ .globl _C_LABEL(local_apic), _C_LABEL(lapic_id) _C_LABEL(local_apic): .space LAPIC_ID -_C_LABEL(lapic_id): +_C_LABEL(lapic_id): .long 0x00000000 .space LAPIC_TPRI-(LAPIC_ID+4) -_C_LABEL(lapic_tpr): +_C_LABEL(lapic_tpr): .space LAPIC_PPRI-LAPIC_TPRI -_C_LABEL(lapic_ppr): +_C_LABEL(lapic_ppr): .space LAPIC_ISR-LAPIC_PPRI _C_LABEL(lapic_isr): .space PAGE_SIZE-LAPIC_ISR #else -_C_LABEL(lapic_tpr): +_C_LABEL(lapic_tpr): .long 0 #endif - + _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 -_C_LABEL(PTDpaddr): .long 0 # paddr of PTD, for libkvm +_C_LABEL(PDPpaddr): .long 0 # paddr of PDP, for libkvm #ifndef REALBASEMEM _C_LABEL(biosbasemem): .long 0 # base memory reported by BIOS #else @@ -239,12 +215,12 @@ _C_LABEL(biosextmem): .long 0 # extended #else _C_LABEL(biosextmem): .long REALEXTMEM #endif - + .space 512 tmpstk: -#define _RELOC(x) ((x) - KERNBASE) +#define _RELOC(x) ((x) - KERNBASE_LOCORE) #define RELOC(x) _RELOC(_C_LABEL(x)) .text @@ -298,7 +274,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 @@ -503,7 +479,7 @@ try586: /* Use the `cpuid' instruction. /* * Virtual address space of kernel: * - * text | data | bss | [syms] | page dir | proc0 kstack + * text | data | bss | [syms] | page dir | proc0 kstack * 0 1 2 3 */ #define PROC0PDIR ((0) * PAGE_SIZE) @@ -513,12 +489,12 @@ try586: /* Use the `cpuid' instruction. /* 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 +506,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 @@ -571,7 +554,7 @@ try586: /* Use the `cpuid' instruction. /* Calculate end of text segment, rounded to a page. */ leal (RELOC(etext)+PGOFSET),%edx andl $~PGOFSET,%edx - + /* Skip over the first 1MB. */ movl $_RELOC(KERNTEXTOFF),%eax movl %eax,%ecx @@ -619,8 +602,8 @@ try586: /* Use the `cpuid' instruction. leal (PROC0PDIR+PG_V|PG_KW)(%esi),%eax # pte for ptd movl %eax,(PROC0PDIR+PDSLOT_PTE*4)(%esi) # recursive PD slot - /* Save phys. addr of PTD, for libkvm. */ - movl %esi,RELOC(PTDpaddr) + /* Save phys. addr of PDP, for libkvm. */ + movl %esi,RELOC(PDPpaddr) /* Load base of page directory and enable mapping. */ movl %esi,%eax # phys address of ptd in proc 0 @@ -634,10 +617,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 +628,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 @@ -660,7 +643,7 @@ begin: pushl %esp call _C_LABEL(initgdt) addl $4,%esp - + movl _C_LABEL(nkpde),%eax shll $PGSHIFT,%eax addl $TABLESIZE,%eax @@ -707,11 +690,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 +708,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 +762,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 +855,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) @@ -878,7 +864,7 @@ ENTRY(i386_copyout) pushl %esi pushl %edi pushl $0 - + movl 16(%esp),%esi movl 20(%esp),%edi movl 24(%esp),%eax @@ -918,9 +904,9 @@ ENTRY(i386_copyout) movl $2f,PCB_ONFAULT(%edx) 1: /* Check PTE for each page. */ - testb $PG_RW,_C_LABEL(PTmap)(,%edi,4) + testb $PG_RW,PTE_BASE(,%edi,4) jz 2f - + 4: incl %edi decl %ecx jns 1b @@ -928,7 +914,7 @@ ENTRY(i386_copyout) movl 20(%esp),%edi movl 24(%esp),%eax jmp 3f - + 2: /* Simulate a trap. */ pushl %ecx movl %edi,%eax @@ -968,7 +954,7 @@ ENTRY(i486_copyout) pushl %esi pushl %edi pushl $0 - + movl 16(%esp),%esi movl 20(%esp),%edi movl 24(%esp),%eax @@ -1011,6 +997,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) || \ @@ -1022,7 +1009,7 @@ ENTRY(i386_copyin) GET_CURPCB(%eax) pushl $0 movl $_C_LABEL(copy_fault),PCB_ONFAULT(%eax) - + movl 16(%esp),%esi movl 20(%esp),%edi movl 24(%esp),%eax @@ -1061,6 +1048,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 +1082,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 @@ -1112,7 +1114,7 @@ ENTRY(copyoutstr) movl %edi,%eax shrl $PGSHIFT,%eax # calculate pte address - testb $PG_RW,_C_LABEL(PTmap)(,%eax,4) + testb $PG_RW,PTE_BASE(,%eax,4) jnz 2f 6: /* Simulate a trap. */ @@ -1160,6 +1162,7 @@ ENTRY(copyoutstr) */ movl $VM_MAXUSER_ADDRESS,%eax subl %edi,%eax + jc _C_LABEL(copystr_efault) cmpl %edx,%eax jae 1f movl %eax,%edx @@ -1199,6 +1202,9 @@ ENTRY(copyoutstr) ENTRY(copyinstr) pushl %esi pushl %edi + + DO_DEFERRED_SWITCH(%eax) + GET_CURPCB(%ecx) movl $_C_LABEL(copystr_fault),PCB_ONFAULT(%ecx) @@ -1211,6 +1217,7 @@ ENTRY(copyinstr) */ movl $VM_MAXUSER_ADDRESS,%eax subl %esi,%eax + jc _C_LABEL(copystr_efault) cmpl %edx,%eax jae 1f movl %eax,%edx @@ -1310,6 +1317,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) @@ -1318,7 +1326,7 @@ ENTRY(fuword) movl (%edx),%eax movl $0,PCB_ONFAULT(%ecx) ret - + /* * int fusword(const void *uaddr); * Fetch a short from the user's address space. @@ -1326,6 +1334,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) @@ -1334,7 +1343,7 @@ ENTRY(fusword) movzwl (%edx),%eax movl $0,PCB_ONFAULT(%ecx) ret - + /* * int fuswintr(const void *uaddr); * Fetch a short from the user's address space. Can be called during an @@ -1343,6 +1352,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) @@ -1352,7 +1363,7 @@ ENTRY(fuswintr) movzwl (%edx),%eax movl $0,PCB_ONFAULT(%ecx) ret - + /* * int fubyte(const void *uaddr); * Fetch a byte from the user's address space. @@ -1360,6 +1371,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 +1416,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) @@ -1419,7 +1432,7 @@ ENTRY(suword) movl %edx,%eax shrl $PGSHIFT,%eax # calculate pte address - testb $PG_RW,_C_LABEL(PTmap)(,%eax,4) + testb $PG_RW,PTE_BASE(,%eax,4) jnz 1f 3: /* Simulate a trap. */ @@ -1443,7 +1456,7 @@ ENTRY(suword) xorl %eax,%eax movl %eax,PCB_ONFAULT(%ecx) ret - + /* * int susword(void *uaddr, short x); * Store a short in the user's address space. @@ -1451,6 +1464,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) @@ -1466,7 +1480,7 @@ ENTRY(susword) movl %edx,%eax shrl $PGSHIFT,%eax # calculate pte address - testb $PG_RW,_C_LABEL(PTmap)(,%eax,4) + testb $PG_RW,PTE_BASE(,%eax,4) jnz 1f 3: /* Simulate a trap. */ @@ -1499,6 +1513,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) @@ -1514,7 +1530,7 @@ ENTRY(suswintr) movl %edx,%eax shrl $PGSHIFT,%eax # calculate pte address - testb $PG_RW,_C_LABEL(PTmap)(,%eax,4) + testb $PG_RW,PTE_BASE(,%eax,4) jnz 1f /* Simulate a trap. */ @@ -1536,6 +1552,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) @@ -1546,12 +1563,12 @@ ENTRY(subyte) jne 2f #endif /* I486_CPU || I586_CPU || I686_CPU */ - GET_CURPCB(%eax) + GET_CURPCB(%eax) movl $3f,PCB_ONFAULT(%eax) movl %edx,%eax shrl $PGSHIFT,%eax # calculate pte address - testb $PG_RW,_C_LABEL(PTmap)(,%eax,4) + testb $PG_RW,PTE_BASE(,%eax,4) jnz 1f 3: /* Simulate a trap. */ @@ -1663,9 +1680,9 @@ NENTRY(switch_error) * 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 + * in and to the code in cpu_fork() which initializes * it for a new lwp. */ ENTRY(cpu_switch) @@ -1680,9 +1697,9 @@ ENTRY(cpu_switch) call _C_LABEL(panic) /* NOTREACHED */ 2: .asciz "not splsched() in cpu_switch!" -1: +1: #endif /* DEBUG */ - + movl 16(%esp),%esi # current /* @@ -1721,7 +1738,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 @@ -1748,12 +1765,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 @@ -1773,8 +1787,8 @@ ENTRY(cpu_switch) xorl %esi,%esi sti -idle_unlock: -#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) +idle_unlock: +#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) call _C_LABEL(sched_unlock_idle) #endif /* Interrupts are okay again. */ @@ -1782,7 +1796,7 @@ idle_unlock: call _C_LABEL(Xspllower) # process pending interrupts addl $4,%esp jmp idle_start -idle_zero: +idle_zero: sti call _C_LABEL(uvm_pageidlezero) cli @@ -1796,23 +1810,24 @@ idle_loop: sti hlt NENTRY(mpidle) -idle_start: +idle_start: cli cmpl $0,_C_LABEL(sched_whichqs) jz idle_loop -idle_exit: +idle_exit: movl $IPL_HIGH,CPUVAR(ILEVEL) # splhigh -#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) + sti +#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) call _C_LABEL(sched_lock_idle) #endif movl _C_LABEL(sched_whichqs),%ecx bsfl %ecx,%ebx jz idle_unlock -switch_dequeue: - /* +switch_dequeue: + /* * we're running at splhigh(), but it's otherwise okay to take - * interrupts here. + * interrupts here. */ sti leal _C_LABEL(sched_qs)(,%ebx,8),%eax # select q @@ -1852,7 +1867,7 @@ switch_resume: SET_CURLWP(%edi,%ecx) /* Skip context switch if same lwp. */ - movl $1, %eax + xorl %ebx,%ebx cmpl %edi,%esi je switch_return @@ -1870,7 +1885,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 @@ -1903,15 +1918,17 @@ 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 +#else /* Load TSS info. */ movl _C_LABEL(gdt),%eax #endif movl L_MD_TSS_SEL(%edi),%edx - /* Switch TSS. Reset "task busy" flag before loading. */ andl $~0x0200,4(%eax,%edx, 1) ltr %dx @@ -1925,16 +1942,16 @@ switch_restored: /* Restore cr0 (including FPU state). */ 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 cmpl CPUVAR(SELF),%ebx jz 1f orl $CR0_TS,%ecx -1: -#endif +1: +#endif movl %ecx,%cr0 /* Record new pcb. */ @@ -1948,34 +1965,42 @@ 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: - xor %eax,%eax + movl $1,%ebx switch_return: -#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG) +#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 + 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. @@ -2020,20 +2045,17 @@ 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 - * if multiprocessor) and deallocate the address space and kernel stack for p. + * 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(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 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 @@ -2052,22 +2074,16 @@ 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 +#else /* Load TSS info. */ 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 @@ -2084,11 +2100,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. */ @@ -2103,7 +2118,7 @@ ENTRY(switch_exit) /* LINTSTUB: Func: void savectx(struct pcb *pcb) */ ENTRY(savectx) movl 4(%esp),%edx # edx = p->p_addr - + /* Save stack pointers. */ movl %esp,PCB_ESP(%edx) movl %ebp,PCB_EBP(%edx) @@ -2132,6 +2147,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 @@ -2141,13 +2162,16 @@ syscall1: #ifdef DDB int $3 #endif -1: +1: #endif /* DIAGNOSTIC */ 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 +.Lsyscall_checkast: + /* Check for ASTs on exit to user mode. */ cli CHECK_ASTPENDING(%eax) je 1f @@ -2155,12 +2179,16 @@ syscall1: CLEAR_ASTPENDING(%eax) sti /* Pushed T_ASTFLT into tf_trapno on entry. */ + pushl %esp call _C_LABEL(trap) - jmp 2b + addl $4,%esp + 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 @@ -2173,8 +2201,12 @@ syscall1: movl $IPL_NONE,CPUVAR(ILEVEL) jmp 2b 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" +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 /*