xref: /minix3/lib/libkvm/kvm_sparc.c (revision 9da227510d14c35cccbd92c6a9e316b4079c4911)
1*9da22751SDavid van Moolenbroek /*	$NetBSD: kvm_sparc.c,v 1.34 2015/10/07 11:56:41 martin Exp $	*/
2*9da22751SDavid van Moolenbroek 
3*9da22751SDavid van Moolenbroek /*-
4*9da22751SDavid van Moolenbroek  * Copyright (c) 1992, 1993
5*9da22751SDavid van Moolenbroek  *	The Regents of the University of California.  All rights reserved.
6*9da22751SDavid van Moolenbroek  *
7*9da22751SDavid van Moolenbroek  * This code is derived from software developed by the Computer Systems
8*9da22751SDavid van Moolenbroek  * Engineering group at Lawrence Berkeley Laboratory under DARPA contract
9*9da22751SDavid van Moolenbroek  * BG 91-66 and contributed to Berkeley.
10*9da22751SDavid van Moolenbroek  *
11*9da22751SDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
12*9da22751SDavid van Moolenbroek  * modification, are permitted provided that the following conditions
13*9da22751SDavid van Moolenbroek  * are met:
14*9da22751SDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
15*9da22751SDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer.
16*9da22751SDavid van Moolenbroek  * 2. Redistributions in binary form must reproduce the above copyright
17*9da22751SDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer in the
18*9da22751SDavid van Moolenbroek  *    documentation and/or other materials provided with the distribution.
19*9da22751SDavid van Moolenbroek  * 3. Neither the name of the University nor the names of its contributors
20*9da22751SDavid van Moolenbroek  *    may be used to endorse or promote products derived from this software
21*9da22751SDavid van Moolenbroek  *    without specific prior written permission.
22*9da22751SDavid van Moolenbroek  *
23*9da22751SDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24*9da22751SDavid van Moolenbroek  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25*9da22751SDavid van Moolenbroek  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26*9da22751SDavid van Moolenbroek  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27*9da22751SDavid van Moolenbroek  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28*9da22751SDavid van Moolenbroek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29*9da22751SDavid van Moolenbroek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30*9da22751SDavid van Moolenbroek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31*9da22751SDavid van Moolenbroek  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32*9da22751SDavid van Moolenbroek  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33*9da22751SDavid van Moolenbroek  * SUCH DAMAGE.
34*9da22751SDavid van Moolenbroek  */
35*9da22751SDavid van Moolenbroek 
36*9da22751SDavid van Moolenbroek #include <sys/cdefs.h>
37*9da22751SDavid van Moolenbroek #if defined(LIBC_SCCS) && !defined(lint)
38*9da22751SDavid van Moolenbroek #if 0
39*9da22751SDavid van Moolenbroek static char sccsid[] = "@(#)kvm_sparc.c	8.1 (Berkeley) 6/4/93";
40*9da22751SDavid van Moolenbroek #else
41*9da22751SDavid van Moolenbroek __RCSID("$NetBSD: kvm_sparc.c,v 1.34 2015/10/07 11:56:41 martin Exp $");
42*9da22751SDavid van Moolenbroek #endif
43*9da22751SDavid van Moolenbroek #endif /* LIBC_SCCS and not lint */
44*9da22751SDavid van Moolenbroek 
45*9da22751SDavid van Moolenbroek /*
46*9da22751SDavid van Moolenbroek  * Sparc machine dependent routines for kvm.  Hopefully, the forthcoming
47*9da22751SDavid van Moolenbroek  * vm code will one day obsolete this module.
48*9da22751SDavid van Moolenbroek  */
49*9da22751SDavid van Moolenbroek 
50*9da22751SDavid van Moolenbroek #include <sys/param.h>
51*9da22751SDavid van Moolenbroek #include <sys/exec.h>
52*9da22751SDavid van Moolenbroek #include <sys/proc.h>
53*9da22751SDavid van Moolenbroek #include <sys/stat.h>
54*9da22751SDavid van Moolenbroek #include <sys/core.h>
55*9da22751SDavid van Moolenbroek #include <sys/kcore.h>
56*9da22751SDavid van Moolenbroek #include <unistd.h>
57*9da22751SDavid van Moolenbroek #include <nlist.h>
58*9da22751SDavid van Moolenbroek #include <kvm.h>
59*9da22751SDavid van Moolenbroek 
60*9da22751SDavid van Moolenbroek #include <uvm/uvm_extern.h>
61*9da22751SDavid van Moolenbroek 
62*9da22751SDavid van Moolenbroek #include <sparc/pmap.h>
63*9da22751SDavid van Moolenbroek #include <sparc/kcore.h>
64*9da22751SDavid van Moolenbroek 
65*9da22751SDavid van Moolenbroek #include <limits.h>
66*9da22751SDavid van Moolenbroek #include <db.h>
67*9da22751SDavid van Moolenbroek 
68*9da22751SDavid van Moolenbroek #include "kvm_private.h"
69*9da22751SDavid van Moolenbroek 
70*9da22751SDavid van Moolenbroek 
71*9da22751SDavid van Moolenbroek static int cputyp = -1;
72*9da22751SDavid van Moolenbroek static int pgshift;
73*9da22751SDavid van Moolenbroek static int nptesg;	/* [sun4/sun4c] only */
74*9da22751SDavid van Moolenbroek 
75*9da22751SDavid van Moolenbroek #undef VA_VPG
76*9da22751SDavid van Moolenbroek #define VA_VPG(va)	((cputyp == CPU_SUN4C || cputyp == CPU_SUN4M) \
77*9da22751SDavid van Moolenbroek 				? VA_SUN4C_VPG(va) \
78*9da22751SDavid van Moolenbroek 				: VA_SUN4_VPG(va))
79*9da22751SDavid van Moolenbroek 
80*9da22751SDavid van Moolenbroek #undef VA_OFF
81*9da22751SDavid van Moolenbroek #define VA_OFF(va) (va & (kd->nbpg - 1))
82*9da22751SDavid van Moolenbroek 
83*9da22751SDavid van Moolenbroek int _kvm_kvatop44c(kvm_t *, vaddr_t, paddr_t *);
84*9da22751SDavid van Moolenbroek int _kvm_kvatop4m (kvm_t *, vaddr_t, paddr_t *);
85*9da22751SDavid van Moolenbroek int _kvm_kvatop4u (kvm_t *, vaddr_t, paddr_t *);
86*9da22751SDavid van Moolenbroek 
87*9da22751SDavid van Moolenbroek /*
88*9da22751SDavid van Moolenbroek  * XXX
89*9da22751SDavid van Moolenbroek  * taken from /sys/arch/sparc64/include/kcore.h.
90*9da22751SDavid van Moolenbroek  * this is the same as the sparc one, except for the kphys addition,
91*9da22751SDavid van Moolenbroek  * so luckily we can use this here...
92*9da22751SDavid van Moolenbroek  */
93*9da22751SDavid van Moolenbroek typedef struct sparc64_cpu_kcore_hdr {
94*9da22751SDavid van Moolenbroek 	int	cputype;		/* CPU type associated with this dump */
95*9da22751SDavid van Moolenbroek 	u_long	kernbase;		/* copy of KERNBASE goes here */
96*9da22751SDavid van Moolenbroek 	int	nmemseg;		/* # of physical memory segments */
97*9da22751SDavid van Moolenbroek 	u_long	memsegoffset;		/* start of memseg array (relative */
98*9da22751SDavid van Moolenbroek 					/*  to the start of this header) */
99*9da22751SDavid van Moolenbroek 	int	nsegmap;		/* # of segmaps following */
100*9da22751SDavid van Moolenbroek 	u_long	segmapoffset;		/* start of segmap array (relative */
101*9da22751SDavid van Moolenbroek 					/*  to the start of this header) */
102*9da22751SDavid van Moolenbroek 	int	npmeg;			/* # of PMEGs; [sun4/sun4c] only */
103*9da22751SDavid van Moolenbroek 	u_long	pmegoffset;		/* start of pmeg array (relative */
104*9da22751SDavid van Moolenbroek 					/*  to the start of this header) */
105*9da22751SDavid van Moolenbroek /* SPARC64 stuff */
106*9da22751SDavid van Moolenbroek 	paddr_t	kphys;			/* Physical address of 4MB locked TLB */
107*9da22751SDavid van Moolenbroek } sparc64_cpu_kcore_hdr_t;
108*9da22751SDavid van Moolenbroek 
109*9da22751SDavid van Moolenbroek void
_kvm_freevtop(kvm_t * kd)110*9da22751SDavid van Moolenbroek _kvm_freevtop(kvm_t *kd)
111*9da22751SDavid van Moolenbroek {
112*9da22751SDavid van Moolenbroek 	if (kd->vmst != 0) {
113*9da22751SDavid van Moolenbroek 		_kvm_err(kd, kd->program, "_kvm_freevtop: internal error");
114*9da22751SDavid van Moolenbroek 		kd->vmst = 0;
115*9da22751SDavid van Moolenbroek 	}
116*9da22751SDavid van Moolenbroek }
117*9da22751SDavid van Moolenbroek 
118*9da22751SDavid van Moolenbroek /*
119*9da22751SDavid van Moolenbroek  * Prepare for translation of kernel virtual addresses into offsets
120*9da22751SDavid van Moolenbroek  * into crash dump files. We use the MMU specific goop written at the
121*9da22751SDavid van Moolenbroek  * front of the crash dump by pmap_dumpmmu().
122*9da22751SDavid van Moolenbroek  */
123*9da22751SDavid van Moolenbroek int
_kvm_initvtop(kvm_t * kd)124*9da22751SDavid van Moolenbroek _kvm_initvtop(kvm_t *kd)
125*9da22751SDavid van Moolenbroek {
126*9da22751SDavid van Moolenbroek 	sparc64_cpu_kcore_hdr_t *cpup = kd->cpu_data;
127*9da22751SDavid van Moolenbroek 
128*9da22751SDavid van Moolenbroek 	switch (cputyp = cpup->cputype) {
129*9da22751SDavid van Moolenbroek 	case CPU_SUN4:
130*9da22751SDavid van Moolenbroek 	case CPU_SUN4U:
131*9da22751SDavid van Moolenbroek 		kd->nbpg = 8196;
132*9da22751SDavid van Moolenbroek 		pgshift = 13;
133*9da22751SDavid van Moolenbroek 		break;
134*9da22751SDavid van Moolenbroek 	case CPU_SUN4C:
135*9da22751SDavid van Moolenbroek 	case CPU_SUN4M:
136*9da22751SDavid van Moolenbroek 		kd->nbpg = 4096;
137*9da22751SDavid van Moolenbroek 		pgshift = 12;
138*9da22751SDavid van Moolenbroek 		break;
139*9da22751SDavid van Moolenbroek 	default:
140*9da22751SDavid van Moolenbroek 		_kvm_err(kd, kd->program, "Unsupported CPU type");
141*9da22751SDavid van Moolenbroek 		return (-1);
142*9da22751SDavid van Moolenbroek 	}
143*9da22751SDavid van Moolenbroek 	nptesg = NBPSG / kd->nbpg;
144*9da22751SDavid van Moolenbroek 	return (0);
145*9da22751SDavid van Moolenbroek }
146*9da22751SDavid van Moolenbroek 
147*9da22751SDavid van Moolenbroek /*
148*9da22751SDavid van Moolenbroek  * Translate a kernel virtual address to a physical address using the
149*9da22751SDavid van Moolenbroek  * mapping information in kd->vm.  Returns the result in pa, and returns
150*9da22751SDavid van Moolenbroek  * the number of bytes that are contiguously available from this
151*9da22751SDavid van Moolenbroek  * physical address.  This routine is used only for crash dumps.
152*9da22751SDavid van Moolenbroek  */
153*9da22751SDavid van Moolenbroek int
_kvm_kvatop(kvm_t * kd,vaddr_t va,paddr_t * pa)154*9da22751SDavid van Moolenbroek _kvm_kvatop(kvm_t *kd, vaddr_t va, paddr_t *pa)
155*9da22751SDavid van Moolenbroek {
156*9da22751SDavid van Moolenbroek 	if (cputyp == -1)
157*9da22751SDavid van Moolenbroek 		if (_kvm_initvtop(kd) != 0)
158*9da22751SDavid van Moolenbroek 			return (-1);
159*9da22751SDavid van Moolenbroek 
160*9da22751SDavid van Moolenbroek 	switch (cputyp) {
161*9da22751SDavid van Moolenbroek 	case CPU_SUN4:
162*9da22751SDavid van Moolenbroek 	case CPU_SUN4C:
163*9da22751SDavid van Moolenbroek 		return _kvm_kvatop44c(kd, va, pa);
164*9da22751SDavid van Moolenbroek 		break;
165*9da22751SDavid van Moolenbroek 	case CPU_SUN4M:
166*9da22751SDavid van Moolenbroek 		return _kvm_kvatop4m(kd, va, pa);
167*9da22751SDavid van Moolenbroek 		break;
168*9da22751SDavid van Moolenbroek 	case CPU_SUN4U:
169*9da22751SDavid van Moolenbroek 	default:
170*9da22751SDavid van Moolenbroek 		return _kvm_kvatop4u(kd, va, pa);
171*9da22751SDavid van Moolenbroek 	}
172*9da22751SDavid van Moolenbroek }
173*9da22751SDavid van Moolenbroek 
174*9da22751SDavid van Moolenbroek /*
175*9da22751SDavid van Moolenbroek  * (note: sun4 3-level MMU not yet supported)
176*9da22751SDavid van Moolenbroek  */
177*9da22751SDavid van Moolenbroek int
_kvm_kvatop44c(kvm_t * kd,vaddr_t va,paddr_t * pa)178*9da22751SDavid van Moolenbroek _kvm_kvatop44c(kvm_t *kd, vaddr_t va, paddr_t *pa)
179*9da22751SDavid van Moolenbroek {
180*9da22751SDavid van Moolenbroek 	int vr, vs, pte;
181*9da22751SDavid van Moolenbroek 	sparc64_cpu_kcore_hdr_t *cpup = kd->cpu_data;
182*9da22751SDavid van Moolenbroek 	struct segmap *sp, *segmaps;
183*9da22751SDavid van Moolenbroek 	int *ptes;
184*9da22751SDavid van Moolenbroek 	int nkreg, nureg;
185*9da22751SDavid van Moolenbroek 	u_long kernbase = cpup->kernbase;
186*9da22751SDavid van Moolenbroek 
187*9da22751SDavid van Moolenbroek 	if (va < kernbase)
188*9da22751SDavid van Moolenbroek 		goto err;
189*9da22751SDavid van Moolenbroek 
190*9da22751SDavid van Moolenbroek 	/*
191*9da22751SDavid van Moolenbroek 	 * Layout of CPU segment:
192*9da22751SDavid van Moolenbroek 	 *	cpu_kcore_hdr_t;
193*9da22751SDavid van Moolenbroek 	 *	[alignment]
194*9da22751SDavid van Moolenbroek 	 *	phys_ram_seg_t[cpup->nmemseg];
195*9da22751SDavid van Moolenbroek 	 *	segmap[cpup->nsegmap];
196*9da22751SDavid van Moolenbroek 	 *	ptes[cpup->npmegs];
197*9da22751SDavid van Moolenbroek 	 */
198*9da22751SDavid van Moolenbroek 	segmaps = (struct segmap *)((long)kd->cpu_data + cpup->segmapoffset);
199*9da22751SDavid van Moolenbroek 	ptes = (int *)((int)kd->cpu_data + cpup->pmegoffset);
200*9da22751SDavid van Moolenbroek 	nkreg = ((int)((-(unsigned)kernbase) / NBPRG));
201*9da22751SDavid van Moolenbroek 	nureg = 256 - nkreg;
202*9da22751SDavid van Moolenbroek 
203*9da22751SDavid van Moolenbroek 	vr = VA_VREG(va);
204*9da22751SDavid van Moolenbroek 	vs = VA_VSEG(va);
205*9da22751SDavid van Moolenbroek 
206*9da22751SDavid van Moolenbroek 	sp = &segmaps[(vr-nureg)*NSEGRG + vs];
207*9da22751SDavid van Moolenbroek 	if (sp->sg_npte == 0)
208*9da22751SDavid van Moolenbroek 		goto err;
209*9da22751SDavid van Moolenbroek 	if (sp->sg_pmeg == cpup->npmeg - 1) /* =seginval */
210*9da22751SDavid van Moolenbroek 		goto err;
211*9da22751SDavid van Moolenbroek 	pte = ptes[sp->sg_pmeg * nptesg + VA_VPG(va)];
212*9da22751SDavid van Moolenbroek 	if ((pte & PG_V) != 0) {
213*9da22751SDavid van Moolenbroek 		paddr_t p, off = VA_OFF(va);
214*9da22751SDavid van Moolenbroek 
215*9da22751SDavid van Moolenbroek 		p = (pte & PG_PFNUM) << pgshift;
216*9da22751SDavid van Moolenbroek 		*pa = p + off;
217*9da22751SDavid van Moolenbroek 		return (kd->nbpg - off);
218*9da22751SDavid van Moolenbroek 	}
219*9da22751SDavid van Moolenbroek err:
220*9da22751SDavid van Moolenbroek 	_kvm_err(kd, 0, "invalid address (%#"PRIxVADDR")", va);
221*9da22751SDavid van Moolenbroek 	return (0);
222*9da22751SDavid van Moolenbroek }
223*9da22751SDavid van Moolenbroek 
224*9da22751SDavid van Moolenbroek int
_kvm_kvatop4m(kvm_t * kd,vaddr_t va,paddr_t * pa)225*9da22751SDavid van Moolenbroek _kvm_kvatop4m(kvm_t *kd, vaddr_t va, paddr_t *pa)
226*9da22751SDavid van Moolenbroek {
227*9da22751SDavid van Moolenbroek 	sparc64_cpu_kcore_hdr_t *cpup = kd->cpu_data;
228*9da22751SDavid van Moolenbroek 	int vr, vs;
229*9da22751SDavid van Moolenbroek 	int pte;
230*9da22751SDavid van Moolenbroek 	off_t foff;
231*9da22751SDavid van Moolenbroek 	struct segmap *sp, *segmaps;
232*9da22751SDavid van Moolenbroek 	int nkreg, nureg;
233*9da22751SDavid van Moolenbroek 	u_long kernbase = cpup->kernbase;
234*9da22751SDavid van Moolenbroek 
235*9da22751SDavid van Moolenbroek 	if (va < kernbase)
236*9da22751SDavid van Moolenbroek 		goto err;
237*9da22751SDavid van Moolenbroek 
238*9da22751SDavid van Moolenbroek 	/*
239*9da22751SDavid van Moolenbroek 	 * Layout of CPU segment:
240*9da22751SDavid van Moolenbroek 	 *	cpu_kcore_hdr_t;
241*9da22751SDavid van Moolenbroek 	 *	[alignment]
242*9da22751SDavid van Moolenbroek 	 *	phys_ram_seg_t[cpup->nmemseg];
243*9da22751SDavid van Moolenbroek 	 *	segmap[cpup->nsegmap];
244*9da22751SDavid van Moolenbroek 	 */
245*9da22751SDavid van Moolenbroek 	segmaps = (struct segmap *)((long)kd->cpu_data + cpup->segmapoffset);
246*9da22751SDavid van Moolenbroek 	nkreg = ((int)((-(unsigned)kernbase) / NBPRG));
247*9da22751SDavid van Moolenbroek 	nureg = 256 - nkreg;
248*9da22751SDavid van Moolenbroek 
249*9da22751SDavid van Moolenbroek 	vr = VA_VREG(va);
250*9da22751SDavid van Moolenbroek 	vs = VA_VSEG(va);
251*9da22751SDavid van Moolenbroek 
252*9da22751SDavid van Moolenbroek 	sp = &segmaps[(vr-nureg)*NSEGRG + vs];
253*9da22751SDavid van Moolenbroek 	if (sp->sg_npte == 0)
254*9da22751SDavid van Moolenbroek 		goto err;
255*9da22751SDavid van Moolenbroek 
256*9da22751SDavid van Moolenbroek 	/* XXX - assume page tables in initial kernel DATA or BSS. */
257*9da22751SDavid van Moolenbroek 	foff = _kvm_pa2off(kd, (u_long)&sp->sg_pte[VA_VPG(va)] - kernbase);
258*9da22751SDavid van Moolenbroek 	if (foff == (off_t)-1)
259*9da22751SDavid van Moolenbroek 		return (0);
260*9da22751SDavid van Moolenbroek 
261*9da22751SDavid van Moolenbroek 	if (_kvm_pread(kd, kd->pmfd, &pte, sizeof(pte), foff) != sizeof(pte)) {
262*9da22751SDavid van Moolenbroek 		_kvm_syserr(kd, kd->program, "cannot read pte for "
263*9da22751SDavid van Moolenbroek 		    "%#" PRIxVADDR, va);
264*9da22751SDavid van Moolenbroek 		return (0);
265*9da22751SDavid van Moolenbroek 	}
266*9da22751SDavid van Moolenbroek 
267*9da22751SDavid van Moolenbroek 	if ((pte & SRMMU_TETYPE) == SRMMU_TEPTE) {
268*9da22751SDavid van Moolenbroek 		long p, off = VA_OFF(va);
269*9da22751SDavid van Moolenbroek 
270*9da22751SDavid van Moolenbroek 		p = (pte & SRMMU_PPNMASK) << SRMMU_PPNPASHIFT;
271*9da22751SDavid van Moolenbroek 		*pa = p + off;
272*9da22751SDavid van Moolenbroek 		return (kd->nbpg - off);
273*9da22751SDavid van Moolenbroek 	}
274*9da22751SDavid van Moolenbroek err:
275*9da22751SDavid van Moolenbroek 	_kvm_err(kd, 0, "invalid address (%#"PRIxVADDR")", va);
276*9da22751SDavid van Moolenbroek 	return (0);
277*9da22751SDavid van Moolenbroek }
278*9da22751SDavid van Moolenbroek 
279*9da22751SDavid van Moolenbroek /*
280*9da22751SDavid van Moolenbroek  * sparc64 pmap's 32-bit page table format
281*9da22751SDavid van Moolenbroek  */
282*9da22751SDavid van Moolenbroek int
_kvm_kvatop4u(kvm_t * kd,vaddr_t va,paddr_t * pa)283*9da22751SDavid van Moolenbroek _kvm_kvatop4u(kvm_t *kd, vaddr_t va, paddr_t *pa)
284*9da22751SDavid van Moolenbroek {
285*9da22751SDavid van Moolenbroek 	sparc64_cpu_kcore_hdr_t *cpup = kd->cpu_data;
286*9da22751SDavid van Moolenbroek 	int64_t **segmaps;
287*9da22751SDavid van Moolenbroek 	int64_t *ptes;
288*9da22751SDavid van Moolenbroek 	int64_t pte;
289*9da22751SDavid van Moolenbroek 	int64_t kphys = cpup->kphys;
290*9da22751SDavid van Moolenbroek 	u_long kernbase = cpup->kernbase;
291*9da22751SDavid van Moolenbroek 
292*9da22751SDavid van Moolenbroek 	if (va < kernbase)
293*9da22751SDavid van Moolenbroek 		goto err;
294*9da22751SDavid van Moolenbroek 
295*9da22751SDavid van Moolenbroek 	/*
296*9da22751SDavid van Moolenbroek 	 * Kernel layout:
297*9da22751SDavid van Moolenbroek 	 *
298*9da22751SDavid van Moolenbroek 	 * kernbase:
299*9da22751SDavid van Moolenbroek 	 *	4MB locked TLB (text+data+BSS)
300*9da22751SDavid van Moolenbroek 	 *	Random other stuff.
301*9da22751SDavid van Moolenbroek 	 */
302*9da22751SDavid van Moolenbroek 	if (va >= kernbase && va < kernbase + 4*1024*1024)
303*9da22751SDavid van Moolenbroek 		return (va - kernbase) + kphys;
304*9da22751SDavid van Moolenbroek 
305*9da22751SDavid van Moolenbroek /* XXX: from sparc64/include/pmap.h */
306*9da22751SDavid van Moolenbroek #define	SPARC64_PTSZ		(kd->nbpg/8)
307*9da22751SDavid van Moolenbroek #define	SPARC64_STSZ		(SPARC64_PTSZ)
308*9da22751SDavid van Moolenbroek #define	SPARC64_PTMASK		(SPARC64_PTSZ-1)
309*9da22751SDavid van Moolenbroek #define	SPARC64_PTSHIFT		(13)
310*9da22751SDavid van Moolenbroek #define	SPARC64_PDSHIFT		(10+SPARC64_PTSHIFT)
311*9da22751SDavid van Moolenbroek #define	SPARC64_STSHIFT		(10+SPARC64_PDSHIFT)
312*9da22751SDavid van Moolenbroek #define	SPARC64_STMASK		(SPARC64_STSZ-1)
313*9da22751SDavid van Moolenbroek #define	sparc64_va_to_seg(v)	(int)((((int64_t)(v))>>SPARC64_STSHIFT)&SPARC64_STMASK)
314*9da22751SDavid van Moolenbroek #define	sparc64_va_to_pte(v)	(int)((((int64_t)(v))>>SPARC64_PTSHIFT)&SPARC64_PTMASK)
315*9da22751SDavid van Moolenbroek 
316*9da22751SDavid van Moolenbroek /* XXX: from sparc64/include/pte.h */
317*9da22751SDavid van Moolenbroek #define	SPARC64_TLB_V			0x8000000000000000LL
318*9da22751SDavid van Moolenbroek #define	SPARC64_TLB_PA_MASK		0x000001ffffffe000LL
319*9da22751SDavid van Moolenbroek 
320*9da22751SDavid van Moolenbroek 	/*
321*9da22751SDavid van Moolenbroek 	 * Layout of CPU segment:
322*9da22751SDavid van Moolenbroek 	 *	cpu_kcore_hdr_t;
323*9da22751SDavid van Moolenbroek 	 *	[alignment]
324*9da22751SDavid van Moolenbroek 	 *	phys_ram_seg_t[cpup->nmemseg];
325*9da22751SDavid van Moolenbroek 	 *	segmap[cpup->nsegmap];
326*9da22751SDavid van Moolenbroek 	 */
327*9da22751SDavid van Moolenbroek 	segmaps = (int64_t **)((long)kd->cpu_data + cpup->segmapoffset);
328*9da22751SDavid van Moolenbroek 	ptes = (int64_t *)(intptr_t)_kvm_pa2off(kd,
329*9da22751SDavid van Moolenbroek 	    (paddr_t)(intptr_t)segmaps[sparc64_va_to_seg(va)]);
330*9da22751SDavid van Moolenbroek 	pte = ptes[sparc64_va_to_pte(va)];
331*9da22751SDavid van Moolenbroek 	if ((pte & SPARC64_TLB_V) != 0)
332*9da22751SDavid van Moolenbroek 		return ((pte & SPARC64_TLB_PA_MASK) | (va & (kd->nbpg - 1)));
333*9da22751SDavid van Moolenbroek err:
334*9da22751SDavid van Moolenbroek 	_kvm_err(kd, 0, "invalid address (%#"PRIxVADDR")", va);
335*9da22751SDavid van Moolenbroek 	return (0);
336*9da22751SDavid van Moolenbroek }
337*9da22751SDavid van Moolenbroek 
338*9da22751SDavid van Moolenbroek 
339*9da22751SDavid van Moolenbroek /*
340*9da22751SDavid van Moolenbroek  * Translate a physical address to a file-offset in the crash dump.
341*9da22751SDavid van Moolenbroek  */
342*9da22751SDavid van Moolenbroek off_t
_kvm_pa2off(kvm_t * kd,paddr_t pa)343*9da22751SDavid van Moolenbroek _kvm_pa2off(kvm_t *kd, paddr_t pa)
344*9da22751SDavid van Moolenbroek {
345*9da22751SDavid van Moolenbroek 	sparc64_cpu_kcore_hdr_t *cpup = kd->cpu_data;
346*9da22751SDavid van Moolenbroek 	phys_ram_seg_t *mp;
347*9da22751SDavid van Moolenbroek 	off_t off;
348*9da22751SDavid van Moolenbroek 	int nmem;
349*9da22751SDavid van Moolenbroek 
350*9da22751SDavid van Moolenbroek 	/*
351*9da22751SDavid van Moolenbroek 	 * Layout of CPU segment:
352*9da22751SDavid van Moolenbroek 	 *	cpu_kcore_hdr_t;
353*9da22751SDavid van Moolenbroek 	 *	[alignment]
354*9da22751SDavid van Moolenbroek 	 *	phys_ram_seg_t[cpup->nmemseg];
355*9da22751SDavid van Moolenbroek 	 */
356*9da22751SDavid van Moolenbroek 	mp = (phys_ram_seg_t *)((int)kd->cpu_data + cpup->memsegoffset);
357*9da22751SDavid van Moolenbroek 	off = 0;
358*9da22751SDavid van Moolenbroek 
359*9da22751SDavid van Moolenbroek 	/* Translate (sparse) pfnum to (packed) dump offset */
360*9da22751SDavid van Moolenbroek 	for (nmem = cpup->nmemseg; --nmem >= 0; mp++) {
361*9da22751SDavid van Moolenbroek 		if (mp->start <= pa && pa < mp->start + mp->size)
362*9da22751SDavid van Moolenbroek 			break;
363*9da22751SDavid van Moolenbroek 		off += mp->size;
364*9da22751SDavid van Moolenbroek 	}
365*9da22751SDavid van Moolenbroek 	if (nmem < 0) {
366*9da22751SDavid van Moolenbroek 		_kvm_err(kd, 0, "invalid address (%lx)", (unsigned long)pa);
367*9da22751SDavid van Moolenbroek 		return (-1);
368*9da22751SDavid van Moolenbroek 	}
369*9da22751SDavid van Moolenbroek 
370*9da22751SDavid van Moolenbroek 	return (kd->dump_off + off + pa - mp->start);
371*9da22751SDavid van Moolenbroek }
372*9da22751SDavid van Moolenbroek 
373*9da22751SDavid van Moolenbroek /*
374*9da22751SDavid van Moolenbroek  * Machine-dependent initialization for ALL open kvm descriptors,
375*9da22751SDavid van Moolenbroek  * not just those for a kernel crash dump.  Some architectures
376*9da22751SDavid van Moolenbroek  * have to deal with these NOT being constants!  (i.e. m68k)
377*9da22751SDavid van Moolenbroek  */
378*9da22751SDavid van Moolenbroek int
_kvm_mdopen(kvm_t * kd)379*9da22751SDavid van Moolenbroek _kvm_mdopen(kvm_t *kd)
380*9da22751SDavid van Moolenbroek {
381*9da22751SDavid van Moolenbroek 	u_long max_uva;
382*9da22751SDavid van Moolenbroek 	extern struct ps_strings *__ps_strings;
383*9da22751SDavid van Moolenbroek 
384*9da22751SDavid van Moolenbroek 	max_uva = (u_long) (__ps_strings + 1);
385*9da22751SDavid van Moolenbroek 	kd->usrstack = max_uva;
386*9da22751SDavid van Moolenbroek 	kd->max_uva  = max_uva;
387*9da22751SDavid van Moolenbroek 	kd->min_uva  = 0;
388*9da22751SDavid van Moolenbroek 
389*9da22751SDavid van Moolenbroek 	return (0);
390*9da22751SDavid van Moolenbroek }
391