Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-1-5]: src/sys/arch/sparc64/sparc64 Pullup 1.72-1.75 [eeh]:



details:   https://anonhg.NetBSD.org/src/rev/78865b401af1
branches:  netbsd-1-5
changeset: 489776:78865b401af1
user:      tv <tv%NetBSD.org@localhost>
date:      Tue Oct 17 02:06:49 2000 +0000

description:
Pullup 1.72-1.75 [eeh]:
Add -V and -D bootflags to print out debug info in pmap_bootstrap() and
a fix for non-DEBUG kernels.
----------------------------
This really does seem to fix the ref/mod issues.  (Yeah, like were did we hear
that before?)
----------------------------
Add locking to pmap operations and support multiple physical memory
segments.
----------------------------
Typo.

diffstat:

 sys/arch/sparc64/sparc64/pmap.c |  474 ++++++++++++++++++++++++++++++++++-----
 1 files changed, 407 insertions(+), 67 deletions(-)

diffs (truncated from 1118 to 300 lines):

diff -r 5e6408d2d905 -r 78865b401af1 sys/arch/sparc64/sparc64/pmap.c
--- a/sys/arch/sparc64/sparc64/pmap.c   Tue Oct 17 01:56:37 2000 +0000
+++ b/sys/arch/sparc64/sparc64/pmap.c   Tue Oct 17 02:06:49 2000 +0000
@@ -1,6 +1,6 @@
-/*     $NetBSD: pmap.c,v 1.56.2.3 2000/08/07 01:09:24 mrg Exp $        */
+/*     $NetBSD: pmap.c,v 1.56.2.4 2000/10/17 02:06:49 tv Exp $ */
 #undef NO_VCACHE /* Don't forget the locked TLB in dostart */
-#define HWREF 1 
+#define        HWREF
 /*
  * 
  * Copyright (C) 1996-1999 Eduardo Horvath.
@@ -87,13 +87,50 @@
 
 extern int64_t asmptechk __P((union sun4u_data* pseg[], int addr)); /* DEBUG XXXXX */
 
+static int pseg_check __P((struct pmap*, vaddr_t addr, int64_t tte, paddr_t spare));
+static int
+pseg_check(struct pmap *pm, vaddr_t addr, int64_t tte, paddr_t spare)
+{
+       int i, k, s;
+       paddr_t *pdir, *ptbl;
+       extern int pseg_set __P((struct pmap*, vaddr_t addr, int64_t tte,
+               paddr_t spare));
+
+       if (!spare) return pseg_set(pm, addr, tte, spare);
+
+       s = splimp();
+       if ((paddr_t)pm->pm_segs == spare) panic("pseg_check: pm_segs == %llx\n", spare);
+       for (i=0; i<STSZ; i++) {
+               if ((pdir = (paddr_t *)(u_long)ldxa((vaddr_t)&pm->pm_segs[i], ASI_PHYS_CACHED))) {
+                       if ((paddr_t)pdir == spare)
+                               panic("pseg_check: pdir %d == %llx\n", i,
+                                       spare);
+                       for (k=0; k<PDSZ; k++) {
+                               if ((ptbl = (paddr_t *)(u_long)ldxa((vaddr_t)&pdir[k], ASI_PHYS_CACHED))) {
+                                       if ((paddr_t)ptbl == spare)
+                               panic("pseg_check: ptbl %d:%d == %llx\n", i, k,
+                                       spare);
+                               }
+                       }
+               }
+       }
+       splx(s);
+       if (addr == -1) return 0;
+       return pseg_set(pm, addr, tte, spare);
+}
+#define pseg_check(a, b, c, d)
+#define cache_flush_phys(a, b, c)
+/* #define pseg_set(a, b, c, d)        pseg_check(a, b, c, d) */
+
 /* These routines are in assembly to allow access thru physical mappings */
 #if 1
 extern int64_t pseg_get __P((struct pmap*, vaddr_t addr));
 extern int pseg_set __P((struct pmap*, vaddr_t addr, int64_t tte, paddr_t spare));
+extern paddr_t pseg_find __P((struct pmap*, vaddr_t addr, paddr_t spare));
 #else
 static int64_t pseg_get __P((struct pmap*, vaddr_t addr));
 static int pseg_set __P((struct pmap*, vaddr_t addr, int64_t tte, paddr_t spare));
