BSD 4_3_Net_2 release
[unix-history] / usr / src / sys / i386 / i386 / machdep.c
index 17ea7e4..c525c34 100644 (file)
@@ -5,34 +5,65 @@
  * This code is derived from software contributed to Berkeley by
  * William Jolitz.
  *
  * This code is derived from software contributed to Berkeley by
  * William Jolitz.
  *
- * %sccs.include.386.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
  *
- *     @(#)machdep.c   5.7 (Berkeley) %G%
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)machdep.c   7.4 (Berkeley) 6/3/91
  */
 
  */
 
+
 #include "param.h"
 #include "systm.h"
 #include "param.h"
 #include "systm.h"
-#include "user.h"
+#include "signalvar.h"
 #include "kernel.h"
 #include "map.h"
 #include "kernel.h"
 #include "map.h"
-#include "vm.h"
 #include "proc.h"
 #include "proc.h"
+#include "user.h"
 #include "buf.h"
 #include "reboot.h"
 #include "conf.h"
 #include "file.h"
 #include "buf.h"
 #include "reboot.h"
 #include "conf.h"
 #include "file.h"
-#include "text.h"
 #include "clist.h"
 #include "callout.h"
 #include "clist.h"
 #include "callout.h"
-#include "cmap.h"
+#include "malloc.h"
 #include "mbuf.h"
 #include "msgbuf.h"
 #include "net/netisr.h"
 
 #include "mbuf.h"
 #include "msgbuf.h"
 #include "net/netisr.h"
 
-#include "machine/frame.h"
+#include "vm/vm.h"
+#include "vm/vm_kern.h"
+#include "vm/vm_page.h"
+
+vm_map_t buffer_map;
+extern vm_offset_t avail_end;
+
+#include "machine/cpu.h"
 #include "machine/reg.h"
 #include "machine/reg.h"
-#include "machine/segments.h"
-#include "machine/pte.h"
 #include "machine/psl.h"
 #include "machine/specialreg.h"
 #include "i386/isa/rtc.h"
 #include "machine/psl.h"
 #include "machine/specialreg.h"
 #include "i386/isa/rtc.h"
@@ -56,10 +87,9 @@ int  msgbufmapped;           /* set when safe to use msgbuf */
 /*
  * Machine-dependent startup code
  */
 /*
  * Machine-dependent startup code
  */
-extern char    Sysbase[];
-/* extern struct pte   EMCmap[];
-extern char            EMCbase[]; */
 int boothowto = 0, Maxmem = 0;
 int boothowto = 0, Maxmem = 0;
+long dumplo;
+int physmem, maxmem;
 extern int bootdev;
 #ifdef SMALL
 extern int forcemaxmem;
 extern int bootdev;
 #ifdef SMALL
 extern int forcemaxmem;
@@ -68,14 +98,7 @@ int biosmem;
 
 extern cyloffset;
 
 
 extern cyloffset;
 
