summaryrefslogtreecommitdiff
path: root/sys/arch/mvme88k
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2001-08-06 20:48:27 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2001-08-06 20:48:27 +0000
commitd4d2211594b47ada476f6e614f10735d22ddae60 (patch)
treef5f7e00ae3e9b516bc16f0c0295465847eb80e5d /sys/arch/mvme88k
parentdbd1a2f4efe2b939ec851ad710e5539829516b7f (diff)
Working kernel crash dumps.
Diffstat (limited to 'sys/arch/mvme88k')
-rw-r--r--sys/arch/mvme88k/include/kcore.h41
-rw-r--r--sys/arch/mvme88k/include/pmap.h3
-rw-r--r--sys/arch/mvme88k/mvme88k/machdep.c141
3 files changed, 162 insertions, 23 deletions
diff --git a/sys/arch/mvme88k/include/kcore.h b/sys/arch/mvme88k/include/kcore.h
new file mode 100644
index 00000000000..43300abcb3c
--- /dev/null
+++ b/sys/arch/mvme88k/include/kcore.h
@@ -0,0 +1,41 @@
+/* $OpenBSD: kcore.h,v 1.1 2001/08/06 20:48:22 miod Exp $ */
+
+/*
+ * Copyright (c) 2001 Miodrag Vallat.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MVME88K_KCORE_H_
+#define _MVME88K_KCORE_H_
+
+/* Keep this define consistent with VM_PHYSSEG_MAX in <machine/vmparam.h> */
+#define NPHYS_RAM_SEGS 1
+
+typedef struct cpu_kcore_hdr {
+ int cputype; /* board type: 187, 188, 197 */
+ phys_ram_seg_t ram_segs[NPHYS_RAM_SEGS];
+} cpu_kcore_hdr_t;
+
+#endif /* _MVME88K_KCORE_H_ */
diff --git a/sys/arch/mvme88k/include/pmap.h b/sys/arch/mvme88k/include/pmap.h
index 35b6ca62894..8c7d1f647e7 100644
--- a/sys/arch/mvme88k/include/pmap.h
+++ b/sys/arch/mvme88k/include/pmap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.h,v 1.12 2001/06/14 21:30:40 miod Exp $ */
+/* $OpenBSD: pmap.h,v 1.13 2001/08/06 20:48:22 miod Exp $ */
/*
* Mach Operating System
* Copyright (c) 1991 Carnegie Mellon University
@@ -70,6 +70,7 @@ typedef struct pv_entry {
#ifdef _KERNEL
extern struct pmap kernel_pmap_store;
+extern caddr_t vmmap;
#define pmap_kernel() (&kernel_pmap_store)
#define pmap_resident_count(pmap) ((pmap)->stats.resident_count)
diff --git a/sys/arch/mvme88k/mvme88k/machdep.c b/sys/arch/mvme88k/mvme88k/machdep.c
index 52cb6d7d8ea..1cfc48a1f88 100644
--- a/sys/arch/mvme88k/mvme88k/machdep.c
+++ b/sys/arch/mvme88k/mvme88k/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.47 2001/08/05 20:35:46 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.48 2001/08/06 20:48:26 miod Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -75,6 +75,8 @@
#include <sys/sysctl.h>
#include <sys/errno.h>
#include <sys/extent.h>
+#include <sys/core.h>
+#include <sys/kcore.h>
#include <net/netisr.h>
@@ -88,6 +90,7 @@
#include <machine/prom.h>
#include <machine/m88100.h> /* DMT_VALID */
#include <machine/m882xx.h> /* CMMU stuff */
+#include <machine/kcore.h>
#include <dev/cons.h>
@@ -1188,26 +1191,51 @@ m188_reset(void)
unsigned dumpmag = 0x8fca0101; /* magic number for savecore */
int dumpsize = 0; /* also for savecore */
long dumplo = 0;
+cpu_kcore_hdr_t cpu_kcore_hdr;
+/*
+ * This is called by configure to set dumplo and dumpsize.
+ * Dumps always skip the first PAGE_SIZE of disk space
+ * in case there might be a disk label stored there.
+ * If there is extra space, put dump at the end to
+ * reduce the chance that swapping trashes it.
+ */
void
dumpconf()
{
- int nblks;
+ int nblks; /* size of dump area */
+ int maj;
+
+ if (dumpdev == NODEV)
+ return;
+ maj = major(dumpdev);
+ if (maj < 0 || maj >= nblkdev)
+ panic("dumpconf: bad dumpdev=0x%x", dumpdev);
+ if (bdevsw[maj].d_psize == NULL)
+ return;
+ nblks = (*bdevsw[maj].d_psize)(dumpdev);
+ if (nblks <= ctod(1))
+ return;
dumpsize = physmem;
- if (dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize) {
- nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
- if (dumpsize > btoc(dbtob(nblks - dumplo)))
- dumpsize = btoc(dbtob(nblks - dumplo));
- else if (dumplo == 0)
- dumplo = nblks - btodb(ctob(physmem));
- }
+
+ /* mvme88k only uses a single segment. */
+ cpu_kcore_hdr.ram_segs[0].start = 0;
+ cpu_kcore_hdr.ram_segs[0].size = ctob(physmem);
+ cpu_kcore_hdr.cputype = cputyp;
+
/*
* Don't dump on the first block
* in case the dump device includes a disk label.
*/
- if (dumplo < btodb(PAGE_SIZE))
- dumplo = btodb(PAGE_SIZE);
+ if (dumplo < ctod(1))
+ dumplo = ctod(1);
+
+ /* Put dump at end of partition, and make it fit. */
+ if (dumpsize + 1 > dtoc(nblks - dumplo))
+ dumpsize = dtoc(nblks - dumplo) - 1;
+ if (dumplo < nblks - ctod(dumpsize) - 1)
+ dumplo = nblks - ctod(dumpsize) - 1;
}
/*
@@ -1218,37 +1246,108 @@ dumpconf()
void
dumpsys()
{
+ int maj;
+ int psize;
+ daddr_t blkno; /* current block to write */
+ /* dump routine */
+ int (*dump) __P((dev_t, daddr_t, caddr_t, size_t));
+ int pg; /* page being dumped */
+ paddr_t maddr; /* PA being dumped */
+ int error; /* error code from (*dump)() */
+ kcore_seg_t *kseg_p;
+ cpu_kcore_hdr_t *chdr_p;
+ char dump_hdr[dbtob(1)]; /* XXX assume hdr fits in 1 block */
+
extern int msgbufmapped;
msgbufmapped = 0;
+
+ /* Make sure dump device is valid. */
if (dumpdev == NODEV)
return;
- /*
- * For dumps during autoconfiguration,
- * if dump device has already configured...
- */
- if (dumpsize == 0)
+ if (dumpsize == 0) {
dumpconf();
- if (dumplo < 0)
+ if (dumpsize == 0)
+ return;
+ }
+ maj = major(dumpdev);
+ if (dumplo < 0) {
+ printf("\ndump to dev %u,%u not possible\n", maj,
+ minor(dumpdev));
return;
- printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
+ }
+ dump = bdevsw[maj].d_dump;
+ blkno = dumplo;
+
+ printf("\ndumping to dev %u,%u offset %ld\n", maj,
+ minor(dumpdev), dumplo);
+
+ /* Setup the dump header */
+ kseg_p = (kcore_seg_t *)dump_hdr;
+ chdr_p = (cpu_kcore_hdr_t *)&dump_hdr[ALIGN(sizeof(*kseg_p))];
+ bzero(dump_hdr, sizeof(dump_hdr));
+
+ CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
+ kseg_p->c_size = dbtob(1) - ALIGN(sizeof(*kseg_p));
+ *chdr_p = cpu_kcore_hdr;
+
printf("dump ");
- switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) {
+ psize = (*bdevsw[maj].d_psize)(dumpdev);
+ if (psize == -1) {
+ printf("area unavailable\n");
+ return;
+ }
+
+ /* Dump the header. */
+ error = (*dump)(dumpdev, blkno++, (caddr_t)dump_hdr, dbtob(1));
+ if (error != 0)
+ goto abort;
+
+ maddr = (paddr_t)0;
+ for (pg = 0; pg < dumpsize; pg++) {
+#define NPGMB (1024 * 1024 / PAGE_SIZE)
+ /* print out how many MBs we have dumped */
+ if (pg != 0 && (pg % NPGMB) == 0)
+ printf("%d ", pg / NPGMB);
+#undef NPGMB
+ pmap_enter(pmap_kernel(), (vaddr_t)vmmap, maddr,
+ VM_PROT_READ, VM_PROT_READ|PMAP_WIRED);
+
+ error = (*dump)(dumpdev, blkno, vmmap, PAGE_SIZE);
+ if (error == 0) {
+ maddr += PAGE_SIZE;
+ blkno += btodb(PAGE_SIZE);
+ } else
+ break;
+ }
+abort:
+ switch (error) {
+ case 0:
+ printf("succeeded\n");
+ break;
case ENXIO:
printf("device bad\n");
break;
+
case EFAULT:
printf("device not ready\n");
break;
+
case EINVAL:
printf("area improper\n");
break;
+
case EIO:
printf("i/o error\n");
break;
+
+ case EINTR:
+ printf("aborted from console\n");
+ break;
+
default:
- printf("succeeded\n");
+ printf("error %d\n", error);
break;
}
}
@@ -2151,8 +2250,6 @@ mvme_bootstrap(void)
uvm_setpagesize();
first_addr = round_page(first_addr);
- if (!no_symbols) boothowto |= RB_KDB;
-
last_addr = size_memory();
cmmu_parity_enable();