Module Name:    src
Committed By:   tsutsui
Date:           Sun Oct 27 02:06:06 UTC 2013

Modified Files:
        src/sys/arch/x68k/x68k: locore.s machdep.c pmap_bootstrap.c

Log Message:
Probe extended memories before pmap_boostrap() for actual fix of PR/45915.

Also expand expected maximum extended memory regions to recognize
upto 1008 MB RAM that is supported by the XM6i emulator.

See my post on port-x68k@ for more details:
http://mail-index.NetBSD.org/port-x68k/2013/10/19/msg000039.html

Probably worth to pullup to netbsd-6.


To generate a diff of this commit:
cvs rdiff -u -r1.110 -r1.111 src/sys/arch/x68k/x68k/locore.s
cvs rdiff -u -r1.186 -r1.187 src/sys/arch/x68k/x68k/machdep.c
cvs rdiff -u -r1.59 -r1.60 src/sys/arch/x68k/x68k/pmap_bootstrap.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/x68k/x68k/locore.s
diff -u src/sys/arch/x68k/x68k/locore.s:1.110 src/sys/arch/x68k/x68k/locore.s:1.111
--- src/sys/arch/x68k/x68k/locore.s:1.110	Sat May 19 08:29:32 2012
+++ src/sys/arch/x68k/x68k/locore.s	Sun Oct 27 02:06:06 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.s,v 1.110 2012/05/19 08:29:32 tsutsui Exp $	*/
+/*	$NetBSD: locore.s,v 1.111 2013/10/27 02:06:06 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -777,6 +777,8 @@ Lstart1:
 #endif
 	movl	#_C_LABEL(end),%d5	| end of static kernel text/data
 Lstart2:
+	RELOC(setmemrange,%a0)		| call setmemrange()
+	jbsr	%a0@			|  to probe all memory regions
 	addl	#PAGE_SIZE-1,%d5
 	andl	#PG_FRAME,%d5		| round to a page
 	movl	%d5,%a4

Index: src/sys/arch/x68k/x68k/machdep.c
diff -u src/sys/arch/x68k/x68k/machdep.c:1.186 src/sys/arch/x68k/x68k/machdep.c:1.187
--- src/sys/arch/x68k/x68k/machdep.c:1.186	Tue Jan 22 11:58:39 2013
+++ src/sys/arch/x68k/x68k/machdep.c	Sun Oct 27 02:06:06 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.c,v 1.186 2013/01/22 11:58:39 isaki Exp $	*/
+/*	$NetBSD: machdep.c,v 1.187 2013/10/27 02:06:06 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.186 2013/01/22 11:58:39 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.187 2013/10/27 02:06:06 tsutsui Exp $");
 
 #include "opt_ddb.h"
 #include "opt_kgdb.h"
@@ -130,10 +130,6 @@ void	initcpu(void);
 int	cpu_dumpsize(void);
 int	cpu_dump(int (*)(dev_t, daddr_t, void *, size_t), daddr_t *);
 void	cpu_init_kcore_hdr(void);
-#ifdef EXTENDED_MEMORY
-static int mem_exists(void *, u_long);
-static void setmemrange(void);
-#endif
 
 /* functions called from locore.s */
 void	x68k_init(void);
@@ -142,6 +138,24 @@ void	straytrap(int, u_short);
 void	nmihand(struct frame);
 void	intrhand(int);
 
+/* memory probe function called from locore.s */
+void	setmemrange(void);
+#ifdef EXTENDED_MEMORY
+static bool mem_exists(paddr_t, paddr_t);
+#endif
+
+typedef struct {
+	paddr_t start;
+	paddr_t end;
+} phys_seg_t;
+
+static int basemem;
+static phys_seg_t phys_basemem_seg;
+#ifdef EXTENDED_MEMORY
+#define EXTMEM_SEGS	(VM_PHYSSEG_MAX - 1)
+static phys_seg_t phys_extmem_seg[EXTMEM_SEGS];
+#endif
+
 /*
  * On the 68020/68030, the value of delay_divisor is roughly
  * 2048 / cpuspeed (where cpuspeed is in MHz).
@@ -167,24 +181,35 @@ x68k_init(void)
 {
 	u_int i;
 	paddr_t msgbuf_pa;
+	paddr_t s, e;
 
 	/*
-	 * Tell the VM system about available physical memory.
+	 * Most m68k ports allocate msgbuf at the end of available memory
+	 * (i.e. just after avail_end), but on x68k we allocate msgbuf
+	 * at the end of main memory for compatibility.
 	 */
