baseline version, warts and all!
authorBill Joy <bill@ucbvax.Berkeley.EDU>
Sat, 14 Apr 1990 09:25:57 +0000 (01:25 -0800)
committerBill Joy <bill@ucbvax.Berkeley.EDU>
Sat, 14 Apr 1990 09:25:57 +0000 (01:25 -0800)
SCCS-vsn: sys/i386/i386/locore.s 1.2

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

index 2a54aaf..d8c9e4d 100644 (file)
@@ -3,7 +3,7 @@
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
- *     @(#)locore.s    1.1 (Berkeley) %G%
+ *     @(#)locore.s    1.2 (Berkeley) %G%
  */
 
 #include "psl.h"
  */
 
 #include "psl.h"
        .set    UPDROFF,0x3F7
        .set    UPTEOFF,0x3FE
 
        .set    UPDROFF,0x3F7
        .set    UPTEOFF,0x3FE
 
+#define        ENTRY(name) \
+       .globl _##name; _##name:
+#define        ALTENTRY(name) \
+       .globl _##name; _##name:
 #ifdef badidea
 /*
  * I/O Memory Map is 0xfffa000-0xffffffff (virtual == real)
 #ifdef badidea
 /*
  * I/O Memory Map is 0xfffa000-0xffffffff (virtual == real)
@@ -89,8 +93,9 @@ _##mname:     .globl  _##mname;               \
        .set    atmemsz,0x100000-0xa0000
        .set    atpgs,(atmemsz>>PGSHIFT)
        SYSMAP(ATDevmem,atdevbase,atpgs)
        .set    atmemsz,0x100000-0xa0000
        .set    atpgs,(atmemsz>>PGSHIFT)
        SYSMAP(ATDevmem,atdevbase,atpgs)
+#define USRIOSIZE 30
+       SYSMAP(Usriomap,usrio,USRIOSIZE+CLSIZE) /* for PHYSIO */
        ZSYSMAP(ekmempt,kmemlimit,0)
        ZSYSMAP(ekmempt,kmemlimit,0)
-
        SYSMAP(Usrptmap,usrpt,USRPTSIZE+CLSIZE)
 
 eSysmap:
        SYSMAP(Usrptmap,usrpt,USRPTSIZE+CLSIZE)
 
 eSysmap:
@@ -105,12 +110,14 @@ eSysmap:
        # .set rptes,(ptes)%1024
        # .set rptes,1024-rptes
        # .set ptes,ptes+rptes
        # .set rptes,(ptes)%1024
        # .set rptes,1024-rptes
        # .set ptes,ptes+rptes
-       .set Npdes,1
+       .set Npdes,3
        .space (NBPG - sz)
 
        .space (NBPG - sz)
 
+       .globl  _tMap
        # SYSMAP(Tmap,tmap,1024)
 _tMap:
        .space  NBPG
        # SYSMAP(Tmap,tmap,1024)
 _tMap:
        .space  NBPG
+       .globl  _PDR
 _PDR:
        # SYSMAP(PDR,pdr,1024)
        .space  NBPG
 _PDR:
        # SYSMAP(PDR,pdr,1024)
        .space  NBPG
@@ -124,6 +131,18 @@ _cpu:      .long   0       # are we 386, 386sx, or 486
        .text
        .globl  start
 start:
        .text
        .globl  start
 start:
+       movw    $0x1234,%ax
+       movw    %ax,0x472       # warm boot
+       jmp     1f
+       .space  0x500   # skip over warm boot shit
+1:
+#ifdef notdef
+       inb     $0x61,%al
+       orb     $3,%al
+       outb    %al,$0x61
+       movl    $0xffff,%ecx
+fooy:  loop    fooy
+#endif
 #ifdef notyet
        # XXX pass parameters on stack
 /* count up memory */
 #ifdef notyet
        # XXX pass parameters on stack
 /* count up memory */
@@ -148,8 +167,8 @@ start:
        addl    $NBPG,%eax
        loop    1b
 2:     movl    %eax,_abovemem-SYSTEM
        addl    $NBPG,%eax
        loop    1b
 2:     movl    %eax,_abovemem-SYSTEM
-
 #endif notyet
 #endif notyet
+
 /* clear memory. is this redundant ? */
        movl    $_edata-SYSTEM,%edi
        movl    $_end-SYSTEM,%ecx
 /* clear memory. is this redundant ? */
        movl    $_edata-SYSTEM,%edi
        movl    $_end-SYSTEM,%ecx
@@ -228,7 +247,7 @@ start:
 
  /*# map proc 0's _u*/
        movl    $UPAGES,%ecx            # for this many pte s,
 
  /*# map proc 0's _u*/
        movl    $UPAGES,%ecx            # for this many pte s,
-       lea     (1*NBPG)(%esi),%eax     # physical address of _u in proc 0
+       lea     (2*NBPG)(%esi),%eax     # physical address of _u in proc 0
        orl     $PG_V|PG_URKW,%eax      #  having these bits set,
        lea     (0*NBPG)(%esi),%ebx     # physical address of stack pt in proc 0
        addl    $(UPTEOFF*4),%ebx
        orl     $PG_V|PG_URKW,%eax      #  having these bits set,
        lea     (0*NBPG)(%esi),%ebx     # physical address of stack pt in proc 0
        addl    $(UPTEOFF*4),%ebx
@@ -238,6 +257,15 @@ start:
        addl    $4,%ebx                         # next pte
        loop    1b
 
        addl    $4,%ebx                         # next pte
        loop    1b
 
+ /*# map proc 0's page directory*/
+       lea     (1*NBPG)(%esi),%eax     # physical address of ptd in proc 0
+       movl    %eax,%edi               # remember ptd physical address
+       orl     $PG_V|PG_URKW,%eax      #  having these bits set,
+       lea     (0*NBPG)(%esi),%ebx     # physical address of stack pt in proc 0
+       addl    $(UPTEOFF*4),%ebx
+       addl    $(UPAGES*4),%ebx
+       movl    %eax,0(%ebx)
+
 /*
  * Construct a page table directory
  * (of page directory elements - pde's)
 /*
  * Construct a page table directory
  * (of page directory elements - pde's)
@@ -246,8 +274,8 @@ start:
        movl    $_Sysmap-SYSTEM,%eax    # physical address of kernel page table
        orl     $PG_V,%eax              # pde entry is valid
        movl    $Npdes,%ecx             # for this many pde s,
        movl    $_Sysmap-SYSTEM,%eax    # physical address of kernel page table
        orl     $PG_V,%eax              # pde entry is valid
        movl    $Npdes,%ecx             # for this many pde s,
-       movl    $_PDR-SYSTEM,%ebx               # address of start of ptd
-       # lea   (2*NBPG)(%esi),%ebx     # address of ptd in proc 0 pt
+       # movl  $_PDR-SYSTEM,%ebx               # address of start of ptd
+       movl    %edi,%ebx               # phys address of ptd in proc 0
        addl    $(SYSPDROFF*4), %ebx    # offset of pde for kernel
 1:     movl    %eax,0(%ebx)
        addl    $NBPG,%eax                      # increment physical address
        addl    $(SYSPDROFF*4), %ebx    # offset of pde for kernel
 1:     movl    %eax,0(%ebx)
        addl    $NBPG,%eax                      # increment physical address
@@ -256,8 +284,8 @@ start:
                                        # install a pde for temporary double map
        movl    $_tMap-SYSTEM,%eax      # physical address of temp page table
        orl     $PG_V,%eax              # pde entry is valid
                                        # install a pde for temporary double map
        movl    $_tMap-SYSTEM,%eax      # physical address of temp page table
        orl     $PG_V,%eax              # pde entry is valid
-       movl    $_PDR-SYSTEM,%ebx               # address of start of ptd
-       # lea   (2*NBPG)(%esi),%ebx     # address of ptd in proc 0 pt
+       # movl  $_PDR-SYSTEM,%ebx               # address of start of ptd
+       movl    %edi,%ebx               # phys address of ptd in proc 0
        movl    %eax,0(%ebx)                    # which is where temp maps!
 #ifdef badidea
                                        # install a pde for IO memory
        movl    %eax,0(%ebx)                    # which is where temp maps!
 #ifdef badidea
                                        # install a pde for IO memory
@@ -271,8 +299,8 @@ start:
                                        # install a pde to map _u for proc 0
        lea     (0*NBPG)(%esi),%eax     # physical address of pt in proc 0
        orl     $PG_V,%eax              # pde entry is valid
                                        # install a pde to map _u for proc 0
        lea     (0*NBPG)(%esi),%eax     # physical address of pt in proc 0
        orl     $PG_V,%eax              # pde entry is valid
-       movl    $_PDR-SYSTEM,%ebx               # address of start of ptd
-       # lea   (2*NBPG)(%esi),%ebx     # address of ptd in proc 0 pt
+       # movl  $_PDR-SYSTEM,%ebx               # address of start of ptd
+       movl    %edi,%ebx               # phys address of ptd in proc 0
        addl    $(UPDROFF*4), %ebx      # offset of pde for kernel
        movl    %eax,0(%ebx)            # which is where _u maps!
 
        addl    $(UPDROFF*4), %ebx      # offset of pde for kernel
        movl    %eax,0(%ebx)            # which is where _u maps!
 
@@ -283,8 +311,8 @@ start:
        # addl  $_PDR-SYSTEM,%eax
        # orl   $PG_V,%eax
 
        # addl  $_PDR-SYSTEM,%eax
        # orl   $PG_V,%eax
 
-       movl    $_PDR-SYSTEM,%eax               # address of start of ptd
-       # lea   (2*NBPG)(%esi),%eax     # address o ptd in proc 0 pt
+       # movl  $_PDR-SYSTEM,%eax               # address of start of ptd
+       movl    %edi,%eax               # phys address of ptd in proc 0
        movl    %eax,%cr3                       # load ptd addr into mmu
        movl    $0x80000001,%eax                # and let s page!
        movl    %eax,%cr0                       # NOW!
        movl    %eax,%cr3                       # load ptd addr into mmu
        movl    $0x80000001,%eax                # and let s page!
        movl    %eax,%cr0                       # NOW!
@@ -292,21 +320,113 @@ start:
        pushl   $begin                          # jump to high mem!
        ret
 begin:
        pushl   $begin                          # jump to high mem!
        ret
 begin:
-       movl    $_u+UPAGES*NBPG-4,%eax
+       # movl  $_u+UPAGES*NBPG-4,%eax
+       # movl  $0xfdfffffc,%eax
+       movl    $_Sysbase,%eax
        movl    %eax,%esp
        movl    %eax,%ebp
        movl    _Crtat,%eax
        subl    $IOPHYSmem,%eax
        addl    $_atdevbase,%eax
        movl    %eax,_Crtat
        movl    %eax,%esp
        movl    %eax,%ebp
        movl    _Crtat,%eax
        subl    $IOPHYSmem,%eax
        addl    $_atdevbase,%eax
        movl    %eax,_Crtat
-       # call  _init386
+       call    _init386
+/* initialize (slightly) the pcb */
+       movl    $_u,%eax                # proc0 u-area
+       movl    $_usrpt,%ecx
+       movl    %ecx,PCB_P0BR(%eax)     # p0br: SVA of text/data user PT
+       xorl    %ecx,%ecx
+       movl    %ecx,PCB_P0LR(%eax)     # p0lr: 0 (doesn t really exist)
+       movl    $_usrpt+NBPG,%ecx       # addr of end of PT
+       subl    $P1PAGES*4,%ecx         # backwards size of P1 region
+       movl    %ecx,PCB_P1BR(%eax)     # p1br: P1PAGES from end of PT
+       movl    $P1PAGES-UPAGES,PCB_P1LR(%eax)  # p1lr: vax style
+       movl    $CLSIZE,PCB_SZPT(%eax)  # page table size
+       #clrw   a1@(PCB_FLAGS)          # clear flags
+#ifdef FPUNOTYET
+#endif
+       pushl   %edi    # cr3
+       movl    %esi,%eax
+       # addl  $(UPAGES*NBPG)+NBPG+NBPG+NBPG,%esi
+       addl    $(UPAGES*NBPG)+NBPG+NBPG+NBPG,%eax
+       shrl    $PGSHIFT,%eax
+       pushl   %eax    # firstaddr
+
+       pushl   $20             # install sigtrampoline code
+       pushl   $_u+PCB_SIGC
+       pushl   $sigcode
+       call    _bcopy
+       addl    $12,%esp
+
        call    _main
        call    _main
-       movw    $0x1234,%ax
-       movw    %ax,0x472       # warm boot
+
+       .globl  __ucodesel,__udatasel
+       movzwl  __ucodesel,%eax
+       movzwl  __udatasel,%ecx
+       # build outer stack frame
+       pushl   %ecx    # user ss
+       # pushl $0xfdffcffc # user esp
+       pushl   $0xfdffd000 # user esp
+       pushl   %eax    # user cs
+       pushl   $0      # user ip
+       movw    %cx,%ds
+       movw    %cx,%es
+       lret    # goto user!
+# pushal; pushl %edx; pushl $lr; call _pg; popl %eax ; popl %eax; popal ; .data ; lr: .asciz "lret %x" ; .text
+
+       .globl  __exit
+__exit:
        lidt    xaxa
        movl    $0,%esp         # segment violation
        ret
 xaxa:  .long   0,0
        lidt    xaxa
        movl    $0,%esp         # segment violation
        ret
 xaxa:  .long   0,0
+       .set    exec,11
+       .set    exit,1
+       .globl  _icode
+       .globl  _initflags
+       .globl  _szicode
+/* gas fucks up offset -- */
+#define        LCALL(x,y)      .byte 0x9a ; .long y; .word x
+/*
+ * Icode is copied out to process 1 to exec /etc/init.
+ * If the exec fails, process 1 exits.
+ */
+_icode:
+       # pushl $argv-_icode
+       movl    $argv,%eax
+       subl    $_icode,%eax
+       pushl   %eax
+
+       # pushl $init-_icode
+       movl    $init,%eax
+       subl    $_icode,%eax
+       pushl   %eax
+       pushl   %eax    # dummy out rta
+
+       movl    %esp,%ebp
+       movl    $exec,%eax
+       LCALL(0x7,0x0)
+       pushl   %eax
+       movl    $exit,%eax
+       pushl   %eax    # dummy out rta
+       LCALL(0x7,0x0)
+
+# init:        .asciz  "/sbin/init"
+init:  .asciz  "/etc/init"
+       .align  2
+_initflags:
+       .long   0
+argv:  .long   init-_icode
+       .long   _initflags-_icode
+       .long   0
+_szicode:
+       .long   _szicode-_icode
+sigcode:
+       movl    12(%esp),%eax   # unsure if call will dec stack 1st
+       call    %eax
+       xorl    %eax,%eax       # smaller movl $103,%eax
+       movb    $103,%al        # sigreturn()
+       LCALL(0x7,0)            # enter kernel with args on stack
+       hlt                     # never gets here
 
 #ifdef newway
 
 
 #ifdef newway
 
@@ -359,550 +479,321 @@ xaxa:   .long   0,0
 
 9:
 /* clear memory from kernel bss and pages for proc 0 u. and page table */
 
 9:
 /* clear memory from kernel bss and pages for proc 0 u. and page table */
-       lea     _edata-SYSTEM,r6
-       lea     _end-SYSTEM,r5
-       bisl3   $SYSTEM,r5,r9                   # convert to virtual address
-       addl2   $NBPG-1,r9                      # roundup to next page
-       addl2   $(UPAGES*NBPG)+NBPG+NBPG,r5
-1:     clrq    (r6); acbl r5,$8,r6,1b
-/* initialize system page table: uba vectors and int stack writeable */
-       clrl    r2
-       movab   eintstack,r1; bbcc $31,r1,1f;
-1:     bisl3   $PG_V|PG_KW,r2,_Sysmap[r2]; aoblss r1,r2,1b
-/* make kernel text space read-only */
-       movab   _etext+NBPG-1,r1; bbcc $31,r1,1f;
-1:     bisl3   $PG_V|PG_URKR,r2,_Sysmap[r2]; aoblss r1,r2,1b
-/* make kernel data, bss, read-write */
-       bicl3   $SYSTEM,r9,r1; ashl $-PGSHIFT,r1,r1
-1:     bisl3   $PG_V|PG_KW,r2,_Sysmap[r2]; aoblss r1,r2,1b
-/* now go to mapped mode */
-       mtpr    $0,$TBIA; mtpr $1,$MAPEN; jmp *$0f; 0:
-/* init mem sizes */
-       ashl    $-PGSHIFT,r7,_maxmem
-       movl    _maxmem,_physmem
-       movl    _maxmem,_freemem
-/* setup context for proc[0] == Scheduler */
-       bicl3   $SYSTEM|(NBPG-1),r9,r6  # make phys, page boundary
-/* setup page table for proc[0] */
-       ashl    $-PGSHIFT,r6,r3                 # r3 = btoc(r6)
-       bisl3   $PG_V|PG_KW,r3,_Usrptmap        # init first upt entry
-       incl    r3
-       movab   _usrpt,r0
-       mtpr    r0,$TBIS
-/* init p0br, p0lr */
-       mtpr    r0,$P0BR
-       mtpr    $0,$P0LR
-/* double map the kernel into the virtual user addresses of phys mem */
-       mtpr    $_Sysmap,$P0BR
-       mtpr    $_Syssize,$P0LR
-/* init p1br, p1lr */
-       movab   NBPG(r0),r0
-       movl    $0x200000-UPAGES,r1
-       mtpr    r1,$P1LR
-       mnegl   r1,r1
-       moval   -4*UPAGES(r0)[r1],r2
-       mtpr    r2,$P1BR
-/* setup mapping for UPAGES of _u */
-       movl    $UPAGES,r2; movab _u+NBPG*UPAGES,r1; addl2 $UPAGES,r3; jbr 2f
-1:     decl    r3
-       moval   -NBPG(r1),r1;
-       bisl3   $PG_V|PG_URKW,r3,-(r0)
-       mtpr    r1,$TBIS
-2:     sobgeq  r2,1b
-/* initialize (slightly) the pcb */
-       movab   UPAGES*NBPG(r1),PCB_KSP(r1)
-       mnegl   $1,PCB_ESP(r1)
-       mnegl   $1,PCB_SSP(r1)
-       movl    r1,PCB_USP(r1)
-       mfpr    $P0BR,PCB_P0BR(r1)
-       mfpr    $P0LR,PCB_P0LR(r1)
-       movb    $4,PCB_P0LR+3(r1)               # disable ast
-       mfpr    $P1BR,PCB_P1BR(r1)
-       mfpr    $P1LR,PCB_P1LR(r1)
-       movl    $CLSIZE,PCB_SZPT(r1)            # init u.u_pcb.pcb_szpt
-       movl    r9,PCB_R9(r1)
-       movl    r10,PCB_R10(r1)
-       movl    r11,PCB_R11(r1)
-       movab   1f,PCB_PC(r1)                   # initial pc
-       clrl    PCB_PSL(r1)                     # mode(k,k), ipl=0
-       ashl    $PGSHIFT,r3,r3
-       mtpr    r3,$PCBB                        # first pcbb
-/* set regs, p0br, p0lr, p1br, p1lr, astlvl, ksp and change to kernel mode */
-       ldpctx
-       rei
-/* put signal trampoline code in u. area */
-1:     movab   _u,r0
-       movc3   $19,sigcode,PCB_SIGC(r0)
-/* save boot device in global _bootdev */
-       movl    r10,_bootdev
-/* save reboot flags in global _boothowto */
-       movl    r11,_boothowto
-#ifdef KADB
-/* save end of symbol & string table in global _bootesym */
-       subl3   $NBPG-1,r9,_bootesym
-#endif
-/* calculate firstaddr, and call main() */
-       bicl3   $SYSTEM,r9,r0; ashl $-PGSHIFT,r0,-(sp)
-       addl2   $UPAGES+1,(sp); calls $1,_main
-/* proc[1] == /etc/init now running here; run icode */
-       pushl   $PSL_CURMOD|PSL_PRVMOD; pushl $0; rei
-
-/* signal trampoline code: it is known that this code takes exactly 19 bytes */
-/* in ../vax/pcb.h and in the movc3 above */
-sigcode:
-       calls   $4,8(pc)        # params pushed by sendsig
-       movl    sp,ap           # calls frame built by sendsig
-       chmk    $103            # cleanup mask and onsigstack
-       halt                    # sigreturn() does not return!
-       .word   0x3f            # registers 0-5
-       callg   (ap),*16(ap)    # call the signal handler
-       ret                     # return to code above
+#endif newway
 
 
-       .set    exec,11
-       .set    exit,1
-       .globl  _icode
-       .globl  _initflags
-       .globl  _szicode
-/*
- * Icode is copied out to process 1 to exec /etc/init.
- * If the exec fails, process 1 exits.
- */
-_icode:
-       pushab  b`argv-l0(pc)
-l0:    pushab  b`init-l1(pc)
-l1:    pushl   $2
-       movl    sp,ap
-       chmk    $exec
-       pushl   r0
-       chmk    $exit
-
-init:  .asciz  "/sbin/init"
-       .align  2
-_initflags:
-       .long   0
-argv:  .long   init+6-_icode
-       .long   _initflags-_icode
-       .long   0
-_szicode:
-       .long   _szicode-_icode
+       .globl ___udivsi3
+___udivsi3:
+       movl 4(%esp),%eax
+       xorl %edx,%edx
+       divl 8(%esp)
+       ret
 
 
-/*
- * Primitives
- */ 
+       .globl ___divsi3
+___divsi3:
+       movl 4(%esp),%eax
+       xorl %edx,%edx
+       cltd
+       idivl 8(%esp)
+       ret
 
 
-#ifdef GPROF
-#define        ENTRY(name, regs) \
-       .globl _##name; .align 1; _##name: .word regs; jsb mcount
-#else
-#define        ENTRY(name, regs) \
-       .globl _##name; .align 1; _##name: .word regs
-#endif GPROF
-#define R0 0x01
-#define R1 0x02
-#define R2 0x04
-#define R3 0x08
-#define R4 0x10
-#define R5 0x20
-#define R6 0x40
+       .globl  _inb
+_inb:  movl    4(%esp),%edx
+       subl    %eax,%eax       # clr eax
+       nop
+       inb     %dx,%al
+       nop
+       ret
 
 
-/*
- * badaddr(addr, len)
- *     see if access addr with a len type instruction causes a machine check
- *     len is length of access (1=byte, 2=short, 4=long)
- */
-       .globl  _badaddr
-_badaddr:
-       .word   0
-       movl    $1,r0
-       mfpr    $IPL,r1
-       mtpr    $HIGH,$IPL
-       movl    4(ap),r3
-       movl    8(ap),r4
-       movab   2f,nofault              # jump to 2f on machcheck
-       bbc     $0,r4,1f; tstb  (r3)
-1:     bbc     $1,r4,1f; tstw  (r3)
-1:     bbc     $2,r4,1f; tstl  (r3)
-1:     clrl    r0                      # made it w/o machine checks
-2:     clrl    nofault
-       mtpr    r1,$IPL
+       .globl  _outb
+_outb: movl    4(%esp),%edx
+       movl    8(%esp),%eax
+       nop
+       outb    %al,%dx
+       nop
        ret
 
        ret
 
-/*
- * update profiling information for the user
- * addupc(pc, &u.u_prof, ticks)
- */
-ENTRY(addupc, 0)
-       movl    8(ap),r2                # &u.u_prof
-       subl3   8(r2),4(ap),r0          # corrected pc
-       blss    9f
-       extzv   $1,$31,r0,r0            # logical right shift
-       extzv   $1,$31,12(r2),r1        # ditto for scale
-       emul    r1,r0,$0,r0
-       ashq    $-14,r0,r0
-       tstl    r1
-       bneq    9f
-       bicl2   $1,r0
-       cmpl    r0,4(r2)                # length
-       bgequ   9f
-       addl2   (r2),r0                 # base
-       probew  $3,$2,(r0)
-       beql    8f
-       addw2   12(ap),(r0)
-9:
+       #
+       # bzero (base,cnt)
+       #
+
+       .globl _bzero
+       .globl _blkclr
+_bzero:
+_blkclr:
+       pushl   %edi
+       movl    8(%esp),%edi
+       movl    12(%esp),%ecx
+       movb    $0x00,%al
+       cld
+       rep
+       stosb
+       popl    %edi
        ret
        ret
-8:
-       clrl    12(r2)
+
+       #
+       # bcopy (src,dst,cnt)
+       # NOTE: does not (yet) handle overlapped copies
+       #
+
+       .globl  _bcopy
+       .globl  _copyout
+       .globl  _copyin
+_bcopy:
+_copyout:
+_copyin:
+       pushl   %esi
+       pushl   %edi
+       movl    12(%esp),%esi
+       movl    16(%esp),%edi
+       movl    20(%esp),%ecx
+       cld
+       rep
+       movsb
+       popl    %edi
+       popl    %esi
+       movl    %ecx,%eax
        ret
 
        ret
 
-/*
- * Copy a null terminated string from the user address space into
- * the kernel address space.
- *
- * copyinstr(fromaddr, toaddr, maxlength, &lencopied)
- */
-ENTRY(copyinstr, R6)
-       movl    12(ap),r6               # r6 = max length
-       jlss    8f
-       movl    4(ap),r1                # r1 = user address
-       bicl3   $~(NBPG*CLSIZE-1),r1,r2 # r2 = bytes on first page
-       subl3   r2,$NBPG*CLSIZE,r2
-       movl    8(ap),r3                # r3 = kernel address
-1:
-       cmpl    r6,r2                   # r2 = min(bytes on page, length left);
-       jgeq    2f
-       movl    r6,r2
-2:
-       prober  $3,r2,(r1)              # bytes accessible?
-       jeql    8f
-       subl2   r2,r6                   # update bytes left count
-#ifdef NOSUBSINST
-       # fake the locc instr. for processors that don t have it
-       movl    r2,r0
-6:
-       tstb    (r1)+
-       jeql    5f
-       sobgtr  r0,6b
-       jbr     7f
-5:
-       decl    r1
-       jbr     3f
-7:
-#else
-       locc    $0,r2,(r1)              # null byte found?
-       jneq    3f
-#endif
-       subl2   r2,r1                   # back up pointer updated by `locc 
-       movc3   r2,(r1),(r3)            # copy in next piece
-       movl    $(NBPG*CLSIZE),r2       # check next page
-       tstl    r6                      # run out of space?
-       jneq    1b
-       movl    $ENOENT,r0              # set error code and return
-       jbr     9f
-3:
-       tstl    16(ap)                  # return length?
-       beql    4f
-       subl3   r6,12(ap),r6            # actual len = maxlen - unused pages
-       subl2   r0,r6                   #       - unused on this page
-       addl3   $1,r6,*16(ap)           #       + the null byte
-4:
-       subl2   r0,r2                   # r2 = number of bytes to move
-       subl2   r2,r1                   # back up pointer updated by `locc 
-       incl    r2                      # copy null byte as well
-       movc3   r2,(r1),(r3)            # copy in last piece
-       clrl    r0                      # redundant
+       # insw(port,addr,cnt)
+       .globl  _insw
+_insw:
+       pushl   %edi
+       movw    8(%esp),%dx
+       movl    12(%esp),%edi
+       movl    16(%esp),%ecx
+       cld
+       nop
+       .byte 0x66,0xf2,0x6d    # rep insw
+       nop
+       movl    %edi,%eax
+       popl    %edi
        ret
        ret
-8:
-       movl    $EFAULT,r0
-9:
-       tstl    16(ap)
-       beql    1f
-       subl3   r6,12(ap),*16(ap)
-1:
+
+       # outsw(port,addr,cnt)
+       .globl  _outsw
+_outsw:
+       pushl   %esi
+       movw    8(%esp),%dx
+       movl    12(%esp),%esi
+       movl    16(%esp),%ecx
+       cld
+       nop
+       .byte 0x66,0xf2,0x6f    # rep outsw
+       nop
+       movl    %esi,%eax
+       popl    %esi
        ret
 
        ret
 
-/*
- * Copy a null terminated string from the kernel
- * address space to the user address space.
- *
- * copyoutstr(fromaddr, toaddr, maxlength, &lencopied)
- */
-ENTRY(copyoutstr, R6)
-       movl    12(ap),r6               # r6 = max length
-       jlss    8b
-       movl    4(ap),r1                # r1 = kernel address
-       movl    8(ap),r3                # r3 = user address
-       bicl3   $~(NBPG*CLSIZE-1),r3,r2 # r2 = bytes on first page
-       subl3   r2,$NBPG*CLSIZE,r2
-1:
-       cmpl    r6,r2                   # r2 = min(bytes on page, length left);
-       jgeq    2f
-       movl    r6,r2
-2:
-       probew  $3,r2,(r3)              # bytes accessible?
-       jeql    8b
-       subl2   r2,r6                   # update bytes left count
-#ifdef NOSUBSINST
-       # fake the locc instr. for processors that don t have it
-       movl    r2,r0
-6:
-       tstb    (r1)+
-       jeql    5f
-       sobgtr  r0,6b
-       jbr     7f
-5:
-       decl    r1
-       jbr     3b
-7:
-#else
-       locc    $0,r2,(r1)              # null byte found?
-       jneq    3b
-#endif
-       subl2   r2,r1                   # back up pointer updated by `locc 
-       movc3   r2,(r1),(r3)            # copy in next piece
-       movl    $(NBPG*CLSIZE),r2       # check next page
-       tstl    r6                      # run out of space?
-       jneq    1b
-       movl    $ENOENT,r0              # set error code and return
-       jbr     9b
+       # lgdt(*gdt, ngdt)
+       .globl  _lgdt
+       # .globl        _gdt
+xxx:   .word 31
+       .long 0
+_lgdt:
+       movl    4(%esp),%eax
+       movl    %eax,xxx+2
+       movl    8(%esp),%eax
+       movw    %ax,xxx
+       lgdt    xxx
+       jmp     1f
+       nop
+1:     movw    $0x10,%ax
+       movw    %ax,%ds
+       movw    %ax,%es
+       movw    %ax,%ss
+       movl    0(%esp),%eax
+       pushl   %eax
+       movl    $8,4(%esp)
+       lret
+
+       # lidt(*idt, nidt)
+       .globl  _lidt
+       # .globl        _idt
+yyy:   .word   255
+       .long   0 # _idt
+_lidt:
+       movl    4(%esp),%eax
+       movl    %eax,yyy+2
+       movl    8(%esp),%eax
+       movw    %ax,yyy
+       lidt    yyy
+       ret
 
 
-/*
- * Copy a null terminated string from one point to another in
- * the kernel address space.
- *
- * copystr(fromaddr, toaddr, maxlength, &lencopied)
- */
-ENTRY(copystr, R6)
-       movl    12(ap),r6               # r6 = max length
-       jlss    8b
-       movl    4(ap),r1                # r1 = src address
-       movl    8(ap),r3                # r3 = dest address
-1:
-       movzwl  $65535,r2               # r2 = bytes in first chunk
-       cmpl    r6,r2                   # r2 = min(bytes in chunk, length left);
-       jgeq    2f
-       movl    r6,r2
-2:
-       subl2   r2,r6                   # update bytes left count
-#ifdef NOSUBSINST
-       # fake the locc instr. for processors that don t have it
-       movl    r2,r0
-6:
-       tstb    (r1)+
-       jeql    5f
-       sobgtr  r0,6b
-       jbr     7f
-5:
-       decl    r1
-       jbr     3b
-7:
-#else
-       locc    $0,r2,(r1)              # null byte found?
-       jneq    3b
-#endif
-       subl2   r2,r1                   # back up pointer updated by `locc 
-       movc3   r2,(r1),(r3)            # copy in next piece
-       tstl    r6                      # run out of space?
-       jneq    1b
-       movl    $ENOENT,r0              # set error code and return
-       jbr     9b
-
-/* 
- * Copy specified amount of data from user space into the kernel
- * Copyin(from, to, len)
- *     r1 == from (user source address)
- *     r3 == to (kernel destination address)
- *     r5 == length
- */
-       .align  1
-JSBENTRY(Copyin, R1|R3|R5)
-       cmpl    r5,$(NBPG*CLSIZE)       # probing one page or less ?
-       bgtru   1f                      # no
-       prober  $3,r5,(r1)              # bytes accessible ?
-       beql    ersb                    # no
-       movc3   r5,(r1),(r3)
-/*     clrl    r0                      # redundant */
-       rsb
-1:
-       blss    ersb                    # negative length?
-       pushl   r6                      # r6 = length
-       movl    r5,r6
-       bicl3   $~(NBPG*CLSIZE-1),r1,r0 # r0 = bytes on first page
-       subl3   r0,$(NBPG*CLSIZE),r0
-       addl2   $(NBPG*CLSIZE),r0       # plus one additional full page
-       jbr     2f
-
-ciloop:
-       movc3   r0,(r1),(r3)
-       movl    $(2*NBPG*CLSIZE),r0     # next amount to move
-2:
-       cmpl    r0,r6
-       bleq    3f
-       movl    r6,r0
-3:
-       prober  $3,r0,(r1)              # bytes accessible ?
-       beql    ersb1                   # no
-       subl2   r0,r6                   # last move?
-       bneq    ciloop                  # no
-
-       movc3   r0,(r1),(r3)
-/*     clrl    r0                      # redundant */
-       movl    (sp)+,r6                # restore r6
-       rsb
-
-ersb1:
-       movl    (sp)+,r6                # restore r6
-ersb:
-       movl    $EFAULT,r0
-       rsb
-
-/* 
- * Copy specified amount of data from kernel to the user space
- * Copyout(from, to, len)
- *     r1 == from (kernel source address)
- *     r3 == to (user destination address)
- *     r5 == length
- */
-       .align  1
-JSBENTRY(Copyout, R1|R3|R5)
-       cmpl    r5,$(NBPG*CLSIZE)       # moving one page or less ?
-       bgtru   1f                      # no
-       probew  $3,r5,(r3)              # bytes writeable?
-       beql    ersb                    # no
-       movc3   r5,(r1),(r3)
-/*     clrl    r0                      # redundant */
-       rsb
-1:
-       blss    ersb                    # negative length?
-       pushl   r6                      # r6 = length
-       movl    r5,r6
-       bicl3   $~(NBPG*CLSIZE-1),r3,r0 # r0 = bytes on first page
-       subl3   r0,$(NBPG*CLSIZE),r0
-       addl2   $(NBPG*CLSIZE),r0       # plus one additional full page
-       jbr     2f
-
-coloop:
-       movc3   r0,(r1),(r3)
-       movl    $(2*NBPG*CLSIZE),r0     # next amount to move
-2:
-       cmpl    r0,r6
-       bleq    3f
-       movl    r6,r0
-3:
-       probew  $3,r0,(r3)              # bytes writeable?
-       beql    ersb1                   # no
-       subl2   r0,r6                   # last move?
-       bneq    coloop                  # no
-
-       movc3   r0,(r1),(r3)
-/*     clrl    r0                      # redundant */
-       movl    (sp)+,r6                # restore r6
-       rsb
+       # lldt(sel)
+       .globl  _lldt
+_lldt:
+       movl    4(%esp),%eax
+       lldt    %eax
+       ret
 
 
-/*
- * non-local goto s
- */
-#ifdef notdef          /* this is now expanded completely inline */
-       .align  1
-JSBENTRY(Setjmp, R0)
-       movl    fp,(r0)+        # current stack frame
-       movl    (sp),(r0)       # resuming pc
-       clrl    r0
-       rsb
-#endif
+       # ltr(sel)
+       .globl  _ltr
+_ltr:
+       movl    4(%esp),%eax
+       ltr     %eax
+       ret
 
 
-#define PCLOC 16       /* location of pc in calls frame */
-#define APLOC 8                /* location of ap,fp in calls frame */
-       .align  1
-JSBENTRY(Longjmp, R0)
-       movl    (r0)+,newfp     # must save parameters in memory as all
-       movl    (r0),newpc      # registers may be clobbered.
-1:
-       cmpl    fp,newfp        # are we there yet?
-       bgequ   2f              # yes
-       moval   1b,PCLOC(fp)    # redirect return pc to us!
-       ret                     # pop next frame
-2:
-       beql    3f              # did we miss our frame?
-       pushab  4f              # yep ?!?
-       calls   $1,_panic
-3:
-       movl    newpc,r0        # all done, just return to the `setjmp 
-       jmp     (r0)            # rsb
+       # lcr3(cr3)
+       .globl  _lcr3
+       .globl  _load_cr3
+_load_cr3:
+_lcr3:
+       movl    4(%esp),%eax
+       movl    %eax,%cr3
+       movl    %cr3,%eax
+       ret
 
 
-       .data
-newpc: .space  4
-newfp: .space  4
-4:     .asciz  "longjmp"
-       .text
-/*
- * setjmp that saves all registers as the call frame may not
- * be available to recover them in the usual mannor by longjmp.
- * Called before swapping out the u. area, restored by resume()
- * below.
- */
-ENTRY(savectx, 0)
-       movl    4(ap),r0
-       movq    r6,(r0)+
-       movq    r8,(r0)+
-       movq    r10,(r0)+
-       movq    APLOC(fp),(r0)+ # save ap, fp
-       addl3   $8,ap,(r0)+     # save sp
-       movl    PCLOC(fp),(r0)  # save pc
-       clrl    r0
+       # lcr0(cr0)
+       .globl  _lcr0
+_lcr0:
+       movl    4(%esp),%eax
+       movl    %eax,%cr0
+       ret
+
+       # rcr0()
+       .globl  _rcr0
+_rcr0:
+       movl    %cr0,%eax
+       ret
+
+       # rcr2()
+       .globl  _rcr2
+_rcr2:
+       movl    %cr2,%eax
+       ret
+
+       # rcr3()
+       .globl  _rcr3
+       .globl  __cr3
+__cr3:
+_rcr3:
+       movl    %cr3,%eax
+       ret
+
+       # ssdtosd(*ssdp,*sdp)
+       .globl  _ssdtosd
+_ssdtosd:
+       pushl   %ebx
+       movl    8(%esp),%ecx
+       movl    8(%ecx),%ebx
+       shll    $16,%ebx
+       movl    (%ecx),%edx
+       roll    $16,%edx
+       movb    %dh,%bl
+       movb    %dl,%bh
+       rorl    $8,%ebx
+       movl    4(%ecx),%eax
+       movw    %ax,%dx
+       andl    $0xf0000,%eax
+       orl     %eax,%ebx
+       movl    12(%esp),%ecx
+       movl    %edx,(%ecx)
+       movl    %ebx,4(%ecx)
+       popl    %ebx
        ret
 
        ret
 
-#ifdef KADB
 /*
 /*
- * C library -- reset, setexit
- *
- *     reset(x)
- * will generate a "return" from
- * the last call to
- *     setexit()
- * by restoring r6 - r12, ap, fp
- * and doing a return.
- * The returned value is x; on the original
- * call the returned value is 0.
+ * {fu,su},{byte,sword,word}
  */
  */
-ENTRY(setexit, 0)
-       movab   setsav,r0
-       movq    r6,(r0)+
-       movq    r8,(r0)+
-       movq    r10,(r0)+
-       movq    8(fp),(r0)+             # ap, fp
-       movab   4(ap),(r0)+             # sp
-       movl    16(fp),(r0)             # pc
-       clrl    r0
+ALTENTRY(fuiword)
+ENTRY(fuword)
+       movl    $fusufault,_nofault     # in case we page/protection violate
+       movl    4(%esp),%edx
+       movl    0(%edx),%eax
+       xorl    %edx,%edx
+       movl    %edx,_nofault
+       ret
+       
+ENTRY(fusword)
+       movl    $fusufault,_nofault     # in case we page/protection violate
+       movl    4(%esp),%edx
+       movzwl  0(%edx),%eax
+       xorl    %edx,%edx
+       movl    %edx,_nofault
+       ret
+       
+ALTENTRY(fuibyte)
+ENTRY(fubyte)
+       movl    $fusufault,_nofault     # in case we page/protection violate
+       movl    4(%esp),%edx
+       movzbl  0(%edx),%eax
+       xorl    %edx,%edx
+       movl    %edx,_nofault
+       ret
+       
+fusufault:
+       xorl    %eax,%eax
+       movl    %eax,_nofault
+       decl    %eax
        ret
 
        ret
 
-ENTRY(reset, 0)
-       movl    4(ap),r0        # returned value
-       movab   setsav,r1
-       movq    (r1)+,r6
-       movq    (r1)+,r8
-       movq    (r1)+,r10
-       movq    (r1)+,r12
-       movl    (r1)+,sp
-       jmp     *(r1)
+ALTENTRY(suiword)
+ENTRY(suword)
+       movl    $fusufault,_nofault     # in case we page/protection violate
+       movl    4(%esp),%edx
+       movl    8(%esp),%eax
+       movl    %eax,0(%edx)
+       xorl    %eax,%eax
+       movl    %eax,_nofault
+       ret
+       
+ENTRY(susword)
+       movl    $fusufault,_nofault     # in case we page/protection violate
+       movl    4(%esp),%edx
+       movl    8(%esp),%eax
+       movl    %eax,0(%edx)
+       xorl    %eax,%eax
+       movl    %eax,_nofault
+       ret
 
 
-       .data
-       .align  2
-setsav:        .space  10*4
-       .text
-#endif
+ALTENTRY(suibyte)
+ENTRY(subyte)
+       movl    $fusufault,_nofault     # in case we page/protection violate
+       movl    4(%esp),%edx
+       movl    8(%esp),%eax
+       movl    %eax,0(%edx)
+       xorl    %eax,%eax
+       movl    %eax,_nofault
+       ret
 
 
-       .globl  _whichqs
-       .globl  _qs
-       .globl  _cnt
+       ALTENTRY(savectx)
+       ENTRY(setjmp)
+       movl    4(%esp),%eax
+       movl    %ebx, 0(%eax)           # save ebx
+       movl    %esp, 4(%eax)           # save esp
+       movl    %ebp, 8(%eax)           # save ebp
+       movl    %esi,12(%eax)           # save esi
+       movl    %edi,16(%eax)           # save edi
+       movl    (%esp),%edx             # get rta
+       movl    %edx,20(%eax)           # save eip
+       movl    $0,%edx                 # return (0);
+       movl    $0,%eax                 # return (0);
+       ret
 
 
-       .globl  _noproc
-       .comm   _noproc,4
-       .globl  _runrun
-       .comm   _runrun,4
+       ENTRY(qsetjmp)
+       movl    4(%esp),%eax
+       movl    %esp, 4(%eax)           # save esp
+       movl    %ebp, 8(%eax)           # save ebp
+       movl    (%esp),%edx             # get rta
+       movl    %edx,20(%eax)           # save eip
+       xorl    %eax,%eax               # return (0);
+       ret
 
 
+       ENTRY(longjmp)
+       movl    4(%esp),%eax
+       movl     0(%eax),%ebx           # restore ebx
+       movl     4(%eax),%esp           # restore esp
+       movl     8(%eax),%ebp           # restore ebp
+       movl    12(%eax),%esi           # restore esi
+       movl    16(%eax),%edi           # restore edi
+       movl    20(%eax),%edx           # get rta
+       movl    %edx,(%esp)             # put in return frame
+       xorl    %eax,%eax               # return (1);
+       incl    %eax
+       ret
 /*
 /*
- * The following primitives use the fancy VAX instructions
- * much like VMS does.  _whichqs tells which of the 32 queues _qs
+ * 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
  * 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
@@ -910,395 +801,252 @@ setsav: .space  10*4
  * queues.
  */
 
  * queues.
  */
 
+       .globl  _whichqs,_qs,_cnt,_panic,_ctasksel
+       .comm   _noproc,4
+       .comm   _runrun,4
+       .comm   _ctasksel,4
+
 /*
 /*
- * Setrq(p), using fancy VAX instructions.
+ * Setrq(p)
  *
  *
- * Call should be made at splclock(), and p->p_stat should be SRUN
+ * Call should be made at spl6(), and p->p_stat should be SRUN
  */
  */
-       .align  1
-JSBENTRY(Setrq, R0)
-       tstl    P_RLINK(r0)             ## firewall: p->p_rlink must be 0
-       beql    set1                    ##
-       pushab  set3                    ##
-       calls   $1,_panic               ##
+ENTRY(setrq)
+       movl    4(%esp),%eax
+       cmpl    $0,P_RLINK(%eax)        # should not be on q already
+       je      set1
+       pushl   $set2
+       call    _panic
 set1:
 set1:
-       movzbl  P_PRI(r0),r1            # put on queue which is p->p_pri / 4
-       ashl    $-2,r1,r1
-       movaq   _qs[r1],r2
-       insque  (r0),*4(r2)             # at end of queue
-       bbss    r1,_whichqs,set2        # mark queue non-empty
-set2:
-       rsb
+       movzbl  P_PRI(%eax),%edx
+       shrl    $2,%edx
+       btsl    %edx,_whichqs           # set q full bit
+       shll    $3,%edx
+       addl    $_qs,%edx               # locate q hdr
+       movl    %edx,P_LINK(%eax)       # link process on tail of q
+       movl    P_RLINK(%edx),%ecx
+       movl    %ecx,P_RLINK(%eax)
+       movl    %eax,P_RLINK(%edx)
+       movl    %eax,P_LINK(%ecx)
+       ret
 
 
-set3:  .asciz  "setrq"
+set2:  .asciz  "setrq"
 
 /*
 
 /*
- * Remrq(p), using fancy VAX instructions
+ * Remrq(p)
  *
  *
- * Call should be made at splclock().
+ * Call should be made at spl6().
  */
  */
-       .align  1
-JSBENTRY(Remrq, R0)
-       movzbl  P_PRI(r0),r1
-       ashl    $-2,r1,r1
-       bbsc    r1,_whichqs,rem1
-       pushab  rem3                    # it wasn t recorded to be on its q
-       calls   $1,_panic
+ENTRY(remrq)
+       movl    4(%esp),%eax
+       movzbl  P_PRI(%eax),%edx
+       shrl    $2,%edx
+       btrl    %edx,_whichqs           # clear full bit, panic if clear already
+       jb      rem1
+       pushl   $rem3
+       call    _panic
 rem1:
 rem1:
-       remque  (r0),r2
-       beql    rem2
-       bbss    r1,_whichqs,rem2
+       pushl   %edx
+       movl    P_LINK(%eax),%ecx       # unlink process
+       movl    P_RLINK(%eax),%edx
+       movl    %edx,P_RLINK(%ecx)
+       movl    P_RLINK(%eax),%ecx
+       movl    P_LINK(%eax),%edx
+       movl    %edx,P_LINK(%ecx)
+       popl    %edx
+       movl    $_qs,%ecx
+       shll    $3,%edx
+       addl    %edx,%ecx
+       cmpl    P_LINK(%ecx),%ecx       # q still has something?
+       je      rem2
+       shrl    $3,%edx                 # yes, set bit as still full
+       btsl    %edx,_whichqs
 rem2:
 rem2:
-       clrl    P_RLINK(r0)             ## for firewall checking
-       rsb
+       movl    $0,P_RLINK(%eax)        # zap reverse link to indicate off list
+       ret
 
 rem3:  .asciz  "remrq"
 
 rem3:  .asciz  "remrq"
-
-/*
- * Masterpaddr is the p->p_addr of the running process on the master
- * processor.  When a multiprocessor system, the slave processors will have
- * an array of slavepaddr s.
- */
-       .globl  _masterpaddr
-       .data
-_masterpaddr:
-       .long   0
-
-       .text
 sw0:   .asciz  "swtch"
 sw0:   .asciz  "swtch"
+sw01:  .asciz  "swtch1"
+sw02:  .asciz  "swtch2"
 
 /*
  * When no processes are on the runq, Swtch branches to idle
  * to wait for something to come ready.
  */
        .globl  Idle
 
 /*
  * When no processes are on the runq, Swtch branches to idle
  * to wait for something to come ready.
  */
        .globl  Idle
-Idle: idle:
-       movl    $1,_noproc
-       mtpr    $0,$IPL                 # must allow interrupts here
-1:
-       tstl    _whichqs                # look for non-empty queue
-       bneq    sw1
-       brb     1b
-
-badsw: pushab  sw0
-       calls   $1,_panic
+Idle:
+idle:
+       call    _spl0
+       cmpl    $0,_whichqs
+       jne     sw1
+       hlt             # wait for interrupt
+       jmp     idle
+
+badsw:
+       pushl   $sw0
+       call    _panic
        /*NOTREACHED*/
 
 /*
        /*NOTREACHED*/
 
 /*
- * Swtch(), using fancy VAX instructions
+ * Swtch()
  */
  */
-       .align  1
-JSBENTRY(Swtch, 0)
+ENTRY(swtch)
+       movl    $1,%eax
+       movl    %eax,_noproc
        incl    _cnt+V_SWTCH
        incl    _cnt+V_SWTCH
-sw1:   ffs     $0,$32,_whichqs,r0      # look for non-empty queue
-       beql    idle                    # if none, idle
-       mtpr    $0x18,$IPL              # lock out all so _whichqs==_qs
-       bbcc    r0,_whichqs,sw1         # proc moved via interrupt
-       movaq   _qs[r0],r1
-       remque  *(r1),r2                # r2 = p = highest pri process
-       bvs     badsw                   # make sure something was there
-       beql    sw2
-       insv    $1,r0,$1,_whichqs       # still more procs in this queue
+sw1:
+       bsfl    _whichqs,%eax   # find a full q
+       jz      idle            # if none, idle
+swfnd:
+       cli
+       btrl    %eax,_whichqs   # clear q full status
+       jnb     sw1             # if it was clear, look for another
+       pushl   %eax            # save which one we are using
+       shll    $3,%eax
+       addl    $_qs,%eax       # select q
+       pushl   %eax
+
+       cmpl    P_LINK(%eax),%eax       # linked to self? (e.g. not on list)
+       je      badsw           # not possible
+       movl    P_LINK(%eax),%ecx       # unlink from front of process q
+       movl    P_LINK(%ecx),%edx
+       movl    %edx,P_LINK(%eax)
+       movl    P_RLINK(%ecx),%eax
+       movl    %eax,P_RLINK(%edx)
+
+       popl    %eax
+       popl    %edx
+       cmpl    P_LINK(%ecx),%eax       # q empty
+       je      sw2
+       btsl    %edx,_whichqs           # nope, indicate full
 sw2:
 sw2:
-       clrl    _noproc
-       clrl    _runrun
-#ifdef notdef
-       tstl    P_WCHAN(r2)             ## firewalls
-       bneq    badsw                   ##
-       cmpb    P_STAT(r2),$SRUN        ##
-       bneq    badsw                   ##
-#endif
-       clrl    P_RLINK(r2)             ##
-       movl    *P_ADDR(r2),r0
-#ifdef notdef
-       cmpl    r0,_masterpaddr         # resume of current proc is easy
-       beql    res0
+       movl    $0,%eax
+       movl    %eax,_noproc
+       movl    %eax,_runrun
+       cmpl    $0,P_WCHAN(%ecx)
+       jne     badsw
+       cmpb    $SRUN,P_STAT(%ecx)
+       jne     badsw
+       movl    %eax,P_RLINK(%ecx)
+       # movl  P_ADDR(%ecx),%edx
+       movl    P_CR3(%ecx),%edx
+/*pushal; pushl %edx; pushl $lc; call _printf; popl %eax ; popl %eax; popal ; .data ; lc: .asciz "swtch %x" ; .text*/
+
+/* switch to new process. first, save context as needed */
+       movl    $_u,%ecx
+
+       movl    (%esp),%eax             # Hardware registers
+       movl    %eax, PCB_EIP(%ecx)
+       movl    %ebx, PCB_EBX(%ecx)
+       movl    %esp, PCB_ESP(%ecx)
+       movl    %ebp, PCB_EBP(%ecx)
+       movl    %esi, PCB_ESI(%ecx)
+       movl    %edi, PCB_EDI(%ecx)
+
+#ifdef FPUNOTYET
 #endif
 #endif
-       movl    r0,_masterpaddr
-       ashl    $PGSHIFT,r0,r0          # r0 = pcbb(p)
-/* fall into... */
 
 
-/*
- * Resume(pf)
- */
-JSBENTRY(Resume, R0)
-       mtpr    $HIGH,$IPL                      # no interrupts, please
-       movl    _CMAP2,_u+PCB_CMAP2     # yech
-       svpctx
-       mtpr    r0,$PCBB
-       ldpctx
-       movl    _u+PCB_CMAP2,_CMAP2     # yech
-       mtpr    $_CADDR2,$TBIS
-res0:
-       tstl    _u+PCB_SSWAP
-       bneq    res1
-       rei
-res1:
-       movl    _u+PCB_SSWAP,r0                 # longjmp to saved context
-       clrl    _u+PCB_SSWAP
-       movq    (r0)+,r6                        # restore r6, r7
-       movq    (r0)+,r8                        # restore r8, r9
-       movq    (r0)+,r10                       # restore r10, r11
-       movq    (r0)+,r12                       # restore ap, fp
-       movl    (r0)+,r1                        # saved sp
-       cmpl    r1,sp                           # must be a pop
-       bgequ   1f
-       pushab  2f
-       calls   $1,_panic
-       /* NOTREACHED */
-1:
-       movl    r1,sp                           # restore sp
-       pushl   $PSL_PRVMOD                     # return psl
-       pushl   (r0)                            # address to return to
-       rei
+       movl    _CMAP2,%eax             # save temporary map PTE
+       movl    %eax,PCB_CMAP2(%ecx)    # in our context
 
 
-2:     .asciz  "ldctx"
 
 
-/*
- * {fu,su},{byte,word}, all massaged by asm.sed to jsb s
- */
-       .align  1
-JSBENTRY(Fuword, R0)
-       prober  $3,$4,(r0)
-       beql    fserr
-       movl    (r0),r0
-       rsb
-fserr:
-       mnegl   $1,r0
-       rsb
-
-       .align  1
-JSBENTRY(Fubyte, R0)
-       prober  $3,$1,(r0)
-       beql    fserr
-       movzbl  (r0),r0
-       rsb
-
-       .align  1
-JSBENTRY(Suword, R0|R1)
-       probew  $3,$4,(r0)
-       beql    fserr
-       movl    r1,(r0)
-       clrl    r0
-       rsb
-
-       .align  1
-JSBENTRY(Subyte, R0|R1)
-       probew  $3,$1,(r0)
-       beql    fserr
-       movb    r1,(r0)
-       clrl    r0
-       rsb
+       movl    %edx,%cr3       # context switch
 
 
-/*
- * Copy 1 relocation unit (NBPG bytes)
- * from user virtual address to physical address
- */
-ENTRY(copyseg, 0)
-       bisl3   $PG_V|PG_KW,8(ap),_CMAP2
-       mtpr    $_CADDR2,$TBIS  # invalidate entry for copy 
-       movc3   $NBPG,*4(ap),_CADDR2
-       ret
+       movl    $_u,%edx
 
 
-/*
- * zero out physical memory
- * specified in relocation units (NBPG bytes)
- */
-ENTRY(clearseg, 0)
-       bisl3   $PG_V|PG_KW,4(ap),_CMAP1
-       mtpr    $_CADDR1,$TBIS
-       movc5   $0,(sp),$0,$NBPG,_CADDR1
+/* restore context */
+       movl    PCB_EBX(%ecx), %ebx
+       movl    PCB_ESP(%ecx), %esp
+       movl    PCB_EBP(%ecx), %ebp
+       movl    PCB_ESI(%ecx), %esi
+       movl    PCB_EDI(%ecx), %edi
+       movl    PCB_EIP(%ecx), %eax
+       movl    %eax, (%esp)
+
+#ifdef FPUNOTYET
+#endif
+
+       movl    PCB_CMAP2(%edx),%eax    # get temporary map
+       movl    %eax,_CMAP2             # reload temporary map PTE
+#ifdef FPUNOTYET
+#endif
+       cmpl    $0,PCB_SSWAP(%edx)      # do an alternate return?
+       jne     res3                    # yes, go reload regs
+       # call  _spl0
+       cli
+       ret
+res3:
+       xorl    %eax,%eax               # inline restore context
+       xchgl   PCB_SSWAP(%edx),%eax    # addr of saved context, clear it
+       movl     0(%eax),%ebx           # restore ebx
+       movl     4(%eax),%esp           # restore esp
+       movl     8(%eax),%ebp           # restore ebp
+       movl    12(%eax),%esi           # restore esi
+       movl    16(%eax),%edi           # restore edi
+       movl    20(%eax),%edx           # get rta
+       movl    %edx,(%esp)             # put in return frame
+       xorl    %eax,%eax               # return (1);
+       incl    %eax
+       sti
        ret
 
 /*
        ret
 
 /*
- * Check address.
- * Given virtual address, byte count, and rw flag
- * returns 0 on no access.
+ * Resume(p_addr)
+ * current just used to fillout u. tss so fork can fake a return to swtch
+ * [ all thats really needed is esp and eip ]
  */
  */
-ENTRY(useracc, 0)
-       movl    4(ap),r0                # get va
-       movl    8(ap),r1                # count
-       tstl    12(ap)                  # test for read access ?
-       bneq    userar                  # yes
-       cmpl    $NBPG,r1                        # can we do it in one probe ?
-       bgeq    uaw2                    # yes
-uaw1:
-       probew  $3,$NBPG,(r0)
-       beql    uaerr                   # no access
-       addl2   $NBPG,r0
-       acbl    $NBPG+1,$-NBPG,r1,uaw1
-uaw2:
-       probew  $3,r1,(r0)
-       beql    uaerr
-       movl    $1,r0
+ENTRY(resume)
+       movl    4(%esp),%ecx
+       movl    (%esp),%eax     
+       movl    %eax, PCB_EIP(%ecx)
+       movl    %ebx, PCB_EBX(%ecx)
+       movl    %esp, PCB_ESP(%ecx)
+       movl    %ebp, PCB_EBP(%ecx)
+       movl    %esi, PCB_ESI(%ecx)
+       movl    %edi, PCB_EDI(%ecx)
+#ifdef FPUNOTYET
+#endif
+       movl    $0,%eax
        ret
 
        ret
 
-userar:
-       cmpl    $NBPG,r1
-       bgeq    uar2
-uar1:
-       prober  $3,$NBPG,(r0)
-       beql    uaerr
-       addl2   $NBPG,r0
-       acbl    $NBPG+1,$-NBPG,r1,uar1
-uar2:
-       prober  $3,r1,(r0)
-       beql    uaerr
-       movl    $1,r0
+.data
+       .globl  _cyloffset
+_cyloffset:    .long   0
+       .globl  _nofault
+_nofault:      .long   0
+.text
+ # To be done:
+       .globl _addupc
+       .globl _astoff
+       .globl _doadump
+       .globl _inittodr
+       .globl _ovbcopy
+       .globl _physaddr
+_addupc:
+       .byte 0xcc
+_astoff:
        ret
        ret
-uaerr:
-       clrl    r0
+_doadump:
+       .byte 0xcc
+_ovbcopy:
+       .byte 0xcc
+_physaddr:
+       .byte 0xcc
+       .globl  _svfpsp,_rsfpsp
+_svfpsp:
+       popl %eax
+       movl    %esp,svesp
+       movl    %ebp,svebp
+       pushl %eax
        ret
 
        ret
 
-/*
- * kernacc - check for kernel access privileges
- *
- * We can t use the probe instruction directly because
- * it ors together current and previous mode.
- */
- ENTRY(kernacc, 0)
-       movl    4(ap),r0        # virtual address
-       bbcc    $31,r0,kacc1
-       bbs     $30,r0,kacerr
-       mfpr    $SBR,r2         # address and length of page table (system)
-       bbss    $31,r2,0f; 0:
-       mfpr    $SLR,r3
-       brb     kacc2
-kacc1:
-       bbsc    $30,r0,kacc3
-       mfpr    $P0BR,r2        # user P0
-       mfpr    $P0LR,r3
-       brb     kacc2
-kacc3:
-       mfpr    $P1BR,r2        # user P1 (stack)
-       mfpr    $P1LR,r3
-kacc2:
-       addl3   8(ap),r0,r1     # ending virtual address
-       addl2   $NBPG-1,r1
-       ashl    $-PGSHIFT,r0,r0
-       ashl    $-PGSHIFT,r1,r1
-       bbs     $31,4(ap),kacc6
-       bbc     $30,4(ap),kacc6
-       cmpl    r0,r3           # user stack
-       blss    kacerr          # address too low
-       brb     kacc4
-kacc6:
-       cmpl    r1,r3           # compare last page to P0LR or SLR
-       bgtr    kacerr          # address too high
-kacc4: 
-       movl    (r2)[r0],r3
-       bbc     $31,4(ap),kacc4a
-       bbc     $31,r3,kacerr   # valid bit is off
-kacc4a:
-       cmpzv   $27,$4,r3,$1    # check protection code
-       bleq    kacerr          # no access allowed
-       tstb    12(ap)
-       bneq    kacc5           # only check read access
-       cmpzv   $27,$2,r3,$3    # check low 2 bits of prot code
-       beql    kacerr          # no write access
-kacc5:
-       aoblss  r1,r0,kacc4     # next page
-       movl    $1,r0           # no errors
+_rsfpsp:
+       popl %eax
+       movl    svesp,%esp
+       movl    svebp,%ebp
+       pushl %eax
        ret
        ret
-kacerr:
-       clrl    r0              # error
-       ret
-/*
- * Extracted and unrolled most common case of pagein (hopefully):
- *     resident and not on free list (reclaim of page is purely
- *     for the purpose of simulating a reference bit)
- *
- * Built in constants:
- *     CLSIZE of 2, any bit fields in pte s
- */
-       .text
-       .globl  Fastreclaim
-Fastreclaim:
-       PUSHR
-#ifdef GPROF
-       movl    fp,-(sp)
-       movab   12(sp),fp
-       jsb     mcount
-       movl    (sp)+,fp
-#endif GPROF
-       extzv   $9,$23,28(sp),r3        # virtual address
-       bicl2   $1,r3                   # v = clbase(btop(virtaddr)); 
-       movl    _u+U_PROCP,r5           # p = u.u_procp 
-                                       # from vtopte(p, v) ...
-       movl    $1,r2                   # type = CTEXT;
-       cmpl    r3,P_TSIZE(r5)
-       jlssu   1f                      # if (isatsv(p, v)) {
-       addl3   P_TSIZE(r5),P_DSIZE(r5),r0
-       cmpl    r3,r0
-       jgequ   2f
-       clrl    r2                      #       type = !CTEXT;
-1:
-       ashl    $2,r3,r4
-       addl2   P_P0BR(r5),r4           #       tptopte(p, vtotp(p, v));
-       jbr     3f
-2:
-       cvtwl   P_SZPT(r5),r4           # } else (isassv(p, v)) {
-       ashl    $7,r4,r4
-       subl2   $0x400000,r4
-       addl2   r3,r4
-       ashl    $2,r4,r4
-       addl2   P_P0BR(r5),r4           #       sptopte(p, vtosp(p, v));
-       clrl    r2                      #       type = !CTEXT;
-3:                                     # }
-       bitb    $0x82,3(r4)
-       beql    2f                      # if (pte->pg_v || pte->pg_fod)
-       POPR; rsb                       #       let pagein handle it
-2:
-       bicl3   $0xffe00000,(r4),r0
-       jneq    2f                      # if (pte->pg_pfnum == 0)
-       POPR; rsb                       #       let pagein handle it 
-2:
-       subl2   _firstfree,r0
-       ashl    $-1,r0,r0       
-       incl    r0                      # pgtocm(pte->pg_pfnum) 
-       mull2   $SZ_CMAP,r0
-       addl2   _cmap,r0                # &cmap[pgtocm(pte->pg_pfnum)] 
-       tstl    r2
-       jeql    2f                      # if (type == CTEXT &&
-       jbc     $C_INTRANS,(r0),2f      #     c_intrans)
-       POPR; rsb                       #       let pagein handle it
-2:
-       jbc     $C_FREE,(r0),2f         # if (c_free)
-       POPR; rsb                       #       let pagein handle it 
-2:
-       bisb2   $0x80,3(r4)             # pte->pg_v = 1;
-       jbc     $26,4(r4),2f            # if (anycl(pte, pg_m) 
-       bisb2   $0x04,3(r4)             #       pte->pg_m = 1;
-2:
-       bicw3   $0x7f,2(r4),r0
-       bicw3   $0xff80,6(r4),r1
-       bisw3   r0,r1,6(r4)             # distcl(pte);
-       ashl    $PGSHIFT,r3,r0
-       mtpr    r0,$TBIS
-       addl2   $NBPG,r0
-       mtpr    r0,$TBIS                # tbiscl(v); 
-       tstl    r2
-       jeql    2f                      # if (type == CTEXT) 
-       movl    P_TEXTP(r5),r0
-       movl    X_CADDR(r0),r5          # for (p = p->p_textp->x_caddr; p; ) {
-       jeql    2f
-       ashl    $2,r3,r3
-3:
-       addl3   P_P0BR(r5),r3,r0        #       tpte = tptopte(p, tp);
-       bisb2   $1,P_FLAG+3(r5)         #       p->p_flag |= SPTECHG;
-       movl    (r4),(r0)+              #       for (i = 0; i < CLSIZE; i++)
-       movl    4(r4),(r0)              #               tpte[i] = pte[i];
-       movl    P_XLINK(r5),r5          #       p = p->p_xlink;
-       jneq    3b                      # }
-2:                                     # collect a few statistics...
-       incl    _u+U_RU+RU_MINFLT       # u.u_ru.ru_minflt++;
-       moval   _cnt,r0
-       incl    V_FAULTS(r0)            # cnt.v_faults++; 
-       incl    V_PGREC(r0)             # cnt.v_pgrec++;
-       incl    V_FASTPGREC(r0)         # cnt.v_fastpgrec++;
-       incl    V_TRAP(r0)              # cnt.v_trap++;
-       POPR
-       addl2   $8,sp                   # pop pc, code
-       mtpr    $HIGH,$IPL              ## dont go to a higher IPL (GROT)
-       rei
-#endif newway
+
+svesp: .long 0
+svebp: .long 0