+static paddr_t pseg_find __P((struct pmap*, vaddr_t addr, paddr_t spare));
 
 static int64_t pseg_get(struct pmap* pm, vaddr_t addr) {
        paddr_t *pdir, *ptbl;
@@ -125,6 +162,28 @@
        stda(&ptbl[va_to_pte(addr)], ASI_PHYS_CACHED, tte);
        return (0);
 }
+
+static paddr_t pseg_find(struct pmap* pm, vaddr_t addr, paddr_t spare) {
+       int i, j, k, s;
+       paddr_t *pdir, *ptbl;
+
+       if (!(pdir = (paddr_t *)ldda(&pm->pm_segs[va_to_seg(addr)],
+           ASI_PHYS_CACHED))) {
+               if (!spare) return (1);
+               stda(&pm->pm_segs[va_to_seg(addr)], ASI_PHYS_CACHED, spare);
+               pdir = spare;
+               spare = NULL;
+       }
+       if (!(ptbl = (paddr_t *)ldda(&pdir[va_to_dir(addr)], ASI_PHYS_CACHED))) {
+               if (!spare) return (1);
+               stda(&pdir[va_to_dir(addr)], ASI_PHYS_CACHED, spare);
+               ptbl = spare;
+               spare = NULL;
+       }
+       return (paddr_t)(&ptbl[va_to_pte(addr)]);
+}
+
+
 #endif
 
 extern vm_page_t vm_page_alloc1 __P((void));
@@ -208,7 +267,13 @@
 
 u_int64_t first_phys_addr;
 #define pa_index(pa)           atop((pa) - first_phys_addr)
-#define pa_to_pvh(pa)          (&pv_table[pa_index(pa)])
+#define        pa_to_pvh(pa)                                                   \
+({                                                                     \
+       int bank_, pg_;                                                 \
+                                                                       \
+       bank_ = vm_physseg_find(atop((pa)), &pg_);                      \
+       (pv_entry_t)&vm_physmem[bank_].pmseg.pvent[pg_];                \
+})
 
 
 
@@ -373,6 +438,10 @@
 
 /*
  * Enter a TTE into the kernel pmap only.  Don't do anything else.
+ * 
+ * Use only during bootstrapping since it does no locking and 
+ * can lose ref/mod info!!!!
+ *
  */
 static void pmap_enter_kpage __P((vaddr_t, int64_t));
 static void
@@ -384,7 +453,12 @@
 
        newp = NULL;
        while (pseg_set(pmap_kernel(), va, data, newp) != NULL) {
+               newp = NULL;
                pmap_get_page(&newp);
+               if (!newp) {
+                       prom_printf("pmap_enter_kpage: out of pages\n");
+                       panic("pmap_enter_kpage");
+               }
                pmap_zero_page(newp);
 #ifdef DEBUG
                enter_stats.ptpneeded ++;
@@ -392,12 +466,52 @@
                BDPRINTF(PDB_BOOT1, 
                         ("pseg_set: pm=%p va=%p data=%lx newp %lx\r\n",
                          pmap_kernel(), va, (long)data, (long)newp));
+#ifdef DEBUG
                if (pmapdebug & PDB_BOOT1)
                {int i; for (i=0; i<140000000; i++) ;}
+#endif
        }
 }
 
 /*
+ * See checp bootargs to see if we need to enable bootdebug.
+ */
+#ifdef DEBUG
+void pmap_bootdebug __P((void));
+void
+pmap_bootdebug() 
+{
+       int chosen;
+       char *cp;
+       char buf[128];
+
+       /*
+        * Grab boot args from PROM
+        */
+       chosen = OF_finddevice("/chosen");
+       /* Setup pointer to boot flags */
+       OF_getprop(chosen, "bootargs", buf, sizeof(buf));
+       cp = buf;
+       if (cp != NULL)
+               return;
+       while (*cp != '-')
+               if (*cp++ == '\0')
+                       return;
+       for (;;) 
+               switch (*++cp) {
+               case '\0':
+                       return;
+               case 'V':
+                       pmapdebug |= PDB_BOOT;
+                       break;
+               case 'D':
+                       pmapdebug |= PDB_BOOT1;
+                       break;
+               }
+}
+#endif
+
+/*
  * This is called during bootstrap, before the system is really initialized.
  *
  * It's called with the start and end virtual addresses of the kernel.  We
@@ -435,9 +549,9 @@
        paddr_t newkp;
        vaddr_t newkv, firstaddr, intstk;
        vsize_t kdsize, ktsize;
+
 #ifdef DEBUG
-       int opmapdebug = pmapdebug;
-       pmapdebug = 0;
+       pmap_bootdebug();
 #endif
 
        BDPRINTF(PDB_BOOT, ("Entered pmap_bootstrap.\r\n"));
@@ -463,13 +577,13 @@
 #ifdef DEBUG
        if (pmapdebug & PDB_BOOT) {
                /* print out mem list */
