void dumpsys() { cpu_kcore_hdr_t *h = &cpu_kcore_hdr; daddr64_t blkno; int (*dump)(dev_t, daddr64_t, caddr_t, size_t); u_int page = 0; paddr_t dumppa; u_int seg; int rc; extern int msgbufmapped; /* Don't record dump messages in msgbuf. */ msgbufmapped = 0; /* Make sure dump settings are valid. */ if (dumpdev == NODEV) return; if (dumpsize == 0) { dumpconf(); if (dumpsize == 0) return; } if (dumplo <= 0) { printf("\ndump to dev 0x%x not possible, not enough space\n", dumpdev); return; } dump = bdevsw[major(dumpdev)].d_dump; blkno = dumplo; printf("\ndumping to dev 0x%x offset %ld\n", dumpdev, dumplo); #ifdef UVM_SWAP_ENCRYPT uvm_swap_finicrypt_all(); #endif printf("dump "); /* Write dump header */ rc = cpu_dump(dump, &blkno); if (rc != 0) goto bad; for (seg = 0; seg < h->kcore_nsegs; seg++) { u_int pagesleft; pagesleft = atop(h->kcore_segs[seg].size); dumppa = (paddr_t)h->kcore_segs[seg].start; while (pagesleft != 0) { u_int npages; #define NPGMB atop(1024 * 1024) if (page != 0 && (page % NPGMB) == 0) printf("%u ", page / NPGMB); /* do not dump more than 1MB at once */ npages = min(pagesleft, NPGMB); #undef NPGMB npages = min(npages, dumpsize); rc = (*dump)(dumpdev, blkno, (caddr_t)SH3_PHYS_TO_P2SEG(dumppa), ptoa(npages)); if (rc != 0) goto bad; pagesleft -= npages; dumppa += ptoa(npages); page += npages; dumpsize -= npages; if (dumpsize == 0) goto bad; /* if truncated dump */ blkno += ctod(npages); } } bad: switch (rc) { case 0: printf("succeeded\n"); break; case ENXIO: printf("device bad\n"); break; case EFAULT: printf("device not ready\n"); break; case EINVAL: printf("area improper\n"); break; case EIO: printf("I/O error\n"); break; case EINTR: printf("aborted\n"); break; default: printf("error %d\n", rc); break; } /* make sure console can output our last message */ delay(1 * 1000 * 1000); }
void dumpsys() { const struct bdevsw *bdev; daddr_t blkno; int psize; int error; int addr; int block; int len; vaddr_t dumpspace; kcore_seg_t *kseg_p; cpu_kcore_hdr_t *chdr_p; char dump_hdr[dbtob(1)]; /* assumes header fits in one block */ /* Save registers. */ savectx(&dumppcb); /* flush everything out of caches */ cpu_dcache_wbinv_all(); cpu_sdcache_wbinv_all(); if (dumpdev == NODEV) return; if (dumpsize == 0) { dumpconf(); if (dumpsize == 0) return; } if (dumplo <= 0) { printf("\ndump to dev %u,%u not possible\n", major(dumpdev), minor(dumpdev)); return; } printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev), minor(dumpdev), dumplo); #ifdef UVM_SWAP_ENCRYPT uvm_swap_finicrypt_all(); #endif blkno = dumplo; dumpspace = (vaddr_t) memhook; bdev = bdevsw_lookup(dumpdev); if (bdev == NULL || bdev->d_psize == NULL) return; psize = (*bdev->d_psize)(dumpdev); printf("dump "); if (psize == -1) { printf("area unavailable\n"); return; } /* Setup the dump header */ kseg_p = (kcore_seg_t *)dump_hdr; chdr_p = (cpu_kcore_hdr_t *)&dump_hdr[ALIGN(sizeof(*kseg_p))]; bzero(dump_hdr, sizeof(dump_hdr)); CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU); kseg_p->c_size = sizeof(dump_hdr) - ALIGN(sizeof(*kseg_p)); *chdr_p = cpu_kcore_hdr; error = (*bdev->d_dump)(dumpdev, blkno++, (caddr_t)dump_hdr, sizeof(dump_hdr)); if (error != 0) goto abort; len = 0; for (block = 0; block < bootconfig.dramblocks && error == 0; ++block) { addr = bootconfig.dram[block].address; for (;addr < (bootconfig.dram[block].address + (bootconfig.dram[block].pages * PAGE_SIZE)); addr += PAGE_SIZE) { if ((len % (1024*1024)) == 0) printf("%d ", len / (1024*1024)); pmap_kenter_pa(dumpspace, addr, PROT_READ); pmap_update(pmap_kernel()); error = (*bdev->d_dump)(dumpdev, blkno, (caddr_t) dumpspace, PAGE_SIZE); pmap_kremove(dumpspace, PAGE_SIZE); pmap_update(pmap_kernel()); if (error) break; blkno += btodb(PAGE_SIZE); len += PAGE_SIZE; } } abort: switch (error) { case ENXIO: printf("device bad\n"); break; case EFAULT: printf("device not ready\n"); break; case EINVAL: printf("area improper\n"); break; case EIO: printf("i/o error\n"); break; case EINTR: printf("aborted from console\n"); break; default: printf("succeeded\n"); break; } printf("\n\n"); delay(1000000); }
/* * Doadump comes here after turning off memory management and * getting on the dump stack, either when called above, or by * the auto-restart code. */ void dumpsys() { int maj; int psize; daddr_t blkno; /* current block to write */ /* dump routine */ int (*dump)(dev_t, daddr_t, caddr_t, size_t); int pg; /* page being dumped */ paddr_t maddr; /* PA being dumped */ int error; /* error code from (*dump)() */ kcore_seg_t *kseg_p; cpu_kcore_hdr_t *chdr_p; char dump_hdr[dbtob(1)]; /* XXX assume hdr fits in 1 block */ extern int msgbufmapped; msgbufmapped = 0; /* Make sure dump device is valid. */ if (dumpdev == NODEV) return; if (dumpsize == 0) { dumpconf(); if (dumpsize == 0) return; } maj = major(dumpdev); if (dumplo < 0) { printf("\ndump to dev %u,%u not possible\n", maj, minor(dumpdev)); return; } dump = bdevsw[maj].d_dump; blkno = dumplo; printf("\ndumping to dev %u,%u offset %ld\n", maj, minor(dumpdev), dumplo); #ifdef UVM_SWAP_ENCRYPT uvm_swap_finicrypt_all(); #endif /* Setup the dump header */ kseg_p = (kcore_seg_t *)dump_hdr; chdr_p = (cpu_kcore_hdr_t *)&dump_hdr[ALIGN(sizeof(*kseg_p))]; bzero(dump_hdr, sizeof(dump_hdr)); CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU); kseg_p->c_size = dbtob(1) - ALIGN(sizeof(*kseg_p)); *chdr_p = cpu_kcore_hdr; printf("dump "); psize = (*bdevsw[maj].d_psize)(dumpdev); if (psize == -1) { printf("area unavailable\n"); return; } /* Dump the header. */ error = (*dump)(dumpdev, blkno++, (caddr_t)dump_hdr, dbtob(1)); if (error != 0) goto abort; maddr = (paddr_t)0; for (pg = 0; pg < dumpsize; pg++) { #define NPGMB (1024 * 1024 / PAGE_SIZE) /* print out how many MBs we have dumped */ if (pg != 0 && (pg % NPGMB) == 0) printf("%d ", pg / NPGMB); #undef NPGMB error = (*dump)(dumpdev, blkno, (caddr_t)maddr, PAGE_SIZE); if (error == 0) { maddr += PAGE_SIZE; blkno += btodb(PAGE_SIZE); } else break; } abort: switch (error) { case 0: printf("succeeded\n"); break; case ENXIO: printf("device bad\n"); break; case EFAULT: printf("device not ready\n"); break; case EINVAL: printf("area improper\n"); break; case EIO: printf("i/o error\n"); break; case EINTR: printf("aborted from console\n"); break; default: printf("error %d\n", error); break; } }