diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2005-10-09 14:01:12 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2005-10-09 14:01:12 +0000 |
commit | 395f0ee15c63f65382729c43f538d5564ffb2177 (patch) | |
tree | 305f8e2122751e4b18184b2a4a1e975a54d9b0d1 /sys/arch | |
parent | d36956cc5016e7586888bc9868dbc2b8334c726f (diff) |
Nearly functional crashdump support for macppc. Because savecore
does not recognize the resulting crashdumps, the writing has been disabled.
Better here than in my forest of trees.
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/macppc/include/powerpc.h | 9 | ||||
-rw-r--r-- | sys/arch/macppc/macppc/autoconf.c | 57 | ||||
-rw-r--r-- | sys/arch/macppc/macppc/clock.c | 3 | ||||
-rw-r--r-- | sys/arch/macppc/macppc/machdep.c | 161 | ||||
-rw-r--r-- | sys/arch/powerpc/include/pmap.h | 3 | ||||
-rw-r--r-- | sys/arch/powerpc/powerpc/pmap.c | 10 |
6 files changed, 186 insertions, 57 deletions
diff --git a/sys/arch/macppc/include/powerpc.h b/sys/arch/macppc/include/powerpc.h index 4a34f0cd251..64dca7da010 100644 --- a/sys/arch/macppc/include/powerpc.h +++ b/sys/arch/macppc/include/powerpc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: powerpc.h,v 1.6 2002/09/15 09:01:58 deraadt Exp $ */ +/* $OpenBSD: powerpc.h,v 1.7 2005/10/09 14:01:11 drahn Exp $ */ /* $NetBSD: powerpc.h,v 1.1 1996/09/30 16:34:30 ws Exp $ */ /* @@ -82,4 +82,11 @@ void install_extint(void (*handler) (void)); void ppc_intr_enable(int enable); int ppc_intr_disable(void); +struct dumpmem { + vaddr_t start; + vm_size_t end; +}; +extern struct dumpmem dumpmem[VM_PHYSSEG_MAX]; +extern u_int ndumpmem; +extern vaddr_t dumpspace; #endif /* _MACHINE_POWERPC_H_ */ diff --git a/sys/arch/macppc/macppc/autoconf.c b/sys/arch/macppc/macppc/autoconf.c index f6650b37e2f..262565bcecf 100644 --- a/sys/arch/macppc/macppc/autoconf.c +++ b/sys/arch/macppc/macppc/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.16 2005/04/21 00:15:42 deraadt Exp $ */ +/* $OpenBSD: autoconf.c,v 1.17 2005/10/09 14:01:11 drahn Exp $ */ /* * Copyright (c) 1996, 1997 Per Fogelstrom * Copyright (c) 1995 Theo de Raadt @@ -37,7 +37,7 @@ * from: Utah Hdr: autoconf.c 1.31 91/01/21 * * from: @(#)autoconf.c 8.1 (Berkeley) 6/10/93 - * $Id: autoconf.c,v 1.16 2005/04/21 00:15:42 deraadt Exp $ + * $Id: autoconf.c,v 1.17 2005/10/09 14:01:11 drahn Exp $ */ /* @@ -58,11 +58,12 @@ #include <dev/cons.h> #include <uvm/uvm_extern.h> #include <machine/autoconf.h> +#include <machine/powerpc.h> struct device *parsedisk(char *, int, int, dev_t *); void setroot(void); void swapconf(void); -extern void dumpconf(void); +void dumpconf(void); int findblkmajor(struct device *); char *findblkname(int); static struct device * getdisk(char *, int, int, dev_t *); @@ -81,6 +82,9 @@ int cold = 1; /* if 1, still working on cold-start */ char bootdev[16]; /* to hold boot dev name */ struct device *bootdv = NULL; +struct dumpmem dumpmem[VM_PHYSSEG_MAX]; +u_int ndumpmem; + /* * Configure all devices found that we know about. * This is done at boot time. @@ -125,9 +129,7 @@ diskconf() #endif setroot(); swapconf(); -#if 0 dumpconf(); -#endif } /* @@ -149,56 +151,11 @@ swapconf() swp->sw_nblks = ctod(dtoc(swp->sw_nblks)); } } -#if 0 - dumpconf(); -#endif } /* * Crash dump handling. */ -u_long dumpmag = 0x8fca0101; /* magic number */ -int dumpsize = 0; /* size of dump in pages */ -long dumplo = -1; /* blocks */ - -/* - * This is called by configure 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 is extra space, put dump at the end to - * reduce the chance that swapping trashes it. - */ -#if 0 -void -dumpconf() -{ - 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 = btoc(IOM_END + ctob(dumpmem_high)); - - /* 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); -} -#endif static struct nam2blk { char *name; diff --git a/sys/arch/macppc/macppc/clock.c b/sys/arch/macppc/macppc/clock.c index c71737311d7..d934478ea54 100644 --- a/sys/arch/macppc/macppc/clock.c +++ b/sys/arch/macppc/macppc/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.14 2004/06/28 02:49:10 aaron Exp $ */ +/* $OpenBSD: clock.c,v 1.15 2005/10/09 14:01:11 drahn Exp $ */ /* $NetBSD: clock.c,v 1.1 1996/09/30 16:34:40 ws Exp $ */ /* @@ -40,6 +40,7 @@ #include <machine/autoconf.h> #include <machine/pio.h> #include <machine/intr.h> +#include <machine/vmparam.h> #include <machine/powerpc.h> #include <dev/ofw/openfirm.h> diff --git a/sys/arch/macppc/macppc/machdep.c b/sys/arch/macppc/macppc/machdep.c index 09ccd65f14d..fe1ec99a0bc 100644 --- a/sys/arch/macppc/macppc/machdep.c +++ b/sys/arch/macppc/macppc/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.74 2005/10/03 04:47:30 drahn Exp $ */ +/* $OpenBSD: machdep.c,v 1.75 2005/10/09 14:01:11 drahn Exp $ */ /* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */ /* @@ -48,6 +48,9 @@ #include <sys/extent.h> #include <sys/systm.h> #include <sys/user.h> +#include <sys/conf.h> +#include <sys/core.h> +#include <sys/kcore.h> #include <uvm/uvm_extern.h> @@ -776,10 +779,164 @@ cpu_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, } } + +u_long dumpmag = 0x04959fca; /* magic number */ +int dumpsize = 0; /* size of dump in pages */ +long dumplo = -1; /* blocks */ + +/* + * This is called by configure 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 is extra space, put dump at the end to + * reduce the chance that swapping trashes it. + */ +void dumpconf(void); +void +dumpconf() +{ + int nblks; /* size of dump area */ + int maj; + int i; + + + 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; + + /* Always skip the first block, in case there is a label there. */ + + if (dumplo < ctod(1)) + dumplo = ctod(1); + + for (i = 0; i < ndumpmem; i++) + dumpsize = max(dumpsize, dumpmem[i].end); + + /* Put dump at end of partition, and make it fit. */ + if (dumpsize > dtoc(nblks - dumplo - 1)) + dumpsize = dtoc(nblks - dumplo - 1); + if (dumplo < nblks - ctod(dumpsize) - 1) + dumplo = nblks - ctod(dumpsize) - 1; + +} + +#define BYTES_PER_DUMP (PAGE_SIZE) /* must be a multiple of pagesize */ +vaddr_t dumpspace; + +int +reserve_dumppages(caddr_t p) +{ + dumpspace = (vaddr_t)p; + return BYTES_PER_DUMP; +} + +/* + * cpu_dump: dump machine-dependent kernel core dump headers. + */ +int cpu_dump(void); +int +cpu_dump() +{ + int (*dump) (dev_t, daddr_t, caddr_t, size_t); + long buf[dbtob(1) / sizeof (long)]; + kcore_seg_t *segp; + + dump = bdevsw[major(dumpdev)].d_dump; + + segp = (kcore_seg_t *)buf; + + /* + * Generate a segment header. + */ + CORE_SETMAGIC(*segp, KCORE_MAGIC, MID_MACHINE, CORE_CPU); + segp->c_size = dbtob(1) - ALIGN(sizeof(*segp)); + + return (dump(dumpdev, dumplo, (caddr_t)buf, dbtob(1))); +} + void dumpsys() { - printf("dumpsys: TBD\n"); +#if 0 + u_int npg; + u_int i, j; + daddr_t blkno; + int (*dump) (dev_t, daddr_t, caddr_t, size_t); + char *str; + int maddr; + extern int msgbufmapped; + int error; + + /* save registers */ + + msgbufmapped = 0; /* don't record dump msgs in msgbuf */ + if (dumpdev == NODEV) + return; + /* + * For dumps during autoconfiguration, + * if dump device has already configured... + */ + if (dumpsize == 0) + dumpconf(); + if (dumplo < 0) + return; + printf("dumping to dev %x, offset %ld\n", dumpdev, dumplo); + + error = (*bdevsw[major(dumpdev)].d_psize)(dumpdev); + if (error == -1) { + printf("area unavailable\n"); + delay (10000000); + return; + } + + dump = bdevsw[major(dumpdev)].d_dump; + error = cpu_dump(); + for (i = 0; !error && i < ndumpmem; i++) { + npg = dumpmem[i].end - dumpmem[i].start; + maddr = ctob(dumpmem[i].start); + blkno = dumplo + btodb(maddr) + 1; + + for (j = npg; j; + j--, maddr += PAGE_SIZE, blkno+= btodb(PAGE_SIZE)) + { + /* Print out how many MBs we have to go. */ + if (dbtob(blkno - dumplo) % (1024 * 1024) < NBPG) + printf("%d ", + (ctob(dumpsize) - maddr) / (1024 * 1024)); + + pmap_enter(pmap_kernel(), dumpspace, maddr, + VM_PROT_READ, PMAP_WIRED); + if ((error = (*dump)(dumpdev, blkno, + (caddr_t)dumpspace, PAGE_SIZE)) != 0) + break; + } + } + + switch (error) { + + case 0: str = "succeeded\n\n"; break; + case ENXIO: str = "device bad\n\n"; break; + case EFAULT: str = "device not ready\n\n"; break; + case EINVAL: str = "area improper\n\n"; break; + case EIO: str = "i/o error\n\n"; break; + case EINTR: str = "aborted from console\n\n"; break; + default: str = "error %d\n\n"; break; + } + printf(str, error); + +#else + printf("dumpsys() - no yet supported\n"); + +#endif + delay(5000000); /* 5 seconds */ + } volatile int cpl, ipending, astpending; diff --git a/sys/arch/powerpc/include/pmap.h b/sys/arch/powerpc/include/pmap.h index 039b320cbbf..dafc5d78490 100644 --- a/sys/arch/powerpc/include/pmap.h +++ b/sys/arch/powerpc/include/pmap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.h,v 1.39 2005/10/03 02:18:50 drahn Exp $ */ +/* $OpenBSD: pmap.h,v 1.40 2005/10/09 14:01:11 drahn Exp $ */ /* $NetBSD: pmap.h,v 1.1 1996/09/30 16:34:29 ws Exp $ */ /*- @@ -134,6 +134,7 @@ void switchexit(struct proc *); int pte_spill_v(struct pmap *pm, u_int32_t va, u_int32_t dsisr, int exec_fault); #define pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr) ; +int reserve_dumppages(caddr_t p); void pmap_proc_iflush(struct proc *proc, vaddr_t va, vsize_t len); #define pmap_unuse_final(p) /* nothing */ diff --git a/sys/arch/powerpc/powerpc/pmap.c b/sys/arch/powerpc/powerpc/pmap.c index 68dcb6eefd5..2e61469ae1b 100644 --- a/sys/arch/powerpc/powerpc/pmap.c +++ b/sys/arch/powerpc/powerpc/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.92 2005/10/08 06:03:00 drahn Exp $ */ +/* $OpenBSD: pmap.c,v 1.93 2005/10/09 14:01:11 drahn Exp $ */ /* * Copyright (c) 2001, 2002 Dale Rahn. @@ -1319,8 +1319,12 @@ pmap_avail_setup(void) pmap_cnt_avail = 0; physmem = 0; - for (mp = pmap_mem; mp->size !=0; mp++) + ndumpmem = 0; + for (mp = pmap_mem; mp->size !=0; mp++, ndumpmem++) { physmem += btoc(mp->size); + dumpmem[ndumpmem].start = atop(mp->start); + dumpmem[ndumpmem].end = atop(mp->start + mp->size); + } for (mp = pmap_avail; mp->size !=0 ; mp++) { if (physmaxaddr < mp->start + mp->size) @@ -1565,6 +1569,8 @@ pmap_bootstrap(u_int kernelstart, u_int kernelend) ppc_kvm_stolen += PAGE_SIZE; copy_dst_page = VM_MIN_KERNEL_ADDRESS + ppc_kvm_stolen; ppc_kvm_stolen += PAGE_SIZE; + ppc_kvm_stolen += reserve_dumppages( (caddr_t)(VM_MIN_KERNEL_ADDRESS + + ppc_kvm_stolen)); /* |