pmap_dumpmmu(int (*dump)(dev_t, daddr_t, caddr_t, size_t), daddr_t blkno)
pmap_dumpmmu(dump, blkno) daddr_t blkno; int (*dump)	__P((dev_t, daddr_t, caddr_t, size_t));
pmap_dumpmmu(int (*dump)(dev_t, daddr_t, caddr_t, size_t), daddr_t blkno)	{	kcore_seg_t	*ksegp;	cpu_kcore_hdr_t	*kcpup;	phys_ram_seg_t	memseg;	int	error = 0;	int	i, memsegoffset, pmegoffset;	int	buffer[dbtob(1) / sizeof(int)];	int	*bp, *ep;#if defined(SUN4C) || defined(SUN4)	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 -= 4;						\	}								\} while (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, 4);	}	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)	/*	 * dump page table entries	 *	 * We dump each pmeg in order (by segment number).  Since the MMU	 * automatically maps the given virtual segment to a pmeg we must	 * iterate over the segments by incrementing an unused segment slot	 * in the MMU.  This fixed segment number is used in the virtual	 * address argument to getpte().	 */	/*	 * Go through the pmegs and dump each one.	 */	for (pmeg = 0; pmeg <= seginval; ++pmeg) {		int va = 0;		setsegmap(va, pmeg);		i = NPTESG;		do {			int pte = getpte4(va);			EXPEDITE(&pte, sizeof(pte));			va += NBPG;		} while (--i > 0);	}	setsegmap(0, seginval);#endifout:	if (bp != buffer)		error = (*dump)(dumpdev, blkno++, (caddr_t)buffer, dbtob(1));	return (error);}