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 Move high-memory detect routine.
details: https://anonhg.NetBSD.org/src/rev/51c62f3a623a
branches: trunk
changeset: 467327:51c62f3a623a
user: minoura <minoura%NetBSD.org@localhost>
date: Tue Mar 23 04:18:50 1999 +0000
description:
Move high-memory detect routine.
This seems to fix the problem that it hangs up on 040turbo without
high-memory.
diffstat:
sys/arch/x68k/x68k/machdep.c | 260 ++++++++++++++++++++++++++++++-----
sys/arch/x68k/x68k/pmap_bootstrap.c | 215 +-----------------------------
2 files changed, 223 insertions(+), 252 deletions(-)
diffs (truncated from 569 to 300 lines):
diff -r f9f55b7b5854 -r 51c62f3a623a sys/arch/x68k/x68k/machdep.c
--- a/sys/arch/x68k/x68k/machdep.c Tue Mar 23 03:53:26 1999 +0000
+++ b/sys/arch/x68k/x68k/machdep.c Tue Mar 23 04:18:50 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.52 1999/03/18 12:27:07 minoura Exp $ */
+/* $NetBSD: machdep.c,v 1.53 1999/03/23 04:18:50 minoura Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -140,15 +140,8 @@
vm_map_t buffer_map;
#endif
-extern paddr_t avail_start;
-
-#ifdef EXTENDED_MEMORY
-extern int numranges;
-extern u_long low[8];
-extern u_long high[8];
-#else
-extern paddr_t avail_end;
-#endif
+extern paddr_t avail_start, avail_end;
+extern vaddr_t virtual_avail;
/*
* Declare these as initialized data so we can patch them.
@@ -192,6 +185,10 @@
int cpu_dumpsize __P((void));
int cpu_dump __P((int (*)(dev_t, daddr_t, caddr_t, size_t), daddr_t *));
void cpu_init_kcore_hdr __P((void));
+#ifdef EXTENDED_MEMORY
+static int mem_exists __P((caddr_t, u_long));
+static void setmemrange __P((void));
+#endif
/* functions called from locore.s */
void dumpsys __P((void));
@@ -212,10 +209,6 @@
void
consinit()
{
-#ifdef EXTENDED_MEMORY
- int i;
-#endif
-
/*
* Set cpuspeed immediately since cninit() called routines
* might use delay. Note that we only set it if a custom value
@@ -250,31 +243,15 @@
* Tell the VM system about available physical memory.
*/
#if defined(UVM)
-#ifdef EXTENDED_MEMORY
- for (i = 0; i < numranges; i++) {
- paddr_t startmem = i == 0 ? avail_start : low[i];
-
- uvm_page_physload(atop(startmem), atop(high[i]),
- atop(startmem), atop(high[i]),
- VM_FREELIST_DEFAULT);
- }
-#else
uvm_page_physload(atop(avail_start), atop(avail_end),
atop(avail_start), atop(avail_end),
VM_FREELIST_DEFAULT);
-#endif
#else /* not UVM */
-#ifdef EXTENDED_MEMORY
- for (i = 0; i < numranges; i++) {
- paddr_t startmem = i == 0 ? avail_start : low[i];
-
- vm_page_physload(atop(startmem), atop(high[i]),
- atop(startmem), atop(high[i]));
- }
-#else
vm_page_physload(atop(avail_start), atop(avail_end),
atop(avail_start), atop(avail_end));
#endif
+#ifdef EXTENDED_MEMORY
+ setmemrange();
#endif
}
@@ -305,13 +282,8 @@
* avail_end was pre-decremented in pmap_bootstrap to compensate.
*/
for (i = 0; i < btoc(MSGBUFSIZE); i++)
-#ifdef EXTENDED_MEMORY
- pmap_enter(pmap_kernel(), (vaddr_t)msgbufaddr + i * NBPG,
- high[numranges - 1] + i * NBPG, VM_PROT_ALL, TRUE);
-#else
pmap_enter(pmap_kernel(), (vaddr_t)msgbufaddr + i * NBPG,
avail_end + i * NBPG, VM_PROT_ALL, TRUE);
-#endif
initmsgbuf(msgbufaddr, m68k_round_page(MSGBUFSIZE));
/*
@@ -853,8 +825,8 @@
/*
* X68k has multiple RAM segments on some models.
*/
- m->ram_segs[0].start = ctob(lowram);
- m->ram_segs[0].size = mem_size;
+ m->ram_segs[0].start = lowram;
+ m->ram_segs[0].size = mem_size - lowram;
for (i = 1; i < vm_nphysseg; i++) {
m->ram_segs[i].start = ctob(vm_physmem[i].start);
m->ram_segs[i].size = ctob(vm_physmem[i].end)
@@ -1415,3 +1387,213 @@
return ENOEXEC;
#endif
}
+
+#ifdef EXTENDED_MEMORY
+static int em_debug = 1;
+#define DPRINTF(str) do{ if (em_debug) printf str; } while (0);
+
+static struct memlist {
+ caddr_t base;
+ psize_t min;
+ psize_t max;
+} memlist[] = {
+ (caddr_t)0x01000000, 0x01000000, 0x01000000, /* TS-6BE16 16MB memory */
+ (caddr_t)0x10000000, 0x00400000, 0x08000000, /* 060turbo SIMM slot (4--128MB) */
+};
+static vaddr_t mem_v, base_v;
+
+/*
+ * check memory existency
+ */
+static int
+mem_exists(mem, basemax)
+ caddr_t mem;
+ u_long basemax;
+{
+ /* most variables must be register! */
+ register volatile unsigned char *m, *b;
+ register unsigned char save_m, save_b;
+ register int baseismem;
+ register int exists = 0;
+ caddr_t base;
+ caddr_t begin_check, end_check;
+ label_t faultbuf;
+
+ DPRINTF (("Enter mem_exists(%p, %x)\n", mem, basemax));
+ DPRINTF ((" pmap_enter(%p, %p) for target... ", mem_v, mem));
+ pmap_enter(pmap_kernel(), mem_v, (paddr_t)mem,
+ VM_PROT_READ|VM_PROT_WRITE, TRUE);
+ DPRINTF ((" done.\n"));
+
+ /* only 24bits are significant on normal X680x0 systems */
+ base = (caddr_t)((u_long)mem & 0x00FFFFFF);
+ DPRINTF ((" pmap_enter(%p, %p) for shadow... ", base_v, base));
+ pmap_enter(pmap_kernel(), base_v, (paddr_t)base,
+ VM_PROT_READ|VM_PROT_WRITE, TRUE);
+ DPRINTF ((" done.\n"));
+
+ m = (void*)mem_v;
+ b = (void*)base_v;
+
+ /* This is somewhat paranoid -- avoid overwriting myself */
+ asm("lea pc@(begin_check_mem),%0" : "=a"(begin_check));
+ asm("lea pc@(end_check_mem),%0" : "=a"(end_check));
+ if (base >= begin_check && base < end_check) {
+ size_t off = end_check - begin_check;
+
+ DPRINTF ((" Adjusting the testing area.\n"));
+ m -= off;
+ b -= off;
+ }
+
+ nofault = (int *) &faultbuf;
+ if (setjmp ((label_t *)nofault)) {
+ nofault = (int *) 0;
+ pmap_remove(pmap_kernel(), mem_v, mem_v+NBPG);
+ pmap_remove(pmap_kernel(), base_v, base_v+NBPG);
+ DPRINTF (("Fault!!! Returning 0.\n"));
+ return 0;
+ }
+
+ 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
+ * base address isn't memory.
+ *
+ * I hope this would be no harm....
+ */
+ baseismem = base < (caddr_t)basemax;
+
+ /* save original value (base must be saved first) */
+ if (baseismem)
+ save_b = *b;
+ save_m = *m;
+
+asm("begin_check_mem:");
+ /*
+ * stack and other data segment variables are unusable
+ * til end_check_mem, because they may be clobbered.
+ */
+
+ /*
+ * check memory by writing/reading
+ */
+ if (baseismem)
+ *b = 0x55;
+ *m = 0xAA;
+ if ((baseismem && *b != 0x55) || *m != 0xAA)
+ goto out;
+
+ *m = 0x55;
+ if (baseismem)
+ *b = 0xAA;
+ if (*m != 0x55 || (baseismem && *b != 0xAA))
+ goto out;
+
+ exists = 1;
+out:
+ *m = save_m;
+ if (baseismem)
+ *b = save_b;
+
+asm("end_check_mem:");
+
+ nofault = (int *)0;
+ pmap_remove(pmap_kernel(), mem_v, mem_v+NBPG);
+ pmap_remove(pmap_kernel(), base_v, base_v+NBPG);
+
+ DPRINTF ((" End."));
+
+ DPRINTF (("Returning from mem_exists. result = %d\n", exists));
+
+ return exists;
+}
+
+static void
+setmemrange(void)
+{
+ int i;
+ psize_t s, min, max;
+ struct memlist *mlist = memlist;
+ int nranges;
+ u_long h;
+
+ /*
+ * 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 + NBPG; /* shadow */
+
+ { /* Turn off the processor cache. */
+ register int cacr;
+ PCIA(); /* cpusha dc */
+ switch (cputype) {
+ 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));
+ }
+
+ /* discover extended memory */
+ for (i = 0; i < sizeof(memlist) / sizeof(memlist[0]); i++) {
+ min = mlist[i].min;
+ max = mlist[i].max;
+ /*
+ * 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, avail_end))
+ continue;
+ h = 0;
+ /* range check */
+ for (s = min; s <= max; s += 0x00100000) {
+ if (!mem_exists(mlist[i].base + s - 4, h))
+ break;
+ h = (u_long)(mlist[i].base + s);
+ }
+ if ((u_long)mlist[i].base < h) {
+#ifdef UVM
+ uvm_page_physload((vaddr_t)mlist[i].base, h,
+ (vaddr_t)mlist[i].base, h,
+ VM_FREELIST_DEFAULT);
+#else /* not UVM */
+ vm_page_physload((vaddr_t)mlist[i].base, h,
+ (vaddr_t)mlist[i].base, h);
+#endif
+ mem_size += h - (u_long) mlist[i].base;
+ }
+
Home |
Main Index |
Thread Index |
Old Index