diff options
author | Jason Downs <downsj@cvs.openbsd.org> | 1999-04-23 05:15:29 +0000 |
---|---|---|
committer | Jason Downs <downsj@cvs.openbsd.org> | 1999-04-23 05:15:29 +0000 |
commit | a54c82f1145fecbd3bed0a3e580cd173fca09099 (patch) | |
tree | 39bb24214ee9e78a357798ed12d8620991cee1ec /sys | |
parent | fcea8e3f7eb9a12a5936af5ac46b9c2ea110f24c (diff) |
Kcore dump, from NetBSD.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/mac68k/mac68k/machdep.c | 353 | ||||
-rw-r--r-- | sys/arch/mac68k/mac68k/pmap_bootstrap.c | 6 |
2 files changed, 190 insertions, 169 deletions
diff --git a/sys/arch/mac68k/mac68k/machdep.c b/sys/arch/mac68k/mac68k/machdep.c index 094b2656d34..008cc7bb57d 100644 --- a/sys/arch/mac68k/mac68k/machdep.c +++ b/sys/arch/mac68k/mac68k/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.57 1999/04/22 00:35:04 downsj Exp $ */ +/* $OpenBSD: machdep.c,v 1.58 1999/04/23 05:15:28 downsj Exp $ */ /* $NetBSD: machdep.c,v 1.134 1997/02/14 06:15:30 scottr Exp $ */ /* @@ -86,6 +86,8 @@ #include <sys/proc.h> #include <sys/buf.h> #include <sys/exec.h> +#include <sys/core.h> +#include <sys/kcore.h> #include <sys/vnode.h> #include <sys/reboot.h> #include <sys/conf.h> @@ -121,7 +123,9 @@ #include <machine/reg.h> #include <machine/psl.h> #include <machine/pte.h> +#include <machine/kcore.h> #include <machine/bus.h> +#include <machine/pmap.h> #include <net/netisr.h> void netintr __P((void)); @@ -235,12 +239,21 @@ struct extent *iomem_ex; int iomem_malloc_safe; /* XXX should be in locore.s for consistency */ -int astpending=0; -int want_resched=0; +int astpending = 0; +int want_resched = 0; static void identifycpu __P((void)); static u_long get_physical __P((u_int, u_long *)); -void dumpsys __P((void)); + +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)); +void dumpsys __P((void)); + +/* + * Machine-dependent crash dump header info. + */ +cpu_kcore_hdr_t cpu_kcore_hdr; /* * Console initialization: called early on from main, @@ -289,6 +302,11 @@ cpu_startup(void) int delay; /* + * Initialize the kernel crash dump header. + */ + cpu_init_kcore_hdr(); + + /* * Initialize error message buffer (at end of core). * high[numranges-1] was decremented in pmap_bootstrap. */ @@ -643,27 +661,77 @@ boot(howto) } /* - * These variables are needed by /sbin/savecore + * Initialize the kernel crash dump header. */ -u_long dumpmag = 0x8fca0101; /* magic number */ -int dumpsize = 0; /* pages */ -long dumplo = 0; /* blocks */ +void +cpu_init_kcore_hdr() +{ + cpu_kcore_hdr_t *h = &cpu_kcore_hdr; + int i; -static int get_max_page __P((void)); + bzero(&cpu_kcore_hdr, sizeof(cpu_kcore_hdr)); -static int -get_max_page() -{ - int i, max = 0; + h->mmutype = mmutype; + h->kernel_pa = low[0]; + h->sysseg_pa = pmap_kernel()->pm_stpa; + /* + * mac68k has multiple RAM segments on some models. + */ for (i = 0; i < numranges; i++) { - if (high[i] > max) - max = high[i]; + h->ram_segs[i].start = low[i]; + h->ram_segs[i].size = high[i] - low[i]; } - return max; } /* + * Compute the size of the machine-dependent crash dump header. + * Returns size in disk blocks. + */ +int +cpu_dumpsize() +{ + int size; + + size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)); + return (btodb(roundup(size, dbtob(1)))); +} + +/* + * Called by dumpsys() to dump the machine-dependent header. + */ +int +cpu_dump(dump, blknop) + int (*dump) __P((dev_t, daddr_t, caddr_t, size_t)); + daddr_t *blknop; +{ + int buf[dbtob(1) / sizeof(int)]; + cpu_kcore_hdr_t *chdr; + kcore_seg_t *kseg; + int error; + + kseg = (kcore_seg_t *)buf; + chdr = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(kcore_seg_t)) / + sizeof(int)]; + + /* Create the segment header. */ + CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU); + kseg->c_size = dbtob(1) - ALIGN(sizeof(kcore_seg_t)); + + bcopy(&cpu_kcore_hdr, chdr, sizeof(cpu_kcore_hdr_t)); + error = (*dump)(dumpdev, *blknop, (caddr_t)buf, sizeof(buf)); + *blknop += btodb(sizeof(buf)); + return (error); +} + +/* + * These variables are needed by /sbin/savecore + */ +u_long dumpmag = 0x8fca0101; /* magic number */ +int dumpsize = 0; /* pages */ +long dumplo = 0; /* blocks */ + +/* * This is called by main to set dumplo and dumpsize. * Dumps always skip the first CLBYTES of disk space in * case there might be a disk label stored there. If there @@ -673,8 +741,11 @@ get_max_page() void dumpconf() { - int nblks; - int maj; + cpu_kcore_hdr_t *h = &cpu_kcore_hdr; + int chdrsize; /* size of dump header */ + int nblks; /* size of dump area */ + int maj; + int i; if (dumpdev == NODEV) return; @@ -682,179 +753,131 @@ dumpconf() maj = major(dumpdev); if (maj < 0 || maj >= nblkdev) panic("dumpconf: bad dumpdev=0x%x", dumpdev); - if (bdevsw[maj].d_psize == NULL) + if (bdevsw[maj].d_psize == NULL) { + printf ("dumpconf: returning for d_psize\n"); return; - nblks = (*bdevsw[maj].d_psize) (dumpdev); - if (nblks <= ctod(1)) - return; - - dumpsize = btoc(get_max_page()); - - /* Always skip the first CLBYTES, in case there is a label there. */ - if (dumplo < ctod(1)) - dumplo = ctod(1); - - /* Put dump at end of partition, and make it fit. */ - if (dumpsize > dtoc(nblks - dumplo)) - dumpsize = dtoc(nblks - dumplo); - if (dumplo < nblks - ctod(dumpsize)) - dumplo = nblks - ctod(dumpsize); -} - -/* - * Doadump comes here after turning off memory management and - * getting on the dump stack, either when called above, or by - * the auto-restart code. - */ -#define BYTES_PER_DUMP NBPG /* Must be a multiple of pagesize XXX small */ -static vm_offset_t dumpspace; - -vm_offset_t reserve_dumppages __P((vm_offset_t)); -static int find_range __P((vm_offset_t)); -static int find_next_range __P((vm_offset_t)); - -vm_offset_t -reserve_dumppages(p) - vm_offset_t p; -{ - dumpspace = p; - return (p + BYTES_PER_DUMP); -} - -static int -find_range(pa) - vm_offset_t pa; -{ - int i; - - for (i = 0; i < numranges; i++) { - if (low[i] <= pa && pa < high[i]) - return i; } - return -1; -} + nblks = (*bdevsw[maj].d_psize)(dumpdev); + chdrsize = cpu_dumpsize(); -static int -find_next_range(pa) - vm_offset_t pa; -{ - int i, near, best, t; + dumpsize = 0; + for (i = 0; h->ram_segs[i].size && i < NPHYS_RAM_SEGS; i++) + dumpsize += btoc(h->ram_segs[i].size); - near = -1; - best = 0x7FFFFFFF; - for (i = 0; i < numranges; i++) { - if (low[i] <= pa && pa < high[i]) - return i; - t = low[i] - pa; - if (t > 0) { - if (t < best) { - near = i; - best = t; - } - } + /* + * Check to see if we will fit. Note we always skip the + * first CLBYTES in case there is a disk label there. + */ + if (nblks < (ctod(dumpsize) + chdrsize + ctod(1))) { + dumpsize = 0; + dumplo = -1; + return; } - return near; + + /* + * Put dump at the end of the partition. + */ + dumplo = (nblks - 1) - ctod(dumpsize) - chdrsize; } void dumpsys() { - unsigned bytes, i, n; - int range; - int maddr, psize; - daddr_t blkno; - int (*dump) __P((dev_t, daddr_t, caddr_t, size_t)); - int error = 0; - - msgbufmapped = 0; /* don't record dump msgs in msgbuf */ + cpu_kcore_hdr_t *h = &cpu_kcore_hdr; + 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 */ + vm_offset_t maddr; /* PA being dumped */ + int seg; /* RAM segment being dumped */ + int error; /* error code from (*dump)() */ + + /* XXX initialized here because of gcc lossage */ + seg = 0; + maddr = h->ram_segs[seg].start; + pg = 0; + + /* Don't record dump msgs in msgbuf. */ + 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) - return; - printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo); - - psize = (*bdevsw[major(dumpdev)].d_psize) (dumpdev); - printf("dump "); - if (psize == -1) { - printf("area unavailable.\n"); + if (dumpsize == 0) + return; + } + if (dumplo <= 0) { + printf("\ndump to dev %u,%u not possible\n", major(dumpdev), + minor(dumpdev)); return; } - bytes = get_max_page(); - maddr = 0; - range = find_range(0); - blkno = dumplo; dump = bdevsw[major(dumpdev)].d_dump; - for (i = 0; i < bytes; i += n) { - /* - * Avoid dumping "holes." - */ - if ((range == -1) || (i >= high[range])) { - range = find_next_range(i); - if (range == -1) { - error = EIO; - break; + blkno = dumplo; + + printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev), + minor(dumpdev), dumplo); + + printf("dump "); + + /* Write the dump header. */ + error = cpu_dump(dump, &blkno); + if (error) + goto bad; + + for (pg = 0; pg < dumpsize; pg++) { +#define NPGMB (1024*1024/NBPG) + /* print out how many MBs we have dumped */ + if (pg && (pg % NPGMB) == 0) + printf("%d ", pg / NPGMB); +#undef NPGMB + while (maddr >= + (h->ram_segs[seg].start + h->ram_segs[seg].size)) { + if (++seg >= NPHYS_RAM_SEGS || + h->ram_segs[seg].size == 0) { + error = EINVAL; /* XXX ?? */ + goto bad; } - n = low[range] - i; - maddr += n; - blkno += btodb(n); - continue; + maddr = h->ram_segs[seg].start; } - /* Print out how many MBs we have to go. */ - n = bytes - i; - if (n && (n % (1024 * 1024)) == 0) - printf("%d ", n / (1024 * 1024)); - - /* Limit size for next transfer. */ - if (n > BYTES_PER_DUMP) - n = BYTES_PER_DUMP; - - (void) pmap_map(dumpspace, maddr, maddr + n, VM_PROT_READ); - error = (*dump) (dumpdev, blkno, (caddr_t) dumpspace, n); - if (error) - break; - maddr += n; - blkno += btodb(n); /* XXX? */ - } - - switch (error) { + pmap_enter(pmap_kernel(), (vm_offset_t)vmmap, maddr, + VM_PROT_READ, TRUE); - case ENXIO: - printf("device bad\n"); - break; + error = (*dump)(dumpdev, blkno, vmmap, NBPG); + bad: + switch (error) { + case 0: + maddr += NBPG; + blkno += btodb(NBPG); + break; - case EFAULT: - printf("device not ready\n"); - break; + case ENXIO: + printf("device bad\n"); + return; - case EINVAL: - printf("area improper\n"); - break; + case EFAULT: + printf("device not ready\n"); + return; - case EIO: - printf("i/o error\n"); - break; + case EINVAL: + printf("area improper\n"); + return; - case EINTR: - printf("aborted from console\n"); - break; + case EIO: + printf("i/o error\n"); + return; - case 0: - printf("succeeded\n"); - break; + case EINTR: + printf("aborted from console\n"); + return; - default: - printf("error %d\n", error); - break; + default: + printf("error %d\n", error); + return; + } } - printf("\n\n"); - delay(5000000); /* 5 seconds */ + printf("succeeded\n"); } /* diff --git a/sys/arch/mac68k/mac68k/pmap_bootstrap.c b/sys/arch/mac68k/mac68k/pmap_bootstrap.c index 3e87a4fc0d8..7cbe7ed1820 100644 --- a/sys/arch/mac68k/mac68k/pmap_bootstrap.c +++ b/sys/arch/mac68k/mac68k/pmap_bootstrap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap_bootstrap.c,v 1.10 1999/01/11 05:11:37 millert Exp $ */ +/* $OpenBSD: pmap_bootstrap.c,v 1.11 1999/04/23 05:15:28 downsj Exp $ */ /* $NetBSD: pmap_bootstrap.c,v 1.30 1997/01/07 07:44:01 scottr Exp $ */ /* @@ -73,8 +73,6 @@ extern vm_offset_t virtual_avail, virtual_end; extern vm_size_t mem_size; extern int protection_codes[]; -extern vm_offset_t reserve_dumppages __P((vm_offset_t)); - /* * These are used to map the RAM: */ @@ -552,7 +550,7 @@ pmap_bootstrap(nextpa, firstpa) va += NBPG; msgbufp = (struct msgbuf *)va; va += NBPG; - virtual_avail = reserve_dumppages(va); + virtual_avail = va; } } |