-	uvm_page_physload(atop(avail_start), atop(avail_end),
-	    atop(avail_start), atop(avail_end),
-	    VM_FREELIST_MAINMEM);
+	msgbuf_pa = phys_basemem_seg.end - m68k_round_page(MSGBUFSIZE);
 
 	/*
-	 * avail_end was pre-decremented in pmap_bootstrap to compensate
-	 * for msgbuf pages, but avail_end is also used to check DMA'able
-	 * memory range for intio devices and it would be updated per
-	 * probed extended memories, so explicitly save msgbuf address here.
+	 * Tell the VM system about available physical memory.
 	 */
-	msgbuf_pa = avail_end;
+	/* load the main memory region */
+	s = avail_start;
+	e = msgbuf_pa;
+	uvm_page_physload(atop(s), atop(e), atop(s), atop(e),
+	    VM_FREELIST_MAINMEM);
 
 #ifdef EXTENDED_MEMORY
-	setmemrange();
+	/* load extended memory regions */
+	for (i = 0; i < EXTMEM_SEGS; i++) {
+		if (phys_extmem_seg[i].start == phys_extmem_seg[i].end)
+			continue;
+		uvm_page_physload(atop(phys_extmem_seg[i].start),
+		    atop(phys_extmem_seg[i].end),
+		    atop(phys_extmem_seg[i].start),
+		    atop(phys_extmem_seg[i].end),
+		    VM_FREELIST_HIGHMEM);
+	}
 #endif
 
 	/*
@@ -1011,57 +1036,63 @@ module_init_md(void)
 #endif
 
 #ifdef EXTENDED_MEMORY
-#ifdef EM_DEBUG
-static int em_debug = 0;
-#define DPRINTF(str) do{ if (em_debug) printf str; } while (0);
-#else
-#define DPRINTF(str)
-#endif
 
-static struct memlist {
-	void *base;
-	psize_t min;
-	psize_t max;
+static const struct memlist {
+	paddr_t exstart;
+	psize_t minsize;
+	psize_t maxsize;
 } memlist[] = {
-	/* TS-6BE16 16MB memory */
-	{(void *)0x01000000, 0x01000000, 0x01000000},
-	/* 060turbo SIMM slot (4--128MB) */
-	{(void *)0x10000000, 0x00400000, 0x08000000},
+	/* We define two extended memory regions for all possible settings. */
+
+	/*
+	 * The first region is at 0x01000000:
+	 *
+	 *  TS-6BE16:	16MB at 0x01000000 (to 0x01FFFFFF)
+	 *  XM6i:	4MB - 240MB at 0x01000000 (upto 0x0FFFFFFF)
+	 */
+	{ 0x01000000, 0x00400000, 0x0f000000 },
+
+	/*
+	 * The second region is at 0x10000000:
+	 *
+	 * 060turbo:	4MB - 128MB at 0x10000000 (upto 0x17FFFFFF)
+	 * XM6i:	4MB - 768MB at 0x10000000 (upto 0x3FFFFFFF)
+	 */
+	{ 0x10000000, 0x00400000, 0x30000000 },
 };
-static vaddr_t mem_v, base_v;
+
+/* check each 4MB region */
+#define EXTMEM_RANGE	(4 * 1024 * 1024)
 
 /*
  * check memory existency
  */
