BSD 3 development
authorBill Joy <wnj@ucbvax.Berkeley.EDU>
Wed, 16 Jan 1980 08:52:53 +0000 (00:52 -0800)
committerBill Joy <wnj@ucbvax.Berkeley.EDU>
Wed, 16 Jan 1980 08:52:53 +0000 (00:52 -0800)
Work on file usr/src/sys/sys/mem.c

Synthesized-from: 3bsd

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

diff --git a/usr/src/sys/sys/mem.c b/usr/src/sys/sys/mem.c
new file mode 100644 (file)
index 0000000..d711c06
--- /dev/null
@@ -0,0 +1,163 @@
+/*     mem.c   2.2     1/14/80 */
+
+/*
+ * Memory special file
+ *     minor device 0 is physical memory
+ *     minor device 1 is kernel memory 
+ *     minor device 2 is EOF/RATHOLE
+ *     minor device 3 is unibus memory (addressed by shorts)
+ */
+
+#include "../h/param.h"
+#include "../h/dir.h"
+#include "../h/user.h"
+#include "../h/conf.h"
+#include "../h/buf.h"
+#include "../h/systm.h"
+#include "../h/pte.h"
+#include "../h/mtpr.h"
+#include "../h/vm.h"
+#include "../h/cmap.h"
+
+mmread(dev)
+{
+       register int o;
+       register unsigned c, v;
+
+       switch (minor(dev)) {
+
+       case 0:
+               while (u.u_count != 0 && u.u_error == 0) {
+                       if (fubyte(u.u_base) == -1)
+                               goto fault;
+                       v = btop(u.u_offset);
+                       if (v >= physmem)
+                               goto fault;
+                       *(int *)mmap = v | (PG_V | PG_KR);
+                       mtpr(TBIS, vmmap);
+                       o = (int)u.u_offset & PGOFSET;
+                       c = min((unsigned)(NBPG - o), u.u_count);
+                       if (copyout((caddr_t)&vmmap[o], u.u_base, c))
+                               goto fault;
+                       u.u_count -= c;
+                       u.u_base += c;
+                       u.u_offset += c;
+               }
+               return;
+
+       case 1:
+               if (u.u_uid != 0) {
+                       if ((caddr_t)u.u_offset < (caddr_t)&umbabeg &&
+                           (caddr_t)u.u_offset + u.u_count >= (caddr_t)&umbabeg)
+                               goto fault;
+                       if ((caddr_t)u.u_offset >= (caddr_t)&umbabeg &&
+                           (caddr_t)u.u_offset < (caddr_t)&umbaend)
+                               goto fault;
+               }
+               if (!kernacc((caddr_t)u.u_offset, u.u_count, B_READ))
+                       goto fault;
+               if (copyout((caddr_t)u.u_offset, u.u_base, u.u_count))
+                       goto fault;
+               c = u.u_count;
+               u.u_count = 0;
+               u.u_base += c;
+               u.u_offset += c;
+               return;
+
+       case 2:
+               return;
+
+       case 3:
+               if (!kernacc((caddr_t)u.u_offset, u.u_count, B_READ))
+                       goto fault;
+               if (!useracc(u.u_base, u.u_count, B_WRITE))
+                       goto fault;
+               UNIcpy((caddr_t)u.u_offset, u.u_base, u.u_count, B_READ);
+               c = u.u_count;
+               u.u_count = 0;
+               u.u_base += c;
+               u.u_offset += c;
+               return;
+       }
+fault:
+       u.u_error = EFAULT;
+       return;
+}
+
+mmwrite(dev)
+{
+       register int o;
+       register unsigned c, v;
+
+       switch (minor(dev)) {
+
+       case 0:
+               while (u.u_count != 0 && u.u_error == 0) {
+                       if (fubyte(u.u_base) == -1)
+                               goto fault;
+                       v = btop(u.u_offset);
+                       if (v >= physmem)
+                               goto fault;
+                       *(int *)mmap = v | (PG_V | PG_KW);
+                       mtpr(TBIS, vmmap);
+                       o = (int)u.u_offset & PGOFSET;
+                       c = min((unsigned)(NBPG - o), u.u_count);
+                       if (copyin(u.u_base, (caddr_t)&vmmap[o], c))
+                               goto fault;
+                       u.u_count -= c;
+                       u.u_base += c;
+                       u.u_offset += c;
+               }
+               return;
+
+       case 1:
+               if (!kernacc((caddr_t)u.u_offset, u.u_count, B_WRITE))
+                       goto fault;
+               if (copyin(u.u_base, (caddr_t)u.u_offset, u.u_count))
+                       goto fault;
+               u.u_base += u.u_count;
+               u.u_offset += u.u_count;
+               u.u_count = 0;
+               return;
+
+       case 2:
+               u.u_offset += u.u_count;
+               u.u_count = 0;
+               return;
+
+       case 3:
+               if (!kernacc((caddr_t)u.u_offset, u.u_count, B_WRITE))
+                       goto fault;
+               if (!useracc(u.u_base, u.u_count, B_READ))
+                       goto fault;
+               UNIcpy((caddr_t)u.u_offset, u.u_base, u.u_count, B_WRITE);
+               u.u_base += u.u_count;
+               u.u_offset += u.u_count;
+               u.u_count = 0;
+               return;
+       }
+fault:
+       u.u_error = EFAULT;
+       return;
+}
+
+/*
+ * UNIBUS Address Space <--> User Space transfer
+ */
+UNIcpy(uniadd, usradd, bknt, direct)
+       caddr_t uniadd, usradd;
+       unsigned bknt;
+{
+       register short *from, *to;
+       register int i;
+       if (direct == B_READ) {
+               from = (short *) uniadd;
+               to = (short *) usradd;
+       } else {
+               from = (short *) usradd;
+               to = (short *) uniadd;
+       }
+       for (i = (bknt>>1); i > 0; i--)
+               *to++ = *from++;
+}