17c478bd9Sstevel@tonic-gate/*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*1ae08745Sheppo * Common Development and Distribution License (the "License").
6*1ae08745Sheppo * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
21*1ae08745Sheppo
227c478bd9Sstevel@tonic-gate/*
23*1ae08745Sheppo * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate#pragma ident	"%Z%%M%	%I%	%E% SMI"
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
307c478bd9Sstevel@tonic-gate#include <sys/machasi.h>
317c478bd9Sstevel@tonic-gate#include <sys/machtrap.h>
327c478bd9Sstevel@tonic-gate#include <sys/privregs.h>
337c478bd9Sstevel@tonic-gate#include <sys/mmu.h>
34*1ae08745Sheppo#include <vm/mach_sfmmu.h>
35*1ae08745Sheppo
36*1ae08745Sheppo#if defined(sun4v) && !defined(lint)
37*1ae08745Sheppo#include <sys/machparam.h>
38*1ae08745Sheppo#endif
39*1ae08745Sheppo
40*1ae08745Sheppo#if defined(sun4v) && defined(KMDB_TRAPCOUNT)
41*1ae08745Sheppo/*
42*1ae08745Sheppo * The sun4v implemenations of the fast miss handlers are larger than those
43*1ae08745Sheppo * of their sun4u kin. This is unfortunate because there is not enough space
44*1ae08745Sheppo * remaining in the respective trap table entries for this debug feature.
45*1ae08745Sheppo */
46*1ae08745Sheppo#error "KMDB_TRAPCOUNT not supported on sun4v"
47*1ae08745Sheppo#endif
487c478bd9Sstevel@tonic-gate
497c478bd9Sstevel@tonic-gate/*
507c478bd9Sstevel@tonic-gate * This file contains the trap handlers that will be copied to kmdb's trap
517c478bd9Sstevel@tonic-gate * table.  See kaif_activate.c for the code that does the actual copying.
527c478bd9Sstevel@tonic-gate *
537c478bd9Sstevel@tonic-gate * The handlers have a debugging feature, enabled when KMDB_TRAPCOUNT is
547c478bd9Sstevel@tonic-gate * defined, which allows them to keep a running count of the number of times
557c478bd9Sstevel@tonic-gate * a given trap has occurred.  The counter is stored in the padding at the end
567c478bd9Sstevel@tonic-gate * of the handler.  Write access is of course required to allow the values to
577c478bd9Sstevel@tonic-gate * be updated, so KMDB_TRAPCOUNT also enables the installation of DTLB entries
587c478bd9Sstevel@tonic-gate * for each trap table page.  Finally, the code in this file is copied into
597c478bd9Sstevel@tonic-gate * the actual location used by the handler, so we can't perform compile-time
607c478bd9Sstevel@tonic-gate * counter location calculations.  The calculations are instead performed at
617c478bd9Sstevel@tonic-gate * run-time, as A) we generally already derive the table location as part of
627c478bd9Sstevel@tonic-gate * the trap processing and B) simplicity is more of a concern than is speed.
637c478bd9Sstevel@tonic-gate */
647c478bd9Sstevel@tonic-gate
657c478bd9Sstevel@tonic-gate#if defined(lint)
667c478bd9Sstevel@tonic-gate#include <kmdb/kaif.h>
677c478bd9Sstevel@tonic-gate
687c478bd9Sstevel@tonic-gatevoid
697c478bd9Sstevel@tonic-gatekaif_hdlr_dmiss(void)
707c478bd9Sstevel@tonic-gate{
717c478bd9Sstevel@tonic-gate}
727c478bd9Sstevel@tonic-gate
737c478bd9Sstevel@tonic-gatevoid
747c478bd9Sstevel@tonic-gatekaif_itlb_handler(void)
757c478bd9Sstevel@tonic-gate{
767c478bd9Sstevel@tonic-gate}
77*1ae08745Sheppo
78*1ae08745Sheppo#else /* lint */
797c478bd9Sstevel@tonic-gate
807c478bd9Sstevel@tonic-gate#ifdef sun4v
81*1ae08745Sheppo
82*1ae08745Sheppo#define	GET_MMU_D_ADDR_CTX(daddr, ctx)			\
83*1ae08745Sheppo	MMU_FAULT_STATUS_AREA(ctx);			\
84*1ae08745Sheppo	ldx	[ctx + MMFSA_D_ADDR], daddr;		\
85*1ae08745Sheppo	ldx	[ctx + MMFSA_D_CTX], ctx
86*1ae08745Sheppo
87*1ae08745Sheppo#define	GET_MMU_I_ADDR_CTX(iaddr, ctx)			\
88*1ae08745Sheppo	MMU_FAULT_STATUS_AREA(ctx);			\
89*1ae08745Sheppo	ldx	[ctx + MMFSA_I_ADDR], iaddr;		\
90*1ae08745Sheppo	ldx	[ctx + MMFSA_I_CTX], ctx
91*1ae08745Sheppo
92*1ae08745Sheppo/*
93*1ae08745Sheppo * KAIF_ITLB_STUFF
94*1ae08745Sheppo * derived from ITLB_STUFF in uts/sun4v/vm/mach_sfmmu.h
95*1ae08745Sheppo *
96*1ae08745Sheppo * Load ITLB entry
97*1ae08745Sheppo *
98*1ae08745Sheppo * In:
99*1ae08745Sheppo *   tte = reg containing tte
100*1ae08745Sheppo *   ouch = branch target label used if hcall fails (sun4v only)
101*1ae08745Sheppo *   scr1, scr2, scr3, scr4 = scratch registers (must not be %o0-%o3)
102*1ae08745Sheppo */
103*1ae08745Sheppo#define	KAIF_ITLB_STUFF(tte, ouch, scr1, scr2, scr3, scr4)	\
104*1ae08745Sheppo	mov	%o0, scr1;				\
105*1ae08745Sheppo	mov	%o1, scr2;				\
106*1ae08745Sheppo	mov	%o2, scr3;				\
107*1ae08745Sheppo	mov	%o3, scr4;				\
108*1ae08745Sheppo	MMU_FAULT_STATUS_AREA(%o2);			\
109*1ae08745Sheppo	ldx	[%o2 + MMFSA_I_ADDR], %o0;		\
110*1ae08745Sheppo	ldx	[%o2 + MMFSA_I_CTX], %o1;		\
111*1ae08745Sheppo	srlx	%o0, PAGESHIFT, %o0;			\
112*1ae08745Sheppo	sllx	%o0, PAGESHIFT, %o0;			\
113*1ae08745Sheppo	mov	tte, %o2;				\
114*1ae08745Sheppo	mov	MAP_ITLB, %o3;				\
115*1ae08745Sheppo	ta	MMU_MAP_ADDR;				\
116*1ae08745Sheppo	/* BEGIN CSTYLED */				\
117*1ae08745Sheppo	brnz,a,pn %o0, ouch;				\
118*1ae08745Sheppo	  nop;						\
119*1ae08745Sheppo	/* END CSTYLED */				\
120*1ae08745Sheppo	mov	scr1, %o0;				\
121*1ae08745Sheppo	mov	scr2, %o1;				\
122*1ae08745Sheppo	mov	scr3, %o2;				\
123*1ae08745Sheppo	mov	scr4, %o3
124*1ae08745Sheppo
125*1ae08745Sheppo/*
126*1ae08745Sheppo * KAIF_DTLB_STUFF
127*1ae08745Sheppo * derived from DTLB_STUFF in uts/sun4v/vm/mach_sfmmu.h
128*1ae08745Sheppo *
129*1ae08745Sheppo * Load DTLB entry
130*1ae08745Sheppo *
131*1ae08745Sheppo * In:
132*1ae08745Sheppo *   tte = reg containing tte
133*1ae08745Sheppo *   ouch = branch target label used if hcall fails (sun4v only)
134*1ae08745Sheppo *   scr1, scr2, scr3, scr4 = scratch registers (must not be %o0-%o3)
135*1ae08745Sheppo */
136*1ae08745Sheppo#define	KAIF_DTLB_STUFF(tte, ouch, scr1, scr2, scr3, scr4)	\
137*1ae08745Sheppo	mov	%o0, scr1;				\
138*1ae08745Sheppo	mov	%o1, scr2;				\
139*1ae08745Sheppo	mov	%o2, scr3;				\
140*1ae08745Sheppo	mov	%o3, scr4;				\
141*1ae08745Sheppo	MMU_FAULT_STATUS_AREA(%o2);			\
142*1ae08745Sheppo	ldx	[%o2 + MMFSA_D_ADDR], %o0;		\
143*1ae08745Sheppo	ldx	[%o2 + MMFSA_D_CTX], %o1;		\
144*1ae08745Sheppo	srlx	%o0, PAGESHIFT, %o0;			\
145*1ae08745Sheppo	sllx	%o0, PAGESHIFT, %o0;			\
146*1ae08745Sheppo	mov	tte, %o2;				\
147*1ae08745Sheppo	mov	MAP_DTLB, %o3;				\
148*1ae08745Sheppo	ta	MMU_MAP_ADDR;				\
149*1ae08745Sheppo	/* BEGIN CSTYLED */				\
150*1ae08745Sheppo	brnz,a,pn %o0, ouch;				\
151*1ae08745Sheppo	  nop;						\
152*1ae08745Sheppo	/* END CSTYLED */				\
153*1ae08745Sheppo	mov	scr1, %o0;				\
154*1ae08745Sheppo	mov	scr2, %o1;				\
155*1ae08745Sheppo	mov	scr3, %o2;				\
156*1ae08745Sheppo	mov	scr4, %o3
157*1ae08745Sheppo
1587c478bd9Sstevel@tonic-gate#else /* sun4v */
1597c478bd9Sstevel@tonic-gate
160*1ae08745Sheppo#define	GET_MMU_D_ADDR_CTX(daddr, ctx)			\
161*1ae08745Sheppo	mov	MMU_TAG_ACCESS, ctx;			\
162*1ae08745Sheppo	ldxa	[ctx]ASI_DMMU, daddr;			\
163*1ae08745Sheppo	sllx	daddr, TAGACC_CTX_LSHIFT, ctx;		\
164*1ae08745Sheppo	srlx	ctx, TAGACC_CTX_LSHIFT, ctx
165*1ae08745Sheppo
166*1ae08745Sheppo#define	GET_MMU_I_ADDR_CTX(iaddr, ctx)			\
167*1ae08745Sheppo	rdpr	%tpc, iaddr;				\
168*1ae08745Sheppo	ldxa	[%g0]ASI_IMMU, ctx;			\
169*1ae08745Sheppo	srlx	ctx, TTARGET_CTX_SHIFT, ctx
170*1ae08745Sheppo
171*1ae08745Sheppo#define	KAIF_DTLB_STUFF(tte, ouch, scr1, scr2, scr3, scr4)	\
172*1ae08745Sheppo	DTLB_STUFF(tte, scr1, scr2, scr3, scr4)
173*1ae08745Sheppo
174*1ae08745Sheppo#define	KAIF_ITLB_STUFF(tte, ouch, scr1, scr2, scr3, scr4)	\
175*1ae08745Sheppo	ITLB_STUFF(tte, scr1, scr2, scr3, scr4)
176*1ae08745Sheppo
177*1ae08745Sheppo#endif /* sun4v */
178*1ae08745Sheppo
179*1ae08745Sheppo/*
180*1ae08745Sheppo * KAIF_CALL_KDI_VATOTTE
181*1ae08745Sheppo *
182*1ae08745Sheppo * Use kdi_vatotte to look up the tte.  We don't bother stripping the
183*1ae08745Sheppo * context, as it won't change the tte we get.
184*1ae08745Sheppo *
185*1ae08745Sheppo * The two instruction at patch_lbl are modified during runtime
186*1ae08745Sheppo * by kaif to point to kdi_vatotte
187*1ae08745Sheppo *
188*1ae08745Sheppo * Clobbers all globals.
189*1ae08745Sheppo * Returns tte in %g1 if successful, otherwise 0 in %g1
190*1ae08745Sheppo * Leaves address of next instruction following this macro in scr1
191*1ae08745Sheppo */
192*1ae08745Sheppo#define	KAIF_CALL_KDI_VATOTTE(addr, ctx, patch_lbl, scr0, scr1)	\
193*1ae08745Sheppo	.global	patch_lbl;					\
194*1ae08745Sheppopatch_lbl:							\
195*1ae08745Sheppo	sethi	%hi(0), scr0;					\
196*1ae08745Sheppo	or	scr0, %lo(0), scr0;				\
197*1ae08745Sheppo	jmpl	scr0, scr1;					\
198*1ae08745Sheppo	add	scr1, 8, scr1
199*1ae08745Sheppo
2007c478bd9Sstevel@tonic-gate
2017c478bd9Sstevel@tonic-gate	ENTRY_NP(kaif_hdlr_dmiss)
202*1ae08745Sheppo	GET_MMU_D_ADDR_CTX(%g1, %g2)
2037c478bd9Sstevel@tonic-gate
204*1ae08745Sheppo	KAIF_CALL_KDI_VATOTTE(%g1, %g2, kaif_hdlr_dmiss_patch, %g3, %g7)
205*1ae08745Sheppo0:	brz	%g1, 1f
2067c478bd9Sstevel@tonic-gate	nop
2077c478bd9Sstevel@tonic-gate
2087c478bd9Sstevel@tonic-gate	/*
2097c478bd9Sstevel@tonic-gate	 * kdi_vatotte gave us a TTE to use.  Load it up and head back
2107c478bd9Sstevel@tonic-gate	 * into the world, but first bump a counter.
2117c478bd9Sstevel@tonic-gate	 */
212*1ae08745Sheppo
213*1ae08745Sheppo#ifdef	KMDB_TRAPCOUNT			/* Trap counter.  See top comment */
214*1ae08745Sheppo	ldx	[%g7 + .count-0b], %g2
2157c478bd9Sstevel@tonic-gate	add	%g2, 1, %g2
216*1ae08745Sheppo	stx	%g2, [%g7 + .count-0b]
2177c478bd9Sstevel@tonic-gate#endif
218*1ae08745Sheppo
219*1ae08745Sheppo	KAIF_DTLB_STUFF(%g1, 1f, %g2, %g3, %g4, %g5)
2207c478bd9Sstevel@tonic-gate	retry
2217c478bd9Sstevel@tonic-gate
2227c478bd9Sstevel@tonic-gate1:	/*
2237c478bd9Sstevel@tonic-gate	 * kdi_vatotte didn't give us a tte, which is unfortunate.  We're
2247c478bd9Sstevel@tonic-gate	 * going to need to jump into the debugger so as to allow it to
2257c478bd9Sstevel@tonic-gate	 * handle the trap.  The debugger itself isn't locked into the TLB,
2267c478bd9Sstevel@tonic-gate	 * so we may well incur a TLB miss while trying to get into it.  As
2277c478bd9Sstevel@tonic-gate	 * such, we're going to switch off the MMU globals before setting foot
2287c478bd9Sstevel@tonic-gate	 * into the debugger, thus allowing a TL>1 miss to be handled without
2297c478bd9Sstevel@tonic-gate	 * clobbering our state.  We'll also save off the tag just in case the
2307c478bd9Sstevel@tonic-gate	 * world ends and someone wants to find out what happened.
2317c478bd9Sstevel@tonic-gate	 *
2327c478bd9Sstevel@tonic-gate	 * We will only reach this point at TL=1, as kdi_vatotte will always
2337c478bd9Sstevel@tonic-gate	 * find the TTE for the debugger without missing.
2347c478bd9Sstevel@tonic-gate	 */
2357c478bd9Sstevel@tonic-gate
236*1ae08745Sheppo#ifdef	KMDB_TRAPCOUNT			/* Trap address "counter". */
237*1ae08745Sheppo	GET_MMU_D_ADDR(%g2, %g3)
238*1ae08745Sheppo	stx	%g2, [%g7 + .daddr-0b]
239*1ae08745Sheppo	stx	%g1, [%g7 + .ecode-0b]
2407c478bd9Sstevel@tonic-gate#endif
2417c478bd9Sstevel@tonic-gate
242*1ae08745Sheppo	sethi	%hi(kaif_dtrap), %g1
243*1ae08745Sheppo	jmp	%g1 + %lo(kaif_dtrap)
2447c478bd9Sstevel@tonic-gate	nop
245*1ae08745Sheppo	/* NOTREACHED */
246*1ae08745Sheppo
247*1ae08745Sheppo#ifdef KMDB_TRAPCOUNT
248*1ae08745Sheppo	.align 8
249*1ae08745Sheppo.count:	.xword 0			/* counter goes here */
250*1ae08745Sheppo.daddr:	.xword 0			/* miss address goes here */
251*1ae08745Sheppo.ecode:	.xword 0			/* sun4v: g1 contains err code */
252*1ae08745Sheppo#endif
253*1ae08745Sheppo
254*1ae08745Sheppo	.align 32*4			/* force length to 32 instr. */
2557c478bd9Sstevel@tonic-gate	SET_SIZE(kaif_hdlr_dmiss)
2567c478bd9Sstevel@tonic-gate
2577c478bd9Sstevel@tonic-gate
2587c478bd9Sstevel@tonic-gate
259*1ae08745Sheppo	ENTRY_NP(kaif_hdlr_imiss)
260*1ae08745Sheppo	GET_MMU_I_ADDR_CTX(%g1, %g2)
261*1ae08745Sheppo
262*1ae08745Sheppo	KAIF_CALL_KDI_VATOTTE(%g1, %g2, kaif_hdlr_imiss_patch, %g3, %g7)
263*1ae08745Sheppo0:	brz	%g1, 1f
2647c478bd9Sstevel@tonic-gate	nop
2657c478bd9Sstevel@tonic-gate
2667c478bd9Sstevel@tonic-gate	/*
2677c478bd9Sstevel@tonic-gate	 * kdi_vatotte gave us a TTE to use.  Load it up and head back
2687c478bd9Sstevel@tonic-gate	 * into the world, but first bump a counter.
2697c478bd9Sstevel@tonic-gate	 */
270*1ae08745Sheppo#ifdef	KMDB_TRAPCOUNT			/* Trap counter.  See top comment */
271*1ae08745Sheppo	ldx	[%g7 + .count-0b], %g2
2727c478bd9Sstevel@tonic-gate	add	%g2, 1, %g2
273*1ae08745Sheppo	stx	%g2, [%g7 + .count-0b]
2747c478bd9Sstevel@tonic-gate#endif
275*1ae08745Sheppo
276*1ae08745Sheppo	KAIF_ITLB_STUFF(%g1, 1f, %g2, %g3, %g4, %g5)
2777c478bd9Sstevel@tonic-gate	retry
2787c478bd9Sstevel@tonic-gate
2797c478bd9Sstevel@tonic-gate1:	/*
2807c478bd9Sstevel@tonic-gate	 * kdi_vatotte didn't give us a tte, which is unfortunate.  We're
2817c478bd9Sstevel@tonic-gate	 * going to need to jump into the debugger so as to allow it to
2827c478bd9Sstevel@tonic-gate	 * handle the trap.  The debugger itself isn't locked into the TLB,
2837c478bd9Sstevel@tonic-gate	 * so we may well incur a TLB miss while trying to get into it.  As
2847c478bd9Sstevel@tonic-gate	 * such, we're going to switch off the MMU globals before setting foot
2857c478bd9Sstevel@tonic-gate	 * into the debugger, thus allowing a TL>1 miss to be handled without
2867c478bd9Sstevel@tonic-gate	 * clobbering our state.
2877c478bd9Sstevel@tonic-gate	 *
2887c478bd9Sstevel@tonic-gate	 * We will only reach this point at TL=1, as kdi_vatotte will always
2897c478bd9Sstevel@tonic-gate	 * find the TTE for the debugger without missing.
2907c478bd9Sstevel@tonic-gate	 */
291*1ae08745Sheppo
292*1ae08745Sheppo	sethi	%hi(kaif_dtrap), %g1
293*1ae08745Sheppo	jmp	%g1 + %lo(kaif_dtrap)
294*1ae08745Sheppo	nop
295*1ae08745Sheppo	/* NOTREACHED */
296*1ae08745Sheppo
297*1ae08745Sheppo#ifdef KMDB_TRAPCOUNT
298*1ae08745Sheppo	.align	8
299*1ae08745Sheppo.count:	.xword	0
300*1ae08745Sheppo#endif
301*1ae08745Sheppo
302*1ae08745Sheppo	.align	32*4			/* force length to 32 instr. */
3037c478bd9Sstevel@tonic-gate	SET_SIZE(kaif_hdlr_imiss)
304*1ae08745Sheppo
305*1ae08745Sheppo
3067c478bd9Sstevel@tonic-gate
3077c478bd9Sstevel@tonic-gate	ENTRY_NP(kaif_hdlr_generic)
308*1ae08745Sheppo#ifdef	KMDB_TRAPCOUNT			/* Trap counter.  See top comment */
309*1ae08745Sheppo0:	rd	%pc, %g3
310*1ae08745Sheppo	ldx	[%g3 + .count-0b], %g4
3117c478bd9Sstevel@tonic-gate	add	%g4, 1, %g4
312*1ae08745Sheppo	stx	%g4, [%g3 + .count-0b]
313*1ae08745Sheppo#endif
314*1ae08745Sheppo
315*1ae08745Sheppo	sethi	%hi(kaif_dtrap), %g1
316*1ae08745Sheppo	jmp	%g1 + %lo(kaif_dtrap)
3177c478bd9Sstevel@tonic-gate	nop
318*1ae08745Sheppo	/* NOTREACHED */
319*1ae08745Sheppo
320*1ae08745Sheppo#ifdef	KMDB_TRAPCOUNT
321*1ae08745Sheppo	.align	8
322*1ae08745Sheppo.count:	.xword	0			/* counter goes here */
3237c478bd9Sstevel@tonic-gate#endif
324*1ae08745Sheppo
325*1ae08745Sheppo	.align	32*4			/* force length to 32 instr. */
3267c478bd9Sstevel@tonic-gate	SET_SIZE(kaif_hdlr_generic)
3277c478bd9Sstevel@tonic-gate
328*1ae08745Sheppo#endif /* lint */
329