-static int
-mem_exists(void *mem, u_long basemax)
+static bool
+mem_exists(paddr_t mem, paddr_t basemax)
 {
 	/* most variables must be register! */
 	volatile unsigned char *m, *b;
 	unsigned char save_m, save_b=0;	/* XXX: shutup gcc */
-	int baseismem;
-	int exists = 0;
+	bool baseismem;
+	bool exists = false;
 	void *base;
 	void *begin_check, *end_check;
 	label_t	faultbuf;
 
-	DPRINTF(("Enter mem_exists(%p, %lx)\n", mem, basemax));
-	DPRINTF((" pmap_enter(%" PRIxVADDR ", %p) for target... ", mem_v, mem));
-	pmap_enter(pmap_kernel(), mem_v, (paddr_t)mem,
-	    VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|PMAP_WIRED);
-	pmap_update(pmap_kernel());
-	DPRINTF((" done.\n"));
+	/*
+	 * In this function we assume:
+	 *  - MMU is not enabled yet but PA == VA
+	 *    (i.e. no RELOC() macro to convert PA to VA)
+	 *  - bus error can be caught by setjmp()
+	 *    (i.e. %vbr register is initialized properly)
+	 *  - all memory cache is not enabled
+	 */
 
 	/* only 24bits are significant on normal X680x0 systems */
-	base = (void *)((u_long)mem & 0x00FFFFFF);
-	DPRINTF((" pmap_enter(%" PRIxVADDR ", %p) for shadow... ", base_v, base));
-	pmap_enter(pmap_kernel(), base_v, (paddr_t)base,
-	    VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|PMAP_WIRED);
-	pmap_update(pmap_kernel());
-	DPRINTF((" done.\n"));
+	base = (void *)(mem & 0x00FFFFFF);
 
-	m = (void *)mem_v;
-	b = (void *)base_v;
+	m = (void *)mem;
+	b = (void *)base;
 
 	/* This is somewhat paranoid -- avoid overwriting myself */
 	__asm("lea %%pc@(begin_check_mem),%0" : "=a"(begin_check));
@@ -1069,7 +1100,6 @@ mem_exists(void *mem, u_long basemax)
 	if (base >= begin_check && base < end_check) {
 		size_t off = (char *)end_check - (char *)begin_check;
 
-		DPRINTF((" Adjusting the testing area.\n"));
 		m -= off;
 		b -= off;
 	}
@@ -1077,16 +1107,9 @@ mem_exists(void *mem, u_long basemax)
 	nofault = (int *)&faultbuf;
 	if (setjmp((label_t *)nofault)) {
 		nofault = (int *)0;
-		pmap_remove(pmap_kernel(), mem_v, mem_v+PAGE_SIZE);
-		pmap_remove(pmap_kernel(), base_v, base_v+PAGE_SIZE);
-		pmap_update(pmap_kernel());
-		DPRINTF(("Fault!!! Returning 0.\n"));
-		return 0;
+		return false;
 	}
 
-	DPRINTF((" Let's begin. mem=%p, base=%p, m=%p, b=%p\n",
-	    mem, base, m, b));
-
 	(void)*m;
 	/*
 	 * Can't check by writing if the corresponding
@@ -1122,7 +1145,7 @@ __asm("begin_check_mem:");
 	if (*m != 0x55 || (baseismem && *b != 0xAA))
 		goto out;
 
-	exists = 1;
+	exists = true;
 out:
 	*m = save_m;
 	if (baseismem)
@@ -1131,100 +1154,69 @@ out:
 __asm("end_check_mem:");
 
 	nofault = (int *)0;
-	pmap_remove(pmap_kernel(), mem_v, mem_v+PAGE_SIZE);
-	pmap_remove(pmap_kernel(), base_v, base_v+PAGE_SIZE);
-	pmap_update(pmap_kernel());
-
-	DPRINTF((" End.\n"));
-
-	DPRINTF(("Returning from mem_exists. result = %d\n", exists));
 
 	return exists;
 }
+#endif
 
-static void
+void
 setmemrange(void)
 {
+#ifdef EXTENDED_MEMORY
 	int i;
-	psize_t s, minimum, maximum;
-	struct memlist *mlist = memlist;
-	u_long h;
-	int basemax = ctob(physmem);
-
-	/*
-	 * VM system is not started yet.  Use the first and second avalable
-	 * pages to map the (possible) target memory and its shadow.
-	 */
-	mem_v = virtual_avail;		/* target */
-	base_v = mem_v + PAGE_SIZE;	/* shadow */
-
-	{	/* Turn off the processor cache. */
-		int cacr;
-		PCIA();		/* cpusha dc */
-		switch (cputype) {
-		default:
-		case CPU_68030:
-			cacr = CACHE_OFF;
-			break;
-		case CPU_68040:
-			cacr = CACHE40_OFF;
-			break;
-		case CPU_68060:
-			cacr = CACHE60_OFF;
-			break;
-		}
-		__asm volatile ("movc %0,%%cacr"::"d"(cacr));
-	}
+	paddr_t exstart, exend;
+	psize_t size, minsize, maxsize;
+	const struct memlist *mlist = memlist;
+	paddr_t basemax = m68k_ptob(physmem);
+#endif
+
+	/*
+	 * VM system is not started yet, and even MMU is not enabled here.
+	 * We assume VA == PA and don't bother to use RELOC() macro
+	 * as pmap_bootstrap() does.
+	 */
+
+	/* save the original base memory range */
+	basemem = physmem;
+
+	/*
+	 * XXX
+	 * Probably we should also probe the main memory region
+	 * for machines which might have a wrong value in a dead SRAM.
+	 */
+	phys_basemem_seg.start = lowram;
+	phys_basemem_seg.end   = m68k_ptob(basemem) + lowram;
 
+#ifdef EXTENDED_MEMORY
 	/* discover extended memory */
-	for (i = 0; i < sizeof(memlist) / sizeof(memlist[0]); i++) {
-		minimum = mlist[i].min;
-		maximum = mlist[i].max;
+	for (i = 0; i < __arraycount(memlist); i++) {
+		exstart = mlist[i].exstart;
+		minsize = mlist[i].minsize;
+		maxsize = mlist[i].maxsize;
 		/*
 		 * Normally, x68k hardware is NOT 32bit-clean.
 		 * But some type of extended memory is in 32bit address space.
 		 * Check whether.
 		 */
-		if (!mem_exists(mlist[i].base, basemax))
+		if (!mem_exists(exstart, basemax))
 			continue;
-		h = 0;
+		exend = 0;
 		/* range check */
-		for (s = minimum; s <= maximum; s += 0x00100000) {
-			if (!mem_exists((char*)mlist[i].base + s - 4, basemax))
+		for (size = minsize; size <= maxsize; size += EXTMEM_RANGE) {
+			if (!mem_exists(exstart + size - 4, basemax))
 				break;
-			h = (u_long)((char*)mlist[i].base + s);
+			exend = exstart + size;
 		}
-		if ((u_long)mlist[i].base < h) {
-			uvm_page_physload(atop(mlist[i].base), atop(h),
-			    atop(mlist[i].base), atop(h),
-			    VM_FREELIST_HIGHMEM);
-			mem_size += h - (u_long) mlist[i].base;
-			if (avail_end < h)
-				avail_end = h;
-		}
-	}
-
-	{	/* Re-enable the processor cache. */
-		int cacr;
-		ICIA();
-		switch (cputype) {
-		default:
-		case CPU_68030:
-			cacr = CACHE_ON;
-			break;
-		case CPU_68040:
-			cacr = CACHE40_ON;
-			break;
-		case CPU_68060:
-			cacr = CACHE60_ON;
-			break;
+		if (exstart < exend) {
+			phys_extmem_seg[i].start = exstart;
+			phys_extmem_seg[i].end   = exend;
+			physmem += m68k_btop(exend - exstart);
+			if (maxmem < m68k_btop(exend))
+				maxmem = m68k_btop(exend);
 		}
-		__asm volatile ("movc %0,%%cacr"::"d"(cacr));
 	}
-
-	physmem = m68k_btop(mem_size);
-}
 #endif
+}
 
 volatile int ssir;
 int idepth;

Index: src/sys/arch/x68k/x68k/pmap_bootstrap.c
diff -u src/sys/arch/x68k/x68k/pmap_bootstrap.c:1.59 src/sys/arch/x68k/x68k/pmap_bootstrap.c:1.60
--- src/sys/arch/x68k/x68k/pmap_bootstrap.c:1.59	Sat Feb 25 02:43:08 2012
+++ src/sys/arch/x68k/x68k/pmap_bootstrap.c	Sun Oct 27 02:06:06 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap_bootstrap.c,v 1.59 2012/02/25 02:43:08 tsutsui Exp $	*/
+/*	$NetBSD: pmap_bootstrap.c,v 1.60 2013/10/27 02:06:06 tsutsui Exp $	*/
 
 /* 
  * Copyright (c) 1991, 1993
@@ -36,10 +36,9 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.59 2012/02/25 02:43:08 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap_bootstrap.c,v 1.60 2013/10/27 02:06:06 tsutsui Exp $");
 
 #include "opt_m68k_arch.h"
-#include "opt_extmem.h"
 
 #include <sys/param.h>
 #include <uvm/uvm_extern.h>
@@ -125,19 +124,6 @@ pmap_bootstrap(paddr_t nextpa, paddr_t f
 	kptpa = nextpa;
 	nptpages = RELOC(Sysptsize, int) + howmany(RELOC(physmem, int), NPTEPG) +
 		(IIOMAPSIZE + NPTEPG - 1) / NPTEPG;
-#ifdef EXTENDED_MEMORY
-	/*
-	 * Current supported maximum EXTENDED_MEMORY is 128MB on 060turbo.
-	 */
-#define MAX_EXTENDED_MEMORY	(128 * 1024 * 1024)
-	nptpages += howmany(btoc(MAX_EXTENDED_MEMORY), NPTEPG);
-
-	/*
-	 * mem_exist() in machdep.c needs two extra VA pages before pmap_init()
-	 * to probe >16MB memory.
-	 */
-	nptpages += 1;
-#endif
 	nextpa += nptpages * PAGE_SIZE;
 
 	/*
@@ -413,12 +399,11 @@ pmap_bootstrap(paddr_t nextpa, paddr_t f
 	 * VM data structures are now initialized, set up data for
 	 * the pmap module.
 	 *
-	 * Note about avail_end: msgbuf is initialized just after
-	 * avail_end in machdep.c.
+	 * Note about avail_end: msgbuf is initialized at the end of
+	 * main memory region (not after avail_end) in machdep.c.
 	 */
 	RELOC(avail_start, paddr_t) = nextpa;
-	RELOC(avail_end, paddr_t) = m68k_ptob(RELOC(maxmem, int)) -
-	    m68k_round_page(MSGBUFSIZE);
+	RELOC(avail_end, paddr_t) = m68k_ptob(RELOC(maxmem, int));
 	RELOC(mem_size, psize_t) = m68k_ptob(RELOC(physmem, int));
 	RELOC(virtual_end, vaddr_t) = VM_MAX_KERNEL_ADDRESS;
 

Reply via email to