xref: /freebsd-src/sys/powerpc/powerpc/minidump_machdep.c (revision 2ff63af9b88c7413b7d71715b5532625752a248e)
10ecc478bSLeandro Lupori /*-
20ecc478bSLeandro Lupori  * Copyright (c) 2019 Leandro Lupori
30ecc478bSLeandro Lupori  * All rights reserved.
40ecc478bSLeandro Lupori  *
50ecc478bSLeandro Lupori  * Redistribution and use in source and binary forms, with or without
60ecc478bSLeandro Lupori  * modification, are permitted provided that the following conditions
70ecc478bSLeandro Lupori  * are met:
80ecc478bSLeandro Lupori  *
90ecc478bSLeandro Lupori  * 1. Redistributions of source code must retain the above copyright
100ecc478bSLeandro Lupori  *    notice, this list of conditions and the following disclaimer.
110ecc478bSLeandro Lupori  * 2. Redistributions in binary form must reproduce the above copyright
120ecc478bSLeandro Lupori  *    notice, this list of conditions and the following disclaimer in the
130ecc478bSLeandro Lupori  *    documentation and/or other materials provided with the distribution.
140ecc478bSLeandro Lupori  *
150ecc478bSLeandro Lupori  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
160ecc478bSLeandro Lupori  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
170ecc478bSLeandro Lupori  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
180ecc478bSLeandro Lupori  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
190ecc478bSLeandro Lupori  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
200ecc478bSLeandro Lupori  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
210ecc478bSLeandro Lupori  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
220ecc478bSLeandro Lupori  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
230ecc478bSLeandro Lupori  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
240ecc478bSLeandro Lupori  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
250ecc478bSLeandro Lupori  */
260ecc478bSLeandro Lupori 
270ecc478bSLeandro Lupori #include <sys/types.h>
280ecc478bSLeandro Lupori #include <sys/param.h>
290ecc478bSLeandro Lupori 
300ecc478bSLeandro Lupori #include <sys/cons.h>
310ecc478bSLeandro Lupori #include <sys/kerneldump.h>
320ecc478bSLeandro Lupori #include <sys/msgbuf.h>
330ecc478bSLeandro Lupori #include <sys/proc.h>
340ecc478bSLeandro Lupori #include <sys/sysctl.h>
350ecc478bSLeandro Lupori 
360ecc478bSLeandro Lupori #include <vm/vm.h>
370ecc478bSLeandro Lupori #include <vm/vm_param.h>
380ecc478bSLeandro Lupori #include <vm/vm_page.h>
390ecc478bSLeandro Lupori #include <vm/vm_phys.h>
406f3b523cSKonstantin Belousov #include <vm/vm_dumpset.h>
410ecc478bSLeandro Lupori #include <vm/pmap.h>
420ecc478bSLeandro Lupori 
430ecc478bSLeandro Lupori #include <machine/atomic.h>
440ecc478bSLeandro Lupori #include <machine/dump.h>
450ecc478bSLeandro Lupori #include <machine/md_var.h>
460ecc478bSLeandro Lupori #include <machine/minidump.h>
470ecc478bSLeandro Lupori 
480ecc478bSLeandro Lupori /* Debugging stuff */
490ecc478bSLeandro Lupori #define	MINIDUMP_DEBUG	0
500ecc478bSLeandro Lupori #if	MINIDUMP_DEBUG
510ecc478bSLeandro Lupori #define dprintf(fmt, ...)	printf(fmt, ## __VA_ARGS__)
520ecc478bSLeandro Lupori #define DBG(...)	__VA_ARGS__
530ecc478bSLeandro Lupori static size_t total, dumptotal;
540ecc478bSLeandro Lupori static void dump_total(const char *id, size_t sz);
550ecc478bSLeandro Lupori #else
560ecc478bSLeandro Lupori #define dprintf(fmt, ...)
570ecc478bSLeandro Lupori #define DBG(...)
580ecc478bSLeandro Lupori #define dump_total(...)
590ecc478bSLeandro Lupori #endif
600ecc478bSLeandro Lupori 
610ecc478bSLeandro Lupori extern vm_offset_t __startkernel, __endkernel;
620ecc478bSLeandro Lupori 
630ecc478bSLeandro Lupori static int dump_retry_count = 5;
640ecc478bSLeandro Lupori SYSCTL_INT(_machdep, OID_AUTO, dump_retry_count, CTLFLAG_RWTUN,
650ecc478bSLeandro Lupori     &dump_retry_count, 0,
660ecc478bSLeandro Lupori     "Number of times dump has to retry before bailing out");
670ecc478bSLeandro Lupori 
680ecc478bSLeandro Lupori static struct kerneldumpheader kdh;
690ecc478bSLeandro Lupori static char pgbuf[PAGE_SIZE];
700ecc478bSLeandro Lupori 
71ab4ed843SMitchell Horne static size_t dumpsize;
720ecc478bSLeandro Lupori 
730ecc478bSLeandro Lupori /* Handle chunked writes. */
740ecc478bSLeandro Lupori static size_t fragsz;
750ecc478bSLeandro Lupori 
760ecc478bSLeandro Lupori static void
pmap_kenter_temporary(vm_offset_t va,vm_paddr_t pa)770ecc478bSLeandro Lupori pmap_kenter_temporary(vm_offset_t va, vm_paddr_t pa)
780ecc478bSLeandro Lupori {
790ecc478bSLeandro Lupori 	pmap_kremove(va);
800ecc478bSLeandro Lupori 	pmap_kenter(va, pa);
810ecc478bSLeandro Lupori }
820ecc478bSLeandro Lupori 
830ecc478bSLeandro Lupori static int
blk_flush(struct dumperinfo * di)840ecc478bSLeandro Lupori blk_flush(struct dumperinfo *di)
850ecc478bSLeandro Lupori {
860ecc478bSLeandro Lupori 	int error;
870ecc478bSLeandro Lupori 
880ecc478bSLeandro Lupori 	if (fragsz == 0)
890ecc478bSLeandro Lupori 		return (0);
900ecc478bSLeandro Lupori 
91*db71383bSMitchell Horne 	error = dump_append(di, crashdumpmap, fragsz);
920ecc478bSLeandro Lupori 	DBG(dumptotal += fragsz;)
930ecc478bSLeandro Lupori 	fragsz = 0;
940ecc478bSLeandro Lupori 	return (error);
950ecc478bSLeandro Lupori }
960ecc478bSLeandro Lupori 
970ecc478bSLeandro Lupori static int
blk_write(struct dumperinfo * di,char * ptr,vm_paddr_t pa,size_t sz)980ecc478bSLeandro Lupori blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz)
990ecc478bSLeandro Lupori {
1000ecc478bSLeandro Lupori 	size_t len, maxdumpsz;
1010ecc478bSLeandro Lupori 	int error, i, c;
1020ecc478bSLeandro Lupori 
1030ecc478bSLeandro Lupori 	maxdumpsz = MIN(di->maxiosize, MAXDUMPPGS * PAGE_SIZE);
1040ecc478bSLeandro Lupori 	if (maxdumpsz == 0)	/* seatbelt */
1050ecc478bSLeandro Lupori 		maxdumpsz = PAGE_SIZE;
1060ecc478bSLeandro Lupori 	error = 0;
1070ecc478bSLeandro Lupori 	if ((sz % PAGE_SIZE) != 0) {
1080ecc478bSLeandro Lupori 		printf("Size not page aligned\n");
1090ecc478bSLeandro Lupori 		return (EINVAL);
1100ecc478bSLeandro Lupori 	}
1110ecc478bSLeandro Lupori 	if (ptr != NULL && pa != 0) {
1120ecc478bSLeandro Lupori 		printf("Can't have both va and pa!\n");
1130ecc478bSLeandro Lupori 		return (EINVAL);
1140ecc478bSLeandro Lupori 	}
1150ecc478bSLeandro Lupori 	if ((pa % PAGE_SIZE) != 0) {
1160ecc478bSLeandro Lupori 		printf("Address not page aligned 0x%lx\n", pa);
1170ecc478bSLeandro Lupori 		return (EINVAL);
1180ecc478bSLeandro Lupori 	}
1190ecc478bSLeandro Lupori 	if (ptr != NULL) {
1200ecc478bSLeandro Lupori 		/*
1210ecc478bSLeandro Lupori 		 * If we're doing a virtual dump, flush any pre-existing
1220ecc478bSLeandro Lupori 		 * pa pages
1230ecc478bSLeandro Lupori 		 */
1240ecc478bSLeandro Lupori 		error = blk_flush(di);
1250ecc478bSLeandro Lupori 		if (error)
1260ecc478bSLeandro Lupori 			return (error);
1270ecc478bSLeandro Lupori 	}
1280ecc478bSLeandro Lupori 	while (sz) {
1290ecc478bSLeandro Lupori 		len = maxdumpsz - fragsz;
1300ecc478bSLeandro Lupori 		if (len > sz)
1310ecc478bSLeandro Lupori 			len = sz;
132ab4ed843SMitchell Horne 
133ab4ed843SMitchell Horne 		dumpsys_pb_progress(len);
1340ecc478bSLeandro Lupori 
1350ecc478bSLeandro Lupori 		if (ptr) {
136*db71383bSMitchell Horne 			error = dump_append(di, ptr, len);
1370ecc478bSLeandro Lupori 			if (error)
1380ecc478bSLeandro Lupori 				return (error);
1390ecc478bSLeandro Lupori 			DBG(dumptotal += len;)
1400ecc478bSLeandro Lupori 			ptr += len;
1410ecc478bSLeandro Lupori 		} else {
1420ecc478bSLeandro Lupori 			for (i = 0; i < len; i += PAGE_SIZE)
1430ecc478bSLeandro Lupori 				pmap_kenter_temporary(
1440ecc478bSLeandro Lupori 				    (vm_offset_t)crashdumpmap + fragsz + i,
1450ecc478bSLeandro Lupori 				    pa + i);
1460ecc478bSLeandro Lupori 
1470ecc478bSLeandro Lupori 			fragsz += len;
1480ecc478bSLeandro Lupori 			pa += len;
1490ecc478bSLeandro Lupori 			if (fragsz == maxdumpsz) {
1500ecc478bSLeandro Lupori 				error = blk_flush(di);
1510ecc478bSLeandro Lupori 				if (error)
1520ecc478bSLeandro Lupori 					return (error);
1530ecc478bSLeandro Lupori 			}
1540ecc478bSLeandro Lupori 		}
1550ecc478bSLeandro Lupori 		sz -= len;
1560ecc478bSLeandro Lupori 
1570ecc478bSLeandro Lupori 		/* Check for user abort. */
1580ecc478bSLeandro Lupori 		c = cncheckc();
1590ecc478bSLeandro Lupori 		if (c == 0x03)
1600ecc478bSLeandro Lupori 			return (ECANCELED);
1610ecc478bSLeandro Lupori 		if (c != -1)
1620ecc478bSLeandro Lupori 			printf(" (CTRL-C to abort) ");
1630ecc478bSLeandro Lupori 	}
1640ecc478bSLeandro Lupori 
1650ecc478bSLeandro Lupori 	return (0);
1660ecc478bSLeandro Lupori }
1670ecc478bSLeandro Lupori 
1680ecc478bSLeandro Lupori static int
dump_pmap(struct dumperinfo * di)1690ecc478bSLeandro Lupori dump_pmap(struct dumperinfo *di)
1700ecc478bSLeandro Lupori {
1710ecc478bSLeandro Lupori 	void *ctx;
1720ecc478bSLeandro Lupori 	char *buf;
1730ecc478bSLeandro Lupori 	u_long nbytes;
1740ecc478bSLeandro Lupori 	int error;
1750ecc478bSLeandro Lupori 
1760ecc478bSLeandro Lupori 	ctx = dumpsys_dump_pmap_init(sizeof(pgbuf) / PAGE_SIZE);
1770ecc478bSLeandro Lupori 
1780ecc478bSLeandro Lupori 	for (;;) {
1790ecc478bSLeandro Lupori 		buf = dumpsys_dump_pmap(ctx, pgbuf, &nbytes);
1800ecc478bSLeandro Lupori 		if (buf == NULL)
1810ecc478bSLeandro Lupori 			break;
1820ecc478bSLeandro Lupori 		error = blk_write(di, buf, 0, nbytes);
1830ecc478bSLeandro Lupori 		if (error)
1840ecc478bSLeandro Lupori 			return (error);
1850ecc478bSLeandro Lupori 	}
1860ecc478bSLeandro Lupori 
1870ecc478bSLeandro Lupori 	return (0);
1880ecc478bSLeandro Lupori }
1890ecc478bSLeandro Lupori 
1900ecc478bSLeandro Lupori int
cpu_minidumpsys(struct dumperinfo * di,const struct minidumpstate * state)1911adebe3cSMitchell Horne cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state)
1920ecc478bSLeandro Lupori {
1930ecc478bSLeandro Lupori 	vm_paddr_t pa;
194ab4ed843SMitchell Horne 	int error, retry_count;
1950ecc478bSLeandro Lupori 	uint32_t pmapsize;
1960ecc478bSLeandro Lupori 	struct minidumphdr mdhdr;
1971d2d1418SMitchell Horne 	struct msgbuf *mbp;
1980ecc478bSLeandro Lupori 
1990ecc478bSLeandro Lupori 	retry_count = 0;
2000ecc478bSLeandro Lupori retry:
2010ecc478bSLeandro Lupori 	retry_count++;
2020ecc478bSLeandro Lupori 	fragsz = 0;
2030ecc478bSLeandro Lupori 	DBG(total = dumptotal = 0;)
2040ecc478bSLeandro Lupori 
2050ecc478bSLeandro Lupori 	/* Build set of dumpable pages from kernel pmap */
20610fe6f80SMitchell Horne 	pmapsize = dumpsys_scan_pmap(state->dump_bitset);
2070ecc478bSLeandro Lupori 	if (pmapsize % PAGE_SIZE != 0) {
2080ecc478bSLeandro Lupori 		printf("pmapsize not page aligned: 0x%x\n", pmapsize);
2090ecc478bSLeandro Lupori 		return (EINVAL);
2100ecc478bSLeandro Lupori 	}
2110ecc478bSLeandro Lupori 
2120ecc478bSLeandro Lupori 	/* Calculate dump size */
2131d2d1418SMitchell Horne 	mbp = state->msgbufp;
2140ecc478bSLeandro Lupori 	dumpsize = PAGE_SIZE;				/* header */
2151d2d1418SMitchell Horne 	dumpsize += round_page(mbp->msg_size);
21600e66147SD Scott Phillips 	dumpsize += round_page(sizeof(dump_avail));
217ab041f71SD Scott Phillips 	dumpsize += round_page(BITSET_SIZE(vm_page_dump_pages));
2180ecc478bSLeandro Lupori 	dumpsize += pmapsize;
21910fe6f80SMitchell Horne 	VM_PAGE_DUMP_FOREACH(state->dump_bitset, pa) {
2200ecc478bSLeandro Lupori 		/* Clear out undumpable pages now if needed */
22131991a5aSMitchell Horne 		if (vm_phys_is_dumpable(pa))
2220ecc478bSLeandro Lupori 			dumpsize += PAGE_SIZE;
2230ecc478bSLeandro Lupori 		else
22410fe6f80SMitchell Horne 			vm_page_dump_drop(state->dump_bitset, pa);
2250ecc478bSLeandro Lupori 	}
226ab4ed843SMitchell Horne 	dumpsys_pb_init(dumpsize);
2270ecc478bSLeandro Lupori 
2280ecc478bSLeandro Lupori 	/* Initialize mdhdr */
2290ecc478bSLeandro Lupori 	bzero(&mdhdr, sizeof(mdhdr));
2300ecc478bSLeandro Lupori 	strcpy(mdhdr.magic, MINIDUMP_MAGIC);
2310ecc478bSLeandro Lupori 	strncpy(mdhdr.mmu_name, pmap_mmu_name(), sizeof(mdhdr.mmu_name) - 1);
2320ecc478bSLeandro Lupori 	mdhdr.version = MINIDUMP_VERSION;
2331d2d1418SMitchell Horne 	mdhdr.msgbufsize = mbp->msg_size;
234ab041f71SD Scott Phillips 	mdhdr.bitmapsize = round_page(BITSET_SIZE(vm_page_dump_pages));
2350ecc478bSLeandro Lupori 	mdhdr.pmapsize = pmapsize;
2360ecc478bSLeandro Lupori 	mdhdr.kernbase = VM_MIN_KERNEL_ADDRESS;
2370ecc478bSLeandro Lupori 	mdhdr.kernend = VM_MAX_SAFE_KERNEL_ADDRESS;
2380ecc478bSLeandro Lupori 	mdhdr.dmapbase = DMAP_BASE_ADDRESS;
2390ecc478bSLeandro Lupori 	mdhdr.dmapend = DMAP_MAX_ADDRESS;
2400ecc478bSLeandro Lupori 	mdhdr.hw_direct_map = hw_direct_map;
2410ecc478bSLeandro Lupori 	mdhdr.startkernel = __startkernel;
2420ecc478bSLeandro Lupori 	mdhdr.endkernel = __endkernel;
24300e66147SD Scott Phillips 	mdhdr.dumpavailsize = round_page(sizeof(dump_avail));
2440ecc478bSLeandro Lupori 
2450ecc478bSLeandro Lupori 	dump_init_header(di, &kdh, KERNELDUMPMAGIC, KERNELDUMP_POWERPC_VERSION,
2460ecc478bSLeandro Lupori 	    dumpsize);
2470ecc478bSLeandro Lupori 
2480ecc478bSLeandro Lupori 	error = dump_start(di, &kdh);
2490ecc478bSLeandro Lupori 	if (error)
2500ecc478bSLeandro Lupori 		goto fail;
2510ecc478bSLeandro Lupori 
2520ecc478bSLeandro Lupori 	printf("Dumping %lu out of %ju MB:", dumpsize >> 20,
2530ecc478bSLeandro Lupori 	    ptoa((uintmax_t)physmem) / 1048576);
2540ecc478bSLeandro Lupori 
2550ecc478bSLeandro Lupori 	/* Dump minidump header */
2560ecc478bSLeandro Lupori 	bzero(pgbuf, sizeof(pgbuf));
2570ecc478bSLeandro Lupori 	memcpy(pgbuf, &mdhdr, sizeof(mdhdr));
2580ecc478bSLeandro Lupori 	error = blk_write(di, pgbuf, 0, PAGE_SIZE);
2590ecc478bSLeandro Lupori 	if (error)
2600ecc478bSLeandro Lupori 		goto fail;
2610ecc478bSLeandro Lupori 	dump_total("header", PAGE_SIZE);
2620ecc478bSLeandro Lupori 
2630ecc478bSLeandro Lupori 	/* Dump msgbuf up front */
2641d2d1418SMitchell Horne 	error = blk_write(di, mbp->msg_ptr, 0, round_page(mbp->msg_size));
2651d2d1418SMitchell Horne 	dump_total("msgbuf", round_page(mbp->msg_size));
2660ecc478bSLeandro Lupori 
26700e66147SD Scott Phillips 	/* Dump dump_avail */
26800e66147SD Scott Phillips 	_Static_assert(sizeof(dump_avail) <= sizeof(pgbuf),
26900e66147SD Scott Phillips 	    "Large dump_avail not handled");
27000e66147SD Scott Phillips 	bzero(pgbuf, sizeof(mdhdr));
27100e66147SD Scott Phillips 	memcpy(pgbuf, dump_avail, sizeof(dump_avail));
27200e66147SD Scott Phillips 	error = blk_write(di, pgbuf, 0, PAGE_SIZE);
27300e66147SD Scott Phillips 	if (error)
27400e66147SD Scott Phillips 		goto fail;
27500e66147SD Scott Phillips 	dump_total("dump_avail", round_page(sizeof(dump_avail)));
27600e66147SD Scott Phillips 
2770ecc478bSLeandro Lupori 	/* Dump bitmap */
2780ecc478bSLeandro Lupori 	error = blk_write(di, (char *)vm_page_dump, 0,
279ab041f71SD Scott Phillips 	    round_page(BITSET_SIZE(vm_page_dump_pages)));
2800ecc478bSLeandro Lupori 	if (error)
2810ecc478bSLeandro Lupori 		goto fail;
282ab041f71SD Scott Phillips 	dump_total("bitmap", round_page(BITSET_SIZE(vm_page_dump_pages)));
2830ecc478bSLeandro Lupori 
2840ecc478bSLeandro Lupori 	/* Dump kernel page directory pages */
2850ecc478bSLeandro Lupori 	error = dump_pmap(di);
2860ecc478bSLeandro Lupori 	if (error)
2870ecc478bSLeandro Lupori 		goto fail;
2880ecc478bSLeandro Lupori 	dump_total("pmap", pmapsize);
2890ecc478bSLeandro Lupori 
2900ecc478bSLeandro Lupori 	/* Dump memory chunks */
29110fe6f80SMitchell Horne 	VM_PAGE_DUMP_FOREACH(state->dump_bitset, pa) {
2920ecc478bSLeandro Lupori 		error = blk_write(di, 0, pa, PAGE_SIZE);
2930ecc478bSLeandro Lupori 		if (error)
2940ecc478bSLeandro Lupori 			goto fail;
2950ecc478bSLeandro Lupori 	}
2960ecc478bSLeandro Lupori 
2970ecc478bSLeandro Lupori 	error = blk_flush(di);
2980ecc478bSLeandro Lupori 	if (error)
2990ecc478bSLeandro Lupori 		goto fail;
3000ecc478bSLeandro Lupori 	dump_total("mem_chunks", dumpsize - total);
3010ecc478bSLeandro Lupori 
3020ecc478bSLeandro Lupori 	error = dump_finish(di, &kdh);
3030ecc478bSLeandro Lupori 	if (error)
3040ecc478bSLeandro Lupori 		goto fail;
3050ecc478bSLeandro Lupori 
3060ecc478bSLeandro Lupori 	printf("\nDump complete\n");
3070ecc478bSLeandro Lupori 	return (0);
3080ecc478bSLeandro Lupori 
3090ecc478bSLeandro Lupori fail:
3100ecc478bSLeandro Lupori 	if (error < 0)
3110ecc478bSLeandro Lupori 		error = -error;
3120ecc478bSLeandro Lupori 
3130ecc478bSLeandro Lupori 	printf("\n");
3140ecc478bSLeandro Lupori 	if (error == ENOSPC) {
3150ecc478bSLeandro Lupori 		printf("Dump map grown while dumping. ");
3160ecc478bSLeandro Lupori 		if (retry_count < dump_retry_count) {
3170ecc478bSLeandro Lupori 			printf("Retrying...\n");
3180ecc478bSLeandro Lupori 			goto retry;
3190ecc478bSLeandro Lupori 		}
3200ecc478bSLeandro Lupori 		printf("Dump failed.\n");
3210ecc478bSLeandro Lupori 	} else if (error == ECANCELED)
3220ecc478bSLeandro Lupori 		printf("Dump aborted\n");
3230ecc478bSLeandro Lupori 	else if (error == E2BIG)
3240ecc478bSLeandro Lupori 		printf("Dump failed. Partition too small.\n");
3250ecc478bSLeandro Lupori 	else
3260ecc478bSLeandro Lupori 		printf("** DUMP FAILED (ERROR %d) **\n", error);
3270ecc478bSLeandro Lupori 	return (error);
3280ecc478bSLeandro Lupori }
3290ecc478bSLeandro Lupori 
3300ecc478bSLeandro Lupori #if	MINIDUMP_DEBUG
3310ecc478bSLeandro Lupori static void
dump_total(const char * id,size_t sz)3320ecc478bSLeandro Lupori dump_total(const char *id, size_t sz)
3330ecc478bSLeandro Lupori {
3340ecc478bSLeandro Lupori 	total += sz;
3350ecc478bSLeandro Lupori 	dprintf("\n%s=%08lx/%08lx/%08lx\n",
3360ecc478bSLeandro Lupori 		id, sz, total, dumptotal);
3370ecc478bSLeandro Lupori }
3380ecc478bSLeandro Lupori #endif
339