-               prom_printf("Available virutal memory:\r\n");
+               prom_printf("Available virtual memory:\r\n");
                for (mp = memlist; mp->size; mp++) {
                        prom_printf("memlist start %p size %lx\r\n", 
                                    (void *)(u_long)mp->start,
                                    (u_long)mp->size);
                }
-               prom_printf("End of available virutal memory\r\n");
+               prom_printf("End of available virtual memory\r\n");
        }
 #endif
        /* 
@@ -1012,6 +1126,16 @@
                        mp1->start = s;
                        mp1->size = sz;
                }
+#ifdef DEBUG
+/* Clear all memory we give to the VM system.  I want to make sure
+ * the PROM isn't using it for something, so this should break the PROM.
+ */
+               {
+                       paddr_t p;
+                       for (p = mp->start; p < mp->start+mp->size; p += NBPG)
+                               pmap_zero_page(p);
+               }
+#endif
                /* 
                 * In future we should be able to specify both allocated
                 * and free.
@@ -1048,6 +1172,7 @@
        /*
         * Allocate and clear out pmap_kernel()->pm_segs[]
         */
+       pmap_pinit(pmap_kernel());
        {
                paddr_t newp;
 
@@ -1184,7 +1309,7 @@
                if ((vmmap ^ INTSTACK) & VA_ALIAS_MASK) 
                        vmmap += NBPG; /* Matchup virtual color for D$ */
                intstk = vmmap;
-               cpus = (struct cpu_info *)(intstk+EINTSTACK-INTSTACK);
+               cpus = (struct cpu_info *)(intstk+CPUINFO_VA-INTSTACK);
 
                BDPRINTF(PDB_BOOT1, 
                         ("Inserting cpu_info into pmap_kernel() at %p\r\n", cpus));
@@ -1233,9 +1358,6 @@
        avail_start = nextavail;
        for (mp = avail; mp->size; mp++)
                avail_end = mp->start+mp->size;
-#ifdef DEBUG
-       pmapdebug = opmapdebug;
-#endif
        BDPRINTF(PDB_BOOT1, ("Finished pmap_bootstrap()\r\n"));
 
 }
@@ -1252,6 +1374,9 @@
        psize_t size;
        vaddr_t va;
        struct pglist mlist;
+       vsize_t         s;
+       int             bank;
+       struct pv_entry *pvh;
 
        BDPRINTF(PDB_BOOT1, ("pmap_init()\r\n"));
        if (PAGE_SIZE != NBPG)
@@ -1288,6 +1413,18 @@
                pmap_enter_kpage(va, data);
                va += NBPG;
        }
+
+       /*
+        * Memory for the pv heads has already been allocated.
+        * Initialize the physical memory segments.
+        */
+       pvh = pv_table;
+       for (bank = 0; bank < vm_nphysseg; bank++) {
+               s = vm_physmem[bank].end - vm_physmem[bank].start;
+               vm_physmem[bank].pmseg.pvent = pvh;
+               pvh += s;
+       }
+
        pmap_initialized = 1;
 
        /* Setup a pool for additional pvlist structures */
@@ -1348,6 +1485,8 @@
        /*
         * Allocate some segment registers for this pmap.
         */
+       simple_lock_init(&pm->pm_lock);
+       simple_lock(&pm->pm_lock);
        pm->pm_refs = 1;
        if(pm != pmap_kernel()) {
                vm_page_t page;
@@ -1376,6 +1515,7 @@
        if (pmapdebug & PDB_CREATE)
                printf("pmap_pinit(%x): ctx %d\n", pm, pm->pm_ctx);
 #endif
+       simple_unlock(&pm->pm_lock);
 }



Home | Main Index | Thread Index | Old Index