Bell 32V development
authorTom London <tbl@research.uucp>
Thu, 22 Mar 1979 01:35:41 +0000 (20:35 -0500)
committerTom London <tbl@research.uucp>
Thu, 22 Mar 1979 01:35:41 +0000 (20:35 -0500)
Work on file usr/src/sys/sys/machdep.c

Co-Authored-By: John Reiser <jfr@research.uucp>
Synthesized-from: 32v

usr/src/sys/sys/machdep.c [new file with mode: 0644]

diff --git a/usr/src/sys/sys/machdep.c b/usr/src/sys/sys/machdep.c
new file mode 100644 (file)
index 0000000..033dbc9
--- /dev/null
@@ -0,0 +1,338 @@
+#include "../h/param.h"
+#include "../h/systm.h"
+#include "../h/acct.h"
+#include "../h/dir.h"
+#include "../h/user.h"
+#include "../h/inode.h"
+#include "../h/proc.h"
+#include "../h/seg.h"
+#include "../h/uba.h"
+#include "../h/map.h"
+#include "../h/reg.h"
+#include "../h/mtpr.h"
+#include "../h/clock.h"
+#include "../h/page.h"
+
+long   icode[] =
+{
+       0x9f19af9f,     /* pushab [&"init",0]; pushab */
+       0x02dd09af,     /* "/etc/init"; pushl $2 */
+       0xbc5c5ed0,     /* movl sp,ap; chmk */
+       0x2ffe110b,     /* $exec; brb .; "/ */
+       0x2f637465,     /* etc/ */
+       0x74696e69,     /* init */
+       0x00000000,     /* ";  0 */
+       0x00000014,     /* [&"init", */
+       0x00000000,     /* 0] */
+};
+int    szicode = sizeof(icode);
+/*
+ * Machine-dependent startup code
+ */
+startup(firstaddr)
+{
+       int unixsize;
+
+       /*
+        * Initialize maps
+        */
+
+       printf("RESTRICTED RIGHTS\n");
+       printf("USE, DUPLICATION OR DISCLOSURE IS\n");
+       printf("SUBJECT TO RESTRICTION STATED IN YOUR\n");
+       printf("CONTRACT WITH WESTERN ELECTRIC COMPANY INC.\n\n");
+       printf("real mem  = %d\n", maxmem*ctob(1) );
+       if (maxmem > PHYSPAGES) {       /* more pages than allocated in bit map */
+               printf("Warning: more page-frames than allocated in bit map\n");
+               printf("   Only %d of %d used. (Increase PHYSPAGES)\n",
+                               PHYSPAGES,maxmem);
+               maxmem = PHYSPAGES;
+       }
+       unixsize = (firstaddr+USIZE);
+       meminit(unixsize, maxmem);
+       maxmem -= unixsize + 1;
+       printf("avail mem = %d\n", maxmem*ctob(1));
+       if(MAXMEM < maxmem)
+               maxmem = MAXMEM;
+       mfree(swapmap, nswap, 1);
+       swplo--;
+       mbainit();              /* setup mba mapping regs map */
+       ubainit();              /* setup uba mapping regs map */
+}
+
+/*
+ * set up a physical address
+ * into users virtual address space.
+ */
+sysphys()
+{
+       register i, s, d;
+
+       if(!suser())
+               return;
+       u.u_error = EINVAL;
+}
+
+/*
+ * Start clock
+ */
+clkstart()
+{
+       mtpr(NICR, -16667);     /* 16.667 milli-seconds */
+       mtpr(ICCS,ICCS_RUN+ICCS_IE+ICCS_TRANS+ICCS_INT+ICCS_ERR);
+}
+
+clkreld()
+{
+       mtpr(ICCS, ICCS_RUN + ICCS_IE + ICCS_INT + ICCS_ERR);
+}
+
+
+/*
+ * Send an interrupt to process
+ */
+sendsig(p, n)
+{
+       register int *usp, *regs;
+       register int mask, r, spa, t;
+       int *s;
+
+       regs = u.u_ar0;
+       usp = (int *)regs[SP];
+       grow((unsigned)(usp-20));
+       mask = (fuword(p) & 0xfff) | 0x3f; /* get register save mask (save r0-r5) */
+       suword( (caddr_t) --usp, n);    /* sig # as param */
+       suword( (caddr_t) --usp, 1);    /* one parameters */
+       s = usp;
+       spa = ((int) usp) & 0x3;
+       if (spa) usp = (int *)((int) (usp - 1) & ~ 0x3);
+       t = 11;
+       for (r=0x800; r; r>>=1)
+               {
+               if (mask & r) suword((caddr_t) --usp, regs[t]);
+               t--;
+               }
+       suword( (caddr_t) --usp, regs[PC]);
+       suword( (caddr_t) --usp, regs[FP]);
+       suword( (caddr_t) --usp, regs[AP]);
+       suword( (caddr_t) --usp, (spa << 30) | (0x2 << 28)
+                               | (mask << 16) | (regs[PS] & 0xfff1));
+       suword( (caddr_t) --usp, 0);
+
+       regs[SP] = (int)usp;
+       regs[FP] = (int)usp;
+       regs[AP] = (int)s;
+       regs[PC] = p + 2;
+       regs[PS] &= ~ 0x1f;
+}
+
+mtpr(regno, value)
+{
+       asm("   mtpr    8(ap),4(ap)");
+}
+
+mfpr(regno)
+{
+       asm("   mfpr    4(ap),r0");
+}
+
+/*
+ * Copy bytes within kernel
+ */
+bcopy(from,to,count)
+{
+       asm("   movc3   12(ap),*4(ap),*8(ap)");
+}
+
+/*
+ * create a duplicate copy of a process
+ */
+procdup(p)
+register struct proc *p;
+{
+       extern int forkutl[], Forkmap[];
+       register int i, *ip, *jp, *kp;
+
+       if (memall(Forkmap,USIZE) == 0)
+               return(NULL);   /* no memory available */
+
+       /* make u-area and page tables addressible */
+       for( i=USIZE; --i>=0; ) {
+               Forkmap[i] |= PG_V + PG_KW;
+               mtpr(TBIS, forkutl + 128*i);
+       }
+
+       if (u.u_dsize)
+               if (memall(&forkutl[UPAGES*128+u.u_tsize],u.u_dsize) == 0) {
+                       memfree(Forkmap,USIZE);
+                       return(NULL);
+               }
+       if (u.u_ssize)
+               if (memall(&forkutl[USIZE*128-u.u_ssize],u.u_ssize) == 0)  {
+                       memfree(&forkutl[UPAGES*128+u.u_tsize],u.u_dsize);
+                       memfree(Forkmap,USIZE);
+                       return(NULL);
+               }
+
+       /* copy the u-area */
+       bcopy(&u, forkutl, ctob(UPAGES));
+
+       /* copy the data segment */
+       ip = ((int *)&u) + UPAGES*128 + u.u_tsize;
+       jp = ip + u.u_dsize;
+       kp = forkutl + UPAGES*128 + u.u_tsize;
+       while(ip < jp) {
+               copyseg(*ip++&PG_PFNUM, *kp);
+               *kp++ |= PG_V + PG_UW;
+       }
+
+       /* copy stack segment */
+       jp = ((int *)&u) + USIZE*128;
+       ip = jp - u.u_ssize;
+       kp = forkutl + USIZE*128 - u.u_ssize;
+       while(ip < jp) {
+               copyseg(*ip++&PG_PFNUM, *kp);
+               *kp++ |= PG_V + PG_UW;
+       }
+
+       /* copy text page table entries */
+       bcopy( ((int *)&u) + UPAGES*128, forkutl + UPAGES*128, 
+               sizeof(struct pt_entry)*u.u_tsize);
+
+       /* clear unused page taple entries */
+       ip = forkutl + UPAGES*128 + u.u_tsize + u.u_dsize;
+       jp = forkutl + USIZE*128 - u.u_ssize;
+       while(ip < jp) 
+               *ip++ = 0;
+
+       /* store page numbers of new page table in new u-area */
+       for(i=u.u_pcb.pcb_szpt; --i>=0; )
+               ((struct user *)forkutl)->u_ptable[i] = (Forkmap+UPAGES)[i]
+                               & PG_PFNUM;
+
+       /* store page numbers of new u-area in proc */
+       for(i=UPAGES; --i>=0; )
+               p->p_addr[i] = Forkmap[i];
+       return(1);
+}
+
+
+/*
+ * change protection codes of a cegment
+ */
+chgprot(text,data,stack)
+{
+       register  int   *ptaddr,i;
+
+       if (text || data) {
+               ptaddr = (int *)mfpr(P0BR);
+               if (text)
+                       for(i=0; i<u.u_tsize; i++) {
+                               ptaddr[i] &= ~PG_PROT;  /* clear prot bits */
+                               ptaddr[i] |= text + PG_V;
+                       }
+               if (data)
+                       for(i=u.u_tsize; i<u.u_tsize+u.u_dsize; i++) {
+                               ptaddr[i] &= ~PG_PROT;  /* clear prot bits */
+                               ptaddr[i] |= data + PG_V;
+                       }
+               }
+       if (stack) {
+               ptaddr = (int *)(mfpr(P1BR) + 4 * mfpr(P1LR));
+               for(i=0; i<u.u_ssize; i++) {
+                       ptaddr[i] &= ~PG_PROT;  /* clear prot bits */
+                       ptaddr[i] |= stack + PG_V;
+               }
+       }
+}
+
+/*
+ * check that a process will not be too large 
+ */
+chksize(text,data,stack)
+{
+       if ( (text + data + stack) > MAXUMEM
+               || text + data + stack + UPAGES + MAXUMEM/128 > maxmem) {
+               u.u_error = ENOMEM;
+               return(-1);
+       }
+       return(0);
+}
+
+
+/*
+ * expand a page table
+ */
+ptexpand(change)
+register int change;
+{
+       register int  *p1, *p2, i, movept;
+       int  newpt[MAXUMEM/128];
+       extern  int  Umap[];
+
+       if (change <= 0)
+               return(change);
+       if (change > MAXUMEM/128 || memall(newpt,change) == 0)
+               return(-1);
+
+       /* calculate where stack entries start */
+       movept = (0x200000 - mfpr(P1LR))/128;
+
+       /* copy the stack page table pages down */
+       for(i=0; i<movept; i++) {
+               Umap[USIZE+change-1-i] = Umap[USIZE-1-i];
+               mtpr(TBIS, ((int)&u) + 512*(USIZE+change-1-i));
+       }
+
+       /* insert and clear new pages */
+       for(i=0; i<change; i++) {
+               Umap[USIZE-movept+i] = newpt[i] | (PG_V+PG_KW);
+               mtpr(TBIS,((int)&u) + 512*(USIZE-movept+i));
+               clearseg(newpt[i]);
+       }
+
+       /* copy any stack entries to new page, then clear entry */
+       p1 = (int *)mfpr(P1BR);
+       p1 += mfpr(P1LR);
+       p2 = p1 + 128*change;
+       while ((int)p1 & 0x1ff) {
+               *p2++ = *p1;
+               *p1++ = 0;
+       }
+
+       /* fixup page table numbers in u-area */
+       for(i=u.u_pcb.pcb_szpt+change; --i>=0; )
+               u.u_ptable[i] = (Umap+UPAGES)[i] & PG_PFNUM;
+       u.u_pcb.pcb_szpt += change;     /* new number of page tables */
+       u.u_pcb.pcb_p1br = mfpr(P1BR) + 512*change;
+       mtpr(P1BR, u.u_pcb.pcb_p1br);
+       mtpr(TBIA,1);
+       return(change);
+}
+
+/*
+ * make some u-area and allied page tables
+ * addressible;
+ */
+
+ptaccess(p, map, addr)
+register struct proc *p;
+register int map[], addr[];
+{
+       register int i;
+
+       /* make u-area addressible */
+       for(i=UPAGES; --i>=0; ) {
+               map[i] = p->p_addr[i] | (PG_V+PG_KW);
+               mtpr(TBIS, addr + 128*i);
+       }
+
+       /* make page tables addressible */
+       for(i=((struct user *)addr)->u_pcb.pcb_szpt; --i>=0; ) {
+               (map+UPAGES)[i] = ((struct user *)addr)->u_ptable[i]
+                               | (PG_V+PG_KW);
+               mtpr(TBIS, addr + 128*(i+UPAGES));
+       }
+}