-caddr_t bypasshole(b,t) caddr_t b,t; {
-
-       if (b <= Sysbase + 0xa0000 && t > Sysbase + 0xa0000)
-               return(Sysbase + 0x100000);
-       return(b);
-}
-
-startup(firstaddr)
+cpu_startup(firstaddr)
        int firstaddr;
 {
        register int unixsize;
        int firstaddr;
 {
        register int unixsize;
@@ -84,77 +107,19 @@ startup(firstaddr)
        int mapaddr, j;
        register caddr_t v;
        int maxbufs, base, residual;
        int mapaddr, j;
        register caddr_t v;
        int maxbufs, base, residual;
-       extern struct map *useriomap;
-
-       /*
-        * Initialize the console before we print anything out.
-        */
-       /*cninit();*/
-
-       /*
-        * Bounds check memory size information against bios values
-        * use the lesser of the two
-        */
-       biosmem = rtcin(RTC_BASELO)+ (rtcin(RTC_BASEHI)<<8);
-printf("Maxmem %x howto %x bootdev %x cyloff %x firstaddr %x bios %d %d\n",
-               Maxmem, boothowto, bootdev, cyloffset, firstaddr,
-biosmem, 
-rtcin(RTC_EXTLO) + (rtcin(RTC_EXTHI)<<8)
-);
-       maxmem = Maxmem-1;
-
-/*
-       if(biosmem != 640)
-               panic("does not have 640K of base memory");
-
-       biosmem = 1024;
-       biosmem += rtcin(RTC_EXTLO) + (rtcin(RTC_EXTHI)<<8);
-       biosmem = biosmem/4 - 1 ;
-       if (biosmem < maxmem) maxmem=biosmem;
-*/
-
-#ifdef SMALL
-if(forcemaxmem && maxmem > forcemaxmem)
-       maxmem = forcemaxmem-1;
-#endif
-/*
-maxmem = 0xA00;*/
+       extern long Usrptsize;
+       vm_offset_t minaddr, maxaddr;
+       vm_size_t size;
 
        /*
         * Initialize error message buffer (at end of core).
         */
 
        /*
         * Initialize error message buffer (at end of core).
         */
-/* Problem to resolve. AT's have memory that is not contigous, as
-I/O address space for video adapters and network cards fall into
-a range of 0xa0000 - 0x100000 . Note that the cmap really expects
-contigous memory. For the moment, use the bottom of memory for
-kernel and run-time configured storage (e.g. valloc), using memory
-above 0x100000 for the cmap, and wasting the stuff left over after
-valloc-end up to 0xa0000 (640K). Will have to fix this before beta,
-and will have to somehow move this out into per bus adapter directory
-(e.g. configurable). For now, punt
-
-How about starting cmap normally following valloc space, and then
-write a routine than allocs only phys pages in the 0xa0000-0x100000
-hole?
-
-Temporary fix for beta, if we only have 640K, then cmap follows valloc
-up to 640K.
-*/
-       maxmem -= btoc(sizeof (struct msgbuf));
-       pte = msgbufmap;
-       for (i = 0; i < btoc(sizeof (struct msgbuf)); i++)
-               *(int *)pte++ = PG_V | PG_KW | ctob(maxmem + i);
-
-#ifdef notdef
-       /* XXX EMC */
-       pte = EMCmap;
-       *(int *)pte = PG_V | PG_UW | 0xc0000000;
-       printf("EMC at %x\n", EMCbase);
-#endif
-
-       freemem = physmem = maxmem;
 
 
-       load_cr3(_cr3());
+       /* avail_end was pre-decremented in pmap_bootstrap to compensate */
+       for (i = 0; i < btoc(sizeof (struct msgbuf)); i++)
+               pmap_enter(pmap_kernel(), msgbufp, avail_end + i * NBPG,
+                          VM_PROT_ALL, TRUE);
+       msgbufmapped = 1;
 
 #ifdef KDB
        kdb_init();                     /* startup kernel debugger */
 
 #ifdef KDB
        kdb_init();                     /* startup kernel debugger */
@@ -175,26 +140,23 @@ up to 640K.
         * An index into the kernel page table corresponding to the
         * virtual memory address maintained in "v" is kept in "mapaddr".
         */
         * An index into the kernel page table corresponding to the
         * virtual memory address maintained in "v" is kept in "mapaddr".
         */
-       v = (caddr_t)(Sysbase + (firstaddr * NBPG));
-       /*v = sbase + (firstaddr * NBPG);*/
+
+       /*
+        * Make two passes.  The first pass calculates how much memory is
+        * needed and allocates it.  The second pass assigns virtual
+        * addresses to the various data structures.
+        */
+       firstaddr = 0;
+again:
+       v = (caddr_t)firstaddr;
+
 #define        valloc(name, type, num) \
 #define        valloc(name, type, num) \
-               v = bypasshole (v, v + (int) ((name)+(num))) ; \
            (name) = (type *)v; v = (caddr_t)((name)+(num))
 #define        valloclim(name, type, num, lim) \
            (name) = (type *)v; v = (caddr_t)((name)+(num))
 #define        valloclim(name, type, num, lim) \
-               v = bypasshole (v, v + (int) ((name)+(num))) ; \
            (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
            (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
-       valloclim(file, struct file, nfile, fileNFILE);
-       valloclim(proc, struct proc, nproc, procNPROC);
-       valloclim(text, struct text, ntext, textNTEXT);
        valloc(cfree, struct cblock, nclist);
        valloc(callout, struct callout, ncallout);
        valloc(cfree, struct cblock, nclist);
        valloc(callout, struct callout, ncallout);
-       valloc(swapmap, struct map, nswapmap = nproc * 2);
-       valloc(argmap, struct map, ARGMAPSIZE);
-       valloc(kernelmap, struct map, nproc);
-       valloc(mbmap, struct map, nmbclusters/4);
-       valloc(kmemmap, struct map, ekmempt - kmempt);
-       valloc(kmemusage, struct kmemusage, ekmempt - kmempt);
-       valloc(useriomap, struct map, nproc);
+       valloc(swapmap, struct map, nswapmap = maxproc * 2);
 #ifdef SYSVSHM
        valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
 #endif
 #ifdef SYSVSHM
        valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
 #endif
@@ -220,124 +182,83 @@ up to 640K.
                        nswbuf = 256;           /* sanity */
        }
        valloc(swbuf, struct buf, nswbuf);
                        nswbuf = 256;           /* sanity */
        }
        valloc(swbuf, struct buf, nswbuf);
-
-       /*
-        * Now the amount of virtual memory remaining for buffers
-        * can be calculated, estimating needs for the cmap.
-        */
-       ncmap = (maxmem*NBPG  - ((int)(v - Sysbase))) /
-               (CLBYTES + sizeof(struct cmap)) + 2;
-       maxbufs = ((SYSPTSIZE * NBPG) -
-               ((int)(v - Sysbase + ncmap * sizeof(struct cmap)))) /
-               (MAXBSIZE + sizeof(struct buf));
-       if (maxbufs < 16)
-               panic("sys pt too small");
-       if (nbuf > maxbufs) {
-               printf("SYSPTSIZE limits number of buffers to %d\n", maxbufs);
-               nbuf = maxbufs;
-       }
-       if (bufpages > nbuf * (MAXBSIZE / CLBYTES))
-               bufpages = nbuf * (MAXBSIZE / CLBYTES);
        valloc(buf, struct buf, nbuf);
 
        /*
        valloc(buf, struct buf, nbuf);
 
        /*
-        * Allocate space for core map.
-        * Allow space for all of physical memory minus the amount 
-        * dedicated to the system. The amount of physical memory
-        * dedicated to the system is the total virtual memory of
-        * the system thus far, plus core map, buffer pages,
-        * and buffer headers not yet allocated.
-        * Add 2: 1 because the 0th entry is unused, 1 for rounding.
+        * End of first pass, size has been calculated so allocate memory
         */
         */
-       /*ncmap = (maxmem*NBPG - ((int)((v - sbase) + bufpages*CLBYTES))) /*/
-       ncmap = (maxmem*NBPG - ((int)((v - Sysbase) + bufpages*CLBYTES))) /
-               (CLBYTES + sizeof(struct cmap)) + 2;
-       valloclim(cmap, struct cmap, ncmap, ecmap);
-
+       if (firstaddr == 0) {
+               size = (vm_size_t)(v - firstaddr);
+               firstaddr = (int)kmem_alloc(kernel_map, round_page(size));
+               if (firstaddr == 0)
+                       panic("startup: no room for tables");
+               goto again;
+       }
        /*
        /*
-        * Clear space allocated thus far, and make r/w entries
-        * for the space in the kernel map.
+        * End of second pass, addresses have been assigned
         */
         */
-       unixsize = btoc((int)(v - Sysbase));
-       while (firstaddr < unixsize) {
-               *(int *)(&Sysmap[firstaddr]) = PG_V | PG_KW | ctob(firstaddr);
-               clearseg((unsigned)firstaddr);
-               firstaddr++;
-       }
-
+       if ((vm_size_t)(v - firstaddr) != size)
+               panic("startup: table size inconsistency");
        /*
         * Now allocate buffers proper.  They are different than the above
         * in that they usually occupy more virtual memory than physical.
         */
        /*
         * Now allocate buffers proper.  They are different than the above
         * in that they usually occupy more virtual memory than physical.
         */
-       v = bypasshole (v, (caddr_t) ((int)(v + PGOFSET) &~ PGOFSET +
-               MAXBSIZE*nbuf));
-       v = (caddr_t) ((int)(v + PGOFSET) &~ PGOFSET);
-       valloc(buffers, char, MAXBSIZE * nbuf);
+       size = MAXBSIZE * nbuf;
+       buffer_map = kmem_suballoc(kernel_map, (vm_offset_t)&buffers,
+                                  &maxaddr, size, FALSE);
+       minaddr = (vm_offset_t)buffers;
+       if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t)0,
+                       &minaddr, size, FALSE) != KERN_SUCCESS)
+               panic("startup: cannot allocate buffers");
        base = bufpages / nbuf;
        residual = bufpages % nbuf;
        base = bufpages / nbuf;
        residual = bufpages % nbuf;
