update with newer changed from NetBSD
authorChris G. Demetriou <cgd@ucbvax.Berkeley.EDU>
Fri, 11 Jun 1993 12:55:57 +0000 (04:55 -0800)
committerChris G. Demetriou <cgd@ucbvax.Berkeley.EDU>
Fri, 11 Jun 1993 12:55:57 +0000 (04:55 -0800)
SCCS-vsn: sys/i386/i386/locore.s 7.11
SCCS-vsn: sys/i386/i386/machdep.c 7.18

usr/src/sys/i386/i386/locore.s
usr/src/sys/i386/i386/machdep.c

index 1f22fa5..8181d01 100644 (file)
@@ -7,18 +7,34 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)locore.s    7.10 (Berkeley) %G%
+ *     from: @(#)locore.s      7.3 (Berkeley) 5/13/91
+ *     from NetBSD: Id: locore.s,v 1.12 1993/05/27 16:44:13 cgd Exp
+ *
+ *      @(#)locore.s   7.11 (Berkeley) %G%
+ */
+
+
+/*
+ * locore.s:   4BSD machine support for the Intel 386
+ *             Preliminary version
+ *             Written by William F. Jolitz, 386BSD Project
  */
 
 #include "assym.s"
  */
 
 #include "assym.s"
-#include <machine/psl.h>
-#include <machine/pte.h>
+#include "machine/psl.h"
+#include "machine/pte.h"
+
+#include "errno.h"
 
 
-#include <sys/errno.h>
+#include "machine/trap.h"
 
 
-#include <machine/trap.h>
+#include "machine/specialreg.h"
 
 
-#include "npx.h"
+#ifdef cgd_notdef
+#include "machine/cputypes.h"
+#endif
+
+#define        KDSEL           0x10
 
 /*
  * Note: This version greatly munged to avoid various assembler errors
 
 /*
  * Note: This version greatly munged to avoid various assembler errors
        /*note: gas copys sign bit (e.g. arithmetic >>), can't do SYSTEM>>22! */
        .set    SYSPDROFF,0x3F8         # Page dir index of System Base
 
        /*note: gas copys sign bit (e.g. arithmetic >>), can't do SYSTEM>>22! */
        .set    SYSPDROFF,0x3F8         # Page dir index of System Base
 
-/* IBM "compatible" nop - sensitive macro on "fast" 386 machines */
-#define        NOP     ;
+#define        NOP     inb $0x84, %al ; inb $0x84, %al 
+#define        ALIGN32 .align 2        /* 2^2  = 4 */
 
 /*
  * PTmap is recursive pagemap at top of virtual address space.
  * Within PTmap, the page directory can be found (third indirection).
  */
        .set    PDRPDROFF,0x3F7         # Page dir index of Page dir
 
 /*
  * PTmap is recursive pagemap at top of virtual address space.
  * Within PTmap, the page directory can be found (third indirection).
  */
        .set    PDRPDROFF,0x3F7         # Page dir index of Page dir
-       .globl  _PTmap, _PTD, _PTDpde
+       .globl  _PTmap, _PTD, _PTDpde, _Sysmap
        .set    _PTmap,0xFDC00000
        .set    _PTD,0xFDFF7000
        .set    _PTmap,0xFDC00000
        .set    _PTD,0xFDFF7000
+       .set    _Sysmap,0xFDFF8000
        .set    _PTDpde,0xFDFF7000+4*PDRPDROFF
 
 /*
        .set    _PTDpde,0xFDFF7000+4*PDRPDROFF
 
 /*
@@ -83,36 +100,15 @@ _atdevphys:        .long   0       # location of device mapping ptes (phys)
 _IdlePTD:      .long   0
 _KPTphys:      .long   0
 
 _IdlePTD:      .long   0
 _KPTphys:      .long   0
 
-pcb:
-       .space 8192
+       .space 512
 tmpstk:
 tmpstk:
-pcb2:
-       .space 8192
-tmpstk2:
        .text
        .globl  start
        .text
        .globl  start
- #start:
-       .set start,0
-       movw    $0x1234,%ax
+start: movw    $0x1234,%ax
        movw    %ax,0x472       # warm boot
        jmp     1f
        .space  0x500           # skip over warm boot shit
 
        movw    %ax,0x472       # warm boot
        jmp     1f
        .space  0x500           # skip over warm boot shit
 
-       /* enable a20! yecchh!! - move this to bootstrap? */
-1:     inb     $0x64,%al
-       andb    $2,%al
-       jnz     1b
-       movb    $0xd1,%al
-       NOP
-       outb    %al,$0x64
-       NOP
-1:     inb     $0x64,%al
-       andb    $2,%al
-       jnz     1b
-       movb    $0xdf,%al
-       NOP
-       outb    %al,$0x60
-
        /*
         * pass parameters on stack (howto, bootdev, unit, cyloffset)
         * note: 0(%esp) is return address of boot
        /*
         * pass parameters on stack (howto, bootdev, unit, cyloffset)
         * note: 0(%esp) is return address of boot
@@ -126,35 +122,60 @@ tmpstk2:
        movl    12(%esp),%eax
        movl    %eax, _cyloffset-SYSTEM
 
        movl    12(%esp),%eax
        movl    %eax, _cyloffset-SYSTEM
 
+#ifdef cgd_notdef
+       /* find out our CPU type. */
+        pushfl
+        popl    %eax
+        movl    %eax, %ecx
+        xorl    $0x40000, %eax
+        pushl   %eax
+        popfl
+        pushfl
+        popl    %eax
+        xorl    %ecx, %eax
+        shrl    $18, %eax
+        andl    $1, %eax
+        push    %ecx
+        popfl
+      
+        cmpl    $0, %eax
+        jne     1f
+        movl    $CPU_386, _cpu-SYSTEM
+       jmp     2f
+1:      movl    $CPU_486, _cpu-SYSTEM
+2:
+#endif
+
+#ifdef garbage
        /* count up memory */
 
        /* count up memory */
 
-       xorl    %edx,%edx               # start with base memory at 0x0
+       xorl    %eax,%eax               # start with base memory at 0x0
        #movl   $ 0xA0000/NBPG,%ecx     # look every 4K up to 640K
        movl    $ 0xA0,%ecx             # look every 4K up to 640K
        #movl   $ 0xA0000/NBPG,%ecx     # look every 4K up to 640K
        movl    $ 0xA0,%ecx             # look every 4K up to 640K
-1:     movl    0(%edx),%ebx            # save location to check
-       movl    $0xa55a5aa5,0(%edx)     # write test pattern
-
-       inb     $0x84,%al               # flush write buffer
+1:     movl    0(%eax),%ebx            # save location to check
+       movl    $0xa55a5aa5,0(%eax)     # write test pattern
        /* flush stupid cache here! (with bcopy (0,0,512*1024) ) */
        /* flush stupid cache here! (with bcopy (0,0,512*1024) ) */
-
-       cmpl    $0xa55a5aa5,0(%edx)     # does not check yet for rollover
+       cmpl    $0xa55a5aa5,0(%eax)     # does not check yet for rollover
        jne     2f
        jne     2f
-       movl    %ebx,0(%edx)            # restore memory
-       addl    $ NBPG,%edx
+       movl    %ebx,0(%eax)            # restore memory
+       addl    $ NBPG,%eax
        loop    1b
        loop    1b
+2:     shrl    $12,%eax
+       movl    %eax,_Maxmem-SYSTEM
 
 
-       movl    $0x100000,%edx          # next, talley remaining memory
+       movl    $0x100000,%eax          # next, talley remaining memory
        #movl   $((0xFFF000-0x100000)/NBPG),%ecx
        movl    $(0xFFF-0x100),%ecx
        #movl   $((0xFFF000-0x100000)/NBPG),%ecx
        movl    $(0xFFF-0x100),%ecx
-1:     movl    0(%edx),%ebx            # save location to check
-       movl    $0xa55a5aa5,0(%edx)     # write test pattern
-       cmpl    $0xa55a5aa5,0(%edx)     # does not check yet for rollover
+1:     movl    0(%eax),%ebx            # save location to check
+       movl    $0xa55a5aa5,0(%eax)     # write test pattern
+       cmpl    $0xa55a5aa5,0(%eax)     # does not check yet for rollover
        jne     2f
        jne     2f
-       movl    %ebx,0(%edx)            # restore memory
-       addl    $ NBPG,%edx
+       movl    %ebx,0(%eax)            # restore memory
+       addl    $ NBPG,%eax
        loop    1b
        loop    1b
-2:     shrl    $12,%edx
-       movl    %edx,_Maxmem-SYSTEM
+2:     shrl    $12,%eax
+       movl    %eax,_Maxmem-SYSTEM
+#endif
 
 /* find end of kernel image */
        movl    $_end-SYSTEM,%ecx
 
 /* find end of kernel image */
        movl    $_end-SYSTEM,%ecx
@@ -204,7 +225,7 @@ tmpstk2:
 /* map I/O memory map */
 
        movl    $0x100-0xa0,%ecx        # for this many pte s,
 /* map I/O memory map */
 
        movl    $0x100-0xa0,%ecx        # for this many pte s,
-       movl    $(0xa0000|PG_V),%eax    #  having these bits set, (perhaps URW?)
+       movl    $(0xa0000|PG_V|PG_UW),%eax # having these bits set,(perhaps URW?) XXX 06 Aug 92
        movl    %ebx,_atdevphys-SYSTEM  #   remember phys addr of ptes
        fillkpt
 
        movl    %ebx,_atdevphys-SYSTEM  #   remember phys addr of ptes
        fillkpt
 
@@ -225,7 +246,7 @@ tmpstk2:
  */
        /* install a pde for temporary double map of bottom of VA */
        lea     (4*NBPG)(%esi),%eax     # physical address of kernel page table
  */
        /* install a pde for temporary double map of bottom of VA */
        lea     (4*NBPG)(%esi),%eax     # physical address of kernel page table
-       orl     $ PG_V,%eax             # pde entry is valid
+       orl     $ PG_V|PG_UW,%eax       # pde entry is valid XXX 06 Aug 92
        movl    %eax,(%esi)             # which is where temp maps!
 
        /* kernel pde's */
        movl    %eax,(%esi)             # which is where temp maps!
 
        /* kernel pde's */
@@ -235,7 +256,7 @@ tmpstk2:
 
        /* install a pde recursively mapping page directory as a page table! */
        movl    %esi,%eax               # phys address of ptd in proc 0
 
        /* install a pde recursively mapping page directory as a page table! */
        movl    %esi,%eax               # phys address of ptd in proc 0
-       orl     $ PG_V,%eax             # pde entry is valid
+       orl     $ PG_V|PG_UW,%eax       # pde entry is valid XXX 06 Aug 92
        movl    %eax, PDRPDROFF*4(%esi) # which is where PTmap maps!
 
        /* install a pde to map kernel stack for proc 0 */
        movl    %eax, PDRPDROFF*4(%esi) # which is where PTmap maps!
 
        /* install a pde to map kernel stack for proc 0 */
@@ -278,10 +299,10 @@ begin: /* now running relocated at SYSTEM where the system is linked to run */
        pushl   %esi
        
        call    _init386                # wire 386 chip for unix operation
        pushl   %esi
        
        call    _init386                # wire 386 chip for unix operation
-       popl    %esi
        
        movl    $0,_PTD
        call    _main
        
        movl    $0,_PTD
        call    _main
+       popl    %esi
 
        .globl  __ucodesel,__udatasel
        movzwl  __ucodesel,%eax
 
        .globl  __ucodesel,__udatasel
        movzwl  __ucodesel,%eax
@@ -293,8 +314,8 @@ begin: /* now running relocated at SYSTEM where the system is linked to run */
        pushl   $0              # user ip
        movw    %cx,%ds
        movw    %cx,%es
        pushl   $0              # user ip
        movw    %cx,%ds
        movw    %cx,%es
-       # movw  %ax,%fs         # double map cs to fs
-       # movw  %cx,%gs         # and ds to gs
+       movw    %ax,%fs         # double map cs to fs
+       movw    %cx,%gs         # and ds to gs
        lret    # goto user!
 
        pushl   $lretmsg1       /* "should never get here!" */
        lret    # goto user!
 
        pushl   $lretmsg1       /* "should never get here!" */
@@ -302,10 +323,6 @@ begin: /* now running relocated at SYSTEM where the system is linked to run */
 lretmsg1:
        .asciz  "lret: toinit\n"
 
 lretmsg1:
        .asciz  "lret: toinit\n"
 
-       .globl  __exit
-__exit:
-       call _reset_cpu
-       /* NOTREACHED */
 
        .set    exec,59
        .set    exit,1
 
        .set    exec,59
        .set    exit,1
@@ -318,8 +335,6 @@ __exit:
  * If the exec fails, process 1 exits.
  */
 _icode:
  * If the exec fails, process 1 exits.
  */
 _icode:
-       pushl   $0 /* environment */
-
        # pushl $argv-_icode    # gas fucks up again
        movl    $argv,%eax
        subl    $_icode,%eax
        # pushl $argv-_icode    # gas fucks up again
        movl    $argv,%eax
        subl    $_icode,%eax
@@ -363,7 +378,11 @@ _sigcode:
 _szsigcode:
        .long   _szsigcode-_sigcode
 
 _szsigcode:
        .long   _szsigcode-_sigcode
 
+       /*
+        * Support routines for GCC
+        */
        .globl ___udivsi3
        .globl ___udivsi3
+       ALIGN32
 ___udivsi3:
        movl 4(%esp),%eax
        xorl %edx,%edx
 ___udivsi3:
        movl 4(%esp),%eax
        xorl %edx,%edx
@@ -371,24 +390,37 @@ ___udivsi3:
        ret
 
        .globl ___divsi3
        ret
 
        .globl ___divsi3
+       ALIGN32
 ___divsi3:
        movl 4(%esp),%eax
 ___divsi3:
        movl 4(%esp),%eax
-       xorl %edx,%edx
+       #xorl %edx,%edx         /* not needed - cltd sign extends into %edx */
        cltd
        idivl 8(%esp)
        ret
 
        cltd
        idivl 8(%esp)
        ret
 
+       /*
+        * I/O bus instructions via C
+        */
        .globl  _inb
        .globl  _inb
+       ALIGN32
 _inb:  movl    4(%esp),%edx
 _inb:  movl    4(%esp),%edx
-       # inb   $0x84,%al       # Compaq SystemPro 
        subl    %eax,%eax       # clr eax
        NOP
        inb     %dx,%al
        subl    %eax,%eax       # clr eax
        NOP
        inb     %dx,%al
+       ret
+
+
+       .globl  _inw
+       ALIGN32
+_inw:  movl    4(%esp),%edx
+       subl    %eax,%eax       # clr eax
        NOP
        NOP
+       inw     %dx,%ax
        ret
 
 
        .globl  _rtcin
        ret
 
 
        .globl  _rtcin
+       ALIGN32
 _rtcin:        movl    4(%esp),%eax
        outb    %al,$0x70
        subl    %eax,%eax       # clr eax
 _rtcin:        movl    4(%esp),%eax
        outb    %al,$0x70
        subl    %eax,%eax       # clr eax
@@ -396,22 +428,30 @@ _rtcin:   movl    4(%esp),%eax
        ret
 
        .globl  _outb
        ret
 
        .globl  _outb
+       ALIGN32
 _outb: movl    4(%esp),%edx
 _outb: movl    4(%esp),%edx
-       movl    8(%esp),%eax
        NOP
        NOP
+       movl    8(%esp),%eax
        outb    %al,%dx
        outb    %al,%dx
-       # inb   $0x84,%al
        NOP
        ret
 
        NOP
        ret
 
-       #
-       # bzero (base,cnt)
-       #
+       .globl  _outw
+       ALIGN32
+_outw: movl    4(%esp),%edx
+       NOP
+       movl    8(%esp),%eax
+       outw    %ax,%dx
+       NOP
+       ret
+
+       /*
+        * void bzero(void *base, u_int cnt)
+        */
 
        .globl _bzero
 
        .globl _bzero
-       .globl _blkclr
+       ALIGN32
 _bzero:
 _bzero:
-_blkclr:
        pushl   %edi
        movl    8(%esp),%edi
        movl    12(%esp),%ecx
        pushl   %edi
        movl    8(%esp),%edi
        movl    12(%esp),%ecx
@@ -427,92 +467,237 @@ _blkclr:
        popl    %edi
        ret
 
        popl    %edi
        ret
 
-       #
-       # fillw (pat,base,cnt)
-       #
+       /*
+        * fillw (pat,base,cnt)
+        */
 
        .globl _fillw
 
        .globl _fillw
+       ALIGN32
 _fillw:
        pushl   %edi
        movl    8(%esp),%eax
        movl    12(%esp),%edi
 _fillw:
        pushl   %edi
        movl    8(%esp),%eax
        movl    12(%esp),%edi
-       movl    16(%esp),%ecx
+       movw    %ax, %cx
+       rorl    $16, %eax
+       movw    %cx, %ax
        cld
        cld
+       movl    16(%esp),%ecx
+       shrl    %ecx
+       rep
+       stosl
+       movl    16(%esp),%ecx
+       andl    $1, %ecx
        rep
        stosw
        popl    %edi
        ret
 
        rep
        stosw
        popl    %edi
        ret
 
-       #
-       # bcopy (src,dst,cnt)
-       # NOTE: does not (yet) handle overlapped copies
-       #
-
-       .globl  _bcopy
-_bcopy:
+       .globl _bcopyb
+       ALIGN32
+_bcopyb:
        pushl   %esi
        pushl   %edi
        movl    12(%esp),%esi
        movl    16(%esp),%edi
        movl    20(%esp),%ecx
        pushl   %esi
        pushl   %edi
        movl    12(%esp),%esi
        movl    16(%esp),%edi
        movl    20(%esp),%ecx
-       shrl    $2,%ecx 
        cld
        rep
        cld
        rep
-       movsl
-       movl    20(%esp),%ecx
-       andl    $3,%ecx
-       rep
        movsb
        popl    %edi
        popl    %esi
        xorl    %eax,%eax
        ret
 
        movsb
        popl    %edi
        popl    %esi
        xorl    %eax,%eax
        ret
 
-       #
-       # ovbcopy (src,dst,cnt)
-       # NOTE: does not (yet) work doing words at a time
-       #
+       /*
+        * (ov)bcopy (src,dst,cnt)
+        *  ws@tools.de     (Wolfgang Solfrank, TooLs GmbH) +49-228-985800
+        */
 
 
-       .globl  _ovbcopy
+       .globl  _bcopy,_ovbcopy
+       ALIGN32
 _ovbcopy:
 _ovbcopy:
+_bcopy:
        pushl   %esi
        pushl   %edi
        movl    12(%esp),%esi
        movl    16(%esp),%edi
        movl    20(%esp),%ecx
        pushl   %esi
        pushl   %edi
        movl    12(%esp),%esi
        movl    16(%esp),%edi
        movl    20(%esp),%ecx
-       addl    %ecx,%esi       /* copy from end to beginning */
-       addl    %ecx,%edi
-       decl    %esi
+       cmpl    %esi,%edi       /* potentially overlapping? */
+       jnb     1f
+       cld                     /* nope, copy forwards. */
+       shrl    $2,%ecx         /* copy by words */
+       rep
+       movsl
+       movl    20(%esp),%ecx
+       andl    $3,%ecx         /* any bytes left? */
+       rep
+       movsb
+       popl    %edi
+       popl    %esi
+       xorl    %eax,%eax
+       ret
+       ALIGN32
+1:
+       addl    %ecx,%edi       /* copy backwards. */
+       addl    %ecx,%esi
+       std
+       andl    $3,%ecx         /* any fractional bytes? */
        decl    %edi
        decl    %edi
-       std                     /* decrementing as we go */
+       decl    %esi
        rep
        movsb
        rep
        movsb
+       movl    20(%esp),%ecx   /* copy remainder by words */
+       shrl    $2,%ecx
+       subl    $3,%esi
+       subl    $3,%edi
+       rep
+       movsl
        popl    %edi
        popl    %esi
        xorl    %eax,%eax
        cld
        ret
 
        popl    %edi
        popl    %esi
        xorl    %eax,%eax
        cld
        ret
 
+#ifdef notdef
+       .globl  _copyout
+       ALIGN32
+_copyout:
+       movl    _curpcb, %eax
+       movl    $cpyflt, PCB_ONFAULT(%eax) # in case we page/protection violate
+       pushl   %esi
+       pushl   %edi
+       pushl   %ebx
+       movl    16(%esp), %esi
+       movl    20(%esp), %edi
+       movl    24(%esp), %ebx
+
+                               /* first, check to see if "write fault" */
+1:     movl    %edi, %eax
+#ifdef notyet
+       shrl    $IDXSHIFT, %eax /* fetch pte associated with address */
+       andb    $0xfc, %al
+       movl    _PTmap(%eax), %eax
+
+       andb    $7, %al         /* if we are the one case that won't trap... */
+       cmpb    $5, %al
+       jne     2f
+                               /* ... then simulate the trap! */
+       pushl   %edi
+       call    _trapwrite      /* trapwrite(addr) */
+       popl    %edx
+
+       cmpl    $0, %eax        /* if not ok, return */
+       jne     cpyflt
+                               /* otherwise, continue with reference */
+2:
+       movl    %edi, %eax      /* calculate remainder this pass */
+       andl    $0xfffff000, %eax
+       movl    $NBPG, %ecx
+       subl    %eax, %ecx
+       cmpl    %ecx, %ebx
+       jle     3f
+       movl    %ebx, %ecx
+3:     subl    %ecx, %ebx
+       movl    %ecx, %edx
+#else
+       movl    %ebx, %ecx
+       movl    %ebx, %edx
+#endif
+
+       shrl    $2,%ecx                 /* movem */
+       cld
+       rep
+       movsl
+       movl    %edx, %ecx              /* don't depend on ecx here! */
+       andl    $3, %ecx
+       rep
+       movsb
+
+#ifdef notyet
+       cmpl    $0, %ebx
+       jl      1b
+#endif
+
+       popl    %ebx
+       popl    %edi
+       popl    %esi
+       xorl    %eax,%eax
+       movl    _curpcb,%edx
+       movl    %eax,PCB_ONFAULT(%edx)
+       ret
+
        .globl  _copyin
        .globl  _copyin
+       ALIGN32
 _copyin:
        movl    _curpcb,%eax
        movl    $cpyflt,PCB_ONFAULT(%eax) # in case we page/protection violate
        pushl   %esi
        pushl   %edi
 _copyin:
        movl    _curpcb,%eax
        movl    $cpyflt,PCB_ONFAULT(%eax) # in case we page/protection violate
        pushl   %esi
        pushl   %edi
+       pushl   %ebx
        movl    12(%esp),%esi
        movl    16(%esp),%edi
        movl    20(%esp),%ecx
        movl    12(%esp),%esi
        movl    16(%esp),%edi
        movl    20(%esp),%ecx
+       shrl    $2,%ecx
+       cld
+       rep
+       movsl
+       movl    20(%esp),%ecx
+       andl    $3,%ecx
+       rep
+       movsb
+       popl    %ebx
+       popl    %edi
+       popl    %esi
+       xorl    %eax,%eax
+       movl    _curpcb,%edx
+       movl    %eax,PCB_ONFAULT(%edx)
+       ret
 
 
-       /* if dest >= USRSTACK, return error */
-       cmpl    $ USRSTACK, %esi
-       jae     cpyflt
-
-       /* if USRSTACK-dest < len, return error */
-       movl    $ USRSTACK, %eax
-       subl    %esi, %eax
-       cmpl    %ecx, %eax
-       jb      cpyflt
+       ALIGN32
+cpyflt:
+       popl    %ebx
+       popl    %edi
+       popl    %esi
+       movl    _curpcb,%edx
+       movl    $0,PCB_ONFAULT(%edx)
+       movl    $ EFAULT,%eax
+       ret
+#else
+       .globl  _copyout
+       ALIGN32
+_copyout:
+       movl    _curpcb,%eax
+       movl    $cpyflt,PCB_ONFAULT(%eax) # in case we page/protection violate
+       pushl   %esi
+       pushl   %edi
+       movl    12(%esp),%esi
+       movl    16(%esp),%edi
+       movl    20(%esp),%ecx
+       shrl    $2,%ecx
+       cld
+       rep
+       movsl
+       movl    20(%esp),%ecx
+       andl    $3,%ecx
+       rep
+       movsb
+       popl    %edi
+       popl    %esi
+       xorl    %eax,%eax
+       movl    _curpcb,%edx
+       movl    %eax,PCB_ONFAULT(%edx)
+       ret
 
 
+       .globl  _copyin
+       ALIGN32
+_copyin:
+       movl    _curpcb,%eax
+       movl    $cpyflt,PCB_ONFAULT(%eax) # in case we page/protection violate
+       pushl   %esi
+       pushl   %edi
+       movl    12(%esp),%esi
+       movl    16(%esp),%edi
+       movl    20(%esp),%ecx
        shrl    $2,%ecx
        cld
        rep
        shrl    $2,%ecx
        cld
        rep
@@ -528,6 +713,7 @@ _copyin:
        movl    %eax,PCB_ONFAULT(%edx)
        ret
 
        movl    %eax,PCB_ONFAULT(%edx)
        ret
 
+       ALIGN32
 cpyflt: popl   %edi
        popl    %esi
        movl    _curpcb,%edx
 cpyflt: popl   %edi
        popl    %esi
        movl    _curpcb,%edx
@@ -535,8 +721,11 @@ cpyflt: popl       %edi
        movl    $ EFAULT,%eax
        ret
 
        movl    $ EFAULT,%eax
        ret
 
+#endif
+
        # insb(port,addr,cnt)
        .globl  _insb
        # insb(port,addr,cnt)
        .globl  _insb
+       ALIGN32
 _insb:
        pushl   %edi
        movw    8(%esp),%dx
 _insb:
        pushl   %edi
        movw    8(%esp),%dx
@@ -553,6 +742,7 @@ _insb:
 
        # insw(port,addr,cnt)
        .globl  _insw
 
        # insw(port,addr,cnt)
        .globl  _insw
+       ALIGN32
 _insw:
        pushl   %edi
        movw    8(%esp),%dx
 _insw:
        pushl   %edi
        movw    8(%esp),%dx
@@ -568,6 +758,7 @@ _insw:
 
        # outsw(port,addr,cnt)
        .globl  _outsw
 
        # outsw(port,addr,cnt)
        .globl  _outsw
+       ALIGN32
 _outsw:
        pushl   %esi
        movw    8(%esp),%dx
 _outsw:
        pushl   %esi
        movw    8(%esp),%dx
@@ -581,100 +772,107 @@ _outsw:
        popl    %esi
        ret
 
        popl    %esi
        ret
 
-       # lgdt(*gdt, ngdt)
+       # outsb(port,addr,cnt)
+       .globl  _outsb
+       ALIGN32
+_outsb:
+       pushl   %esi
+       movw    8(%esp),%dx
+       movl    12(%esp),%esi
+       movl    16(%esp),%ecx
+       cld
+       NOP
+       rep
+       outsb
+       NOP
+       movl    %esi,%eax
+       popl    %esi
+       ret
+
+       /*
+        * void lgdt(struct region_descriptor *rdp);
+        */
        .globl  _lgdt
        .globl  _lgdt
-       # .globl        _gdt
-xxx:   .word 31
-       .long 0
+       ALIGN32
 _lgdt:
 _lgdt:
+       /* reload the descriptor table */
        movl    4(%esp),%eax
        movl    4(%esp),%eax
-       movl    %eax,xxx+2
-       movl    8(%esp),%eax
-       movw    %ax,xxx
-       lgdt    xxx
+       lgdt    (%eax)
+       /* flush the prefetch q */
        jmp     1f
        jmp     1f
-       NOP
-1:     movw    $0x10,%ax
+       nop
+1:
+       /* reload "stale" selectors */
+       # movw  $KDSEL,%ax
+       movw    $0x10,%ax
        movw    %ax,%ds
        movw    %ax,%es
        movw    %ax,%ss
        movw    %ax,%ds
        movw    %ax,%es
        movw    %ax,%ss
+
+       /* reload code selector by turning return into intersegmental return */
        movl    0(%esp),%eax
        pushl   %eax
        movl    0(%esp),%eax
        pushl   %eax
+       # movl  $KCSEL,4(%esp)
        movl    $8,4(%esp)
        lret
 
        movl    $8,4(%esp)
        lret
 
-       # lidt(*idt, nidt)
+       /*
+        * void lidt(struct region_descriptor *rdp);
+        */
        .globl  _lidt
        .globl  _lidt
-yyy:   .word   255
-       .long   0 
+       ALIGN32
 _lidt:
        movl    4(%esp),%eax
 _lidt:
        movl    4(%esp),%eax
-       movl    %eax,yyy+2
-       movl    8(%esp),%eax
-       movw    %ax,yyy
-       lidt    yyy
+       lidt    (%eax)
        ret
 
        ret
 
-       # lldt(sel)
+       /*
+        * void lldt(u_short sel)
+        */
        .globl  _lldt
        .globl  _lldt
+       ALIGN32
 _lldt:
 _lldt:
-       movl    4(%esp),%eax
-       lldt    %eax
+       lldt    4(%esp)
        ret
 
        ret
 
-       # ltr(sel)
+       /*
+        * void ltr(u_short sel)
+        */
        .globl  _ltr
        .globl  _ltr
+       ALIGN32
 _ltr:
 _ltr:
-       movl    4(%esp),%eax
-       ltr     %eax
+       ltr     4(%esp)
        ret
 
        ret
 
-       # lcr3(cr3)
+       /*
+        * void lcr3(caddr_t cr3)
+        */
        .globl  _lcr3
        .globl  _load_cr3
        .globl  _lcr3
        .globl  _load_cr3
+       ALIGN32
 _load_cr3:
 _lcr3:
        inb     $0x84,%al       # check wristwatch
        movl    4(%esp),%eax
        orl     $ I386_CR3PAT,%eax
 _load_cr3:
 _lcr3:
        inb     $0x84,%al       # check wristwatch
        movl    4(%esp),%eax
        orl     $ I386_CR3PAT,%eax
-
-       movl    $tmpstk2,%edx
-       movl    (%edx),%ecx     # touch stack, fault if not there
-       movl    %ecx,(%edx)
-       movl    %esp,%ecx
-       movl    %edx,%esp
-
        movl    %eax,%cr3
        inb     $0x84,%al       # check wristwatch
        movl    %eax,%cr3
        inb     $0x84,%al       # check wristwatch
-
-       movl    (%ecx),%edx     # touch stack, fault if not there
-       movl    %edx,(%ecx)
-       movl    %ecx,%esp
        ret
 
        # tlbflush()
        .globl  _tlbflush
        ret
 
        # tlbflush()
        .globl  _tlbflush
+       ALIGN32
 _tlbflush:
        inb     $0x84,%al       # check wristwatch
        movl    %cr3,%eax
        orl     $ I386_CR3PAT,%eax
 _tlbflush:
        inb     $0x84,%al       # check wristwatch
        movl    %cr3,%eax
        orl     $ I386_CR3PAT,%eax
-
-       movl    $tmpstk2,%edx
-       movl    (%edx),%ecx     # touch stack, fault if not there
-       movl    %ecx,(%edx)
-       movl    %esp,%ecx
-       movl    %edx,%esp
-
        movl    %eax,%cr3
        inb     $0x84,%al       # check wristwatch
        movl    %eax,%cr3
        inb     $0x84,%al       # check wristwatch
-
-       movl    (%ecx),%edx     # touch stack, fault if not there
-       movl    %edx,(%ecx)
-       movl    %ecx,%esp
        ret
 
        # lcr0(cr0)
        .globl  _lcr0,_load_cr0
        ret
 
        # lcr0(cr0)
        .globl  _lcr0,_load_cr0
+       ALIGN32
 _lcr0:
 _load_cr0:
        movl    4(%esp),%eax
 _lcr0:
 _load_cr0:
        movl    4(%esp),%eax
@@ -683,12 +881,14 @@ _load_cr0:
 
        # rcr0()
        .globl  _rcr0
 
        # rcr0()
        .globl  _rcr0
+       ALIGN32
 _rcr0:
        movl    %cr0,%eax
        ret
 
        # rcr2()
        .globl  _rcr2
 _rcr0:
        movl    %cr0,%eax
        ret
 
        # rcr2()
        .globl  _rcr2
+       ALIGN32
 _rcr2:
        movl    %cr2,%eax
        ret
 _rcr2:
        movl    %cr2,%eax
        ret
@@ -696,6 +896,7 @@ _rcr2:
        # rcr3()
        .globl  _rcr3
        .globl  __cr3
        # rcr3()
        .globl  _rcr3
        .globl  __cr3
+       ALIGN32
 __cr3:
 _rcr3:
        movl    %cr3,%eax
 __cr3:
 _rcr3:
        movl    %cr3,%eax
@@ -703,6 +904,7 @@ _rcr3:
 
        # ssdtosd(*ssdp,*sdp)
        .globl  _ssdtosd
 
        # ssdtosd(*ssdp,*sdp)
        .globl  _ssdtosd
+       ALIGN32
 _ssdtosd:
        pushl   %ebx
        movl    8(%esp),%ecx
 _ssdtosd:
        pushl   %ebx
        movl    8(%esp),%ecx
@@ -726,34 +928,39 @@ _ssdtosd:
 /*
  * {fu,su},{byte,word}
  */
 /*
  * {fu,su},{byte,word}
  */
+       ALIGN32
 ALTENTRY(fuiword)
 ENTRY(fuword)
        movl    _curpcb,%ecx
        movl    $fusufault,PCB_ONFAULT(%ecx)
        movl    4(%esp),%edx
 ALTENTRY(fuiword)
 ENTRY(fuword)
        movl    _curpcb,%ecx
        movl    $fusufault,PCB_ONFAULT(%ecx)
        movl    4(%esp),%edx
-
-       cmpl    $ USRSTACK - 3, %edx
-       jae     fusufault
-
-       # .byte 0x65            # use gs
+       .byte   0x65            # use gs
        movl    0(%edx),%eax
        movl    $0,PCB_ONFAULT(%ecx)
        ret
        
        movl    0(%edx),%eax
        movl    $0,PCB_ONFAULT(%ecx)
        ret
        
+       ALIGN32
+ENTRY(fusword)
+       movl    _curpcb,%ecx
+       movl    $fusufault,PCB_ONFAULT(%ecx) #in case we page/protection violate
+       movl    4(%esp),%edx
+       .byte   0x65            # use gs
+       movzwl  0(%edx),%eax
+       movl    $0,PCB_ONFAULT(%ecx)
+       ret
+       
+       ALIGN32
 ALTENTRY(fuibyte)
 ENTRY(fubyte)
        movl    _curpcb,%ecx
        movl    $fusufault,PCB_ONFAULT(%ecx) #in case we page/protection violate
        movl    4(%esp),%edx
 ALTENTRY(fuibyte)
 ENTRY(fubyte)
        movl    _curpcb,%ecx
        movl    $fusufault,PCB_ONFAULT(%ecx) #in case we page/protection violate
        movl    4(%esp),%edx
-
-       cmpl    $ USRSTACK, %edx
-       jae     fusufault
-
-       # .byte 0x65            # use gs
+       .byte   0x65            # use gs
        movzbl  0(%edx),%eax
        movl    $0,PCB_ONFAULT(%ecx)
        ret
        
        movzbl  0(%edx),%eax
        movl    $0,PCB_ONFAULT(%ecx)
        ret
        
+       ALIGN32
 fusufault:
        movl    _curpcb,%ecx
        xorl    %eax,%eax
 fusufault:
        movl    _curpcb,%ecx
        xorl    %eax,%eax
@@ -761,158 +968,98 @@ fusufault:
        decl    %eax
        ret
 
        decl    %eax
        ret
 
-
-/*
- * There is a little bit of duplicated code so we can avoid flushing the
- * prefetch queue in the common case.
- */
-
+       ALIGN32
 ALTENTRY(suiword)
 ENTRY(suword)
 ALTENTRY(suiword)
 ENTRY(suword)
-       movl 4(%esp), %eax /* address */
-
-       cmpl $ USRSTACK, %eax
-       jae return_minus_one
-
-       /* check if the destination crosses a page boundary */
-       movl %eax, %ecx
-       andl $ NBPG - 1, %ecx
-       cmpl $ NBPG - 4, %ecx
-       ja suword_breakup
-
-       /* make sure the page table is present */
-       movl %eax, %ecx
-       shrl $ PDRSHIFT, %ecx
-       movl _PTD(,%ecx,4), %ecx
-       andl $ PG_V, %ecx
-       jnz suword_fault
-
-       /* now make sure the page is present with user write permission */
-       movl %eax, %ecx
-       shrl $ PGSHIFT, %ecx
-       movl _PTmap(,%ecx,4), %ecx
-       andl $ PG_V | PG_UW, %ecx
-       cmpl $ PG_V | PG_UW, %ecx
-       jnz suword_fault
-
-       movl 8(%esp), %ecx
-       movl %ecx, (%eax)
-       xorl %eax, %eax
-       ret
-
-suword_fault:
-       /* 
-        * this is a slow case anyway, so build a frame to make the debugger
-        * more useful
-        */
-       pushl %ebp
-       movl %esp, %ebp
-
-       pushl %eax
-       call _user_write_fault
-
-       leave
-
-       cmpl $0, %eax
-       jnz return_minus_one
-
-       movl 4(%esp), %eax
-       movl 8(%esp), %ecx
-       movl %ecx, (%eax)
-       xorl %eax, %eax
-       ret
+       movl    _curpcb,%ecx
+       movl    $fusufault,PCB_ONFAULT(%ecx) #in case we page/protection violate
+       movl    4(%esp),%edx
+       movl    8(%esp),%eax
 
 
+#ifdef notdef
+       shrl    $IDXSHIFT, %edx /* fetch pte associated with address */
+       andb    $0xfc, %dl
+       movl    _PTmap(%edx), %edx
 
 
-suword_breakup:
-       /* crosses page boundary ... do each byte separately */
-       pushl %ebp
-       movl %esp, %ebp
-       pushl %esi
-       pushl %edi
-       pushl %ebx
-
-       movl %eax, %edi
-       movl 12(%ebp), %ebx
-       movl $4, %esi
-
-suword_breakup_loop:
-       pushl %ebx
-       pushl %edi
-       call _subyte
-       addl $8, %esp
-
-       cmpl $-1, %eax
-       jz suword_breakup_error
-
-       incl %edi
-       shrl $8, %ebx
-       decl %esi
-       jnz suword_breakup_loop
-
-       xorl %eax, %eax
-       popl %ebx
-       popl %edi
-       popl %esi
-       leave
+       andb    $7, %dl         /* if we are the one case that won't trap... */
+       cmpb    $5 , %edx
+       jne     1f
+                               /* ... then simulate the trap! */
+       pushl   %edi
+       call    _trapwrite      /* trapwrite(addr) */
+       popl    %edx
+       cmpl    $0, %eax        /* if not ok, return */
+       jne     fusufault
+       movl    8(%esp),%eax    /* otherwise, continue with reference */
+1:
+       movl    4(%esp),%edx
+#endif
+       .byte   0x65            # use gs
+       movl    %eax,0(%edx)
+       xorl    %eax,%eax
+       movl    %eax,PCB_ONFAULT(%ecx) #in case we page/protection violate
        ret
        ret
-
-suword_breakup_error:
-       movl $-1, %eax
-       popl %ebx
-       popl %edi
-       popl %esi
-       leave
+       
+       ALIGN32
+ENTRY(susword)
+       movl    _curpcb,%ecx
+       movl    $fusufault,PCB_ONFAULT(%ecx) #in case we page/protection violate
+       movl    4(%esp),%edx
+       movl    8(%esp),%eax
+#ifdef notdef
+shrl   $IDXSHIFT, %edx /* calculate pte address */
+andb   $0xfc, %dl
+movl   _PTmap(%edx), %edx
+andb   $7, %edx        /* if we are the one case that won't trap... */
+cmpb   $5 , %edx
+jne    1f
+/* ..., then simulate the trap! */
+       pushl   %edi
+       call    _trapwrite      /* trapwrite(addr) */
+       popl    %edx
+movl   _curpcb, %ecx   # restore trashed registers
+cmpl   $0, %eax        /* if not ok, return */
+jne    fusufault
+movl   8(%esp),%eax
+1: movl        4(%esp),%edx
+#endif
+       .byte   0x65            # use gs
+       movw    %ax,0(%edx)
+       xorl    %eax,%eax
+       movl    %eax,PCB_ONFAULT(%ecx) #in case we page/protection violate
        ret
 
        ret
 
+       ALIGN32
 ALTENTRY(suibyte)
 ENTRY(subyte)
 ALTENTRY(suibyte)
 ENTRY(subyte)
-       movl 4(%esp), %eax /* address */
-
-       cmpl $ USRSTACK, %eax
-       jae return_minus_one
-
-       /* make sure the page table is present */
-       movl %eax, %ecx
-       shrl $ PDRSHIFT, %ecx
-       movl _PTD(,%ecx,4), %ecx
-       andl $ PG_V, %ecx
-       jnz subyte_fault
-
-       /* now make sure the page is present with user write permission */
-       movl %eax, %ecx
-       shrl $ PGSHIFT, %ecx
-       movl _PTmap(,%ecx,4), %ecx
-       andl $ PG_V | PG_UW, %ecx
-       cmpl $ PG_V | PG_UW, %ecx
-       jnz subyte_fault
-
-       movl 8(%esp), %ecx
-       movb %cl, (%eax)
-       xorl %eax, %eax
-       ret
-
-subyte_fault:
-       pushl %ebp
-       movl %esp, %ebp
-
-       pushl %eax
-       call _user_write_fault
-
-       leave
-
-       cmpl $0, %eax
-       jnz return_minus_one
-
-       movl 4(%esp), %eax
-       movl 8(%esp), %ecx
-       movb %cl, (%eax)
-       xorl %eax, %eax
-       ret
-
-return_minus_one:
-       movl $-1, %eax
+       movl    _curpcb,%ecx
+       movl    $fusufault,PCB_ONFAULT(%ecx) #in case we page/protection violate
+       movl    4(%esp),%edx
+       movl    8(%esp),%eax
+#ifdef notdef
+shrl   $IDXSHIFT, %edx /* calculate pte address */
+andb   $0xfc, %dl
+movl   _PTmap(%edx), %edx
+andb   $7, %edx        /* if we are the one case that won't trap... */
+cmpb   $5 , %edx
+jne    1f
+/* ..., then simulate the trap! */
+       pushl   %edi
+       call    _trapwrite      /* trapwrite(addr) */
+       popl    %edx
+movl   _curpcb, %ecx   # restore trashed registers
+cmpl   $0, %eax        /* if not ok, return */
+jne    fusufault
+movl   8(%esp),%eax
+1: movl        4(%esp),%edx
+#endif
+       .byte   0x65            # use gs
+       movb    %eax,0(%edx)
+       xorl    %eax,%eax
+       movl    %eax,PCB_ONFAULT(%ecx) #in case we page/protection violate
        ret
 
        ret
 
+       ALIGN32
        ENTRY(setjmp)
        movl    4(%esp),%eax
        movl    %ebx, 0(%eax)           # save ebx
        ENTRY(setjmp)
        movl    4(%esp),%eax
        movl    %ebx, 0(%eax)           # save ebx
@@ -925,7 +1072,7 @@ return_minus_one:
        xorl    %eax,%eax               # return (0);
        ret
 
        xorl    %eax,%eax               # return (0);
        ret
 
-#ifdef notdef
+       ALIGN32
        ENTRY(longjmp)
        movl    4(%esp),%eax
        movl     0(%eax),%ebx           # restore ebx
        ENTRY(longjmp)
        movl    4(%esp),%eax
        movl     0(%eax),%ebx           # restore ebx
@@ -938,7 +1085,6 @@ return_minus_one:
        xorl    %eax,%eax               # return (1);
        incl    %eax
        ret
        xorl    %eax,%eax               # return (1);
        incl    %eax
        ret
-#endif
 /*
  * The following primitives manipulate the run queues.
  * _whichqs tells which of the 32 queues _qs
 /*
  * The following primitives manipulate the run queues.
  * _whichqs tells which of the 32 queues _qs
@@ -958,6 +1104,7 @@ return_minus_one:
  *
  * Call should be made at spl6(), and p->p_stat should be SRUN
  */
  *
  * Call should be made at spl6(), and p->p_stat should be SRUN
  */
+       ALIGN32
 ENTRY(setrq)
        movl    4(%esp),%eax
        cmpl    $0,P_RLINK(%eax)        # should not be on q already
 ENTRY(setrq)
        movl    4(%esp),%eax
        cmpl    $0,P_RLINK(%eax)        # should not be on q already
@@ -984,6 +1131,7 @@ set2:      .asciz  "setrq"
  *
  * Call should be made at spl6().
  */
  *
  * Call should be made at spl6().
  */
+       ALIGN32
 ENTRY(remrq)
        movl    4(%esp),%eax
        movzbl  P_PRI(%eax),%edx
 ENTRY(remrq)
        movl    4(%esp),%eax
        movzbl  P_PRI(%eax),%edx
@@ -1020,6 +1168,7 @@ sw0:      .asciz  "swtch"
  * to wait for something to come ready.
  */
        .globl  Idle
  * to wait for something to come ready.
  */
        .globl  Idle
+       ALIGN32
 Idle:
 idle:
        call    _spl0
 Idle:
 idle:
        call    _spl0
@@ -1028,6 +1177,7 @@ idle:
        hlt             # wait for interrupt
        jmp     idle
 
        hlt             # wait for interrupt
        jmp     idle
 
+       .align 4 /* ..so that profiling doesn't lump Idle with swtch().. */
 badsw:
        pushl   $sw0
        call    _panic
 badsw:
        pushl   $sw0
        call    _panic
@@ -1036,6 +1186,7 @@ badsw:
 /*
  * Swtch()
  */
 /*
  * Swtch()
  */
+       ALIGN32
 ENTRY(swtch)
 
        incl    _cnt+V_SWTCH
 ENTRY(swtch)
 
        incl    _cnt+V_SWTCH
@@ -1043,6 +1194,11 @@ ENTRY(swtch)
        /* switch to new process. first, save context as needed */
 
        movl    _curproc,%ecx
        /* switch to new process. first, save context as needed */
 
        movl    _curproc,%ecx
+
+       /* if no process to save, don't bother */
+       cmpl    $0,%ecx
+       je      sw1
+
        movl    P_ADDR(%ecx),%ecx
 
 
        movl    P_ADDR(%ecx),%ecx
 
 
@@ -1054,41 +1210,32 @@ ENTRY(swtch)
        movl    %esi, PCB_ESI(%ecx)
        movl    %edi, PCB_EDI(%ecx)
 
        movl    %esi, PCB_ESI(%ecx)
        movl    %edi, PCB_EDI(%ecx)
 
-#if 0 && NNPX > 0
-       movb    PCB_FLAGS(%ecx),%al
+#ifdef NPX
        /* have we used fp, and need a save? */
        /* have we used fp, and need a save? */
-       andb    $ FP_WASUSED|FP_NEEDSSAVE,%al
-       cmpb    $ FP_WASUSED|FP_NEEDSSAVE,%al
+       mov     _curproc,%eax
+       cmp     %eax,_npxproc
        jne     1f
        jne     1f
-       movl    %cr0,%eax               /* insure fp is enabled */
-       andb    $0xfb,%al
-       movl    %eax,%cr0
-       fnsave  PCB_SAVEFPU(%ecx)
-       orb     $4,%al                  /* disable it */
-       movl    %eax,%cr0
-       movb    PCB_FLAGS(%ecx),%al
-       xorb    $ FP_NEEDSSAVE,%al      /* save processed */
-       movb    %al,PCB_FLAGS(%ecx)
+       pushl   %ecx                    /* h/w bugs make saving complicated */
+       leal    PCB_SAVEFPU(%ecx),%eax
+       pushl   %eax
+       call    _npxsave                /* do it in a big C function */
+       popl    %eax
+       popl    %ecx
 1:
 #endif
 
        movl    _CMAP2,%eax             # save temporary map PTE
        movl    %eax,PCB_CMAP2(%ecx)    # in our context
 1:
 #endif
 
        movl    _CMAP2,%eax             # save temporary map PTE
        movl    %eax,PCB_CMAP2(%ecx)    # in our context
+       movl    $0,_curproc             #  out of process
 
 
-       movw    _cpl, %ax
-       movw    %ax, PCB_IML(%ecx)      # save ipl
-
-       movl    $tmpstk2,%edx
-       movl    (%edx),%eax     # touch stack, fault if not there
-       movl    %eax,(%edx)
-       movl    %edx,%esp
-       movl    $pcb2,_curpcb
+       # movw  _cpl, %ax
+       # movw  %ax, PCB_IML(%ecx)      # save ipl
 
        /* save is done, now choose a new process or idle */
 sw1:
 
        /* save is done, now choose a new process or idle */
 sw1:
-       cli                             # XXX?
        movl    _whichqs,%edi
 2:
        movl    _whichqs,%edi
 2:
+       cli
        bsfl    %edi,%eax               # find a full q
        jz      idle                    # if none, idle
        # XX update whichqs?
        bsfl    %edi,%eax               # find a full q
        jz      idle                    # if none, idle
        # XX update whichqs?
@@ -1119,7 +1266,6 @@ swfnd:
        movl    %edi,_whichqs           # update q status
 
        movl    $0,%eax
        movl    %edi,_whichqs           # update q status
 
        movl    $0,%eax
-       movl    %ecx,_curproc
        movl    %eax,_want_resched
 
 #ifdef DIAGNOSTIC
        movl    %eax,_want_resched
 
 #ifdef DIAGNOSTIC
@@ -1131,22 +1277,10 @@ swfnd:
 
        movl    %eax,P_RLINK(%ecx) /* isolate process to run */
        movl    P_ADDR(%ecx),%edx
 
        movl    %eax,P_RLINK(%ecx) /* isolate process to run */
        movl    P_ADDR(%ecx),%edx
-       movl    %edx,_curpcb
-       inb     $0x84,%al       # flush write buffers
        movl    PCB_CR3(%edx),%ebx
 
        /* switch address space */
        movl    PCB_CR3(%edx),%ebx
 
        /* switch address space */
-       cli
-       orl     $ I386_CR3PAT,%ebx
-       movl    %ebx,%cr3       # context switch address space
-
-       jmp     7f
-       nop
- 7:    inb     $0x84,%al       # flush write buffers
-       movl    PCB_ESP(%edx), %ecx
-       movl    (%ecx),%eax     # touch stack, fault if not there
-       movl    %eax,(%ecx)
-       movl    %ecx,%esp
+       movl    %ebx,%cr3
 
        /* restore context */
        movl    PCB_EBX(%edx), %ebx
 
        /* restore context */
        movl    PCB_EBX(%edx), %ebx
@@ -1157,30 +1291,23 @@ swfnd:
        movl    PCB_EIP(%edx), %eax
        movl    %eax, (%esp)
 
        movl    PCB_EIP(%edx), %eax
        movl    %eax, (%esp)
 
-#if NNPX > 0
-#ifdef notdef
-       movb    PCB_FLAGS(%edx),%al
-       /* if fp could be used, a dna trap will do a restore */
-       testb   $ FP_WASUSED,%al
-       je      1f
-       orb     $ FP_NEEDSRESTORE,PCB_FLAGS(%ecx)
-1:
-#endif
-       movl    %cr0,%eax
-       orb     $4,%al                  /* disable it */
-       movl    %eax,%cr0
-#endif
-
        movl    PCB_CMAP2(%edx),%eax    # get temporary map
        movl    %eax,_CMAP2             # reload temporary map PTE
 
        movl    PCB_CMAP2(%edx),%eax    # get temporary map
        movl    %eax,_CMAP2             # reload temporary map PTE
 
-       pushl   PCB_IML(%edx)
+       movl    %ecx,_curproc           # into next process
+       movl    %edx,_curpcb
+
+       /* pushl        PCB_IML(%edx)
        call    _splx
        call    _splx
-       popl    %eax
+       popl    %eax*/
 
        movl    %edx,%eax               # return (1);
        ret
 
 
        movl    %edx,%eax               # return (1);
        ret
 
+       .globl  _mvesp
+       ALIGN32
+_mvesp:        movl    %esp,%eax
+       ret
 /*
  * struct proc *swtch_to_inactive(p) ; struct proc *p;
  *
 /*
  * struct proc *swtch_to_inactive(p) ; struct proc *p;
  *
@@ -1190,25 +1317,14 @@ swfnd:
  * Since this code requires a parameter from the "old" stack,
  * pass it back as a return value.
  */
  * Since this code requires a parameter from the "old" stack,
  * pass it back as a return value.
  */
+       ALIGN32
 ENTRY(swtch_to_inactive)
 ENTRY(swtch_to_inactive)
-
-       movl    $tmpstk2-4,%ecx         # temporary stack, compensated for call
-       movl    (%ecx),%eax             # touch stack, fault if not there
-       movl    %eax,(%ecx)
-
        popl    %edx                    # old pc
        popl    %eax                    # arg, our return value
        popl    %edx                    # old pc
        popl    %eax                    # arg, our return value
-       inb     $0x84,%al       # flush write buffers
-
-       movl    %ecx,%esp
-
        movl    _IdlePTD,%ecx
        movl    _IdlePTD,%ecx
-
        movl    %ecx,%cr3               # good bye address space
        movl    %ecx,%cr3               # good bye address space
-       inb     $0x84,%al       # flush write buffers
-
  #write buffer?
  #write buffer?
-       movl    $pcb2,_curpcb
+       movl    $tmpstk-4,%esp          # temporary stack, compensated for call
        jmp     %edx                    # return, execute remainder of cleanup
 
 /*
        jmp     %edx                    # return, execute remainder of cleanup
 
 /*
@@ -1216,6 +1332,7 @@ ENTRY(swtch_to_inactive)
  * Update pcb, saving current processor state and arranging
  * for alternate return ala longjmp in swtch if altreturn is true.
  */
  * Update pcb, saving current processor state and arranging
  * for alternate return ala longjmp in swtch if altreturn is true.
  */
+       ALIGN32
 ENTRY(savectx)
        movl    4(%esp), %ecx
        movw    _cpl, %ax
 ENTRY(savectx)
        movl    4(%esp), %ecx
        movw    _cpl, %ax
@@ -1227,18 +1344,45 @@ ENTRY(savectx)
        movl    %ebp, PCB_EBP(%ecx)
        movl    %esi, PCB_ESI(%ecx)
        movl    %edi, PCB_EDI(%ecx)
        movl    %ebp, PCB_EBP(%ecx)
        movl    %esi, PCB_ESI(%ecx)
        movl    %edi, PCB_EDI(%ecx)
-#if 0 && NNPX > 0
-       /* have we ever used fp, and need to save? */
-       testb   $ FP_WASUSED, PCB_FLAGS(%ecx)
-       je      1f
-       movl    %cr0, %edx
-       andb    $0xfb, %dl
-       movl    %edx, %cr0
-       fnsave  PCB_SAVEFPU(%ecx)
-       orb     $4, %edx
-       movl    %edx, %cr0
+
+#ifdef NPX
+       /*
+        * If npxproc == NULL, then the npx h/w state is irrelevant and the
+        * state had better already be in the pcb.  This is true for forks
+        * but not for dumps (the old book-keeping with FP flags in the pcb
+        * always lost for dumps because the dump pcb has 0 flags).
+        *
+        * If npxproc != NULL, then we have to save the npx h/w state to
+        * npxproc's pcb and copy it to the requested pcb, or save to the
+        * requested pcb and reload.  Copying is easier because we would
+        * have to handle h/w bugs for reloading.  We used to lose the
+        * parent's npx state for forks by forgetting to reload.
+        */
+       mov     _npxproc,%eax
+       testl   %eax,%eax
+       je      1f
+
+       pushl   %ecx
+       movl    P_ADDR(%eax),%eax
+       leal    PCB_SAVEFPU(%eax),%eax
+       pushl   %eax
+       pushl   %eax
+       call    _npxsave
+       popl    %eax
+       popl    %eax
+       popl    %ecx
+
+       pushl   %ecx
+       pushl   $108+8*2        /* XXX h/w state size + padding */
+       leal    PCB_SAVEFPU(%ecx),%ecx
+       pushl   %ecx
+       pushl   %eax
+       call    _bcopy
+       addl    $12,%esp
+       popl    %ecx
 1:
 #endif
 1:
 #endif
+
        movl    _CMAP2, %edx            # save temporary map PTE
        movl    %edx, PCB_CMAP2(%ecx)   # in our context
 
        movl    _CMAP2, %edx            # save temporary map PTE
        movl    %edx, PCB_CMAP2(%ecx)   # in our context
 
@@ -1261,52 +1405,52 @@ ENTRY(savectx)
        xorl    %eax, %eax              # return 0
        ret
 
        xorl    %eax, %eax              # return 0
        ret
 
-       .globl  _mvesp
-_mvesp:        movl    %esp,%eax
-       ret
-
 /*
 /*
- * update profiling information for the user
- * addupc(pc, up, ticks) struct uprof *up;
+ * addupc(int pc, struct uprof *up, int ticks):
+ * update profiling information for the user process.
  */
 
  */
 
+       ALIGN32
 ENTRY(addupc)
 ENTRY(addupc)
-       movl    4(%esp),%eax            /* pc */
-       movl    8(%esp),%ecx            /* up */
-
-       /* does sampled pc fall within bottom of profiling window? */
-       subl    PR_OFF(%ecx),%eax       /* pc -= up->pr_off; */
-       jl      1f                      /* if (pc < 0) return; */
-
-       /* construct scaled index */
-       shrl    $1,%eax                 /* reduce pc to a short index */
-       mull    PR_SCALE(%ecx)          /* pc*up->pr_scale */
-       shrdl   $15,%edx,%eax           /* praddr >> 15 */
-       cmpl    $0,%edx                 /* if overflow, ignore */
-       jne     1f
-       andb    $0xfe,%al               /* praddr &= ~1 */
-
-       /* within profiling buffer? if so, compute address */
-       cmpl    %eax,PR_SIZE(%ecx)      /* if (praddr > up->pr_size) return; */
-       jg      1f
-       addl    PR_BASE(%ecx),%eax      /* praddr += up->pr_base; */
-
-       /* tally ticks to selected counter */
-       movl    _curpcb,%ecx
-       movl    $proffault,PCB_ONFAULT(%ecx) #in case we page/protection violate
-       movl    12(%esp),%edx           /* ticks */
-       addw    %dx,(%eax)
-       movl    $0,PCB_ONFAULT(%ecx)
-1:     ret
+       pushl %ebp
+       movl %esp,%ebp
+       movl 12(%ebp),%edx              /* up */
+       movl 8(%ebp),%eax               /* pc */
+
+       subl PR_OFF(%edx),%eax          /* pc -= up->pr_off */
+       jl L1                           /* if (pc < 0) return */
+
+       shrl $1,%eax                    /* praddr = pc >> 1 */
+       imull PR_SCALE(%edx),%eax       /* praddr *= up->pr_scale */
+       shrl $15,%eax                   /* praddr = praddr << 15 */
+       andl $-2,%eax                   /* praddr &= ~1 */
+
+       cmpl PR_SIZE(%edx),%eax         /* if (praddr > up->pr_size) return */
+       ja L1
+
+/*     addl %eax,%eax                  /* praddr -> word offset */
+       addl PR_BASE(%edx),%eax         /* praddr += up-> pr_base */
+       movl 16(%ebp),%ecx              /* ticks */
+
+       movl _curpcb,%edx
+       movl $proffault,PCB_ONFAULT(%edx)
+       addl %ecx,(%eax)                /* storage location += ticks */
+       movl $0,PCB_ONFAULT(%edx)
+L1:
+       leave
+       ret
 
 
+       ALIGN32
 proffault:
 proffault:
-       /* disable profiling if we get a fault */
-       movl    $0,PR_SCALE(%ecx) /*    up->pr_scale = 0; */
-       movl    _curpcb,%ecx
-       movl    $0,PCB_ONFAULT(%ecx)
+       /* if we get a fault, then kill profiling all together */
+       movl $0,PCB_ONFAULT(%edx)       /* squish the fault handler */
+       movl 12(%ebp),%ecx
+       movl $0,PR_SCALE(%ecx)          /* up->pr_scale = 0 */
+       leave
        ret
 
 .data
        ret
 
 .data
+       ALIGN32
        .globl  _cyloffset, _curpcb
 _cyloffset:    .long   0
        .globl  _proc0paddr
        .globl  _cyloffset, _curpcb
 _cyloffset:    .long   0
        .globl  _proc0paddr
@@ -1314,15 +1458,15 @@ _proc0paddr:    .long   0
 LF:    .asciz "swtch %x"
 
 .text
 LF:    .asciz "swtch %x"
 
 .text
+ # To be done:
        .globl _astoff
 _astoff:
        .globl _astoff
 _astoff:
-       movl    $0,_astpending
        ret
 
 #define        IDTVEC(name)    .align 4; .globl _X/**/name; _X/**/name:
 #define        PANIC(msg)      xorl %eax,%eax; movl %eax,_waittime; pushl 1f; \
                        call _panic; 1: .asciz msg
        ret
 
 #define        IDTVEC(name)    .align 4; .globl _X/**/name; _X/**/name:
 #define        PANIC(msg)      xorl %eax,%eax; movl %eax,_waittime; pushl 1f; \
                        call _panic; 1: .asciz msg
-#define        PRINTF(n,msg)   pushal ; pushl 1f; call _printf; MSG(msg) ; \
+#define        PRINTF(n,msg)   pushal ; nop ; pushl 1f; call _printf; MSG(msg) ; \
                         popl %eax ; popal
 #define        MSG(msg)        .data; 1: .asciz msg; .text
 
                         popl %eax ; popal
 #define        MSG(msg)        .data; 1: .asciz msg; .text
 
@@ -1331,9 +1475,9 @@ _astoff:
 /*
  * Trap and fault vector routines
  */ 
 /*
  * Trap and fault vector routines
  */ 
-#define        TRAP(a)         pushl $a ; jmp alltraps
+#define        TRAP(a)         pushl $(a) ; jmp alltraps
 #ifdef KGDB
 #ifdef KGDB
-#define        BPTTRAP(a)      pushl $a ; jmp bpttraps
+#define        BPTTRAP(a)      pushl $(a) ; jmp bpttraps
 #else
 #define        BPTTRAP(a)      TRAP(a)
 #endif
 #else
 #define        BPTTRAP(a)      TRAP(a)
 #endif
@@ -1373,7 +1517,31 @@ IDTVEC(page)
 IDTVEC(rsvd)
        pushl $0; TRAP(T_RESERVED)
 IDTVEC(fpu)
 IDTVEC(rsvd)
        pushl $0; TRAP(T_RESERVED)
 IDTVEC(fpu)
+#ifdef NPX
+       /*
+        * Handle like an interrupt so that we can call npxintr to clear the
+        * error.  It would be better to handle npx interrupts as traps but
+        * this is difficult for nested interrupts.
+        */
+       pushl   $0              /* dummy error code */
+       pushl   $T_ASTFLT
+       pushal
+       nop                     /* silly, the bug is for popal and it only
+                                * bites when the next instruction has a
+                                * complicated address mode */
+       pushl   %ds
+       pushl   %es             /* now the stack frame is a trap frame */
+       movl    $KDSEL,%eax
+       movl    %ax,%ds
+       movl    %ax,%es
+       pushl   _cpl
+       pushl   $0              /* dummy unit to finish building intr frame */
+       incl    _cnt+V_TRAP
+       call    _npxintr
+       jmp     doreti
+#else
        pushl $0; TRAP(T_ARITHTRAP)
        pushl $0; TRAP(T_ARITHTRAP)
+#endif
        /* 17 - 31 reserved for future exp */
 IDTVEC(rsvd0)
        pushl $0; TRAP(17)
        /* 17 - 31 reserved for future exp */
 IDTVEC(rsvd0)
        pushl $0; TRAP(17)
@@ -1406,62 +1574,40 @@ IDTVEC(rsvd13)
 IDTVEC(rsvd14)
        pushl $0; TRAP(31)
 
 IDTVEC(rsvd14)
        pushl $0; TRAP(31)
 
+       ALIGN32
 alltraps:
        pushal
 alltraps:
        pushal
+       nop
        push %ds
        push %es
        push %ds
        push %es
+       # movw  $KDSEL,%ax
        movw    $0x10,%ax
        movw    %ax,%ds
        movw    %ax,%es
 calltrap:
        incl    _cnt+V_TRAP
        call    _trap
        movw    $0x10,%ax
        movw    %ax,%ds
        movw    %ax,%es
 calltrap:
        incl    _cnt+V_TRAP
        call    _trap
-
-       cli
-
-       /* this value may also be used in return_to_user_mode */
-       movl    0x34(%esp),%esi /* previous cs */
-       andl    $3,%esi
-       jz      trap_return
-
-       cmpl    $0,_astpending
-       jnz     do_astflt
-
-       cmpw    $0,_cpl
-       jnz     return_to_user_mode /* in icu.s */
-
-trap_return:
-       pop %es
-       pop %ds
-       popal
-       nop
-       addl    $8,%esp                 # pop type, code
-       iret
-
-do_astflt:
-       /* pop off the old trap frame, then create a new one that
-        * will give trap() another chance
+       /*
+        * Return through doreti to handle ASTs.  Have to change trap frame
+        * to interrupt frame.
         */
         */
-       pop     %es
-       pop     %ds
-       popa
-       addl    $8,%esp
-
-       pushl   $0
-       TRAP (T_ASTFLT)
-       /* NORETURN */
-               
-
+       movl    $T_ASTFLT,4+4+32(%esp)  /* new trap type (err code not used) */
+       pushl   _cpl
+       pushl   $0                      /* dummy unit */
+       jmp     doreti
 
 #ifdef KGDB
 /*
  * This code checks for a kgdb trap, then falls through
  * to the regular trap code.
  */
 
 #ifdef KGDB
 /*
  * This code checks for a kgdb trap, then falls through
  * to the regular trap code.
  */
+       ALIGN32
 bpttraps:
        pushal
 bpttraps:
        pushal
+       nop
        push    %es
        push    %ds
        push    %es
        push    %ds
+       # movw  $KDSEL,%ax
        movw    $0x10,%ax
        movw    %ax,%ds
        movw    %ax,%es
        movw    $0x10,%ax
        movw    %ax,%ds
        movw    %ax,%es
@@ -1476,80 +1622,44 @@ bpttraps:
  * Call gate entry for syscall
  */
 
  * Call gate entry for syscall
  */
 
+       ALIGN32
 IDTVEC(syscall)
        pushfl  # only for stupid carry bit and more stupid wait3 cc kludge
        pushal  # only need eax,ecx,edx - trap resaves others
 IDTVEC(syscall)
        pushfl  # only for stupid carry bit and more stupid wait3 cc kludge
        pushal  # only need eax,ecx,edx - trap resaves others
-       movw    $0x10,%ax       # switch to kernel segments
-       movw    %ax,%ds
-       movw    %ax,%es
-       call    _syscall
-
-       cli
-
-       cmpl    $0,_astpending
-       jnz     syscall_ast
-
-       cmpw    $0,_cpl
-       jnz     syscall_fix_cpl
-
-       movw    __udatasel,%ax  # switch back to user segments
-       movw    %ax,%ds
-       movw    %ax,%es
-       popal
        nop
        nop
-       popfl
-       lret
-
-syscall_ast:
-       movw    __udatasel,%ax
-       movw    %ax,%ds
-       movw    %ax,%es
-       popal
-
-       /* convert to trap frame
-        * stack is now ss, sp, cs,    ip, flags
-        * we want      ss, sp, flags, cs, ip   
-        * offsets      16  12  8      4   0    
+       movl    $KDSEL,%eax             # switch to kernel segments
+       movl    %ax,%ds
+       movl    %ax,%es
+       incl    _cnt+V_SYSCALL  # kml 3/25/93
+       call    _syscall
+       /*
+        * Return through doreti to handle ASTs.  Have to change syscall frame
+        * to interrupt frame.
+        *
+        * XXX - we should have set up the frame earlier to avoid the
+        * following popal/pushal (not much can be done to avoid shuffling
+        * the flags).  Consistent frames would simplify things all over.
         */
         */
-       xchgl   %eax,8(%esp) /* now eax has cs */
-       xchgl   %eax,4(%esp) /* now eax has ip */
-       xchgl   %eax,0(%esp) /* now eax has flags */
-       xchgl   %eax,8(%esp) /* now eax has its original value */
-       pushl $0
-       TRAP (T_ASTFLT)
-       /* NORETURN */
-
-syscall_fix_cpl:
-       movw    __udatasel,%ax
-       movw    %ax,%ds
-       movw    %ax,%es
+       movl    32+0(%esp),%eax /* old flags, shuffle to above cs:eip */
+       movl    32+4(%esp),%ebx /* `int' frame should have been ef, eip, cs */
+       movl    32+8(%esp),%ecx
+       movl    %ebx,32+0(%esp)
+       movl    %ecx,32+4(%esp)
+       movl    %eax,32+8(%esp)
        popal
        popal
-
-       /* convert to trap frame
-        * stack is now ss, sp, cs,    ip, flags
-        * we want      ss, sp, flags, cs, ip   
-        * offsets      16  12  8      4   0    
-        */
-       xchgl   %eax,8(%esp) /* now eax has cs */
-       xchgl   %eax,4(%esp) /* now eax has ip */
-       xchgl   %eax,0(%esp) /* now eax has flags */
-       xchgl   %eax,8(%esp) /* now eax has its original value */
-       
-       pushl $0
-       pushl $ T_ASTFLT
-
+       nop
+       pushl   $0              /* dummy error code */
+       pushl   $T_ASTFLT
        pushal
        nop
        pushal
        nop
-       push %ds
-       push %es
-       movw    $0x10,%ax
-       movw    %ax,%ds
-       movw    %ax,%es
-
-       movl    $1, %esi /* non-zero to indicate return to user mode */
-       jmp     return_to_user_mode /* in icu.s */
+       movl    __udatasel,%eax /* switch back to user segments */
+       push    %eax            /* XXX - better to preserve originals? */
+       push    %eax
+       pushl   _cpl
+       pushl   $0
+       jmp     doreti
 
 
-       
+       ALIGN32
 ENTRY(htonl)
 ENTRY(ntohl)
        movl    4(%esp),%eax
 ENTRY(htonl)
 ENTRY(ntohl)
        movl    4(%esp),%eax
@@ -1558,27 +1668,12 @@ ENTRY(ntohl)
        xchgb   %al,%ah
        ret
 
        xchgb   %al,%ah
        ret
 
+       ALIGN32
 ENTRY(htons)
 ENTRY(ntohs)
        movzwl  4(%esp),%eax
        xchgb   %al,%ah
        ret
 
 ENTRY(htons)
 ENTRY(ntohs)
        movzwl  4(%esp),%eax
        xchgb   %al,%ah
        ret
 
-/* DELAY(n)  delay about n microseconds */
-ENTRY(DELAY)
-       movl 4(%esp), %ecx
-       incl %ecx /* make DELAY(0) go through the loop just once */
-
-       /* 
-        * 0x80 is the manufacturing test port, which should be safe to
-        * write to on any motherboard.  The output instruction will
-        * be executed at bus speed, rather than processor speed, so
-        * it will be about 750ns on any ISA or EISA machine.
-        */
-1:
-       outb %al, $0x80
-       loop 1b
-       ret     
-
 #include "vector.s"
 #include "vector.s"
-#include <i386/isa/icu.s>
+#include "i386/isa/icu.s"
index 5009c1c..ae6a2ab 100644 (file)
@@ -5,9 +5,35 @@
  * This code is derived from software contributed to Berkeley by
  * William Jolitz.
  *
  * This code is derived from software contributed to Berkeley by
  * William Jolitz.
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 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
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
  *
- *     @(#)machdep.c   7.17 (Berkeley) %G%
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)machdep.c   7.17 (Berkeley) 5/24/93
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
@@ -456,7 +482,7 @@ boot(arghowto)
 extern int cold;
 
        howto = arghowto;
 extern int cold;
 
        howto = arghowto;
-       if ((howto&RB_NOSYNC) == 0 && waittime < 0 && bfreelist[0].b_forw) {
+       if ((howto&RB_NOSYNC) == 0 && waittime < 0) {
                register struct buf *bp;
                int iter, nbusy;
 
                register struct buf *bp;
                int iter, nbusy;