diff options
author | grr <grr@cvs.openbsd.org> | 1997-06-11 10:32:17 +0000 |
---|---|---|
committer | grr <grr@cvs.openbsd.org> | 1997-06-11 10:32:17 +0000 |
commit | 9df4a19b899fa3a4c101303ac0a3ebabc42d6864 (patch) | |
tree | 24eedfc979b5077b618a10d4b9f8f4a0cb681e08 /sys/arch/sparc | |
parent | dd49726b3910cc1aa590ff5007c4c3e23d2153c6 (diff) |
import some cleanup for libkvm/kvm.c from netbsd, udpate libkvm so that sparc can use libkvm vs. libkvm.old and update sparc pmap.c and machdep.c to make dumps compatible with the new libkvm's notions.
Diffstat (limited to 'sys/arch/sparc')
-rw-r--r-- | sys/arch/sparc/sparc/machdep.c | 75 | ||||
-rw-r--r-- | sys/arch/sparc/sparc/pmap.c | 144 |
2 files changed, 120 insertions, 99 deletions
diff --git a/sys/arch/sparc/sparc/machdep.c b/sys/arch/sparc/sparc/machdep.c index e305fcbd69a..081e5be5204 100644 --- a/sys/arch/sparc/sparc/machdep.c +++ b/sys/arch/sparc/sparc/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.21 1997/03/26 22:14:41 niklas Exp $ */ +/* $OpenBSD: machdep.c,v 1.22 1997/06/11 10:32:11 grr Exp $ */ /* $NetBSD: machdep.c,v 1.64 1996/05/19 04:12:56 mrg Exp $ */ /* @@ -703,6 +703,7 @@ boot(howto) /*NOTREACHED*/ } +/* XXX - dumpmag not eplicitly used, savecore may search for it to get here */ u_long dumpmag = 0x8fca0101; /* magic number for savecore */ int dumpsize = 0; /* also for savecore */ long dumplo = 0; @@ -710,46 +711,39 @@ long dumplo = 0; void dumpconf() { - register int nblks, nmem; - register struct memarr *mp; - extern struct memarr pmemarr[]; /* XXX */ - extern int npmemarr; /* XXX */ + register int nblks, dumpblks; - dumpsize = 0; - for (mp = pmemarr, nmem = npmemarr; --nmem >= 0; mp++) - dumpsize += btoc(mp->len); + if (dumpdev == NODEV || bdevsw[major(dumpdev)].d_psize == 0) + /* No usable dump device */ + return; - /* - * savecore views the image in units of pages (i.e., dumpsize is in - * pages) so we round the two mmu entities into page-sized chunks. - * The PMEGs (32kB) and the segment table (512 bytes plus padding) - * are appending to the end of the crash dump. - */ - dumpsize += pmap_dumpsize(); - if (dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize) { nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev); + + dumpblks = ctod(physmem) + ctod(pmap_dumpsize()); + if (dumpblks > (nblks - ctod(1))) /* - * Don't dump on the first CLBYTES (why CLBYTES?) - * in case the dump device includes a disk label. + * dump size is too big for the partition. + * Note, we safeguard a click at the front for a + * possible disk label. */ - if (dumplo < btodb(CLBYTES)) - dumplo = btodb(CLBYTES); + return; + + /* Put the dump at the end of the partition */ + dumplo = nblks - dumpblks; /* - * If dumpsize is too big for the partition, truncate it. - * Otherwise, put the dump at the end of the partition - * by making dumplo as large as possible. - */ - if (dumpsize > btoc(dbtob(nblks - dumplo))) - dumpsize = btoc(dbtob(nblks - dumplo)); - else if (dumplo + ctod(dumpsize) > nblks) - dumplo = nblks - ctod(dumpsize); - } + * savecore(8) expects dumpsize to be the number of pages + * of actual core dumped (i.e. excluding the MMU stuff). + */ + dumpsize = physmem; } #define BYTES_PER_DUMP (32 * 1024) /* must be a multiple of pagesize */ static vm_offset_t dumpspace; +/* + * Allocate the dump i/o buffer area during kernel memory allocation + */ caddr_t reserve_dumppages(p) caddr_t p; @@ -766,7 +760,7 @@ void dumpsys() { register int psize; - register daddr_t blkno; + daddr_t blkno; register int (*dump) __P((dev_t, daddr_t, caddr_t, size_t)); int error = 0; register struct memarr *mp; @@ -787,9 +781,10 @@ dumpsys() */ if (dumpsize == 0) dumpconf(); - if (dumplo < 0) + if (dumplo <= 0) return; - printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo); + printf("\ndumping to dev(%d,%d), at offset %ld blocks\n", + major(dumpdev), minor(dumpdev), dumplo); psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev); printf("dump "); @@ -800,10 +795,16 @@ dumpsys() blkno = dumplo; dump = bdevsw[major(dumpdev)].d_dump; - for (mp = pmemarr, nmem = npmemarr; --nmem >= 0; mp++) { + printf("mmu "); + error = pmap_dumpmmu(dump, blkno); + blkno += ctod(pmap_dumpsize()); + + printf("memory "); + for (mp = pmemarr, nmem = npmemarr; --nmem >= 0 && error == 0; mp++) { register unsigned i = 0, n; register maddr = mp->addr; + /* XXX - what's so special about PA 0 that we can't dump it? */ if (maddr == 0) { /* Skip first page at physical address 0 */ maddr += NBPG; @@ -811,13 +812,15 @@ dumpsys() blkno += btodb(NBPG); } + printf("@%p:",maddr); + for (; i < mp->len; i += n) { n = mp->len - i; if (n > BYTES_PER_DUMP) n = BYTES_PER_DUMP; - /* print out how many MBs we have dumped */ - if (i && (i % (1024*1024)) == 0) + /* print out which MBs we are dumping */ + if (i % (1024*1024) <= NBPG) printf("%d ", i / (1024*1024)); (void) pmap_map(dumpspace, maddr, maddr + n, @@ -831,8 +834,6 @@ dumpsys() blkno += btodb(n); } } - if (!error) - error = pmap_dumpmmu(dump, blkno); switch (error) { diff --git a/sys/arch/sparc/sparc/pmap.c b/sys/arch/sparc/sparc/pmap.c index 07e1bc3be80..f5ec4ccc09f 100644 --- a/sys/arch/sparc/sparc/pmap.c +++ b/sys/arch/sparc/sparc/pmap.c @@ -62,6 +62,9 @@ #include <sys/proc.h> #include <sys/queue.h> #include <sys/malloc.h> +#include <sys/kcore.h> +#include <sys/core.h> +#include <sys/exec_aout.h> #include <vm/vm.h> #include <vm/vm_kern.h> @@ -73,6 +76,7 @@ #include <machine/oldmon.h> #include <machine/cpu.h> #include <machine/ctlreg.h> +#include <machine/kcore.h> #include <sparc/sparc/asm.h> #include <sparc/sparc/cache.h> @@ -6544,38 +6548,93 @@ pm_check_k(s, pm) /* Note: not as extensive as pm_check_u. */ int pmap_dumpsize() { - if (CPU_ISSUN4M) /* No need to dump on 4m; its in-core. */ - return (0); + long sz; + + sz = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)); + sz += npmemarr * sizeof(phys_ram_seg_t); if (CPU_ISSUN4OR4C) - return btoc(((seginval + 1) * NPTESG * sizeof(int)) + - sizeof(seginval) + - sizeof(pmemarr) + - sizeof(kernel_segmap_store)); - return 0; + sz += (seginval + 1) * NPTESG * sizeof(int); + + return (btoc(sz)); } /* - * Write the mmu contents to the dump device. - * This gets appended to the end of a crash dump since - * there is no in-core copy of kernel memory mappings on a 4/4c machine. + * Write the dump header and memory mapping information at the front + * of the dumpfile to make life easy for savecore and libkvm. Also + * dump the MMU contents for Sun 4/4c systems since they don't have + * a separate incore copy of the kernel memory mappings. */ int pmap_dumpmmu(dump, blkno) register daddr_t blkno; register int (*dump) __P((dev_t, daddr_t, caddr_t, size_t)); { -#if defined(SUN4C) || defined(SUN4) - register int pmeg; - register int i; - register int *pte, *ptend; + kcore_seg_t *ksegp; + cpu_kcore_hdr_t *kcpup; + phys_ram_seg_t memseg; register int error = 0; - register int *kp; + register int i, memsegoffset, pmegoffset; int buffer[dbtob(1) / sizeof(int)]; -#endif + int *bp, *ep; +#if defined(SUN4C) || defined(SUN4) + register int pmeg; +#endif + +#define EXPEDITE(p,n) do { \ + int *sp = (int *)(p); \ + int sz = (n); \ + while (sz > 0) { \ + *bp++ = *sp++; \ + if (bp >= ep) { \ + error = (*dump)(dumpdev, blkno, \ + (caddr_t)buffer, dbtob(1)); \ + if (error != 0) \ + return (error); \ + ++blkno; \ + bp = buffer; \ + } \ + sz -= sizeof *sp; \ + } \ +} while (0) - if (CPU_ISSUN4M) /* No need to dump on 4m; its in-core. */ - return (0); + setcontext(0); + + /* Setup bookkeeping pointers */ + bp = buffer; + ep = &buffer[sizeof(buffer) / sizeof(buffer[0])]; + + /* Fill in MI segment header */ + ksegp = (kcore_seg_t *)bp; + CORE_SETMAGIC(*ksegp, KCORE_MAGIC, MID_MACHINE, CORE_CPU); + ksegp->c_size = ctob(pmap_dumpsize()) - ALIGN(sizeof(kcore_seg_t)); + + /* Fill in MD segment header (interpreted by MD part of libkvm) */ + kcpup = (cpu_kcore_hdr_t *)((int)bp + ALIGN(sizeof(kcore_seg_t))); + kcpup->cputype = cputyp; + kcpup->nmemseg = npmemarr; + kcpup->memsegoffset = memsegoffset = ALIGN(sizeof(cpu_kcore_hdr_t)); + kcpup->npmeg = (CPU_ISSUN4OR4C) ? seginval + 1 : 0; + kcpup->pmegoffset = pmegoffset = + memsegoffset + npmemarr * sizeof(phys_ram_seg_t); + + /* Note: we have assumed everything fits in buffer[] so far... */ + bp = (int *)&kcpup->segmap_store; + EXPEDITE(&kernel_segmap_store, sizeof(kernel_segmap_store)); + + /* Align storage for upcoming quad-aligned segment array */ + while (bp != (int *)ALIGN(bp)) { + int dummy = 0; + EXPEDITE(&dummy, sizeof dummy); + } + for (i = 0; i < npmemarr; i++) { + memseg.start = pmemarr[i].addr; + memseg.size = pmemarr[i].len; + EXPEDITE(&memseg, sizeof(phys_ram_seg_t)); + } + + if (CPU_ISSUN4M) + goto out; #if defined(SUN4C) || defined(SUN4) /* @@ -6588,67 +6647,28 @@ pmap_dumpmmu(dump, blkno) * address argument to getpte(). */ - setcontext(0); - /* * Go through the pmegs and dump each one. */ - pte = buffer; - ptend = &buffer[sizeof(buffer) / sizeof(buffer[0])]; for (pmeg = 0; pmeg <= seginval; ++pmeg) { register int va = 0; setsegmap(va, pmeg); i = NPTESG; do { - *pte++ = getpte4(va); - if (pte >= ptend) { - /* - * Note that we'll dump the last block - * the last time through the loops because - * all the PMEGs occupy 32KB which is - * a multiple of the block size. - */ - error = (*dump)(dumpdev, blkno, - (caddr_t)buffer, - dbtob(1)); - if (error != 0) - return (error); - ++blkno; - pte = buffer; - } + int pte = getpte4(va); + EXPEDITE(&pte, sizeof(pte)); va += NBPG; } while (--i > 0); } setsegmap(0, seginval); +#endif - /* - * Next, dump # of pmegs, the physical memory table and the - * kernel's segment map. - */ - pte = buffer; - *pte++ = seginval; - *pte++ = npmemarr; - bcopy((char *)pmemarr, (char *)pte, sizeof(pmemarr)); - pte = (int *)((int)pte + sizeof(pmemarr)); - kp = (int *)kernel_segmap_store; - i = sizeof(kernel_segmap_store) / sizeof(int); - do { - *pte++ = *kp++; - if (pte >= ptend) { - error = (*dump)(dumpdev, blkno, (caddr_t)buffer, - dbtob(1)); - if (error != 0) - return (error); - ++blkno; - pte = buffer; - } - } while (--i > 0); - if (pte != buffer) +out: + if (bp != buffer) error = (*dump)(dumpdev, blkno++, (caddr_t)buffer, dbtob(1)); return (error); -#endif } #ifdef EXTREME_DEBUG |