-       mapaddr = firstaddr = btoc((unsigned) buffers - (unsigned)Sysbase);
-       for (i = 0; i < residual; i++) {
-               for (j = 0; j < (base + 1) * CLSIZE; j++) {
-                       *(int *)(&Sysmap[mapaddr+j]) = PG_V | PG_KW | ctob(firstaddr);
-                       clearseg((unsigned)firstaddr);
-                       firstaddr++;
-               }
-               mapaddr += MAXBSIZE / NBPG;
-       }
-       for (i = residual; i < nbuf; i++) {
-               for (j = 0; j < base * CLSIZE; j++) {
-                       *(int *)(&Sysmap[mapaddr+j]) = PG_V | PG_KW | ctob(firstaddr);
-                       clearseg((unsigned)firstaddr);
-                       firstaddr++;
-               }
-               mapaddr += MAXBSIZE / NBPG;
-       }
-
-       unixsize = btoc((int)(v - Sysbase));
-       if (firstaddr >= physmem - 8*UPAGES)
-               panic("no memory");
+       for (i = 0; i < nbuf; i++) {
+               vm_size_t curbufsize;
+               vm_offset_t curbuf;
 
 
+               /*
+                * First <residual> buffers get (base+1) physical pages
+                * allocated for them.  The rest get (base) physical pages.
+                *
+                * The rest of each buffer occupies virtual space,
+                * but has no physical memory allocated for it.
+                */
+               curbuf = (vm_offset_t)buffers + i * MAXBSIZE;
+               curbufsize = CLBYTES * (i < residual ? base+1 : base);
+               vm_map_pageable(buffer_map, curbuf, curbuf+curbufsize, FALSE);
+               vm_map_simplify(buffer_map, curbuf);
+       }
        /*
        /*
-        * Initialize callouts
+        * Allocate a submap for exec arguments.  This map effectively
+        * limits the number of processes exec'ing at any time.
         */
         */
-       callfree = callout;
-       for (i = 1; i < ncallout; i++)
-               callout[i-1].c_next = &callout[i];
-
+       exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
+                                16*NCARGS, TRUE);
        /*
        /*
-        * Initialize memory allocator and swap
-        * and user page table maps.
-        *
-        * THE USER PAGE TABLE MAP IS CALLED ``kernelmap''
-        * WHICH IS A VERY UNDESCRIPTIVE AND INCONSISTENT NAME.
+        * Allocate a submap for physio
         */
         */
+       phys_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
+                                VM_PHYS_SIZE, TRUE);
 
        /*
 
        /*
-        *  cmap must not allocate the hole, so toss memory
+        * Finally, allocate mbuf pool.  Since mclrefcnt is an off-size
+        * we use the more space efficient malloc in place of kmem_alloc.
         */
         */
-       if(firstaddr < 640/4 && maxmem > 1024/4){
-               printf("[not using %dK due to hole]\n", 4*(640/4 - firstaddr));
-               firstaddr = 0x100;
-       }
-       if(maxmem < 2048/4-10)
-         printf("WARNING: NOT ENOUGH RAM MEMORY - RUNNING IN DEGRADED MODE\n");
+       mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES,
+                                  M_MBUF, M_NOWAIT);
+       bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES);
+       mb_map = kmem_suballoc(kernel_map, (vm_offset_t)&mbutl, &maxaddr,
+                              VM_MBUF_SIZE, FALSE);
+       /*
+        * Initialize callouts
+        */
+       callfree = callout;
+       for (i = 1; i < ncallout; i++)
+               callout[i-1].c_next = &callout[i];
 
 
-       meminit(firstaddr, maxmem);
-       maxmem = freemem;
-       printf("avail mem = %d\n", ctob(maxmem));
+       printf("avail mem = %d\n", ptoa(vm_page_free_count));
        printf("using %d buffers containing %d bytes of memory\n",
                nbuf, bufpages * CLBYTES);
        printf("using %d buffers containing %d bytes of memory\n",
                nbuf, bufpages * CLBYTES);
