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