xref: /onnv-gate/usr/src/cmd/mdb/sparc/v9/kmdb/kaif_handlers.s (revision 1991:f29baf5bf770)
10Sstevel@tonic-gate/*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*1991Sheppo * Common Development and Distribution License (the "License").
6*1991Sheppo * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21*1991Sheppo
220Sstevel@tonic-gate/*
23*1991Sheppo * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate#pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate
290Sstevel@tonic-gate#include <sys/asm_linkage.h>
300Sstevel@tonic-gate#include <sys/machasi.h>
310Sstevel@tonic-gate#include <sys/machtrap.h>
320Sstevel@tonic-gate#include <sys/privregs.h>
330Sstevel@tonic-gate#include <sys/mmu.h>
34*1991Sheppo#include <vm/mach_sfmmu.h>
35*1991Sheppo
36*1991Sheppo#if defined(sun4v) && !defined(lint)
37*1991Sheppo#include <sys/machparam.h>
38*1991Sheppo#endif
39*1991Sheppo
40*1991Sheppo#if defined(sun4v) && defined(KMDB_TRAPCOUNT)
41*1991Sheppo/*
42*1991Sheppo * The sun4v implemenations of the fast miss handlers are larger than those
43*1991Sheppo * of their sun4u kin. This is unfortunate because there is not enough space
44*1991Sheppo * remaining in the respective trap table entries for this debug feature.
45*1991Sheppo */
46*1991Sheppo#error "KMDB_TRAPCOUNT not supported on sun4v"
47*1991Sheppo#endif
480Sstevel@tonic-gate
490Sstevel@tonic-gate/*
500Sstevel@tonic-gate * This file contains the trap handlers that will be copied to kmdb's trap
510Sstevel@tonic-gate * table.  See kaif_activate.c for the code that does the actual copying.
520Sstevel@tonic-gate *
530Sstevel@tonic-gate * The handlers have a debugging feature, enabled when KMDB_TRAPCOUNT is
540Sstevel@tonic-gate * defined, which allows them to keep a running count of the number of times
550Sstevel@tonic-gate * a given trap has occurred.  The counter is stored in the padding at the end
560Sstevel@tonic-gate * of the handler.  Write access is of course required to allow the values to
570Sstevel@tonic-gate * be updated, so KMDB_TRAPCOUNT also enables the installation of DTLB entries
580Sstevel@tonic-gate * for each trap table page.  Finally, the code in this file is copied into
590Sstevel@tonic-gate * the actual location used by the handler, so we can't perform compile-time
600Sstevel@tonic-gate * counter location calculations.  The calculations are instead performed at
610Sstevel@tonic-gate * run-time, as A) we generally already derive the table location as part of
620Sstevel@tonic-gate * the trap processing and B) simplicity is more of a concern than is speed.
630Sstevel@tonic-gate */
640Sstevel@tonic-gate
650Sstevel@tonic-gate#if defined(lint)
660Sstevel@tonic-gate#include <kmdb/kaif.h>
670Sstevel@tonic-gate
680Sstevel@tonic-gatevoid
690Sstevel@tonic-gatekaif_hdlr_dmiss(void)
700Sstevel@tonic-gate{
710Sstevel@tonic-gate}
720Sstevel@tonic-gate
730Sstevel@tonic-gatevoid
740Sstevel@tonic-gatekaif_itlb_handler(void)
750Sstevel@tonic-gate{
760Sstevel@tonic-gate}
77*1991Sheppo
78*1991Sheppo#else /* lint */
790Sstevel@tonic-gate
800Sstevel@tonic-gate#ifdef sun4v
81*1991Sheppo
82*1991Sheppo#define	GET_MMU_D_ADDR_CTX(daddr, ctx)			\
83*1991Sheppo	MMU_FAULT_STATUS_AREA(ctx);			\
84*1991Sheppo	ldx	[ctx + MMFSA_D_ADDR], daddr;		\
85*1991Sheppo	ldx	[ctx + MMFSA_D_CTX], ctx
86*1991Sheppo
87*1991Sheppo#define	GET_MMU_I_ADDR_CTX(iaddr, ctx)			\
88*1991Sheppo	MMU_FAULT_STATUS_AREA(ctx);			\
89*1991Sheppo	ldx	[ctx + MMFSA_I_ADDR], iaddr;		\
90*1991Sheppo	ldx	[ctx + MMFSA_I_CTX], ctx
91*1991Sheppo
92*1991Sheppo/*
93*1991Sheppo * KAIF_ITLB_STUFF
94*1991Sheppo * derived from ITLB_STUFF in uts/sun4v/vm/mach_sfmmu.h
95*1991Sheppo *
96*1991Sheppo * Load ITLB entry
97*1991Sheppo *
98*1991Sheppo * In:
99*1991Sheppo *   tte = reg containing tte
100*1991Sheppo *   ouch = branch target label used if hcall fails (sun4v only)
101*1991Sheppo *   scr1, scr2, scr3, scr4 = scratch registers (must not be %o0-%o3)
102*1991Sheppo */
103*1991Sheppo#define	KAIF_ITLB_STUFF(tte, ouch, scr1, scr2, scr3, scr4)	\
104*1991Sheppo	mov	%o0, scr1;				\
105*1991Sheppo	mov	%o1, scr2;				\
106*1991Sheppo	mov	%o2, scr3;				\
107*1991Sheppo	mov	%o3, scr4;				\
108*1991Sheppo	MMU_FAULT_STATUS_AREA(%o2);			\
109*1991Sheppo	ldx	[%o2 + MMFSA_I_ADDR], %o0;		\
110*1991Sheppo	ldx	[%o2 + MMFSA_I_CTX], %o1;		\
111*1991Sheppo	srlx	%o0, PAGESHIFT, %o0;			\
112*1991Sheppo	sllx	%o0, PAGESHIFT, %o0;			\
113*1991Sheppo	mov	tte, %o2;				\
114*1991Sheppo	mov	MAP_ITLB, %o3;				\
115*1991Sheppo	ta	MMU_MAP_ADDR;				\
116*1991Sheppo	/* BEGIN CSTYLED */				\
117*1991Sheppo	brnz,a,pn %o0, ouch;				\
118*1991Sheppo	  nop;						\
119*1991Sheppo	/* END CSTYLED */				\
120*1991Sheppo	mov	scr1, %o0;				\
121*1991Sheppo	mov	scr2, %o1;				\
122*1991Sheppo	mov	scr3, %o2;				\
123*1991Sheppo	mov	scr4, %o3
124*1991Sheppo
125*1991Sheppo/*
126*1991Sheppo * KAIF_DTLB_STUFF
127*1991Sheppo * derived from DTLB_STUFF in uts/sun4v/vm/mach_sfmmu.h
128*1991Sheppo *
129*1991Sheppo * Load DTLB entry
130*1991Sheppo *
131*1991Sheppo * In:
132*1991Sheppo *   tte = reg containing tte
133*1991Sheppo *   ouch = branch target label used if hcall fails (sun4v only)
134*1991Sheppo *   scr1, scr2, scr3, scr4 = scratch registers (must not be %o0-%o3)
135*1991Sheppo */
136*1991Sheppo#define	KAIF_DTLB_STUFF(tte, ouch, scr1, scr2, scr3, scr4)	\
137*1991Sheppo	mov	%o0, scr1;				\
138*1991Sheppo	mov	%o1, scr2;				\
139*1991Sheppo	mov	%o2, scr3;				\
140*1991Sheppo	mov	%o3, scr4;				\
141*1991Sheppo	MMU_FAULT_STATUS_AREA(%o2);			\
142*1991Sheppo	ldx	[%o2 + MMFSA_D_ADDR], %o0;		\
143*1991Sheppo	ldx	[%o2 + MMFSA_D_CTX], %o1;		\
144*1991Sheppo	srlx	%o0, PAGESHIFT, %o0;			\
145*1991Sheppo	sllx	%o0, PAGESHIFT, %o0;			\
146*1991Sheppo	mov	tte, %o2;				\
147*1991Sheppo	mov	MAP_DTLB, %o3;				\
148*1991Sheppo	ta	MMU_MAP_ADDR;				\
149*1991Sheppo	/* BEGIN CSTYLED */				\
150*1991Sheppo	brnz,a,pn %o0, ouch;				\
151*1991Sheppo	  nop;						\
152*1991Sheppo	/* END CSTYLED */				\
153*1991Sheppo	mov	scr1, %o0;				\
154*1991Sheppo	mov	scr2, %o1;				\
155*1991Sheppo	mov	scr3, %o2;				\
156*1991Sheppo	mov	scr4, %o3
157*1991Sheppo
1580Sstevel@tonic-gate#else /* sun4v */
1590Sstevel@tonic-gate
160*1991Sheppo#define	GET_MMU_D_ADDR_CTX(daddr, ctx)			\
161*1991Sheppo	mov	MMU_TAG_ACCESS, ctx;			\
162*1991Sheppo	ldxa	[ctx]ASI_DMMU, daddr;			\
163*1991Sheppo	sllx	daddr, TAGACC_CTX_LSHIFT, ctx;		\
164*1991Sheppo	srlx	ctx, TAGACC_CTX_LSHIFT, ctx
1650Sstevel@tonic-gate
166*1991Sheppo#define	GET_MMU_I_ADDR_CTX(iaddr, ctx)			\
167*1991Sheppo	rdpr	%tpc, iaddr;				\
168*1991Sheppo	ldxa	[%g0]ASI_IMMU, ctx;			\
169*1991Sheppo	srlx	ctx, TTARGET_CTX_SHIFT, ctx
170*1991Sheppo
171*1991Sheppo#define	KAIF_DTLB_STUFF(tte, ouch, scr1, scr2, scr3, scr4)	\
172*1991Sheppo	DTLB_STUFF(tte, scr1, scr2, scr3, scr4)
173*1991Sheppo
174*1991Sheppo#define	KAIF_ITLB_STUFF(tte, ouch, scr1, scr2, scr3, scr4)	\
175*1991Sheppo	ITLB_STUFF(tte, scr1, scr2, scr3, scr4)
1760Sstevel@tonic-gate
177*1991Sheppo#endif /* sun4v */
178*1991Sheppo
179*1991Sheppo/*
180*1991Sheppo * KAIF_CALL_KDI_VATOTTE
181*1991Sheppo *
182*1991Sheppo * Use kdi_vatotte to look up the tte.  We don't bother stripping the
183*1991Sheppo * context, as it won't change the tte we get.
184*1991Sheppo *
185*1991Sheppo * The two instruction at patch_lbl are modified during runtime
186*1991Sheppo * by kaif to point to kdi_vatotte
187*1991Sheppo *
188*1991Sheppo * Clobbers all globals.
189*1991Sheppo * Returns tte in %g1 if successful, otherwise 0 in %g1
190*1991Sheppo * Leaves address of next instruction following this macro in scr1
191*1991Sheppo */
192*1991Sheppo#define	KAIF_CALL_KDI_VATOTTE(addr, ctx, patch_lbl, scr0, scr1)	\
193*1991Sheppo	.global	patch_lbl;					\
194*1991Sheppopatch_lbl:							\
195*1991Sheppo	sethi	%hi(0), scr0;					\
196*1991Sheppo	or	scr0, %lo(0), scr0;				\
197*1991Sheppo	jmpl	scr0, scr1;					\
198*1991Sheppo	add	scr1, 8, scr1
1990Sstevel@tonic-gate
200*1991Sheppo
201*1991Sheppo	ENTRY_NP(kaif_hdlr_dmiss)
202*1991Sheppo	GET_MMU_D_ADDR_CTX(%g1, %g2)
203*1991Sheppo
204*1991Sheppo	KAIF_CALL_KDI_VATOTTE(%g1, %g2, kaif_hdlr_dmiss_patch, %g3, %g7)
205*1991Sheppo0:	brz	%g1, 1f
2060Sstevel@tonic-gate	nop
2070Sstevel@tonic-gate
2080Sstevel@tonic-gate	/*
2090Sstevel@tonic-gate	 * kdi_vatotte gave us a TTE to use.  Load it up and head back
2100Sstevel@tonic-gate	 * into the world, but first bump a counter.
2110Sstevel@tonic-gate	 */
212*1991Sheppo
213*1991Sheppo#ifdef	KMDB_TRAPCOUNT			/* Trap counter.  See top comment */
214*1991Sheppo	ldx	[%g7 + .count-0b], %g2
2150Sstevel@tonic-gate	add	%g2, 1, %g2
216*1991Sheppo	stx	%g2, [%g7 + .count-0b]
2170Sstevel@tonic-gate#endif
218*1991Sheppo
219*1991Sheppo	KAIF_DTLB_STUFF(%g1, 1f, %g2, %g3, %g4, %g5)
2200Sstevel@tonic-gate	retry
2210Sstevel@tonic-gate
2220Sstevel@tonic-gate1:	/*
2230Sstevel@tonic-gate	 * kdi_vatotte didn't give us a tte, which is unfortunate.  We're
2240Sstevel@tonic-gate	 * going to need to jump into the debugger so as to allow it to
2250Sstevel@tonic-gate	 * handle the trap.  The debugger itself isn't locked into the TLB,
2260Sstevel@tonic-gate	 * so we may well incur a TLB miss while trying to get into it.  As
2270Sstevel@tonic-gate	 * such, we're going to switch off the MMU globals before setting foot
2280Sstevel@tonic-gate	 * into the debugger, thus allowing a TL>1 miss to be handled without
2290Sstevel@tonic-gate	 * clobbering our state.  We'll also save off the tag just in case the
2300Sstevel@tonic-gate	 * world ends and someone wants to find out what happened.
2310Sstevel@tonic-gate	 *
2320Sstevel@tonic-gate	 * We will only reach this point at TL=1, as kdi_vatotte will always
2330Sstevel@tonic-gate	 * find the TTE for the debugger without missing.
2340Sstevel@tonic-gate	 */
2350Sstevel@tonic-gate
236*1991Sheppo#ifdef	KMDB_TRAPCOUNT			/* Trap address "counter". */
237*1991Sheppo	GET_MMU_D_ADDR(%g2, %g3)
238*1991Sheppo	stx	%g2, [%g7 + .daddr-0b]
239*1991Sheppo	stx	%g1, [%g7 + .ecode-0b]
2400Sstevel@tonic-gate#endif
2410Sstevel@tonic-gate
242*1991Sheppo	sethi	%hi(kaif_dtrap), %g1
243*1991Sheppo	jmp	%g1 + %lo(kaif_dtrap)
2440Sstevel@tonic-gate	nop
245*1991Sheppo	/* NOTREACHED */
246*1991Sheppo
247*1991Sheppo#ifdef KMDB_TRAPCOUNT
248*1991Sheppo	.align 8
249*1991Sheppo.count:	.xword 0			/* counter goes here */
250*1991Sheppo.daddr:	.xword 0			/* miss address goes here */
251*1991Sheppo.ecode:	.xword 0			/* sun4v: g1 contains err code */
252*1991Sheppo#endif
253*1991Sheppo
254*1991Sheppo	.align 32*4			/* force length to 32 instr. */
2550Sstevel@tonic-gate	SET_SIZE(kaif_hdlr_dmiss)
2560Sstevel@tonic-gate
257*1991Sheppo
2580Sstevel@tonic-gate
259*1991Sheppo	ENTRY_NP(kaif_hdlr_imiss)
260*1991Sheppo	GET_MMU_I_ADDR_CTX(%g1, %g2)
2610Sstevel@tonic-gate
262*1991Sheppo	KAIF_CALL_KDI_VATOTTE(%g1, %g2, kaif_hdlr_imiss_patch, %g3, %g7)
263*1991Sheppo0:	brz	%g1, 1f
2640Sstevel@tonic-gate	nop
2650Sstevel@tonic-gate
2660Sstevel@tonic-gate	/*
2670Sstevel@tonic-gate	 * kdi_vatotte gave us a TTE to use.  Load it up and head back
2680Sstevel@tonic-gate	 * into the world, but first bump a counter.
2690Sstevel@tonic-gate	 */
270*1991Sheppo#ifdef	KMDB_TRAPCOUNT			/* Trap counter.  See top comment */
271*1991Sheppo	ldx	[%g7 + .count-0b], %g2
2720Sstevel@tonic-gate	add	%g2, 1, %g2
273*1991Sheppo	stx	%g2, [%g7 + .count-0b]
2740Sstevel@tonic-gate#endif
275*1991Sheppo
276*1991Sheppo	KAIF_ITLB_STUFF(%g1, 1f, %g2, %g3, %g4, %g5)
2770Sstevel@tonic-gate	retry
2780Sstevel@tonic-gate
2790Sstevel@tonic-gate1:	/*
2800Sstevel@tonic-gate	 * kdi_vatotte didn't give us a tte, which is unfortunate.  We're
2810Sstevel@tonic-gate	 * going to need to jump into the debugger so as to allow it to
2820Sstevel@tonic-gate	 * handle the trap.  The debugger itself isn't locked into the TLB,
2830Sstevel@tonic-gate	 * so we may well incur a TLB miss while trying to get into it.  As
2840Sstevel@tonic-gate	 * such, we're going to switch off the MMU globals before setting foot
2850Sstevel@tonic-gate	 * into the debugger, thus allowing a TL>1 miss to be handled without
2860Sstevel@tonic-gate	 * clobbering our state.
2870Sstevel@tonic-gate	 *
2880Sstevel@tonic-gate	 * We will only reach this point at TL=1, as kdi_vatotte will always
2890Sstevel@tonic-gate	 * find the TTE for the debugger without missing.
2900Sstevel@tonic-gate	 */
291*1991Sheppo
292*1991Sheppo	sethi	%hi(kaif_dtrap), %g1
293*1991Sheppo	jmp	%g1 + %lo(kaif_dtrap)
294*1991Sheppo	nop
295*1991Sheppo	/* NOTREACHED */
296*1991Sheppo
297*1991Sheppo#ifdef KMDB_TRAPCOUNT
298*1991Sheppo	.align	8
299*1991Sheppo.count:	.xword	0
300*1991Sheppo#endif
301*1991Sheppo
302*1991Sheppo	.align	32*4			/* force length to 32 instr. */
3030Sstevel@tonic-gate	SET_SIZE(kaif_hdlr_imiss)
304*1991Sheppo
305*1991Sheppo
3060Sstevel@tonic-gate
3070Sstevel@tonic-gate	ENTRY_NP(kaif_hdlr_generic)
308*1991Sheppo#ifdef	KMDB_TRAPCOUNT			/* Trap counter.  See top comment */
309*1991Sheppo0:	rd	%pc, %g3
310*1991Sheppo	ldx	[%g3 + .count-0b], %g4
3110Sstevel@tonic-gate	add	%g4, 1, %g4
312*1991Sheppo	stx	%g4, [%g3 + .count-0b]
313*1991Sheppo#endif
314*1991Sheppo
315*1991Sheppo	sethi	%hi(kaif_dtrap), %g1
316*1991Sheppo	jmp	%g1 + %lo(kaif_dtrap)
3170Sstevel@tonic-gate	nop
318*1991Sheppo	/* NOTREACHED */
319*1991Sheppo
320*1991Sheppo#ifdef	KMDB_TRAPCOUNT
321*1991Sheppo	.align	8
322*1991Sheppo.count:	.xword	0			/* counter goes here */
3230Sstevel@tonic-gate#endif
324*1991Sheppo
325*1991Sheppo	.align	32*4			/* force length to 32 instr. */
3260Sstevel@tonic-gate	SET_SIZE(kaif_hdlr_generic)
3270Sstevel@tonic-gate
328*1991Sheppo#endif /* lint */
329