-       rminit(kernelmap, (long)USRPTSIZE, (long)1,
-           "usrpt", nproc);
-/*
- * PTEs for mapping user space into kernel for phyio operations.
- * One page is enough to handle 4Mb of simultaneous raw IO operations.
- */
-       rminit(useriomap, (long)USRIOSIZE, (long)1, "usrio", nproc);
-       rminit(mbmap, (long)(nmbclusters * CLSIZE), (long)CLSIZE,
-           "mbclusters", nmbclusters/4);
-       kmeminit();     /* now safe to do malloc/free */
-       /*intenable = 1;                /* Enable interrupts from now on */
 
        /*
         * Set up CPU-specific registers, cache, etc.
 
        /*
         * Set up CPU-specific registers, cache, etc.
@@ -347,8 +268,7 @@ up to 640K.
        /*
         * Set up buffers, so they can be used to read disk labels.
         */
        /*
         * Set up buffers, so they can be used to read disk labels.
         */
-       bhinit();
-       binit();
+       bufinit();
 
        /*
         * Configure the system.
 
        /*
         * Configure the system.
@@ -385,6 +305,8 @@ struct sigframe {
        struct  sigcontext sf_sc;
 } ;
 
        struct  sigcontext sf_sc;
 } ;
 
+extern int kstack[];
+
 /*
  * Send an interrupt to process.
  *
 /*
  * Send an interrupt to process.
  *
@@ -395,18 +317,21 @@ struct sigframe {
  * frame pointer, it returns to the user
  * specified pc, psl.
  */
  * frame pointer, it returns to the user
  * specified pc, psl.
  */
-sendsig(catcher, sig, mask, code, frm)
+void
+sendsig(catcher, sig, mask, code)
        sig_t catcher;
        int sig, mask;
        unsigned code;
 {
        sig_t catcher;
        int sig, mask;
        unsigned code;
 {
-       register struct proc *p = u.u_procp;
+       register struct proc *p = curproc;
        register int *regs;
        register struct sigframe *fp;
        register int *regs;
        register struct sigframe *fp;
+       struct sigacts *ps = p->p_sigacts;
+       int oonstack, frmtrap;
 
 
-       regs = u.u_ar0;
-/*#include "dbg.h"
-dprintf(DALLTRAPS|DPAGIN,"s %d %d ", sig, frm);*/
+       regs = p->p_regs;
+        oonstack = ps->ps_onstack;
+       frmtrap = curpcb->pcb_flags & FM_TRAP;
        /*
         * Allocate and validate space for the signal handler
         * context. Note that if the stack is in P0 space, the
        /*
         * Allocate and validate space for the signal handler
         * context. Note that if the stack is in P0 space, the
@@ -414,12 +339,12 @@ dprintf(DALLTRAPS|DPAGIN,"s %d %d ", sig, frm);*/
         * will fail if the process has not already allocated
         * the space with a `brk'.
         */
         * will fail if the process has not already allocated
         * the space with a `brk'.
         */
-       if (!u.u_onstack && (u.u_sigonstack & sigmask(sig))) {
-printf("onstack?");
-               fp = (struct sigframe *)(u.u_sigsp - sizeof(struct sigframe));
-               u.u_onstack = 1;
+        if (!ps->ps_onstack && (ps->ps_sigonstack & sigmask(sig))) {
+               fp = (struct sigframe *)(ps->ps_sigsp
+                               - sizeof(struct sigframe));
+                ps->ps_onstack = 1;
        } else {
        } else {
-               if (frm)
+               if (frmtrap)
                        fp = (struct sigframe *)(regs[tESP]
                                - sizeof(struct sigframe));
                else
                        fp = (struct sigframe *)(regs[tESP]
                                - sizeof(struct sigframe));
                else
@@ -427,11 +352,10 @@ printf("onstack?");
                                - sizeof(struct sigframe));
        }
 
                                - sizeof(struct sigframe));
        }
 
-       if ((unsigned)fp <= USRSTACK - ctob(u.u_ssize)) 
+       if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize)) 
                (void)grow((unsigned)fp);
 
        if (useracc((caddr_t)fp, sizeof (struct sigframe), B_WRITE) == 0) {
                (void)grow((unsigned)fp);
 
        if (useracc((caddr_t)fp, sizeof (struct sigframe), B_WRITE) == 0) {
-printf("fail %x %x\n", fp, regs[frm?tESP:sESP]);
                /*
                 * Process has trashed its stack; give it an illegal
                 * instruction to halt it in its tracks.
                /*
                 * Process has trashed its stack; give it an illegal
                 * instruction to halt it in its tracks.
@@ -442,7 +366,6 @@ printf("fail %x %x\n", fp, regs[frm?tESP:sESP]);
                p->p_sigcatch &= ~sig;
                p->p_sigmask &= ~sig;
                psignal(p, SIGILL);
                p->p_sigcatch &= ~sig;
                p->p_sigmask &= ~sig;
                psignal(p, SIGILL);
-/*dprintf(DALLTRAPS|DPAGIN,"ill ");*/
                return;
        }
 
                return;
        }
 
@@ -451,19 +374,11 @@ printf("fail %x %x\n", fp, regs[frm?tESP:sESP]);
         */
        fp->sf_signum = sig;
        fp->sf_code = code;
         */
        fp->sf_signum = sig;
        fp->sf_code = code;
-       /*if (sig == SIGILL || sig == SIGFPE) {
-               fp->sf_code = u.u_code;
-               u.u_code = 0;
-       } else
-               fp->sf_code = 0; */
-       /* indicate trap occured from system call */
-       /*if(!(code&FRMTRAP)) fp->sf_code |= 0x80;*/
-
        fp->sf_scp = &fp->sf_sc;
        fp->sf_handler = catcher;
 
        /* save scratch registers */
        fp->sf_scp = &fp->sf_sc;
        fp->sf_handler = catcher;
 
        /* save scratch registers */
