summaryrefslogtreecommitdiffstats
path: root/sys/sparc64
diff options
context:
space:
mode:
authormarkj <markj@FreeBSD.org>2015-01-07 01:01:39 +0000
committermarkj <markj@FreeBSD.org>2015-01-07 01:01:39 +0000
commit7e7e145818dbebec11d3fb1dded0452f0c3d99f9 (patch)
tree6d50f1ee65f4ceaf3fa5c14faf47e9ecd3aae3e5 /sys/sparc64
parentd7969594c9a8a347e4914f5381da2436c1a93710 (diff)
downloadFreeBSD-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.h76
-rw-r--r--sys/sparc64/sparc64/dump_machdep.c117
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);
OpenPOWER on IntegriCloud