Switch the i386 port to the new kernel crash dump format.

This commit is contained in:
thorpej 1998-02-18 01:09:25 +00:00
parent 9084f293a7
commit b7d1ce7766
2 changed files with 200 additions and 53 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.290 1998/02/11 03:03:52 thorpej Exp $ */
/* $NetBSD: machdep.c,v 1.291 1998/02/18 01:09:25 thorpej Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@ -6,7 +6,7 @@
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center.
* NASA Ames Research Center and by Chris G. Demetriou.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -105,6 +105,9 @@
#include <sys/device.h>
#include <sys/extent.h>
#include <sys/syscallargs.h>
#include <sys/core.h>
#include <sys/kcore.h>
#include <machine/kcore.h>
#ifdef SYSVMSG
#include <sys/msg.h>
#endif
@ -262,7 +265,16 @@ struct extent *ioport_ex;
struct extent *iomem_ex;
static ioport_malloc_safe;
/*
* Size of memory segments, before any memory is stolen.
*/
phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX];
int mem_cluster_cnt;
caddr_t allocsys __P((caddr_t));
int cpu_dump __P((void));
int cpu_dumpsize __P((void));
u_long cpu_dump_mempagecnt __P((void));
void dumpsys __P((void));
void identifycpu __P((void));
void init386 __P((vm_offset_t));
@ -1320,6 +1332,81 @@ u_long dumpmag = 0x8fca0101; /* magic number */
int dumpsize = 0; /* pages */
long dumplo = 0; /* blocks */
/*
* cpu_dumpsize: calculate size of machine-dependent kernel core dump headers.
*/
int
cpu_dumpsize()
{
int size;
size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)) +
ALIGN(mem_cluster_cnt * sizeof(phys_ram_seg_t));
if (roundup(size, dbtob(1)) != dbtob(1))
return (-1);
return (1);
}
/*
* cpu_dump_mempagecnt: calculate the size of RAM (in pages) to be dumped.
*/
u_long
cpu_dump_mempagecnt()
{
u_long i, n;
n = 0;
for (i = 0; i < mem_cluster_cnt; i++)
n += atop(mem_clusters[i].size);
return (n);
}
/*
* cpu_dump: dump the machine-dependent kernel core dump headers.
*/
int
cpu_dump()
{
int (*dump) __P((dev_t, daddr_t, caddr_t, size_t));
char buf[dbtob(1)];
kcore_seg_t *segp;
cpu_kcore_hdr_t *cpuhdrp;
phys_ram_seg_t *memsegp;
int i;
extern u_long PTDpaddr; /* from locore */
dump = bdevsw[major(dumpdev)].d_dump;
bzero(buf, sizeof buf);
segp = (kcore_seg_t *)buf;
cpuhdrp = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(*segp))];
memsegp = (phys_ram_seg_t *)&buf[ ALIGN(sizeof(*segp)) +
ALIGN(sizeof(*cpuhdrp))];
/*
* Generate a segment header.
*/
CORE_SETMAGIC(*segp, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
segp->c_size = dbtob(1) - ALIGN(sizeof(*segp));
/*
* Add the machine-dependent header info.
*/
cpuhdrp->ptdpaddr = PTDpaddr;
cpuhdrp->nmemsegs = mem_cluster_cnt;
/*
* Fill in the memory segment descriptors.
*/
for (i = 0; i < mem_cluster_cnt; i++) {
memsegp[i].start = mem_clusters[i].start;
memsegp[i].size = mem_clusters[i].size;
}
return (dump(dumpdev, dumplo, (caddr_t)buf, dbtob(1)));
}
/*
* This is called by main to set dumplo and dumpsize.
* Dumps always skip the first CLBYTES of disk space
@ -1330,31 +1417,38 @@ long dumplo = 0; /* blocks */
void
cpu_dumpconf()
{
int nblks; /* size of dump area */
int nblks, dumpblks; /* size of dump area */
int maj;
if (dumpdev == NODEV)
return;
goto bad;
maj = major(dumpdev);
if (maj < 0 || maj >= nblkdev)
panic("dumpconf: bad dumpdev=0x%x", dumpdev);
if (bdevsw[maj].d_psize == NULL)
return;
goto bad;
nblks = (*bdevsw[maj].d_psize)(dumpdev);
if (nblks <= ctod(1))
return;
goto bad;
dumpsize = btoc(IOM_END + ctob(dumpmem_high));
dumpblks = cpu_dumpsize();
if (dumpblks < 0)
goto bad;
dumpblks += ctod(cpu_dump_mempagecnt());
/* Always skip the first CLBYTES, in case there is a label there. */
if (dumplo < ctod(1))
dumplo = ctod(1);
/* If dump won't fit (incl. room for possible label), punt. */
if (dumpblks > (nblks - ctod(1)))
goto bad;
/* 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);
/* Put dump at end of partition */
dumplo = nblks - dumpblks;
/* dumpsize is in page units, and doesn't include headers. */
dumpsize = cpu_dump_mempagecnt();
return;
bad:
dumpsize = 0;
}
/*
@ -1377,8 +1471,9 @@ reserve_dumppages(p)
void
dumpsys()
{
unsigned bytes, i, n;
int maddr, psize;
u_long totalbytesleft, bytes, i, n, memseg;
u_long maddr;
int psize;
daddr_t blkno;
int (*dump) __P((dev_t, daddr_t, caddr_t, size_t));
int error;
@ -1416,48 +1511,48 @@ dumpsys()
while (sget() != NULL); /*syscons and pccons differ */
#endif
bytes = ctob(dumpmem_high) + IOM_END;
maddr = 0;
blkno = dumplo;
if ((error = cpu_dump()) != 0)
goto err;
totalbytesleft = ptoa(cpu_dump_mempagecnt());
blkno = dumplo + cpu_dumpsize();
dump = bdevsw[major(dumpdev)].d_dump;
error = 0;
for (i = 0; i < bytes; i += n) {
/*
* Avoid dumping the ISA memory hole, and areas that
* BIOS claims aren't in low memory.
*/
if (i >= ctob(dumpmem_low) && i < IOM_END) {
n = IOM_END - i;
for (memseg = 0; memseg < mem_cluster_cnt; memseg++) {
maddr = mem_clusters[memseg].start;
bytes = mem_clusters[memseg].size;
for (i = 0; i < bytes; i += n, totalbytesleft -= n) {
/* Print out how many MBs we have left to go. */
if ((totalbytesleft % (1024*1024)) == 0)
printf("%ld ", totalbytesleft / (1024 * 1024));
/* Limit size for next transfer. */
n = bytes - i;
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)
goto err;
maddr += n;
blkno += btodb(n);
continue;
}
/* Print out how many MBs we 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? */
blkno += btodb(n); /* XXX? */
#if 0 /* XXX this doesn't work. grr. */
/* operator aborting dump? */
if (sget() != NULL) {
error = EINTR;
break;
}
/* operator aborting dump? */
if (sget() != NULL) {
error = EINTR;
break;
}
#endif
}
}
err:
switch (error) {
case ENXIO:
@ -1767,8 +1862,14 @@ init386(first_avail)
/* number of pages of physmem addr space */
physmem = btoc(biosbasemem * 1024) + btoc(biosextmem * 1024);
dumpmem_low = btoc(biosbasemem * 1024);
dumpmem_high = btoc(biosextmem * 1024);
mem_clusters[0].start = 0;
mem_clusters[0].size = trunc_page(biosbasemem * 1024);
mem_clusters[1].start = IOM_END;
mem_clusters[1].size = trunc_page(biosextmem * 1024);
mem_cluster_cnt = 2;
if (physmem < btoc(2 * 1024 * 1024)) {
printf("warning: too little memory available; "

View File

@ -0,0 +1,46 @@
/* $NetBSD: kcore.h,v 1.1 1998/02/18 01:09:26 thorpej Exp $ */
/*
* Copyright (c) 1996 Carnegie-Mellon University.
* All rights reserved.
*
* Author: Chris G. Demetriou
*
* Permission to use, copy, modify and distribute this software and
* its documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
/*
* Modified for NetBSD/i386 by Jason R. Thorpe, Numerical Aerospace
* Simulation Facility, NASA Ames Research Center.
*/
#ifndef _I386_KCORE_H_
#define _I386_KCORE_H_
typedef struct cpu_kcore_hdr {
u_int32_t ptdpaddr; /* PA of PTD */
u_int32_t nmemsegs; /* Number of RAM segments */
#if 0
phys_ram_seg_t memsegs[]; /* RAM segments */
#endif
} cpu_kcore_hdr_t;
#endif /* _I386_KCORE_H_ */