-       if(frm) {
+       if(frmtrap) {
                fp->sf_eax = regs[tEAX];
                fp->sf_edx = regs[tEDX];
                fp->sf_ecx = regs[tECX];
                fp->sf_eax = regs[tEAX];
                fp->sf_edx = regs[tEDX];
                fp->sf_ecx = regs[tECX];
@@ -475,24 +390,22 @@ printf("fail %x %x\n", fp, regs[frm?tESP:sESP]);
        /*
         * Build the signal context to be used by sigreturn.
         */
        /*
         * Build the signal context to be used by sigreturn.
         */
-       fp->sf_sc.sc_onstack = u.u_onstack;
+       fp->sf_sc.sc_onstack = oonstack;
        fp->sf_sc.sc_mask = mask;
        fp->sf_sc.sc_mask = mask;
-       if(frm) {
+       if(frmtrap) {
                fp->sf_sc.sc_sp = regs[tESP];
                fp->sf_sc.sc_fp = regs[tEBP];
                fp->sf_sc.sc_pc = regs[tEIP];
                fp->sf_sc.sc_ps = regs[tEFLAGS];
                regs[tESP] = (int)fp;
                fp->sf_sc.sc_sp = regs[tESP];
                fp->sf_sc.sc_fp = regs[tEBP];
                fp->sf_sc.sc_pc = regs[tEIP];
                fp->sf_sc.sc_ps = regs[tEFLAGS];
                regs[tESP] = (int)fp;
-               regs[tEIP] = (int)u.u_pcb.pcb_sigc;
-/*dprintf(DALLTRAPS|DPAGIN,"E ");*/
+               regs[tEIP] = (int)((struct pcb *)kstack)->pcb_sigc;
        } else {
                fp->sf_sc.sc_sp = regs[sESP];
                fp->sf_sc.sc_fp = regs[sEBP];
                fp->sf_sc.sc_pc = regs[sEIP];
                fp->sf_sc.sc_ps = regs[sEFLAGS];
                regs[sESP] = (int)fp;
        } else {
                fp->sf_sc.sc_sp = regs[sESP];
                fp->sf_sc.sc_fp = regs[sEBP];
                fp->sf_sc.sc_pc = regs[sEIP];
                fp->sf_sc.sc_ps = regs[sEFLAGS];
                regs[sESP] = (int)fp;
-               regs[sEIP] = (int)u.u_pcb.pcb_sigc;
-/*dprintf(DALLTRAPS|DPAGIN,"e "); */
+               regs[sEIP] = (int)((struct pcb *)kstack)->pcb_sigc;
        }
 }
 
        }
 }
 
@@ -515,7 +428,8 @@ sigreturn(p, uap, retval)
 {
        register struct sigcontext *scp;
        register struct sigframe *fp;
 {
        register struct sigcontext *scp;
        register struct sigframe *fp;
-       register int *regs = u.u_ar0;
+       register int *regs = p->p_regs;
+
 
        fp = (struct sigframe *) regs[sESP] ;
 
 
        fp = (struct sigframe *) regs[sESP] ;
 
@@ -535,7 +449,7 @@ sigreturn(p, uap, retval)
                return(EINVAL);
        }
 #endif
                return(EINVAL);
        }
 #endif
-       u.u_onstack = scp->sc_onstack & 01;
+        p->p_sigacts->ps_onstack = scp->sc_onstack & 01;
        p->p_sigmask = scp->sc_mask &~
            (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP));
        regs[sEBP] = scp->sc_fp;
        p->p_sigmask = scp->sc_mask &~
            (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP));
        regs[sEBP] = scp->sc_fp;
@@ -567,7 +481,7 @@ boot(arghowto)
                 * Release inodes held by texts before update.
                 */
                if (panicstr == 0)
                 * Release inodes held by texts before update.
                 */
                if (panicstr == 0)
