diff options
Diffstat (limited to 'sys')
-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 |