]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/pc/mmu.c
kernel: cleanup the software mouse cursor mess
[plan9front.git] / sys / src / 9 / pc / mmu.c
index cfcdf879336d56e80da481fa8b42c3801241a411..c0b13674a6cab1083b782d7c4dbcb4480ac96416 100644 (file)
@@ -66,11 +66,17 @@ static void memglobal(void);
 #define        VPTX(va)                (((ulong)(va))>>12)
 #define        vpd (vpt+VPTX(VPT))
 
+enum {
+       /* PAT entry used for write combining */
+       PATWC   = 7,
+};
+
 void
 mmuinit(void)
 {
        ulong x, *p;
        ushort ptr[3];
+       vlong v;
 
        if(0) print("vpt=%#.8ux vpd=%#p kmap=%#.8ux\n",
                VPT, vpd, KMAP);
@@ -119,6 +125,14 @@ mmuinit(void)
 
        taskswitch(PADDR(m->pdb),  (ulong)m + BY2PG);
        ltr(TSSSEL);
+
+       /* IA32_PAT write combining */
+       if((MACHP(0)->cpuiddx & Pat) != 0
+       && rdmsr(0x277, &v) != -1){
+               v &= ~(255LL<<(PATWC*8));
+               v |= 1LL<<(PATWC*8);    /* WC */
+               wrmsr(0x277, v);
+       }
 }
 
 /* 
@@ -184,7 +198,7 @@ flushmmu(void)
 void
 flushpg(ulong va)
 {
-       if(X86FAMILY(m->cpuidax) >= 4)
+       if(m->cpuidfamily >= 4)
                invlpg(va);
        else
                putcr3(getcr3());
@@ -509,17 +523,8 @@ mmuwalk(ulong* pdb, ulong va, int level, int create)
                if(*table & PTESIZE)
                        panic("mmuwalk2: va %luX entry %luX", va, *table);
                if(!(*table & PTEVALID)){
-                       /*
-                        * Have to call low-level allocator from
-                        * memory.c if we haven't set up the xalloc
-                        * tables yet.
-                        */
-                       if(conf.mem[0].npage != 0)
-                               map = xspanalloc(BY2PG, BY2PG, 0);
-                       else
-                               map = rampage();
-                       if(map == nil)
-                               panic("mmuwalk xspanalloc failed");
+                       map = rampage();
+                       memset(map, 0, BY2PG);
                        *table = PADDR(map)|PTEWRITE|PTEVALID;
                }
                table = KADDR(PPN(*table));
@@ -538,6 +543,7 @@ static Lock vmaplock;
 
 static int findhole(ulong *a, int n, int count);
 static ulong vmapalloc(ulong size);
+static int pdbmap(ulong *, ulong, ulong, int);
 static void pdbunmap(ulong*, ulong, int);
 
 /*
@@ -637,10 +643,7 @@ vmapalloc(ulong size)
 void
 vunmap(void *v, int size)
 {
-       int i;
        ulong va, o;
-       Mach *nm;
-       Proc *p;
        
        /*
         * might not be aligned
@@ -665,35 +668,18 @@ vunmap(void *v, int size)
         * boot. In that case it suffices to flush the MACH(0) TLB
         * and return.
         */
-       if(!active.thunderbirdsarego){
+       if(up == nil){
                putcr3(PADDR(MACHP(0)->pdb));
                return;
        }
-       for(i=0; i<conf.nproc; i++){
-               p = proctab(i);
-               if(p->state == Dead)
-                       continue;
-               if(p != up)
-                       p->newtlb = 1;
-       }
-       for(i=0; i<conf.nmach; i++){
-               nm = MACHP(i);
-               if(nm != m)
-                       nm->flushmmu = 1;
-       }
+       procflushothers();
        flushmmu();
-       for(i=0; i<conf.nmach; i++){
-               nm = MACHP(i);
-               if(nm != m)
-                       while((active.machs&(1<<nm->machno)) && nm->flushmmu)
-                               ;
-       }
 }
 
 /*
  * Add kernel mappings for pa -> va for a section of size bytes.
  */
-int
+static int
 pdbmap(ulong *pdb, ulong pa, ulong va, int size)
 {
        int pse;
@@ -763,6 +749,19 @@ pdbunmap(ulong *pdb, ulong va, int size)
        }
 }
 
+void
+pmap(ulong pa, ulong va, int size)
+{
+       pdbmap(MACHP(0)->pdb, pa, va, size);
+}
+
+void
+punmap(ulong va, int size)
+{
+       pdbunmap(MACHP(0)->pdb, va, size);
+       mmuflushtlb(PADDR(m->pdb));
+}
+
 /*
  * Handle a fault by bringing vmap up to date.
  * Only copy pdb entries and they never go away,
@@ -957,97 +956,6 @@ paddr(void *v)
 /*
  * More debugging.
  */