-                       xumount(NODEV);
+                       vnode_pager_umount(NULL);
                sync((struct sigcontext *)0);
 
                for (iter = 0; iter < 20; iter++) {
                sync((struct sigcontext *)0);
 
                for (iter = 0; iter < 20; iter++) {
@@ -590,11 +504,11 @@ boot(arghowto)
        devtype = major(rootdev);
        if (howto&RB_HALT) {
                printf("halting (in tight loop); hit reset\n\n");
        devtype = major(rootdev);
        if (howto&RB_HALT) {
                printf("halting (in tight loop); hit reset\n\n");
-               reset_cpu();
+               splx(0xfffd);   /* all but keyboard XXX */
                for (;;) ;
        } else {
                if (howto & RB_DUMP) {
                for (;;) ;
        } else {
                if (howto & RB_DUMP) {
-                       doadump();              /* CPBOOT's itsself */
+                       dumpsys();      
                        /*NOTREACHED*/
                }
        }
                        /*NOTREACHED*/
                }
        }
@@ -619,10 +533,8 @@ dumpsys()
 
        if (dumpdev == NODEV)
                return;
 
        if (dumpdev == NODEV)
                return;
-#ifdef notdef
        if ((minor(dumpdev)&07) != 1)
                return;
        if ((minor(dumpdev)&07) != 1)
                return;
-#endif
        dumpsize = physmem;
        printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
        printf("dump ");
        dumpsize = physmem;
        printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
        printf("dump ");
@@ -697,27 +609,20 @@ physstrat(bp, strat, prio)
 
 initcpu()
 {
 
 initcpu()
 {
-       register struct proc *p;
-
-       p = &proc[0];
 }
 
 /*
  * Clear registers on exec
  */
 }
 
 /*
  * Clear registers on exec
  */
-setregs(entry)
+setregs(p, entry)
+       struct proc *p;
        u_long entry;
 {
 
        u_long entry;
 {
 
-#ifdef notdef
-       /* should pass args to init on the stack */
-       for (rp = &u.u_ar0[0]; rp < &u.u_ar0[16];)
-               *rp++ = 0;
-#endif
-       u.u_ar0[sEBP] = 0;      /* bottom of the fp chain */
-       u.u_ar0[sEIP] = entry;
+       p->p_regs[sEBP] = 0;    /* bottom of the fp chain */
+       p->p_regs[sEIP] = entry;
 
 
-       u.u_pcb.pcb_flags = 0;  /* no fp at all */
+       p->p_addr->u_pcb.pcb_flags = 0; /* no fp at all */
        load_cr0(rcr0() | CR0_EM);      /* start emulating */
 #ifdef NPX
        npxinit(0x262);
        load_cr0(rcr0() | CR0_EM);      /* start emulating */
 #ifdef NPX
        npxinit(0x262);
@@ -740,8 +645,9 @@ setregs(entry)
 #define        GTGATE_SEL      4       /* Process task switch gate */
 #define        GPANIC_SEL      5       /* Task state to consider panic from */
 #define        GPROC0_SEL      6       /* Task state process slot zero and up */
 #define        GTGATE_SEL      4       /* Process task switch gate */
 #define        GPANIC_SEL      5       /* Task state to consider panic from */
 #define        GPROC0_SEL      6       /* Task state process slot zero and up */
+#define NGDT   GPROC0_SEL+1
 
 
-union descriptor gdt[GPROC0_SEL];
+union descriptor gdt[GPROC0_SEL+1];
 
 /* interrupt descriptor table */
 struct gate_descriptor idt[32+16];
 
 /* interrupt descriptor table */
 struct gate_descriptor idt[32+16];
@@ -757,7 +663,9 @@ union descriptor ldt[5];
 /* seperate stack, es,fs,gs sels ? */
 /* #define     LPOSIXCALLS_SEL 5       /* notyet */
 
 /* seperate stack, es,fs,gs sels ? */
 /* #define     LPOSIXCALLS_SEL 5       /* notyet */
 
-struct i386tss tss;
+struct i386tss tss, panic_tss;
+
+extern  struct user *proc0paddr;
 
 /* software prototypes -- in more palitable form */
 struct soft_segment_descriptor gdt_segs[] = {
 
 /* software prototypes -- in more palitable form */
 struct soft_segment_descriptor gdt_segs[] = {
@@ -807,7 +715,16 @@ struct soft_segment_descriptor gdt_segs[] = {
        0,                      /* default 32 vs 16 bit size */
        0                       /* limit granularity (byte/page units)*/ },
        /* Panic Tss Descriptor */
        0,                      /* default 32 vs 16 bit size */
        0                       /* limit granularity (byte/page units)*/ },
        /* Panic Tss Descriptor */
-{      (int) &u,                       /* segment base address  */
+{      (int) &panic_tss,               /* segment base address  */
+       sizeof(tss)-1,          /* length - all address space */
+       SDT_SYS386TSS,          /* segment type */
+       0,                      /* segment descriptor priority level */
+       1,                      /* segment descriptor present */
+       0,0,
+       0,                      /* unused - default 32 vs 16 bit size */
+       0                       /* limit granularity (byte/page units)*/ },
+       /* Proc 0 Tss Descriptor */
+{      (int) kstack,                   /* segment base address  */
        sizeof(tss)-1,          /* length - all address space */
        SDT_SYS386TSS,          /* segment type */
        0,                      /* segment descriptor priority level */
        sizeof(tss)-1,          /* length - all address space */
        SDT_SYS386TSS,          /* segment type */
        0,                      /* segment descriptor priority level */
@@ -885,7 +802,7 @@ setidt(idx, func, typ, dpl) char *func; {
        ip->gd_hioffset = ((int)func)>>16 ;
 }
 
        ip->gd_hioffset = ((int)func)>>16 ;
 }
 
-#define        IDTVEC(name)    X/**/name
+#define        IDTVEC(name)    __CONCAT(X, name)
 extern IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl),
        IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(dble), IDTVEC(fpusegm),
        IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot),
 extern IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl),
        IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(dble), IDTVEC(fpusegm),
        IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot),
@@ -900,19 +817,28 @@ int _udatasel, _ucodesel, _gsel_tss;
 
 init386(first) { extern ssdtosd(), lgdt(), lidt(), lldt(), etext; 
        int x, *pi;
 
 init386(first) { extern ssdtosd(), lgdt(), lidt(), lldt(), etext; 
        int x, *pi;
+       unsigned biosbasemem, biosextmem;
        struct gate_descriptor *gdp;
        struct gate_descriptor *gdp;
+       extern int sigcode,szsigcode;
+
+       proc0.p_addr = proc0paddr;
+
+       /*
+        * Initialize the console before we print anything out.
+        */
+
+       cninit (KERNBASE+0xa0000);
 
        /* make gdt memory segments */
        gdt_segs[GCODE_SEL].ssd_limit = btoc((int) &etext + NBPG);
 
        /* make gdt memory segments */
        gdt_segs[GCODE_SEL].ssd_limit = btoc((int) &etext + NBPG);
-       for (x=0; x < 6; x++) ssdtosd(gdt_segs+x, gdt+x);
+       for (x=0; x < NGDT; x++) ssdtosd(gdt_segs+x, gdt+x);
        /* make ldt memory segments */
        /* make ldt memory segments */
-       ldt_segs[LUCODE_SEL].ssd_limit = btoc((int) Sysbase);
-       /*ldt_segs[LUDATA_SEL].ssd_limit = btoc((int) Sysbase); */
-       ldt_segs[LUDATA_SEL].ssd_limit = btoc(0xfffff000);
-/* Note. eventually want private ldts per process */
+       ldt_segs[LUCODE_SEL].ssd_limit = btoc(UPT_MIN_ADDRESS);
+       ldt_segs[LUDATA_SEL].ssd_limit = btoc(UPT_MIN_ADDRESS);
+       /* Note. eventually want private ldts per process */
        for (x=0; x < 5; x++) ssdtosd(ldt_segs+x, ldt+x);
 
        for (x=0; x < 5; x++) ssdtosd(ldt_segs+x, ldt+x);
 
-/* exceptions */
+       /* exceptions */
        setidt(0, &IDTVEC(div),  SDT_SYS386TGT, SEL_KPL);
        setidt(1, &IDTVEC(dbg),  SDT_SYS386TGT, SEL_KPL);
        setidt(2, &IDTVEC(nmi),  SDT_SYS386TGT, SEL_KPL);
        setidt(0, &IDTVEC(div),  SDT_SYS386TGT, SEL_KPL);
        setidt(1, &IDTVEC(dbg),  SDT_SYS386TGT, SEL_KPL);
        setidt(2, &IDTVEC(nmi),  SDT_SYS386TGT, SEL_KPL);
@@ -955,11 +881,44 @@ init386(first) { extern ssdtosd(), lgdt(), lidt(), lldt(), etext;
        lidt(idt, sizeof(idt)-1);
        lldt(GSEL(GLDT_SEL, SEL_KPL));
 
        lidt(idt, sizeof(idt)-1);
        lldt(GSEL(GLDT_SEL, SEL_KPL));
 
+#ifdef notyet
+       /* determine amount of memory present so we can scale kernel PT */
+       for (i= RAM_BEGIN; i < IOM_BEGIN; i += NBPG)
+               if (probemem(i) == 0) break;
+       if (i == IOM_BEGIN) {
+               if (maxphysmem == 0) maxphysmem = RAM_END;
+               for (i= IOM_END; i < maxphysmem; i += NBPG)
+                       if (probemem(i) == 0) break;
+       }
+       maxmem = i / NBPG;
+#else
+Maxmem = 8192 *1024 /NBPG;
+       maxmem = Maxmem;
+#endif
+
+       /* reconcile against BIOS's recorded values in RTC
+        * we trust neither of them, as both can lie!
+        */
+       biosbasemem = rtcin(RTC_BASELO)+ (rtcin(RTC_BASEHI)<<8);
+       biosextmem = rtcin(RTC_EXTLO)+ (rtcin(RTC_EXTHI)<<8);
+       if (biosbasemem == 0xffff || biosextmem == 0xffff) {
+               if (maxmem > 0xffc)
+                       maxmem = 640/4;
+       } else if (biosextmem > 0 && biosbasemem == 640) {
+               int totbios = (biosbasemem + 0x60000 + biosextmem)/4;
+               if (totbios < maxmem) maxmem = totbios;
+       } else  maxmem = 640/4;
+       maxmem = maxmem-1;
+       physmem = maxmem - (0x100 -0xa0);
+
+       /* call pmap initialization to make new kernel address space */
+       pmap_bootstrap (first, 0);
+       /* now running on new page tables, configured,and u/iom is accessible */
 
        /* make a initial tss so microp can get interrupt stack on syscall! */
 
        /* make a initial tss so microp can get interrupt stack on syscall! */
-       u.u_pcb.pcbtss.tss_esp0 = (int) &u + UPAGES*NBPG;
-       u.u_pcb.pcbtss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ;
-       _gsel_tss = GSEL(GPANIC_SEL, SEL_KPL);
+       proc0.p_addr->u_pcb.pcb_tss.tss_esp0 = (int) kstack + UPAGES*NBPG;
+       proc0.p_addr->u_pcb.pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ;
+       _gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
        ltr(_gsel_tss);
 
        /* make a call gate to reenter kernel with */
        ltr(_gsel_tss);
 
        /* make a call gate to reenter kernel with */
@@ -978,18 +937,25 @@ init386(first) { extern ssdtosd(), lgdt(), lidt(), lldt(), etext;
 
        _ucodesel = LSEL(LUCODE_SEL, SEL_UPL);
        _udatasel = LSEL(LUDATA_SEL, SEL_UPL);
 
        _ucodesel = LSEL(LUCODE_SEL, SEL_UPL);
        _udatasel = LSEL(LUDATA_SEL, SEL_UPL);
+
+       /* setup proc 0's pcb */
+       bcopy(&sigcode, proc0.p_addr->u_pcb.pcb_sigc, szsigcode);
+       proc0.p_addr->u_pcb.pcb_flags = 0;
+       proc0.p_addr->u_pcb.pcb_ptd = IdlePTD;
 }
 
 }
 
+extern struct pte      *CMAP1, *CMAP2;
+extern caddr_t         CADDR1, CADDR2;
 /*
  * zero out physical memory
  * specified in relocation units (NBPG bytes)
  */
 clearseg(n) {
 /*
  * zero out physical memory
  * specified in relocation units (NBPG bytes)
  */
 clearseg(n) {
-       extern CMAP1, CADDR1;
 
 
-       CMAP1 = PG_V | PG_KW | ctob(n);
-       load_cr3(u.u_pcb.pcb_cr3);
-       bzero(&CADDR1,NBPG);
+       *(int *)CMAP2 = PG_V | PG_KW | ctob(n);
+       load_cr3(rcr3());
+       bzero(CADDR2,NBPG);
+       *(int *) CADDR2 = 0;
 }
 
 /*
 }
 
 /*
@@ -997,17 +963,28 @@ clearseg(n) {
  * specified in relocation units (NBPG bytes)
  */
 copyseg(frm, n) {
  * specified in relocation units (NBPG bytes)
  */
 copyseg(frm, n) {
-       extern CMAP2, CADDR2;
 
 
-       CMAP2 = PG_V | PG_KW | ctob(n);
-       load_cr3(u.u_pcb.pcb_cr3);
-       bcopy(frm, &CADDR2,NBPG);
+       *(int *)CMAP2 = PG_V | PG_KW | ctob(n);
+       load_cr3(rcr3());
+       bcopy((void *)frm, (void *)CADDR2, NBPG);
 }
 
 }
 
-aston() {
-       schednetisr(NETISR_AST);
+/*
+ * copy a page of physical memory
+ * specified in relocation units (NBPG bytes)
+ */
+physcopyseg(frm, to) {
+
+       *(int *)CMAP1 = PG_V | PG_KW | ctob(frm);
+       *(int *)CMAP2 = PG_V | PG_KW | ctob(to);
+       load_cr3(rcr3());
+       bcopy(CADDR1, CADDR2, NBPG);
 }
 
 }
 
+/*aston() {
+       schednetisr(NETISR_AST);
+}*/
+
 setsoftclock() {
        schednetisr(NETISR_SCLK);
 }
 setsoftclock() {
        schednetisr(NETISR_SCLK);
 }
@@ -1042,9 +1019,9 @@ vmunaccess() {}
 /*
  * Below written in C to allow access to debugging code
  */
 /*
  * Below written in C to allow access to debugging code
  */
-copyinstr(fromaddr, toaddr, maxlength, lencopied) int *lencopied;
-       char *toaddr; {
-       int c,tally;
+copyinstr(fromaddr, toaddr, maxlength, lencopied) u_int *lencopied, maxlength;
+       void *toaddr, *fromaddr; {
+       u_int c,tally;
 
        tally = 0;
        while (maxlength--) {
 
        tally = 0;
        while (maxlength--) {
@@ -1054,7 +1031,7 @@ copyinstr(fromaddr, toaddr, maxlength, lencopied) int *lencopied;
                        return(EFAULT);
                }
                tally++;
                        return(EFAULT);
                }
                tally++;
-               *toaddr++ = (char) c;
+               *(char *)toaddr++ = (char) c;
                if (c == 0){
                        if(lencopied) *lencopied = tally;
                        return(0);
                if (c == 0){
                        if(lencopied) *lencopied = tally;
                        return(0);
@@ -1064,17 +1041,17 @@ copyinstr(fromaddr, toaddr, maxlength, lencopied) int *lencopied;
        return(ENAMETOOLONG);
 }
 
        return(ENAMETOOLONG);
 }
 
-copyoutstr(fromaddr, toaddr, maxlength, lencopied) int *lencopied;
-       u_char *fromaddr; {
+copyoutstr(fromaddr, toaddr, maxlength, lencopied) u_int *lencopied, maxlength;
+       void *fromaddr, *toaddr; {
        int c;
        int tally;
 
        tally = 0;
        while (maxlength--) {
        int c;
        int tally;
 
        tally = 0;
        while (maxlength--) {
-               c = subyte(toaddr++,*fromaddr);
+               c = subyte(toaddr++, *(char *)fromaddr);
                if (c == -1) return(EFAULT);
                tally++;
                if (c == -1) return(EFAULT);
                tally++;
-               if (*fromaddr++ == 0){
+               if (*(char *)fromaddr++ == 0){
                        if(lencopied) *lencopied = tally;
                        return(0);
                }
                        if(lencopied) *lencopied = tally;
                        return(0);
                }
@@ -1083,15 +1060,15 @@ copyoutstr(fromaddr, toaddr, maxlength, lencopied) int *lencopied;
        return(ENAMETOOLONG);
 }
 
        return(ENAMETOOLONG);
 }
 
-copystr(fromaddr, toaddr, maxlength, lencopied) int *lencopied;
-       u_char *fromaddr, *toaddr; {
-       int tally;
+copystr(fromaddr, toaddr, maxlength, lencopied) u_int *lencopied, maxlength;
+       void *fromaddr, *toaddr; {
+       u_int tally;
 
        tally = 0;
        while (maxlength--) {
 
        tally = 0;
        while (maxlength--) {
-               *toaddr = *fromaddr++;
+               *(u_char *)toaddr = *(u_char *)fromaddr++;
                tally++;
                tally++;
-               if (*toaddr++ == 0) {
+               if (*(u_char *)toaddr++ == 0) {
                        if(lencopied) *lencopied = tally;
                        return(0);
                }
                        if(lencopied) *lencopied = tally;
                        return(0);
                }
@@ -1099,25 +1076,3 @@ copystr(fromaddr, toaddr, maxlength, lencopied) int *lencopied;
        if(lencopied) *lencopied = tally;
        return(ENAMETOOLONG);
 }
        if(lencopied) *lencopied = tally;
        return(ENAMETOOLONG);
 }
-
-/* 
- * ovbcopy - like bcopy, but recognizes overlapping ranges and handles 
- *           them correctly.
- */
-ovbcopy(from, to, bytes)
-       char *from, *to;
-       int bytes;                      /* num bytes to copy */
-{
-       /* Assume that bcopy copies left-to-right (low addr first). */
-       if (from + bytes <= to || to + bytes <= from || to == from)
-               bcopy(from, to, bytes); /* non-overlapping or no-op*/
-       else if (from > to)
-               bcopy(from, to, bytes); /* overlapping but OK */
-       else {
-               /* to > from: overlapping, and must copy right-to-left. */
-               from += bytes - 1;
-               to += bytes - 1;
-               while (bytes-- > 0)
-                       *to-- = *from--;
-       }
-}