- addl a5,a4
-/* allocate kernel segment table */
- RELOC(_Sysseg, a0)
- movl d5,a0@ | remember VA for pmap module
- movl a4,sp@- | remember PA for loading MMU
- addl #NBPG,a4
- addl #NBPG,d5
-/* allocate initial page table pages (including internal IO map) */
- RELOC(_Sysptsize, a0)
- movl a0@,d0 | initial system PT size (pages)
- addl #(IIOMAPSIZE+EIOMAPSIZE+NPTEPG-1)/NPTEPG,d0
- | add pages for IO maps
- movl #PGSHIFT,d1
- lsll d1,d0 | convert to bytes
- movl a4,sp@- | remember PA for ST load
- addl d0,a4
- addl d0,d5
-/* allocate kernel page table map */
- RELOC(_Sysptmap, a0)
- movl d5,a0@ | remember VA for pmap module
- movl a4,sp@- | remember PA for PT map load
- addl #NBPG,a4
- addl #NBPG,d5
-/* compute KVA of Sysptmap; mapped after page table pages */
- movl d0,d2 | remember PT size (bytes)
- moveq #SG_ISHIFT-PGSHIFT,d1
- lsll d1,d0 | page table size serves as seg index
- RELOC(_Sysmap, a0)
- movl d0,a0@ | remember VA for pmap module
-/* initialize ST and PT map: PT pages + PT map */
- movl sp@+,a1 | PT map PA
- movl sp@+,d4 | start of PT pages
- movl sp@+,a0 | ST phys addr
- lea a0@(NBPG-4),a2 | (almost) end of ST
- movl d4,d3
- orl #SG_RW+SG_V,d4 | create proto STE for ST
- orl #PG_RW+PG_CI+PG_V,d3 | create proto PTE for PT map
-List1:
- movl d4,a0@+
- movl d3,a1@+
- addl #NBPG,d4
- addl #NBPG,d3
- cmpl a4,d4 | sleezy, but works ok
- jcs List1
-/* initialize ST and PT map: invalidate up to last entry */
-List2:
- movl #SG_NV,a0@+
- movl #PG_NV,a1@+
- cmpl a2,a0
- jcs List2
-/*
- * Portions of the last segment of KVA space (0xFFF00000 - 0xFFFFFFFF)
- * are mapped for a couple of purposes. 0xFFF00000 for UPAGES is used
- * for mapping the current process u-area (u + kernel stack). The
- * very last page (0xFFFFF000) is mapped to the last physical page of
- * RAM to give us a region in which PA == VA. We use this page for
- * enabling/disabling mapping.
- */
- movl a4,d1 | grab next available for PT page
- andl #SG_FRAME,d1 | mask to frame number
- orl #SG_RW+SG_V,d1 | RW and valid
- movl d1,a0@+ | store in last ST entry
- movl a0,a2 | remember addr for PT load
- andl #PG_FRAME,d1
- orl #PG_RW+PG_V,d1 | convert to PTE
- movl d1,a1@+ | store in PT map
- movl a4,a0 | physical beginning of PT page
- lea a0@(NBPG-4),a1 | (almost) end of page
-Lispt7:
- movl #PG_NV,a0@+ | invalidate
- cmpl a1,a0
- jcs Lispt7
- movl #MAXADDR,d1 | get last phys page addr
- andl #PG_FRAME,d1
- orl #PG_RW+PG_V,d1
- movl d1,a0@+ | map to last virt page
- addl #NBPG,a4
- addl #NBPG,d5
-/* record KVA at which to access current u-area PTEs */
- RELOC(_Sysmap, a0)
- movl a0@,d0 | get system PT address
- addl #NPTEPG*NBPG,d0 | end of system PT
- subl #HIGHPAGES*4,d0 | back up to first PTE for u-area
- RELOC(_Umap, a0)
- movl d0,a0@ | remember location
-/* initialize page table pages */
- movl a2,a0 | end of ST is start of PT
- addl d2,a2 | add size to get end of PT
-/* text pages are read-only */
- clrl d0 | assume load at VA 0
- movl a5,d1 | get load PA
- andl #PG_FRAME,d1 | convert to a page frame
-#ifdef KGDB
- orl #PG_RW+PG_V,d1 | XXX: RW for now
-#else
- orl #PG_RO+PG_V,d1 | create proto PTE
-#endif
- movl #_etext,a1 | go til end of text
-Lipt1:
- movl d1,a0@+ | load PTE
- addl #NBPG,d1 | increment page frame number
- addl #NBPG,d0 | and address counter
- cmpl a1,d0 | done yet?
- jcs Lipt1 | no, keep going
-/* data, bss and dynamic tables are read/write */
- andl #PG_FRAME,d1 | mask out old prot bits
- orl #PG_RW+PG_V,d1 | mark as valid and RW
- movl d5,a1 | go til end of data allocated so far
- addl #(UPAGES+1)*NBPG,a1 | and proc0 PT/u-area (to be allocated)
-Lipt2:
- movl d1,a0@+ | load PTE
- addl #NBPG,d1 | increment page frame number
- addl #NBPG,d0 | and address counter
- cmpl a1,d0 | done yet?
- jcs Lipt2 | no, keep going
-/* invalidate remainder of kernel PT */
- movl a2,a1 | end of PT
-Lipt3:
- movl #PG_NV,a0@+ | invalidate PTE
- cmpl a1,a0 | done yet?
- jcs Lipt3 | no, keep going
-/* go back and validate internal IO PTEs at end of allocated PT space */
- movl a2,a0 | end of allocated PT space
- subl #(IIOMAPSIZE+EIOMAPSIZE)*4,a0 | back up IOMAPSIZE PTEs
- subl #EIOMAPSIZE*4,a2 | only initialize internal IO PTEs
- movl #INTIOBASE,d1 | physical internal IO base
- orl #PG_RW+PG_CI+PG_V,d1 | create proto PTE
-Lipt4:
- movl d1,a0@+ | load PTE
- addl #NBPG,d1 | increment page frame number
- cmpl a2,a0 | done yet?
- jcs Lipt4 | no, keep going
-/* record base KVA of IO spaces which are just before Sysmap */
- RELOC(_Sysmap, a0)
- movl a0@,d0 | Sysmap VA
- subl #EIOMAPSIZE*NBPG,d0 | back up size of external IO space
- RELOC(_extiobase, a0)
- movl d0,a0@ | and record
- RELOC(_intiolimit, a0)
- movl d0,a0@ | external base is also internal limit
- subl #IIOMAPSIZE*NBPG,d0 | back up size of internal IO space
- RELOC(_intiobase, a0)
- movl d0,a0@ | and record
-/* also record base of clock and MMU registers for fast access */
- addl #CLKBASE,d0
- RELOC(_CLKbase, a0)
- movl d0,a0@
- subl #CLKBASE,d0
- addl #MMUBASE,d0
- RELOC(_MMUbase, a0)
- movl d0,a0@
-
-/*
- * Setup page table for process 0.
- *
- * We set up page table access for the kernel via Usrptmap (usrpt)
- * and access to the u-area itself via Umap (u). First available
- * page (VA: d5, PA: a4) is used for proc0 page table. Next UPAGES
- * pages following are for u-area.
- */
- movl a4,d0
- movl d0,d1
- andl #PG_FRAME,d1 | mask to page frame number
- orl #PG_RW+PG_V,d1 | RW and valid
- movl d1,d4 | remember for later Usrptmap load
- movl d0,a0 | base of proc0 PT
- addl #NBPG,d0 | plus one page yields base of u-area
- movl d0,a2 | and end of PT
- addl #NBPG,d5 | keep VA in sync
-/* invalidate entire page table */
-Liudot1:
- movl #PG_NV,a0@+ | invalidate PTE
- cmpl a2,a0 | done yet?
- jcs Liudot1 | no, keep going
-/* now go back and validate u-area PTEs in PT and in Umap */
- lea a0@(-HIGHPAGES*4),a0 | base of PTEs for u-area (p_addr)
- lea a0@(UPAGES*4),a1 | end of PTEs for u-area
- lea a4@(-HIGHPAGES*4),a3 | u-area PTE base in Umap PT
- movl d0,d1 | get base of u-area
- andl #PG_FRAME,d1 | mask to page frame number
- orl #PG_RW+PG_V,d1 | add valid and writable
-Liudot2:
- movl d1,a0@+ | validate p_addr PTE
- movl d1,a3@+ | validate u PTE
- addl #NBPG,d1 | to next page
- cmpl a1,a0 | done yet?
- jcs Liudot2 | no, keep going
-/* clear process 0 u-area */
- addl #NBPG*UPAGES,d0 | end of u-area
-Lclru1:
- clrl a2@+ | clear
- cmpl d0,a2 | done yet?
- jcs Lclru1 | no, keep going
- movl a2,a4 | save phys addr of first avail page
- RELOC(_proc0paddr, a0)
- movl d5,a0@ | save KVA of proc0 u-area
- addl #UPAGES*NBPG,d5 | increment virtual addr as well