Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/x68k/x68k Probe extended memories before pmap_boost...
details: https://anonhg.NetBSD.org/src/rev/37047f84fc35
branches: trunk
changeset: 790925:37047f84fc35
user: tsutsui <tsutsui%NetBSD.org@localhost>
date: Sun Oct 27 02:06:06 2013 +0000
description:
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.
diffstat:
sys/arch/x68k/x68k/locore.s | 4 +-
sys/arch/x68k/x68k/machdep.c | 252 +++++++++++++++++------------------
sys/arch/x68k/x68k/pmap_bootstrap.c | 25 +--
3 files changed, 130 insertions(+), 151 deletions(-)
diffs (truncated from 448 to 300 lines):
diff -r b88492fb6131 -r 37047f84fc35 sys/arch/x68k/x68k/locore.s
--- a/sys/arch/x68k/x68k/locore.s Sat Oct 26 22:59:28 2013 +0000
+++ b/sys/arch/x68k/x68k/locore.s Sun Oct 27 02:06:06 2013 +0000
@@ -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 @@
#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
diff -r b88492fb6131 -r 37047f84fc35 sys/arch/x68k/x68k/machdep.c
--- a/sys/arch/x68k/x68k/machdep.c Sat Oct 26 22:59:28 2013 +0000
+++ b/sys/arch/x68k/x68k/machdep.c Sun Oct 27 02:06:06 2013 +0000
@@ -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 @@
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 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 @@
{
u_int i;
paddr_t msgbuf_pa;
+ paddr_t s, e;
+
+ /*
+ * 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.
+ */
+ msgbuf_pa = phys_basemem_seg.end - m68k_round_page(MSGBUFSIZE);
/*
* Tell the VM system about available physical memory.
*/
- uvm_page_physload(atop(avail_start), atop(avail_end),
- atop(avail_start), atop(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);
- /*
- * 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.
- */
- msgbuf_pa = avail_end;
-
#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 @@
#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 const struct memlist {
+ paddr_t exstart;
+ psize_t minsize;
+ psize_t maxsize;
+} memlist[] = {
+ /* We define two extended memory regions for all possible settings. */
-static struct memlist {
- void *base;
- psize_t min;
- psize_t max;
-} memlist[] = {
- /* TS-6BE16 16MB memory */
- {(void *)0x01000000, 0x01000000, 0x01000000},
- /* 060turbo SIMM slot (4--128MB) */
- {(void *)0x10000000, 0x00400000, 0x08000000},
+ /*
+ * 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 @@
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 @@
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 @@
if (*m != 0x55 || (baseismem && *b != 0xAA))
goto out;
- exists = 1;
+ exists = true;
out:
*m = save_m;
if (baseismem)
@@ -1131,100 +1154,69 @@
__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);
+ 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. Use the first and second avalable
- * pages to map the (possible) target memory and its shadow.
+ * 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.
*/
- mem_v = virtual_avail; /* target */
- base_v = mem_v + PAGE_SIZE; /* shadow */
+
+ /* save the original base memory range */
+ basemem = physmem;
- { /* Turn off the processor cache. */
- int cacr;
- PCIA(); /* cpusha dc */
Home |
Main Index |
Thread Index |
Old Index