BSD 3 development
authorOzalp Babaoglu <ozalp@ucbvax.Berkeley.EDU>
Wed, 16 Jan 1980 08:08:32 +0000 (00:08 -0800)
committerOzalp Babaoglu <ozalp@ucbvax.Berkeley.EDU>
Wed, 16 Jan 1980 08:08:32 +0000 (00:08 -0800)
Work on file usr/src/sys/sys/locore.s

Co-Authored-By: Bill Joy <wnj@ucbvax.Berkeley.EDU>
Co-Authored-By: Juan Porcar <x-jp@ucbvax.Berkeley.EDU>
Synthesized-from: 3bsd

usr/src/sys/sys/locore.s [new file with mode: 0644]

diff --git a/usr/src/sys/sys/locore.s b/usr/src/sys/sys/locore.s
new file mode 100644 (file)
index 0000000..10dd727
--- /dev/null
@@ -0,0 +1,1385 @@
+#
+# Machine Language Assist for UC Berkeley Virtual Vax/Unix
+#
+#      locore.s        2.2     1/15/80
+#
+
+       .set    HIGH,31         # mask for total disable
+       .set    MCKVEC,4        # offset into Scbbase of machine check vector
+       .set    NBPG,512
+       .set    PGSHIFT,9
+
+       .set    CLSIZE,2
+       .set    BSIZE,NBPG*CLSIZE
+       .set    NBUF,48
+       .set    UPAGES,6        # size of user area, in pages
+
+# ====================================
+# Trap vectors and C interface for Vax
+# ====================================
+
+#
+# System control block
+#
+
+       .set    INTSTK,1        # handle this interrupt on the interrupt stack
+       .set    HALT,3          # halt if this interrupt occurs
+       .align  PGSHIFT
+       .globl  Scbbase
+Scbbase:
+       .long   Xrandom + HALT          # unused
+       .long   Xmachcheck + HALT       # machine check interrupt
+       .long   Xkspnotval + HALT       # kernel stack not valid
+       .long   Xpowfail + HALT         # power fail
+       .long   Xprivinflt              # privileged instruction 
+       .long   Xxfcflt                 # xfc instruction 
+       .long   Xresopflt               # reserved operand 
+       .long   Xresadflt               # reserved addressing 
+       .long   Xprotflt                # protection and pt length violation
+       .long   Xtransflt               # address translation not valid fault 
+       .long   Xtracep                 # trace pending
+       .long   Xbptflt                 # bpt instruction
+       .long   Xcompatflt              # compatibility mode fault
+       .long   Xarithtrap              # arithmetic trap
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xsyscall                # chmk
+       .long   Xchme+HALT              # chme
+       .long   Xchms+HALT              # chms
+       .long   Xchmu+HALT              # chmu
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # software level 1
+       .long   Xrandom + HALT          # software level 2 (asts)
+       .long   Xresched                # reschedule nudge
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+ubabase:
+       .long   Xclockint               # clock
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xcnrint + INTSTK        # console receiver 
+       .long   Xcnxint + INTSTK        # console transmitter
+
+#
+# I/O vectors
+#
+
+# IPL 14
+       .long   X14stray + INTSTK       # stray!
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xua0int + INTSTK        # UBA 0 br4
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+
+# IPL 15
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xua0int + INTSTK        # UBA 0 br5
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xmba0int + INTSTK       # mass bus adapter 0
+       .long   Xmba1int + INTSTK       # mass bus adapter 1
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+
+# IPL 16
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xua0int + INTSTK        # UBA 0 br6
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+
+# IPL 17
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+       .long   Xrandom + HALT          # unused
+
+# 0x200
+
+# =====================================
+# Produce a core image dump on mag tape
+# =====================================
+       .globl  doadump
+doadump:
+       movl    sp,dumpstack            # save stack pointer
+       movab   dumpstack,sp            # reinit stack
+       mfpr    $PCBB,-(sp)             # save u-area pointer
+       mfpr    $MAPEN,-(sp)            # save value
+       mfpr    $IPL,-(sp)              # ...
+       mtpr    $0,$MAPEN               # turn off memory mapping
+       mtpr    $HIGH,$IPL              # disable interrupts
+       pushr   $0x3fff                 # save regs 0 - 13
+       calls   $0,_dump                # produce dump
+       halt
+
+       .data
+       .align  2
+       .globl  dumpstack
+       .space  58*4                    # separate stack for tape dumps
+dumpstack: 
+       .space  4
+       .text
+
+#
+# Debugging print switches given here so they won't move around
+#
+       .data
+       .align  2
+       .globl  _printsw
+_printsw:
+       .space  4
+       .globl  _coresw
+_coresw:
+       .space  4
+       .text
+
+# =============================
+# I/O interrupt vector routines
+# =============================
+
+#
+# Physical i/o addresses
+#
+       .set    PHYSUBA,0x20006000      # uba 0
+       .set    PHYSMBA0,0x20010000     # mba 0
+       .set    PHYSMBA1,0x20012000     # mba 1
+       .set    PHYSUMEM,0x2013e000     # unibus memory
+
+#
+# Catch random or unexpected interrupts
+#
+       .align  2
+Xrandom:
+Xmachcheck:
+Xkspnotval:
+Xpowfail:
+Xchme:
+Xchms:
+Xchmu:
+       halt
+
+X14stray:
+       pushr   $0x3f
+       pushab  straym
+       calls   $1,_printf
+       popr    $0x3f
+       rei
+
+#
+# Massbus 0 adapter interrupts
+#
+       .align  2
+Xmba0int:
+       pushr   $0x3f                   # save r0 - r5
+       movab   MBA0_CSR,r0             # point at mba regs
+       movl    MBA_AS(r0),r1           # get attn summary bits
+       cvtwl   r1,-(sp)                # push attn summary as arg
+       pushl   MBA_SR(r0)              # pass sr as argument
+       mnegl   $1,MBA_SR(r0)           # clear attention bit
+       calls   $2,_hpintr              # call rp06 interrupt dispatcher
+       brw     int_ret                 # merge with common interrupt code
+
+#
+# Massbus 1 adapter interrupts
+#
+       .align  2
+Xmba1int:
+       pushr   $0x3f
+       movab   MBA1_CSR,r0
+       pushl   MBA_AS(r0)
+       mnegl   $1,MBA_AS(r0)
+       pushl   MBA_SR(r0)              # pass sr as argument
+       mnegl   $1,MBA_SR(r0)           # clear attention bit
+       calls   $2,_htintr              # call te16 interrupt dispatcher
+       brw     int_ret                 # return from interrupt
+
+#
+# Unibus adapter interrupts
+#
+       .align  2
+Xua0int:
+       pushr   $0x3f                   # save regs 0-5
+       mfpr    $IPL,r2                 # get br level
+       movl    UBA0+UBR_OFF-20*4[r2],r3# get unibus device vector
+       bleq    ubasrv                  # branch if zero vector
+                                       # ... or UBA service required
+
+#
+# Normal UBA interrupt point - device on a UBA has generated an
+# interrupt - r3 holds interrupt vector.  Get the service routine
+# address and controller code from the UNIBUS vector area
+# and service the interrupt.
+#
+ubanorm:
+       movl    _UNIvec(r3),r1 
+       extzv   $27,$4,r1,r0            # controller code is in 4 most
+                                       # significant bits-1 of ISR addr
+       bicl2   $0x78000000,r1          # clear code
+       jlbc    r1,ubanpdma             # no pseudo dma here
+       jmp     -1(r1)                  # branch to pseudo dma rtn
+ubanpdma:
+       pushl   r0                      # controller code
+       calls   $1,(r1)                 # call ISR
+       brw     int_ret                 # go to common interrupt return
+
+#
+# Come here for zero or negative UBA interrupt vector.
+# Negative vector -> UBA requires service.
+#
+ubasrv:
+       beql    ubapass
+#
+# UBA service required.
+# The following 'printf' calls should probably be replaced
+# with calls to an error logger and/or some corrective action.
+#
+       bitl    $CFGFLT,UBA0+UCN_OFF    # any SBI faults ?
+       beql    UBAflt
+       pushr   $0xf                    # save regs 0-3
+       pushab  SBImsg
+       calls   $1,_printf
+       popr    $0xf
+       halt
+#
+# No SBI fault bits set in UBA config reg - must be
+# some error bits set in UBA status reg.
+#
+UBAflt:
+       movl    UBA0+UST_OFF,r2         # UBA status reg
+       pushr   $0xf                    # save regs 0-3
+       mfpr    $IPL,-(sp)
+       mtpr    $HIGH,$IPL
+       pushl   UBA0+UFUBAR_OFF
+       pushl   UBA0+UFMER_OFF
+       pushl   r2
+       pushab  UBAmsg
+       calls   $4,_printf
+       mtpr    (sp)+,$IPL
+       popr    $0xf
+       movl    r2,UBA0+UST_OFF         # clear error bits
+       bicl2   $0x80000000,r3          # clear neg bit in vector
+       jneq    ubanorm                 # branch if normal UBA interrupt
+                                       # to process
+       brw     int_ret                 # restore regs and return
+#
+# Zero interrupt vector - print message & continue
+#
+# WE GET SO MANY OF THESE THAT WE ONLY COUNT THEM
+#
+ubapass:
+#      pushr   $0xf
+#      pushab  ZERmsg
+#      calls   $1,_printf
+#      popr    $0xf
+       incl    _zvcnt
+       brw     int_ret
+       .data
+       .globl  _zvcnt
+_zvcnt:        .space  4
+       .text
+
+#
+# DZ pseudo dma routine:
+#      r0 - controller number
+#
+       .align  1
+       .globl  _dzdma
+_dzdma:
+#      bisw2   $4,*_draddr     # leading edge for dr11-c
+       mull2   $8*20,r0
+       movab   _dzpdma(r0),r3          # pdma structure base
+                                       # for this controller
+dzploop:
+       movl    r3,r0   
+       movl    (r0)+,r1                # device register address
+       movzbl  1(r1),r2                # get line number
+       bitb    $0x80,r2                # TRDY on?
+       beql    dzprei                  # no    
+       bicb2   $0xf8,r2                # clear garbage bits
+       mull2   $20,r2
+       addl2   r2,r0                   # point at line's pdma structure
+       movl    (r0)+,r2                # p_mem
+       cmpl    r2,(r0)+                # p_mem < p_end ?
+       bgequ   dzpcall                 # no, go call dzxint
+       movb    (r2)+,6(r1)             # dztbuf = *p_mem++
+       movl    r2,-8(r0)
+       brb     dzploop                 # check for another line
+dzprei:
+#      bicw2   $4,*_draddr     # trailing edge for dr11-c
+       popr    $0x3f
+       rei
+
+dzpcall:
+       pushl   (r0)                    # push tty address
+       calls   $1,_dzxint              # call interrupt rtn
+       brb     dzploop                 # check for another line
+
+#
+# Console receiver interrupt
+#
+       .align  2
+Xcnrint:
+       pushr   $0x3f                   # save registers 0 - 5
+       calls   $0,_cnrint
+       brb     int_ret                 # merge
+
+#
+# Console transmit interrupt
+#
+       .align  2
+Xcnxint:
+       pushr   $0x3f                   # save registers 0 - 5
+       calls   $0,_cnxint
+       brb     int_ret
+
+#
+# Clock interrupt
+#
+       .align  2
+Xclockint:
+       pushr   $0x3f                   # save regs 0 - 5
+       pushl   4+6*4(sp)               # push psl
+       pushl   4+6*4(sp)               # push pc
+       calls   $2,_clock
+       brb     int_ret
+
+#
+# Common code for interrupts.
+# At this point, the interrupt stack looks like:
+#
+#      r0      <- isp
+#      ...
+#      r5
+#      pc
+#      psl
+#
+
+int_ret:
+       bbssi   $0,idleflag,int_r0      # set idle escape flag (no wait instr)
+int_r0:
+       popr    $0x3f                   # restore regs 0 - 5
+       bitl    $PSL_CURMOD,4(sp)       # interrupt from user mode?
+       beql    int_r1                  # no, from kernel, just rei
+       tstb    _runrun                 # should we reschedule?
+       beql    int_r1                  # no, just rei
+#
+# If here, interrupt from user mode, and time to reschedule.
+# To do this, we set a software level 3 interrupt to
+# change to kernel mode, switch stacks, and format
+# kernel stack for a `qswitch' trap to force a reschedule.
+#
+       mtpr    $3,$SIRR                # request level 1 software interrupt
+int_r1:
+       rei                             # return to interrupted process
+
+# ==================================
+# User area virtual addresses
+# ==================================
+
+       .set    kernsize,512            # number of pte's allocated to kernel
+       .globl  _u
+       .set    _u,0x80000000 + kernsize*NBPG
+       .globl  _utilutl
+       .set    _utilutl,_u+16*NBPG
+       .globl  _umbabeg
+       .set    _umbabeg,_utilutl+16*NBPG
+       .globl  _umbaend
+       .set    _umbaend,_umbabeg+6*16*NBPG
+       .globl  _swaputl
+       .set    _swaputl,_u+128*NBPG
+       .globl  _forkutl
+       .set    _forkutl,_swaputl+UPAGES*NBPG
+       .globl  _xswaputl
+       .set    _xswaputl,_forkutl+UPAGES*NBPG
+       .globl  _xswap2utl
+       .set    _xswap2utl,_xswaputl+UPAGES*NBPG
+       .globl  _pushutl
+       .set    _pushutl,_xswap2utl+UPAGES*NBPG
+       .globl  _vfutl
+       .set    _vfutl,_pushutl+UPAGES*NBPG
+       .globl  _usrpt
+       .set    _usrpt,_vfutl+UPAGES*NBPG
+       .set    u_ptoffset,kernsize*4   # offset in _Sysmap of pte's of _u
+       .set    CMAP1,u_ptoffset+16*4   # offset in _sysmap of 1st copyseg entry
+       .set    CMAP2,CMAP1+4           # ... of 2nd copyseg entry
+       .set    CADDR1,_u+16*NBPG       # virtual address of 1st copy segment
+       .set    CADDR2,CADDR1+NBPG      # ... of second copy segment
+
+
+#
+# offsets in Sysmap
+#
+       .set    uba_offset,u_ptoffset+32*4      # ... of uba entries
+       .set    umem_offset,uba_offset+16*4     # ... of unibus device registers
+       .set    mba0_offset,umem_offset+16*4    # ... of massbus 0
+       .set    mba1_offset,mba0_offset+16*4    # ... of massbus 1
+       .set    mba2_offset,mba1_offset+16*4    # ... of massbus 2
+       .set    mba3_offset,mba2_offset+16*4    # ... of massbus 3
+
+# ==========================
+# Sysmap - system page table
+# ==========================
+#
+#      structure:
+#              4 pages of page table entries
+#                      reserved for kernel text and data.
+#              1 page to map u area and other utilities
+#                      used in mapping the u area (16 entries),
+#                      utility entries (16 entries),
+#                      unibus adapter (16 entries),
+#                      unibus device memory (16 entries),
+#                      massbus adapter 0 (16 entries),
+#                      massbus adapter 1 (16 entries),
+#                      massbus adapter 2 (16 entries),
+#                      massbus adapter 3 (16 entries).
+#                      used for phys & swap I/O
+#              6*4 entries for various other utilities
+#              4 pages to map user page tables of resident processes
+#
+
+       .data
+       .align  2
+       .globl  _Sysmap
+       .globl  _Umap
+       .globl  _Tempmap
+       .globl  _Swapmap
+       .globl  _Forkmap
+       .globl  _Xswapmap
+       .globl  _Xswap2map
+       .globl  _Pushmap
+       .globl  _Vfmap
+       .globl  _Usrptmap
+_Sysmap:
+       .space  4*128*4                 # four pages of pte's for kernel
+_Umap:
+       .space  16*4                    # u-area (could be just 6*4)
+_Tempmap:
+       .space  16*4*7                  # utility area & others
+_Swapmap:
+       .space  UPAGES*4                # swap utility area
+_Forkmap:
+       .space  UPAGES*4                # fork area
+_Xswapmap:
+       .space  UPAGES*4                # xswap area
+_Xswap2map:
+       .space  UPAGES*4                # xswap2 area
+_Pushmap:
+       .space  UPAGES*4                # pageout daemon utility
+_Vfmap:
+       .space  UPAGES*4                # vfork utility
+_Usrptmap:
+       .space  8*128*4                 # user page table area
+
+       .set    Syssize,13*128+6*UPAGES # number pt entries in sys page table
+       .globl  _mmap
+       .set    _mmap,_Sysmap+CMAP2+4
+       .globl  _vmmap
+       .set    _vmmap,CADDR2+NBPG
+       .globl  _mcrmap
+       .set    _mcrmap,_Sysmap+CMAP2+8
+       .globl  _mcr
+       .set    _mcr,CADDR2+(2*NBPG)
+       .set    mcr_offset,CMAP2+8
+       .text
+
+# ==============================
+# Trap and fault vector routines
+# ==============================
+
+#
+# Reschedule trap (Software level 3 interrupt)
+#
+       .align  2
+Xresched:
+       mtpr    $0,$IPL                 # lower ipl
+       pushl   $0                      # dummy code
+       pushl   $RESCHED                # type
+       brw     alltraps                # merge
+
+#
+# Privileged instruction fault
+#
+       .align  2
+Xprivinflt:
+       pushl   $0                      # push dummy code
+       pushl   $PRIVINFLT              # push type
+       brw     alltraps                # merge
+
+#
+# Xfc instruction fault
+#
+       .align  2
+Xxfcflt:
+       pushl   $0                      # push dummy code value
+       pushl   $XFCFLT                 # push type value
+       brw     alltraps                # merge
+
+#
+# Reserved operand fault
+#
+       .align  2
+Xresopflt:
+       pushl   $0                      # push dummy code value
+       pushl   $RESOPFLT               # push type value
+       brw     alltraps                # merge
+
+#
+# Reserved addressing mode fault
+#
+       .align  2
+Xresadflt:
+       pushl   $0                      # push dummy code value
+       pushl   $RESADFLT               # push type value
+       brw     alltraps                # merge with common code
+
+#
+# Bpt instruction fault
+#
+       .align  2
+Xbptflt:
+       pushl   $0                      # push dummy code value
+       pushl   $BPTFLT                 # push type value
+       brw     alltraps                # merge with common code
+
+#
+# Compatibility mode fault
+#
+       .align  2
+Xcompatflt:
+       pushl   $COMPATFLT              # push type value
+       brw     alltraps                # merge with common code
+
+#
+# Trace trap
+#
+       .align  2
+Xtracep:
+       pushl   $0                      # push dummy code value
+       pushl   $TRCTRAP                # push type value
+       brw     alltraps                # go do it
+
+#
+# Arithmetic trap
+#
+       .align  2
+Xarithtrap:
+       pushl   $ARITHTRAP              # push type value
+       brw     alltraps                # merge with common code
+
+#
+# Protection and segmentation fault
+#
+       .align  2
+Xprotflt:
+       blbs    (sp),segflt             # check for pt length violation
+       addl2   $4,sp                   # pop fault param word 
+       pushl   $PROTFLT
+       brw     alltraps
+
+#
+# Segmentation fault
+#
+segflt:
+       addl2   $4,sp
+       pushl   $SEGFLT
+       brb     alltraps
+
+#
+# Translation Not Valid Fault
+#
+       .align  2
+Xtransflt:
+       bbs     $1,(sp),tableflt        # check for page table fault
+       addl2   $4,sp                   # pop fault parameter word
+       pushl   $PAGEFLT                # push type value
+       bbs     $31,4(sp),alltraps      # is faulting address in kernel
+       brb     usrtraps                # page faults in user space
+                                       # even in kernel mode are ok
+#
+# Page table fault
+#
+tableflt: 
+       addl2   $4,sp                   # pop fault parameter word
+       pushl   $TABLEFLT               # push type value
+       cmpl    _end,4(sp)              # cannot tolerate sysmap faults
+       bgequ   alltraps
+       brb     usrtraps                # a table fault on a user page
+                                       # table in kernel mode is ok
+
+#
+# CHMK trap (syscall trap)
+#
+# Kernel stack on entry:
+#
+#      code    <- ksp
+#      pc
+#      psl
+#
+#
+# Stack (parameters) at calls to _trap:
+#
+#      ap      <- ksp
+#      r0
+#      ...
+#      r13
+#      usp
+#      type
+#      code
+#      pc
+#      psl
+#
+       .align  2
+Xsyscall:
+       pushl   $SYSCALL                # push type value
+alltraps:
+       bitl    $PSL_CURMOD,12(sp)      # from user mode?
+       beql    sysc1                   # no
+#
+# Prepare arguments to _trap.  Note that type has already been pushed.
+#
+usrtraps:
+       mfpr    $USP,-(sp)              # get usp
+       pushr   $0x3fff                 # registers 0 - 13
+       pushl   ap                      # ptr to syscall parameters
+#
+# Call _trap with wrong number of arguments
+# so args not popped by ret.
+#
+       calls   $1,_trap
+#
+# Restore
+#
+       popr    $0x3fff                 # restore regs 0 - 13
+       mtpr    (sp)+,$USP              # restore usp
+ignresch:
+       addl2   $8,sp                   # pop type, code
+       mtpr    $HIGH,$IPL              # make sure we are not going to
+                                       # a higher IPL
+       rei
+
+#
+# ``Trap from kernel mode'' -- one special case here is to ignore
+#      RESCHED traps which happen in the kernel... these happen only
+#      when a clock interrupt occured before the RESCHED AST could
+#      be delivered, and the clock interrupt lowered the ipl, usually
+#      because the addupc() in clock page faulted because the running
+#      process was profiling.  In this case we are context switching
+#      away from the current process anyways, so ignoring the RESCHED
+#      trap is the right thing to do.
+#
+sysc1:
+       cmpl    (sp),$RESCHED           # spurious RESCHED traps from kernel
+       beql    ignresch                # ... can be ignored
+       movab   emsg1,eptr              # set message pointer
+       brb     err_print               # print message and halt
+
+#
+# err_print
+#      print message on console and die
+#      message pointed to by eptr, terminated by zero byte.
+#
+err_print:
+       mtpr    $HIGH,$IPL              # disable all interrupts
+       mtpr    $0,$TXCS                # dis. interrupts on cons. xmtr.
+eloop1:
+       mfpr    $TXCS,ewk1              # get transmitter status
+       bbc     $TXCS_BRDY,ewk1,eloop1  # loop if not ready to transmit
+       tstb    *eptr                   # end of message?
+       beql    eout                    # yes, out of loop
+       movzbl  *eptr,ewk1              # get byte of message
+       incl    eptr                    # bump pointer
+       mtpr    ewk1,$TXDB              # give byte to transmitter
+       brb     eloop1                  # loop
+eout:
+       halt
+
+       .data
+eptr:  .long   0
+ewk1:  .long   0
+       .text
+
+# ==============
+# Initialization
+# ==============
+#
+#      IPL == 1F
+#      MAPEN == off
+#      SCBB, PCBB not set
+#      SBR, SLR not set
+#      ISP, KSP not set
+#
+       .globl  start
+start:
+       .word   0x0000
+       mtpr    $HIGH,$IPL              # no interrupts yet
+       mtpr    $Scbbase,$SCBB          # set SCBB
+       mtpr    $_Sysmap,$SBR           # set SBR
+       mtpr    $Syssize,$SLR           # set SLR
+       mtpr    $_Sysmap,$P0BR          # set temp P0BR
+       mtpr    $Syssize,$P0LR          # set temp P0LR
+       movl    $_intstack+2048,sp      # set ISP
+#
+# Initialize I/O adapters.
+#
+       movl    $1,PHYSMBA0+4           # init & interrupt enable
+       movl    $4,PHYSMBA0+4           # init & interrupt enable
+       movl    $1,PHYSMBA1+4           # init & interrupt enable
+       movl    $4,PHYSMBA1+4           # init & interrupt enable
+       movl    $1,PHYSUBA+4            # init & interrupt enable
+       movl    $0x78,PHYSUBA+4         # init & interrupt enable
+
+       movl    Scbbase+MCKVEC,r5       # save machine check entry
+       movab   startint+INTSTK,Scbbase+MCKVEC  # set new vector address
+#
+# Will now see how much memory there really is
+# in 64kb chunks.  Save number of bytes in r7.
+#
+       mtpr    $HIGH-1,$IPL            # allow machine check interrupts
+       clrl    r7
+startlp:
+       tstl    (r7)                    # this chunk really there?
+       acbl    $8096*1024-1,$64*1024,r7,startlp        # loop till mach check
+       brb     startint                # full load of memory
+
+       .align  2
+startint:
+       mtpr    $0,$SBIFS               # clear sbi fault status
+       movl    r5,Scbbase+MCKVEC       # restore machine check vector
+       movl    $_intstack+2048,sp      # reset interrupt stack pointer
+#
+# calculate size of cmap[] based on available memory, and allocate space for it
+#
+       movab   _end,r5
+       movl    r5,_cmap
+       bbss    $31,_cmap,cm0
+cm0:
+       subl3   r5,r7,r1
+       divl2   $(NBPG*CLSIZE)+CMSIZE,r1
+       mull2   $CMSIZE,r1
+       addl3   _cmap,r1,_ecmap
+#
+# Clear memory starting with kernel bss
+#
+       movab   _edata,r6
+       movab   _ecmap,r5               # clear to end of cmap[]
+strtclr:
+       clrq    (r6)
+       acbl    r5,$8,r6,strtclr
+
+#
+# Initialize system page table
+#
+       movab   _etext+NBPG-1,r1        # end of kernel text segment
+       bbcc    $31,r1,strt1            # turn off high order bit
+strt1:
+       ashl    $-9,r1,r1               # last page of kernel text
+       clrl    r2                      # point at first kernel text page
+strtlp1:
+       bisl3   $PG_V|PG_KR,r2,_Sysmap[r2]      # initialize page table entry
+       aoblss  r1,r2,strtlp1           # fill text entries
+       addl3   _ecmap,$NBPG-1,r1       # end of cmap[]
+       bbcc    $31,r1,strt2            # turn off high order bit
+strt2:
+       ashl    $-9,r1,r1               # last page of kernel data
+strtlp2:
+       bisl3   $PG_V|PG_KW,r2,_Sysmap[r2]      # fill data entries
+       aoblss  r1,r2,strtlp2
+#
+# initialize memory controller mapping
+#
+       .set    PHYSMCR,0x20002000
+       movl    $PHYSMCR/NBPG,r1
+       movab   _Sysmap+mcr_offset,r2
+       bisl3   $PG_V|PG_KW,r1,(r2)
+#
+# Initialize I/O space page table entries
+#
+       movl    $PHYSUBA/NBPG,r1        # page frame number for uba
+       movab   _Sysmap+uba_offset,r2   # page table address
+       movab   15(r1),r3               # last pt entry
+strtlp3:
+       bisl3   $PG_V|PG_KW,r1,(r2)+    # init pt entry
+       aobleq  r3,r1,strtlp3
+       movl    $PHYSUMEM/NBPG,r1
+       movab   _Sysmap+umem_offset,r2  # page table address
+       movab   15(r1),r3               # limit
+strtlp4:
+       bisl3   $PG_V|PG_KW,r1,(r2)+
+       aobleq  r3,r1,strtlp4
+       movl    $PHYSMBA0/NBPG,r1
+       movab   _Sysmap+mba0_offset,r2
+       movab   15(r1),r3
+strtlp5:
+       bisl3   $PG_V|PG_KW,r1,(r2)+
+       aobleq  r3,r1,strtlp5
+       movl    $PHYSMBA1/NBPG,r1
+       movab   _Sysmap+mba1_offset,r2
+       movab   15(r1),r3
+strtlp6:
+       bisl3   $PG_V|PG_KW,r1,(r2)+
+       aobleq  r3,r1,strtlp6
+
+       mtpr    $1,$TBIA                # invalidate all trans buffer entries
+       mtpr    $1,$MAPEN               # turn on memory mapping
+       jmp     *$startmap              # put system virtual address in pc
+#
+# Now we move forward, virtually.
+#
+startmap:
+       ashl    $-9,r7,_maxmem          # set maxmem = btoc(r7)
+       movl    _maxmem,_physmem
+       movl    _maxmem,_freemem
+
+#
+# Setup context for proc[0] == Scheduler
+#
+# Address first page past _ecmap.
+# This will be u area for proc[0].
+# Initialize u area page table entries.
+# Initialize (slightly) the pcb.
+#
+       addl3   _ecmap,$NBPG-1,r6
+       bicl2   $NBPG-1,r6              # make page boundary
+#
+# set up u area page table
+#
+       bbcc    $31,r6,strt3
+strt3:
+       ashl    $-9,r6,r3                       # r3 = btoc(r6)
+       bisl3   $PG_V|PG_KW,r3,_Sysmap+u_ptoffset       # init first upt entry
+       movab   _u,r1                           # point at _u area
+       mtpr    r1,$TBIS
+       movab   UPAGES*NBPG(r1),PCB_KSP(r1)     # init ksp
+       mnegl   $1,PCB_ESP(r1)                  # invalidate esp
+       mnegl   $1,PCB_SSP(r1)                  # invalidate ssp
+       movl    $0x80000000,PCB_USP(r1)         # set user sp
+# The shape of the following computation is historical...
+# P0BR and P1BR should CLSIZE*NBPG bytes apart,
+# otherwise their values are irrelevant.
+       movab   _u+UPAGES*NBPG,PCB_P0BR(r1)     # p0 page table pointer
+       clrl    PCB_P0LR(r1)                    # size zero page table
+       movb    $4,PCB_P0LR+3(r1)               # disable ast
+       movab   _u+(UPAGES+CLSIZE)*NBPG-0x800000,PCB_P1BR(r1)   # p1 pt pointer
+       movl    $0x200000,PCB_P1LR(r1)          # invalid p1 pt length
+       movl    $CLSIZE,PCB_SZPT(r1)            # init u.u_pcb.pcb_szpt
+       movl    $1,r2
+strt5:
+       incl    r3
+       bisl3   $PG_V|PG_KW,r3,_Sysmap+u_ptoffset[r2]
+       addl2   $NBPG,r1
+       mtpr    r1,$TBIS
+       aoblss  $UPAGES,r2,strt5
+
+       mtpr    r6,$PCBB                        # first pcb
+#
+# set regs, p0br, p0lr, p1br, p1lr, 
+# astlvl, ksp, and change to kernel mode
+#
+       ldpctx          
+       addl2   $8,sp                           # pop dummy pc, psl
+       mtpr    $0,$IPL                         # enable interrupts
+       addl3   _ecmap,$NBPG-1,r0               # calculate firstaddr
+       bbcc    $31,r0,strt4
+strt4:
+       ashl    $-9,r0,-(sp)                    # convert to clicks and stack
+       calls   $1,_main                        # startup, fork off /etc/init.vm
+#
+# proc[1] == /etc/init now running here.
+# execute code at location 0, in user mode.
+#
+       pushl   $PSL_CURMOD|PSL_PRVMOD          # psl, user mode, ipl = 0
+       pushl   $0                              # pc, $location 0
+       rei                                     # do /etc/init.vm
+
+# ==========
+# Primitives
+# ==========
+
+_addupc:       .globl  _addupc
+       .word   0x0000
+       movl    8(ap),r2                # &u.u_prof
+       subl3   8(r2),4(ap),r0          # corrected pc
+       blss    addret
+       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    addret
+       incl    r0
+       bicb2   $1,r0
+       blss    addret
+       cmpl    r0,4(r2)                # length
+       bgequ   addret
+       addl2   (r2),r0                 # base
+       probew  $3,$2,(r0)
+       beql    adderr
+       addw2   12(ap),(r0)
+addret:
+       ret
+adderr:
+       clrl    12(r2)
+       ret
+
+_fubyte:       .globl  _fubyte
+_fuibyte:      .globl  _fuibyte
+       .word   0x0000
+       prober  $3,$1,*4(ap)            # byte accessible ?
+       beql    eret                    # no
+       movzbl  *4(ap),r0
+       ret
+
+_subyte:       .globl  _subyte
+_suibyte:      .globl  _suibyte
+       .word   0x0000
+       probew  $3,$1,*4(ap)            # byte accessible ?
+       beql    eret                    # no
+       movb    8(ap),*4(ap)
+       clrl    r0
+       ret
+
+_fuword:       .globl  _fuword
+_fuiword:      .globl  _fuiword
+       .word   0x0000
+       prober  $3,$4,*4(ap)
+       beql    eret
+       movl    *4(ap),r0
+       ret
+
+_suword:       .globl  _suword
+_suiword:      .globl  _suiword
+       .word   0x0000
+       probew  $3,$4,*4(ap)
+       beql    eret
+       movl    8(ap),*4(ap)
+       clrl    r0
+       ret
+eret:
+       mnegl   $1,r0                   # error return
+       ret
+
+_copyin:       .globl  _copyin
+       .word   0x0000
+       movl    12(ap),r0               # copy length
+       blss    eret
+       movl    4(ap),r1                # copy user address
+       cmpl    $NBPG,r0                # probing one page or less ?
+       bgeq    cishort                 # yes
+ciloop:
+       prober  $3,$NBPG,(r1)           # bytes accessible ?
+       beql    eret                    # no
+       addl2   $NBPG,r1                # incr user address ptr
+       acbl    $NBPG+1,$-NBPG,r0,ciloop        # reduce count and loop
+cishort:
+       prober  $3,r0,(r1)              # bytes accessible ?
+       beql    eret                    # no
+       movc3   12(ap),*4(ap),*8(ap)
+       clrl    r0
+       ret
+
+_copyout:      .globl  _copyout
+       .word   0x0000
+       movl    12(ap),r0               # get count
+       blss    eret
+       movl    8(ap),r1                # get user address
+       cmpl    $NBPG,r0                # can do in one probew?
+       bgeq    coshort                 # yes
+coloop:
+       probew  $3,$NBPG,(r1)           # bytes accessible?
+       beql    eret                    # no 
+       addl2   $NBPG,r1                # increment user address
+       acbl    $NBPG+1,$-NBPG,r0,coloop        # reduce count and loop
+coshort:
+       probew  $3,r0,(r1)              # bytes accessible?
+       beql    eret                    # no
+       movc3   12(ap),*4(ap),*8(ap)
+       clrl    r0
+       ret
+
+_idle: .globl  _idle
+       .word   0x0000
+       mtpr    $0,$IPL                 # enable interrupts
+waitloc:
+       blbc    idleflag,waitloc        # loop until interrupt
+ewaitloc:
+       bbcci   $0,idleflag,idle1       # clear idle escape flag
+idle1:
+       ret
+       .data
+       .globl  _waitloc
+       .globl  _ewaitloc
+       .align  2
+_waitloc:      .long   waitloc
+_ewaitloc:     .long   ewaitloc
+idleflag:      .long   0
+       .text
+
+#
+# save(save_area)
+#
+# Save reg's and ret loc into save area - return 0.
+# The contents of CMAP2 will be saved in the soft pcb extension.
+#
+       .globl  _save
+_save:
+       .word   0x0
+       mtpr    $HIGH,$IPL
+       movl    _Sysmap+CMAP2,_u+PCB_CMAP2      # save copyseg mapping
+       movl    4(ap),r0                # save area addr
+       movab   3*4(ap),sp              # restore stack to val before call
+       movl    8(fp),ap                # restore ap    "       "       "
+       movl    16(fp),r1               # restore pc    "       "       "
+       movl    12(fp),fp               # restore fp    "       "       "
+       movq    r6,(r0)+
+       movq    r8,(r0)+
+       movq    r10,(r0)+
+       movq    ap,(r0)+                # ap & fp
+       movl    sp,(r0)+
+       movl    r1,(r0)+                # ret loc of call to 'save'
+       movpsl  -(sp)
+       pushl   r1
+       svpctx                          # save reg's -> PCB
+       movpsl  -(sp)                   # set up for return
+       bicl2   $PSL_IS|PSL_IPL,(sp)    # undo SVPCTX
+       pushl   r1                      # ret loc
+       clrl    r0                      # return val
+       rei
+
+#
+# resume(proc_addr, save_addr)
+#
+# Switch to another process's '_u' area - return val 1
+# restores CMAP2 contents from from software pcb
+#
+       .globl  _resume
+_resume :      
+       .word   0x0
+       mtpr    $HIGH,$IPL              # inhibit interrupts
+       movl    8(ap),retloc
+# map u-area
+       clrl    r0
+       movab   _u,r1
+       movl    4(ap),r2
+res1:  cvtwl   (r2)[r0],r3             # get u click number from proc
+       bisl3   $PG_V|PG_KW,r3,_Umap[r0]
+       mtpr    r1,$TBIS
+       addl2   $NBPG,r1
+       aoblss  $UPAGES,r0,res1
+
+# restore CMAP2 contents for copyseg
+       movl    _u+PCB_CMAP2,_Sysmap+CMAP2
+       mtpr    $CADDR2,$TBIS
+
+       movl    _u,sp                   # KSP from u-area
+       ashl    $9,_Umap,r5             # pcb address
+       mtpr    r5,$PCBB
+       ldpctx
+       addl2   $8,sp                   # clear ps,pc from stack
+
+       movl    retloc,r1               # 'ssav' or 'qsav' addr
+       movq    (r1)+,r6
+       movq    (r1)+,r8
+       movq    (r1)+,r10
+       movq    (r1)+,ap
+       movl    (r1)+,sp
+       movl    $1,r0                   # return val
+       mtpr    $0,$IPL
+       jmp     *(r1)+                  # return to caller at 'save' address
+
+       .data
+       .align  2
+retloc:        .space  1*4
+       .text
+
+#
+# Disable interrupts
+#
+_spl1: .globl  _spl1
+       .word   0x0000
+       mfpr    $IPL,r0                 # get IPL value
+       mtpr    $2,$IPL                 # disable RESCHED & AST interrupts
+       ret
+
+_spl4: .globl  _spl4
+       .word   0x0000
+       mfpr    $IPL,r0
+       mtpr    $0x14,$IPL              # disable bus level 4 interrupts
+       ret
+
+_spl5: .globl  _spl5
+       .word   0x0000
+       mfpr    $IPL,r0
+       mtpr    $0x15,$IPL              # disable bus level 5 interrupts
+       ret
+
+_spl6: .globl  _spl6
+_spl7: .globl  _spl7
+       .word   0x0000
+       mfpr    $IPL,r0
+       mtpr    $0x18,$IPL              # disable bus level 7 and clock ints
+       ret
+
+#
+# enable interrupts
+#
+_spl0: .globl  _spl0
+       .word   0x0000
+       mfpr    $IPL,r0
+       mtpr    $0,$IPL
+       ret
+
+#
+# restore interrupt state
+#
+_splx: .globl  _splx
+       .word   0x0000
+       mfpr    $IPL,r0
+       mtpr    4(ap),$IPL
+       ret
+
+#
+# Copy 1 relocation unit (NBPG bytes)
+# from user virtual address to physical address
+#
+_copyseg:      .globl  _copyseg
+       .word   0x0000
+       mfpr    $IPL,r0         # get current pri level
+       mtpr    $HIGH,$IPL      # turn off interrupts
+       bisl3   $PG_V|PG_KW,8(ap),_Sysmap+CMAP2
+       mtpr    $CADDR2,$TBIS   # invalidate entry for copy 
+       movc3   $NBPG,*4(ap),CADDR2
+       bicl3   $PG_V|PG_M|PG_KW,_Sysmap+CMAP2,r1
+       cmpl    r1,8(ap)
+       beql    okcseg
+badcseg:
+       halt
+       jmp     badcseg
+okcseg:
+       mtpr    r0,$IPL         # restore pri level
+       ret
+
+#
+# zero out physical memory
+# specified in relocation units (NBPG bytes)
+#
+_clearseg:     .globl  _clearseg
+       .word   0x0000
+       mfpr    $IPL,r0         # get current pri level
+       mtpr    $HIGH,$IPL      # extreme pri level
+       bisl3   $PG_V|PG_KW,4(ap),_Sysmap+CMAP1
+       mtpr    $CADDR1,$TBIS
+       movc5   $0,(sp),$0,$NBPG,CADDR1
+       mtpr    r0,$IPL         # restore pri level
+       ret
+
+#
+# Check address.
+# Given virtual address, byte count, and rw flag
+# returns 0 on no access.
+#
+_useracc:      .globl  _useracc
+       .word   0x0000
+       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
+       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
+       ret
+uaerr:
+       clrl    r0
+       ret
+
+#
+# kernacc - check for kernel access privileges
+#
+# We can't use the probe instruction directly because
+# it ors together current and previous mode.
+#
+       .globl  _kernacc
+_kernacc:
+       .word   0x0000
+       movl    4(ap),r0        # virtual address
+       bbcc    $31,r0,kacc1
+       mfpr    $SBR,r2         # address and length of page table (system)
+       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
+       ashl    $-9,r0,r0       # page number
+       ashl    $-9,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
+       bgeq    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:
+       aobleq  r1,r0,kacc4     # next page
+       movl    $1,r0           # no errors
+       ret
+kacerr:
+       clrl    r0              # error
+       ret
+
+#
+# unsigned int divide:
+#      (int) i = udiv( (int)dvdnd , (int) divis)
+#
+#  unsigned int remainder:
+#      (int) j = urem( (int)dvdnd , (int) divis)
+#
+       .text
+       .align  1
+       .globl  _udiv
+_udiv :
+       .word   0                       # no reg save
+       movl    4(ap),r0                # dividend
+       clrl    r1
+       ediv    8(ap),r0,r0,r1          # quotient in r0
+       ret
+
+#      .globl  _urem
+#      .align  1
+#_urem:
+#      .word   0
+#      movl    4(ap),r0
+#      clrl    r1
+#      ediv    8(ap),r0,r1,r0          #  remainder in r0
+#      ret
+
+# ==============
+# Error messages
+# ==============
+
+       .data
+emsg1: .asciz  "\nTrap from kernel mode\n\r"
+SBImsg: .asciz "SBI fault\n"
+UBAmsg: .asciz "UBA error UBASR %X, FMER %X, FUBAR %X\n"
+ZERmsg: .asciz "Zero vector\n"
+straym: .asciz "Stray interrupt\n"
+
+# these should be memall'ed
+       .data
+       .globl _buffers
+       .align  PGSHIFT
+_buffers:      .space NBUF*BSIZE