BSD 4_3_Tahoe release
[unix-history] / usr / src / sys / sys / kern_mman.c
index 029d7a3..89ed99b 100644 (file)
@@ -3,13 +3,9 @@
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
- *     @(#)kern_mman.c 7.1 (Berkeley) 6/5/86
+ *     @(#)kern_mman.c 7.4 (Berkeley) 7/10/87
  */
 
  */
 
-#include "../machine/reg.h"
-#include "../machine/psl.h"
-#include "../machine/pte.h"
-
 #include "param.h"
 #include "systm.h"
 #include "map.h"
 #include "param.h"
 #include "systm.h"
 #include "map.h"
 #include "mman.h"
 #include "conf.h"
 
 #include "mman.h"
 #include "conf.h"
 
+#include "../machine/cpu.h"
+#include "../machine/reg.h"
+#include "../machine/psl.h"
+#include "../machine/pte.h"
+#include "../machine/mtpr.h"
+
 sbrk()
 {
 
 sbrk()
 {
 
@@ -48,7 +50,7 @@ getpagesize()
 
 smmap()
 {
 
 smmap()
 {
-#ifdef notdef
+#ifdef MMAP
        struct a {
                caddr_t addr;
                int     len;
        struct a {
                caddr_t addr;
                int     len;
@@ -59,11 +61,9 @@ smmap()
        } *uap = (struct a *)u.u_ap;
        register struct file *fp;
        register struct inode *ip;
        } *uap = (struct a *)u.u_ap;
        register struct file *fp;
        register struct inode *ip;
-       register struct fpte *pte;
-       int off;
-       int fv, lv, pm;
+       register struct pte *pte;
+       int off, fv, lv, pm, (*mapfun)();
        dev_t dev;
        dev_t dev;
-       int (*mapfun)();
        extern struct file *getinode();
 
        fp = getinode(uap->fd);
        extern struct file *getinode();
 
        fp = getinode(uap->fd);
@@ -97,52 +97,55 @@ smmap()
                u.u_error = EINVAL;
                return;
        }
                u.u_error = EINVAL;
                return;
        }
+       if (u.u_pofile[uap->fd]&UF_MAPPED) {            /* XXX */
+               u.u_error = EBUSY;                      /* XXX */
+               return;                                 /* XXX */
+       }                                               /* XXX */
        fv = btop(uap->addr);
        lv = btop(uap->addr + uap->len - 1);
        if (lv < fv || !isadsv(u.u_procp, fv) || !isadsv(u.u_procp, lv)) {
                u.u_error = EINVAL;
                return;
        }
        fv = btop(uap->addr);
        lv = btop(uap->addr + uap->len - 1);
        if (lv < fv || !isadsv(u.u_procp, fv) || !isadsv(u.u_procp, lv)) {
                u.u_error = EINVAL;
                return;
        }
-       for (off=0; off<uap->len; off += NBPG) {
+       for (off = 0; off < uap->len; off += NBPG)
                if ((*mapfun)(dev, uap->pos+off, uap->prot) == -1) {
                if ((*mapfun)(dev, uap->pos+off, uap->prot) == -1) {
-                       u.u_error = EINVAL;
+                       u.u_error = EINVAL;             /* XXX */
                        return;
                }
                        return;
                }
-       }
        if (uap->prot & PROT_WRITE)
                pm = PG_UW;
        else
                pm = PG_URKR;
        for (off = 0; off < uap->len; off += NBPG) {
        if (uap->prot & PROT_WRITE)
                pm = PG_UW;
        else
                pm = PG_URKR;
        for (off = 0; off < uap->len; off += NBPG) {
-               pte = (struct fpte *)vtopte(u.u_procp, fv);
+               pte = (struct pte *)vtopte(u.u_procp, fv);
                u.u_procp->p_rssize -= vmemfree(pte, 1);
                *(int *)pte = pm;
                pte->pg_v = 1;
                pte->pg_fod = 1;
                u.u_procp->p_rssize -= vmemfree(pte, 1);
                *(int *)pte = pm;
                pte->pg_v = 1;
                pte->pg_fod = 1;
-               pte->pg_fileno = uap->fd;
-               pte->pg_blkno = (*mapfun)(dev, uap->pos+off, uap->prot);
+               pte->pg_pfnum = (*mapfun)(dev, uap->pos+off, uap->prot);
                fv++;
        }
        u.u_procp->p_flag |= SPTECHG;
                fv++;
        }
        u.u_procp->p_flag |= SPTECHG;
+       u.u_mmap[uap->fd].um_base = fv;
+       u.u_mmap[uap->fd].um_len = btoc(uap->len);
        u.u_pofile[uap->fd] |= UF_MAPPED;
 #endif
 }
 
        u.u_pofile[uap->fd] |= UF_MAPPED;
 #endif
 }
 
-mremap()
+msync()
 {
 
 }
 
 munmap()
 {
 {
 
 }
 
 munmap()
 {
-#ifdef notdef
+#ifdef MMAP
        register struct a {
                caddr_t addr;
                int     len;
        } *uap = (struct a *)u.u_ap;
        register struct a {
                caddr_t addr;
                int     len;
        } *uap = (struct a *)u.u_ap;
-       int off;
-       int fv, lv;
        register struct pte *pte;
        register struct pte *pte;
+       int off, fv, lv;
 
        if (((int)uap->addr & CLOFSET) || (uap->len & CLOFSET)) {
                u.u_error = EINVAL;
 
        if (((int)uap->addr & CLOFSET) || (uap->len & CLOFSET)) {
                u.u_error = EINVAL;
@@ -157,7 +160,7 @@ munmap()
        for (off = 0; off < uap->len; off += NBPG) {
                pte = vtopte(u.u_procp, fv);
                u.u_procp->p_rssize -= vmemfree(pte, 1);
        for (off = 0; off < uap->len; off += NBPG) {
                pte = vtopte(u.u_procp, fv);
                u.u_procp->p_rssize -= vmemfree(pte, 1);
-               *(int *)pte = (PG_UW|PG_FOD);
+               *(int *)pte = PG_UW|PG_FOD;
                ((struct fpte *)pte)->pg_fileno = PG_FZERO;
                fv++;
        }
                ((struct fpte *)pte)->pg_fileno = PG_FZERO;
                fv++;
        }
@@ -166,21 +169,29 @@ munmap()
 }
 
 munmapfd(fd)
 }
 
 munmapfd(fd)
+       int fd;
 {
 {
-#ifdef notdef
-       register struct fpte *pte;
+#ifdef MMAP
+       register struct pte *pte;
        register int i;
        register int i;
+       register struct mmap *mmp;
 
 
-       for (i = 0; i < u.u_dsize; i++) {
-               pte = (struct fpte *)dptopte(u.u_procp, i);
-               if (pte->pg_v && pte->pg_fod && pte->pg_fileno == fd) {
-                       *(int *)pte = (PG_UW|PG_FOD);
-                       pte->pg_fileno = PG_FZERO;
+       if ((u.u_pofile[fd]&UF_MAPPED) == 0)
+               panic("munmapfd");
+       mmp = &u.u_mmap[fd];
+       pte = vtopte(u.u_procp, mmp->um_base);
+       for (i = 0;  i < mmp->um_len; i++) {
+               if (pte->pg_v && pte->pg_fod) {
+                       *(int *)pte = PG_UW|PG_FOD;
+                       ((struct fpte *)pte)->pg_fileno = PG_FZERO;
                }
                }
+               pte++;
        }
        }
+       newptes(vtopte(u.u_procp, mmp->um_base), mmp->um_base, mmp->um_len);
+       mmp->um_base = 0;
+       mmp->um_len = 0;
 #endif
        u.u_pofile[fd] &= ~UF_MAPPED;
 #endif
        u.u_pofile[fd] &= ~UF_MAPPED;
-       
 }
 
 mprotect()
 }
 
 mprotect()
@@ -235,6 +246,58 @@ obreak()
 
 int    both;
 
 
 int    both;
 
+/*
+ * Clear a data page's reference bits.
+ */
+#if defined(tahoe)
+#define        dpte_clrref(pte, c) { \
+       uncache(pte); \
+       if (pte->pg_u) { \
+               c = &cmap[pgtocm(pte->pg_pfnum)]; \
+               if (c->c_lock) \
+                       continue; \
+               pte->pg_u = 0; \
+               if (anycl(pte, pg_m)) \
+                       pte->pg_m = 1; \
+               distcl(pte); \
+       } \
+}
+#else
+#define        dpte_clrref(pte, c) { \
+       c = &cmap[pgtocm(pte->pg_pfnum)]; \
+       if (c->c_lock) \
+               continue; \
+       pte->pg_v = 0; \
+       if (anycl(pte, pg_m)) \
+               pte->pg_m = 1; \
+       distcl(pte); \
+}
+#endif
+
+/*
+ * Clear a text page's reference bits.
+ */
+#if defined(tahoe)
+#define        tpte_clrref(pte, c, rp, i) { \
+       uncache(pte); \
+       if (pte->pg_u) { \
+               c = &cmap[pgtocm(pte->pg_pfnum)]; \
+               if (c->c_lock) \
+                       continue; \
+               pte->pg_u = 0; \
+               if (anycl(pte, pg_m)) \
+                       pte->pg_m = 1; \
+               distcl(pte); \
+               distpte(rp->p_textp, i, pte); \
+       } \
+}
+#else
+#define        tpte_clrref(pte, c, rp, i) { \
+       dpte_clrref(pte, c); \
+       distpte(rp->p_textp, i, pte); \
+}
+#endif
+
 ovadvise()
 {
        register struct a {
 ovadvise()
 {
        register struct a {
@@ -265,46 +328,23 @@ ovadvise()
        if ((oanom && (rp->p_flag & SUANOM) == 0) || uap->anom == VA_FLUSH) {
                for (i = 0; i < rp->p_dsize; i += CLSIZE) {
                        pte = dptopte(rp, i);
        if ((oanom && (rp->p_flag & SUANOM) == 0) || uap->anom == VA_FLUSH) {
                for (i = 0; i < rp->p_dsize; i += CLSIZE) {
                        pte = dptopte(rp, i);
-                       if (pte->pg_v) {
-                               c = &cmap[pgtocm(pte->pg_pfnum)];
-                               if (c->c_lock)
-                                       continue;
-                               pte->pg_v = 0;
-                               if (anycl(pte, pg_m))
-                                       pte->pg_m = 1;
-                               distcl(pte);
-                       }
+                       if (pte->pg_v)
+                               dpte_clrref(pte, c);
                }
        }
        if (uap->anom == VA_FLUSH) {    /* invalidate all pages */
                for (i = 1; i < rp->p_ssize; i += CLSIZE) {
                        pte = sptopte(rp, i);
                }
        }
        if (uap->anom == VA_FLUSH) {    /* invalidate all pages */
                for (i = 1; i < rp->p_ssize; i += CLSIZE) {
                        pte = sptopte(rp, i);
-                       if (pte->pg_v) {
-                               c = &cmap[pgtocm(pte->pg_pfnum)];
-                               if (c->c_lock)
-                                       continue;
-                               pte->pg_v = 0;
-                               if (anycl(pte, pg_m))
-                                       pte->pg_m = 1;
-                               distcl(pte);
-                       }
+                       if (pte->pg_v)
+                               dpte_clrref(pte, c);
                }
                for (i = 0; i < rp->p_tsize; i += CLSIZE) {
                        pte = tptopte(rp, i);
                }
                for (i = 0; i < rp->p_tsize; i += CLSIZE) {
                        pte = tptopte(rp, i);
-                       if (pte->pg_v) {
-                               c = &cmap[pgtocm(pte->pg_pfnum)];
-                               if (c->c_lock)
-                                       continue;
-                               pte->pg_v = 0;
-                               if (anycl(pte, pg_m))
-                                       pte->pg_m = 1;
-                               distcl(pte);
-                               distpte(rp->p_textp, i, pte);
-                       }
+                       if (pte->pg_v)
+                               tpte_clrref(pte, c, rp, i);
                }
        }
                }
        }
-#ifdef vax
-#include "../vax/mtpr.h"               /* XXX */
+#if defined(vax) || defined(tahoe)
        mtpr(TBIA, 0);
 #endif
 }
        mtpr(TBIA, 0);
 #endif
 }