-void
-countpagerefs(ulong *ref, int print)
-{
-       int i, n;
-       Mach *mm;
-       Page *pg;
-       Proc *p;
-       
-       n = 0;
-       for(i=0; i<conf.nproc; i++){
-               p = proctab(i);
-               if(p->mmupdb){
-                       if(print){
-                               if(ref[pagenumber(p->mmupdb)])
-                                       iprint("page %#.8lux is proc %d (pid %lud) pdb\n",
-                                               p->mmupdb->pa, i, p->pid);
-                               continue;
-                       }
-                       if(ref[pagenumber(p->mmupdb)]++ == 0)
-                               n++;
-                       else
-                               iprint("page %#.8lux is proc %d (pid %lud) pdb but has other refs!\n",
-                                       p->mmupdb->pa, i, p->pid);
-               }
-               if(p->kmaptable){
-                       if(print){
-                               if(ref[pagenumber(p->kmaptable)])
-                                       iprint("page %#.8lux is proc %d (pid %lud) kmaptable\n",
-                                               p->kmaptable->pa, i, p->pid);
-                               continue;
-                       }
-                       if(ref[pagenumber(p->kmaptable)]++ == 0)
-                               n++;
-                       else
-                               iprint("page %#.8lux is proc %d (pid %lud) kmaptable but has other refs!\n",
-                                       p->kmaptable->pa, i, p->pid);
-               }
-               for(pg=p->mmuused; pg; pg=pg->next){
-                       if(print){
-                               if(ref[pagenumber(pg)])
-                                       iprint("page %#.8lux is on proc %d (pid %lud) mmuused\n",
-                                               pg->pa, i, p->pid);
-                               continue;
-                       }
-                       if(ref[pagenumber(pg)]++ == 0)
-                               n++;
-                       else
-                               iprint("page %#.8lux is on proc %d (pid %lud) mmuused but has other refs!\n",
-                                       pg->pa, i, p->pid);
-               }
-               for(pg=p->mmufree; pg; pg=pg->next){
-                       if(print){
-                               if(ref[pagenumber(pg)])
-                                       iprint("page %#.8lux is on proc %d (pid %lud) mmufree\n",
-                                               pg->pa, i, p->pid);
-                               continue;
-                       }
-                       if(ref[pagenumber(pg)]++ == 0)
-                               n++;
-                       else
-                               iprint("page %#.8lux is on proc %d (pid %lud) mmufree but has other refs!\n",
-                                       pg->pa, i, p->pid);
-               }
-       }
-       if(!print)
-               iprint("%d pages in proc mmu\n", n);
-       n = 0;
-       for(i=0; i<conf.nmach; i++){
-               mm = MACHP(i);
-               for(pg=mm->pdbpool; pg; pg=pg->next){
-                       if(print){
-                               if(ref[pagenumber(pg)])
-                                       iprint("page %#.8lux is in cpu%d pdbpool\n",
-                                               pg->pa, i);
-                               continue;
-                       }
-                       if(ref[pagenumber(pg)]++ == 0)
-                               n++;
-                       else
-                               iprint("page %#.8lux is in cpu%d pdbpool but has other refs!\n",
-                                       pg->pa, i);
-               }
-       }
-       if(!print){
-               iprint("%d pages in mach pdbpools\n", n);
-               for(i=0; i<conf.nmach; i++)
-                       iprint("cpu%d: %d pdballoc, %d pdbfree\n",
-                               i, MACHP(i)->pdballoc, MACHP(i)->pdbfree);
-       }
-}
-
 void
 checkfault(ulong, ulong)
 {
@@ -1065,3 +973,36 @@ cankaddr(ulong pa)
        return -KZERO - pa;
 }
 
+/*
+ * mark pages as write combining (used for framebuffer)
+ */
+void
+patwc(void *a, int n)
+{
+       ulong *pte, mask, attr, va;
+       vlong v;
+       int z;
+
+       /* check if pat is usable */
+       if((MACHP(0)->cpuiddx & Pat) == 0
+       || rdmsr(0x277, &v) == -1
+       || ((v >> PATWC*8) & 7) != 1)
+               return;
+
+       /* set the bits for all pages in range */
+       for(va = (ulong)a; n > 0; n -= z, va += z){
+               pte = mmuwalk(MACHP(0)->pdb, va, 1, 0);
+               if(pte && (*pte & (PTEVALID|PTESIZE)) == (PTEVALID|PTESIZE)){
+                       z = 4*MB - (va & (4*MB-1));
+                       mask = 3<<3 | 1<<12;
+               } else {
+                       pte = mmuwalk(MACHP(0)->pdb, va, 2, 0);
+                       if(pte == 0 || (*pte & PTEVALID) == 0)
+                               panic("patwc: va=%#p", va);
+                       z = BY2PG - (va & (BY2PG-1));
+                       mask = 3<<3 | 1<<7;
+               }
+               attr = (((PATWC&3)<<3) | ((PATWC&4)<<5) | ((PATWC&4)<<10));
+               *pte = (*pte & ~mask) | (attr & mask);
+       }
+}