diff options
author | markj <markj@FreeBSD.org> | 2015-01-07 01:01:39 +0000 |
---|---|---|
committer | markj <markj@FreeBSD.org> | 2015-01-07 01:01:39 +0000 |
commit | 7e7e145818dbebec11d3fb1dded0452f0c3d99f9 (patch) | |
tree | 6d50f1ee65f4ceaf3fa5c14faf47e9ecd3aae3e5 /sys/sparc64 | |
parent | d7969594c9a8a347e4914f5381da2436c1a93710 (diff) | |
download | FreeBSD-src-7e7e145818dbebec11d3fb1dded0452f0c3d99f9.zip FreeBSD-src-7e7e145818dbebec11d3fb1dded0452f0c3d99f9.tar.gz |
Factor out duplicated code from dumpsys() on each architecture into generic
code in sys/kern/kern_dump.c. Most dumpsys() implementations are nearly
identical and simply redefine a number of constants and helper subroutines;
a generic implementation will make it easier to implement features around
kernel core dumps. This change does not alter any minidump code and should
have no functional impact.
PR: 193873
Differential Revision: https://reviews.freebsd.org/D904
Submitted by: Conrad Meyer <conrad.meyer@isilon.com>
Reviewed by: jhibbits (earlier version)
Sponsored by: EMC / Isilon Storage Division
Diffstat (limited to 'sys/sparc64')
-rw-r--r-- | sys/sparc64/include/dump.h | 76 | ||||
-rw-r--r-- | sys/sparc64/sparc64/dump_machdep.c | 117 |
2 files changed, 107 insertions, 86 deletions
diff --git a/sys/sparc64/include/dump.h b/sys/sparc64/include/dump.h new file mode 100644 index 0000000..aee0f58 --- /dev/null +++ b/sys/sparc64/include/dump.h @@ -0,0 +1,76 @@ +/*- + * Copyright (c) 2014 EMC Corp. + * Author: Conrad Meyer <conrad.meyer@isilon.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE_DUMP_H_ +#define _MACHINE_DUMP_H_ + +#define DUMPSYS_MD_PA_NPAIRS 128 +#define DUMPSYS_NUM_AUX_HDRS 0 +#define KERNELDUMP_ARCH_VERSION KERNELDUMP_SPARC64_VERSION +#define EM_VALUE EM_SPARCV9 + +void dumpsys_pa_init(void); +int dumpsys(struct dumperinfo *); + +static inline struct dump_pa * +dumpsys_pa_next(struct dump_pa *p) +{ + + return (dumpsys_gen_pa_next(p)); +} + +static inline void +dumpsys_wbinv_all(void) +{ + + dumpsys_gen_wbinv_all(); +} + +static inline void +dumpsys_unmap_chunk(vm_paddr_t pa, size_t s, void *va) +{ + + dumpsys_gen_unmap_chunk(pa, s, va); +} + +static inline int +dumpsys_write_aux_headers(struct dumperinfo *di) +{ + + return (dumpsys_gen_write_aux_headers(di)); +} + +static inline int +minidumpsys(struct dumperinfo *di) +{ + + return (-ENOSYS); +} + +#endif /* !_MACHINE_DUMP_H_ */ diff --git a/sys/sparc64/sparc64/dump_machdep.c b/sys/sparc64/sparc64/dump_machdep.c index 5af21cc..1f28b6d 100644 --- a/sys/sparc64/sparc64/dump_machdep.c +++ b/sys/sparc64/sparc64/dump_machdep.c @@ -39,62 +39,38 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_param.h> #include <vm/pmap.h> +#include <machine/dump.h> +#include <machine/md_var.h> #include <machine/metadata.h> #include <machine/kerneldump.h> #include <machine/ofw_mem.h> #include <machine/tsb.h> #include <machine/tlb.h> -CTASSERT(sizeof(struct kerneldumpheader) == DEV_BSIZE); +static off_t fileofs; -static struct kerneldumpheader kdh; -static off_t dumplo, dumppos; +extern off_t dumplo; +extern struct dump_pa dump_map[DUMPSYS_MD_PA_NPAIRS]; -/* Handle buffered writes. */ -static char buffer[DEV_BSIZE]; -static vm_size_t fragsz; +int do_minidump = 0; -#define MAXDUMPSZ (MAXDUMPPGS << PAGE_SHIFT) - -static int -buf_write(struct dumperinfo *di, char *ptr, size_t sz) +void +dumpsys_pa_init(void) { - size_t len; - int error; - - while (sz) { - len = DEV_BSIZE - fragsz; - if (len > sz) - len = sz; - bcopy(ptr, buffer + fragsz, len); - fragsz += len; - ptr += len; - sz -= len; - if (fragsz == DEV_BSIZE) { - error = dump_write(di, buffer, 0, dumplo, - DEV_BSIZE); - if (error) - return error; - dumplo += DEV_BSIZE; - fragsz = 0; - } - } + int i; - return (0); + memset(dump_map, 0, sizeof(dump_map)); + for (i = 0; i < sparc64_nmemreg; i++) { + dump_map[i].pa_start = sparc64_memreg[i].mr_start; + dump_map[i].pa_size = sparc64_memreg[i].mr_size; + } } -static int -buf_flush(struct dumperinfo *di) +void +dumpsys_map_chunk(vm_paddr_t pa, size_t chunk __unused, void **va) { - int error; - - if (fragsz == 0) - return (0); - error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE); - dumplo += DEV_BSIZE; - fragsz = 0; - return (error); + *va = (void *)TLB_PHYS_TO_DIRECT(pa); } static int @@ -104,47 +80,16 @@ reg_write(struct dumperinfo *di, vm_paddr_t pa, vm_size_t size) r.dr_pa = pa; r.dr_size = size; - r.dr_offs = dumppos; - dumppos += size; - return (buf_write(di, (char *)&r, sizeof(r))); -} - -static int -blk_dump(struct dumperinfo *di, vm_paddr_t pa, vm_size_t size) -{ - vm_size_t pos, rsz; - vm_offset_t va; - int c, counter, error, twiddle; - - printf(" chunk at %#lx: %ld bytes ", (u_long)pa, (long)size); - - va = 0L; - error = counter = twiddle = 0; - for (pos = 0; pos < size; pos += MAXDUMPSZ, counter++) { - if (counter % 128 == 0) - printf("%c\b", "|/-\\"[twiddle++ & 3]); - rsz = size - pos; - rsz = (rsz > MAXDUMPSZ) ? MAXDUMPSZ : rsz; - va = TLB_PHYS_TO_DIRECT(pa + pos); - error = dump_write(di, (void *)va, 0, dumplo, rsz); - if (error) - break; - dumplo += rsz; - - /* Check for user abort. */ - c = cncheckc(); - if (c == 0x03) - return (ECANCELED); - if (c != -1) - printf("(CTRL-C to abort) "); - } - printf("... %s\n", (error) ? "fail" : "ok"); - return (error); + r.dr_offs = fileofs; + fileofs += size; + return (dumpsys_buf_write(di, (char *)&r, sizeof(r))); } int dumpsys(struct dumperinfo *di) { + static struct kerneldumpheader kdh; + struct sparc64_dump_hdr hdr; vm_size_t size, totsize, hdrsize; int error, i, nreg; @@ -189,10 +134,10 @@ dumpsys(struct dumperinfo *di) hdr.dh_tsb_mask = tsb_kernel_mask; hdr.dh_nregions = nreg; - if (buf_write(di, (char *)&hdr, sizeof(hdr)) != 0) + if (dumpsys_buf_write(di, (char *)&hdr, sizeof(hdr)) != 0) goto fail; - dumppos = hdrsize; + fileofs = hdrsize; /* Now, write out the region descriptors. */ for (i = 0; i < sparc64_nmemreg; i++) { error = reg_write(di, sparc64_memreg[i].mr_start, @@ -200,15 +145,12 @@ dumpsys(struct dumperinfo *di) if (error != 0) goto fail; } - buf_flush(di); + dumpsys_buf_flush(di); /* Dump memory chunks. */ - for (i = 0; i < sparc64_nmemreg; i++) { - error = blk_dump(di, sparc64_memreg[i].mr_start, - sparc64_memreg[i].mr_size); - if (error != 0) - goto fail; - } + error = dumpsys_foreach_chunk(dumpsys_cb_dumpdata, di); + if (error < 0) + goto fail; /* Dump trailer */ error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh)); @@ -221,6 +163,9 @@ dumpsys(struct dumperinfo *di) return (0); fail: + if (error < 0) + error = -error; + /* XXX It should look more like VMS :-) */ printf("** DUMP FAILED (ERROR %d) **\n", error); return (error); |