diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2001-08-06 20:48:27 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2001-08-06 20:48:27 +0000 |
commit | d4d2211594b47ada476f6e614f10735d22ddae60 (patch) | |
tree | f5f7e00ae3e9b516bc16f0c0295465847eb80e5d /sys/arch/mvme88k | |
parent | dbd1a2f4efe2b939ec851ad710e5539829516b7f (diff) |
Working kernel crash dumps.
Diffstat (limited to 'sys/arch/mvme88k')
-rw-r--r-- | sys/arch/mvme88k/include/kcore.h | 41 | ||||
-rw-r--r-- | sys/arch/mvme88k/include/pmap.h | 3 | ||||
-rw-r--r-- | sys/arch/mvme88k/mvme88k/machdep.c | 141 |
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(); |