xref: /illumos-gate/usr/src/uts/sun4u/ml/mach_xc.S (revision 55fea89d)
1*5d9d9091SRichard Lowe/*
2*5d9d9091SRichard Lowe * CDDL HEADER START
3*5d9d9091SRichard Lowe *
4*5d9d9091SRichard Lowe * The contents of this file are subject to the terms of the
5*5d9d9091SRichard Lowe * Common Development and Distribution License (the "License").
6*5d9d9091SRichard Lowe * You may not use this file except in compliance with the License.
7*5d9d9091SRichard Lowe *
8*5d9d9091SRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5d9d9091SRichard Lowe * or http://www.opensolaris.org/os/licensing.
10*5d9d9091SRichard Lowe * See the License for the specific language governing permissions
11*5d9d9091SRichard Lowe * and limitations under the License.
12*5d9d9091SRichard Lowe *
13*5d9d9091SRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each
14*5d9d9091SRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5d9d9091SRichard Lowe * If applicable, add the following below this CDDL HEADER, with the
16*5d9d9091SRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
17*5d9d9091SRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
18*5d9d9091SRichard Lowe *
19*5d9d9091SRichard Lowe * CDDL HEADER END
20*5d9d9091SRichard Lowe */
21*5d9d9091SRichard Lowe/*
22*5d9d9091SRichard Lowe * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23*5d9d9091SRichard Lowe * Use is subject to license terms.
24*5d9d9091SRichard Lowe */
25*5d9d9091SRichard Lowe
26*5d9d9091SRichard Lowe#include "assym.h"
27*5d9d9091SRichard Lowe
28*5d9d9091SRichard Lowe#include <sys/asm_linkage.h>
29*5d9d9091SRichard Lowe#include <sys/privregs.h>
30*5d9d9091SRichard Lowe#include <sys/x_call.h>
31*5d9d9091SRichard Lowe#include <sys/xc_impl.h>
32*5d9d9091SRichard Lowe
33*5d9d9091SRichard Lowe#ifdef TRAPTRACE
34*5d9d9091SRichard Lowe#include <sys/traptrace.h>
35*5d9d9091SRichard Lowe#endif /* TRAPTRACE */
36*5d9d9091SRichard Lowe
37*5d9d9091SRichard Lowe
38*5d9d9091SRichard Lowe/*
39*5d9d9091SRichard Lowe * Entered by the software trap (TT=ST_SELFXCALL, TL>0) thru send_self_xcall().
40*5d9d9091SRichard Lowe * Emulate the mondo handler - vec_interrupt().
41*5d9d9091SRichard Lowe *
42*5d9d9091SRichard Lowe * Global registers are the Alternate Globals.
43*5d9d9091SRichard Lowe * Arguments:
44*5d9d9091SRichard Lowe * 	%o0 - CPU
45*5d9d9091SRichard Lowe * 	ILP32 kernel:
46*5d9d9091SRichard Lowe * 		%o5 - function to call
47*5d9d9091SRichard Lowe * 		%o1, %o2, %o3, %o4  - arguments
48*5d9d9091SRichard Lowe * 	LP64 kernel:
49*5d9d9091SRichard Lowe * 		%o3 - function to call
50*5d9d9091SRichard Lowe * 		%o1, %o2 - arguments
51*5d9d9091SRichard Lowe */
52*5d9d9091SRichard Lowe	ENTRY_NP(self_xcall)
53*5d9d9091SRichard Lowe	!
54*5d9d9091SRichard Lowe	! TL>0 handlers are expected to do "retry"
55*5d9d9091SRichard Lowe	! prepare their return PC and nPC now
56*5d9d9091SRichard Lowe	!
57*5d9d9091SRichard Lowe	rdpr	%tnpc, %g1
58*5d9d9091SRichard Lowe	wrpr	%g1, %tpc			!  PC <- TNPC[TL]
59*5d9d9091SRichard Lowe 	add	%g1, 4, %g1
60*5d9d9091SRichard Lowe	wrpr	%g1, %tnpc			! nPC <- TNPC[TL] + 4
61*5d9d9091SRichard Lowe
62*5d9d9091SRichard Lowe#ifdef TRAPTRACE
63*5d9d9091SRichard Lowe	TRACE_PTR(%g4, %g6)
64*5d9d9091SRichard Lowe	GET_TRACE_TICK(%g6, %g3)
65*5d9d9091SRichard Lowe	stxa	%g6, [%g4 + TRAP_ENT_TICK]%asi
66*5d9d9091SRichard Lowe	rdpr	%tl, %g6
67*5d9d9091SRichard Lowe	stha	%g6, [%g4 + TRAP_ENT_TL]%asi
68*5d9d9091SRichard Lowe	rdpr	%tt, %g6
69*5d9d9091SRichard Lowe	stha	%g6, [%g4 + TRAP_ENT_TT]%asi
70*5d9d9091SRichard Lowe	stna	%o3, [%g4 + TRAP_ENT_TR]%asi ! pc of the TL>0 handler
71*5d9d9091SRichard Lowe	rdpr	%tpc, %g6
72*5d9d9091SRichard Lowe	stna	%g6, [%g4 + TRAP_ENT_TPC]%asi
73*5d9d9091SRichard Lowe	rdpr	%tstate, %g6
74*5d9d9091SRichard Lowe	stxa	%g6, [%g4 + TRAP_ENT_TSTATE]%asi
75*5d9d9091SRichard Lowe	stna	%sp, [%g4 + TRAP_ENT_SP]%asi
76*5d9d9091SRichard Lowe	stna	%o1, [%g4 + TRAP_ENT_F1]%asi ! arg 1
77*5d9d9091SRichard Lowe	stna	%o2, [%g4 + TRAP_ENT_F2]%asi ! arg 2
78*5d9d9091SRichard Lowe	stna	%g0, [%g4 + TRAP_ENT_F3]%asi
79*5d9d9091SRichard Lowe	stna	%g0, [%g4 + TRAP_ENT_F4]%asi
80*5d9d9091SRichard Lowe	TRACE_NEXT(%g4, %g6, %g3)
81*5d9d9091SRichard Lowe#endif /* TRAPTRACE */
82*5d9d9091SRichard Lowe	!
83*5d9d9091SRichard Lowe	! Load the arguments for the fast trap handler.
84*5d9d9091SRichard Lowe	!
85*5d9d9091SRichard Lowe	mov	%o1, %g1
86*5d9d9091SRichard Lowe	jmp	%o3				! call the fast trap handler
87*5d9d9091SRichard Lowe	mov	%o2, %g2
88*5d9d9091SRichard Lowe	/* Not Reached */
89*5d9d9091SRichard Lowe	SET_SIZE(self_xcall)
90*5d9d9091SRichard Lowe
91*5d9d9091SRichard Lowe#ifdef  TRAPTRACE
92*5d9d9091SRichard Lowe	ENTRY(xc_trace)
93*5d9d9091SRichard Lowe	rdpr	%pstate, %g1
94*5d9d9091SRichard Lowe	andn	%g1, PSTATE_IE | PSTATE_AM, %g2
95*5d9d9091SRichard Lowe	wrpr	%g0, %g2, %pstate			/* disable interrupts */
96*5d9d9091SRichard Lowe	TRACE_PTR(%g3, %g4)
97*5d9d9091SRichard Lowe	GET_TRACE_TICK(%g6, %g4)
98*5d9d9091SRichard Lowe	stxa	%g6, [%g3 + TRAP_ENT_TICK]%asi
99*5d9d9091SRichard Lowe	stha	%g0, [%g3 + TRAP_ENT_TL]%asi
100*5d9d9091SRichard Lowe	set	TT_XCALL, %g2
101*5d9d9091SRichard Lowe	or	%o0, %g2, %g4
102*5d9d9091SRichard Lowe	stha	%g4, [%g3 + TRAP_ENT_TT]%asi
103*5d9d9091SRichard Lowe	stna	%o7, [%g3 + TRAP_ENT_TPC]%asi
104*5d9d9091SRichard Lowe	ldn	[%o1], %g2
105*5d9d9091SRichard Lowe	stna	%g2, [%g3 + TRAP_ENT_SP]%asi		/* sp = cpuset */
106*5d9d9091SRichard Lowe	stna	%o2, [%g3 + TRAP_ENT_TR]%asi		/* tr = func */
107*5d9d9091SRichard Lowe	stna	%o3, [%g3 + TRAP_ENT_F1]%asi		/* f1 = arg1 */
108*5d9d9091SRichard Lowe	stna	%o4, [%g3 + TRAP_ENT_F2]%asi		/* f2 = arg2 */
109*5d9d9091SRichard Lowe	stna	%g0, [%g3 + TRAP_ENT_F3]%asi		/* f3 = 0 */
110*5d9d9091SRichard Lowe	stna	%i7, [%g3 + TRAP_ENT_F4]%asi		/* f4 = xcall caller */
111*5d9d9091SRichard Lowe	stxa	%g1, [%g3 + TRAP_ENT_TSTATE]%asi	/* tstate = pstate */
112*5d9d9091SRichard Lowe	TRACE_NEXT(%g2, %g3, %g4)
113*5d9d9091SRichard Lowe/*
114*5d9d9091SRichard Lowe * In the case of a cpuset of greater size than a long we
115*5d9d9091SRichard Lowe * grab extra trace buffers just to store the cpuset.
116*5d9d9091SRichard Lowe * Seems like a waste but popular opinion opted for this
117*5d9d9091SRichard Lowe * rather than increase the size of the buffer.
118*5d9d9091SRichard Lowe */
119*5d9d9091SRichard Lowe#if CPUSET_SIZE > CLONGSIZE
120*5d9d9091SRichard Lowe	add	%o1, CPUSET_SIZE, %g5			/* end of cpuset */
121*5d9d9091SRichard Lowe	clr	%o2
122*5d9d9091SRichard Lowe1:
123*5d9d9091SRichard Lowe	TRACE_PTR(%g3, %g4)
124*5d9d9091SRichard Lowe	stha	%g0, [%g3 + TRAP_ENT_TL]%asi
125*5d9d9091SRichard Lowe	set	TT_XCALL_CONT, %g2
126*5d9d9091SRichard Lowe	or	%g2, %o2, %g2				/* continuation # */
127*5d9d9091SRichard Lowe	stha	%g2, [%g3 + TRAP_ENT_TT]%asi
128*5d9d9091SRichard Lowe	stxa	%g6, [%g3 + TRAP_ENT_TICK]%asi		/* same tick */
129*5d9d9091SRichard Lowe	stna	%g0, [%g3 + TRAP_ENT_TPC]%asi		/* clr unused fields */
130*5d9d9091SRichard Lowe	stna	%g0, [%g3 + TRAP_ENT_SP]%asi
131*5d9d9091SRichard Lowe	stna	%g0, [%g3 + TRAP_ENT_TR]%asi
132*5d9d9091SRichard Lowe	stxa	%g0, [%g3 + TRAP_ENT_TSTATE]%asi
133*5d9d9091SRichard Lowe	stna	%g0, [%g3 + TRAP_ENT_F2]%asi
134*5d9d9091SRichard Lowe	stna	%g0, [%g3 + TRAP_ENT_F3]%asi
135*5d9d9091SRichard Lowe	stna	%g0, [%g3 + TRAP_ENT_F4]%asi
136*5d9d9091SRichard Lowe	ldn	[%o1], %g2
137*5d9d9091SRichard Lowe	stna	%g2, [%g3 + TRAP_ENT_F1]%asi
138*5d9d9091SRichard Lowe	add	%o1, CLONGSIZE, %o1
139*5d9d9091SRichard Lowe	cmp	%o1, %g5
140*5d9d9091SRichard Lowe	bge	2f
141*5d9d9091SRichard Lowe	ldn	[%o1], %g2
142*5d9d9091SRichard Lowe	stna	%g2, [%g3 + TRAP_ENT_F2]%asi
143*5d9d9091SRichard Lowe	add	%o1, CLONGSIZE, %o1
144*5d9d9091SRichard Lowe	cmp	%o1, %g5
145*5d9d9091SRichard Lowe	bge	2f
146*5d9d9091SRichard Lowe	ldn	[%o1], %g2
147*5d9d9091SRichard Lowe	stna	%g2, [%g3 + TRAP_ENT_F3]%asi
148*5d9d9091SRichard Lowe	add	%o1, CLONGSIZE, %o1
149*5d9d9091SRichard Lowe	cmp	%o1, %g5
150*5d9d9091SRichard Lowe	bge	2f
151*5d9d9091SRichard Lowe	ldn	[%o1], %g2
152*5d9d9091SRichard Lowe	stna	%g2, [%g3 + TRAP_ENT_F4]%asi
153*5d9d9091SRichard Lowe	add	%o1, CLONGSIZE, %o1
154*5d9d9091SRichard Lowe2:
155*5d9d9091SRichard Lowe	TRACE_NEXT(%g2, %g3, %g4)
156*5d9d9091SRichard Lowe	cmp	%o1, %g5
157*5d9d9091SRichard Lowe	bl	1b
158*5d9d9091SRichard Lowe	inc	%o2
159*5d9d9091SRichard Lowe#endif	/* CPUSET_SIZE */
160*5d9d9091SRichard Lowe	retl
161*5d9d9091SRichard Lowe	wrpr	%g0, %g1, %pstate			/* enable interrupts */
162*5d9d9091SRichard Lowe	SET_SIZE(xc_trace)
163*5d9d9091SRichard Lowe
164*5d9d9091SRichard Lowe#endif	/* TRAPTRACE */
165*5d9d9091SRichard Lowe
166*5d9d9091SRichard Lowe/*
167*5d9d9091SRichard Lowe * This dummy tl1 function is there to ensure that previously called
168*5d9d9091SRichard Lowe * xtrap handlers have exececuted. The hardware (mondo dispatch
169*5d9d9091SRichard Lowe * mechanism) is such that return from xtrap doesn't guarantee execution
170*5d9d9091SRichard Lowe * of xtrap handler. So, callers can call this xtrap-handler to ensure
171*5d9d9091SRichard Lowe * that the previous one is complete. This is because the hardware only
172*5d9d9091SRichard Lowe * can handle 1 mondo at a time - when this mondo is handled, we are sure
173*5d9d9091SRichard Lowe * that the mondo for the previous xtrap must have been handled.
174*5d9d9091SRichard Lowe */
175*5d9d9091SRichard Lowe	ENTRY_NP(xt_sync_tl1)
176*5d9d9091SRichard Lowe	retry
177*5d9d9091SRichard Lowe	SET_SIZE(xt_sync_tl1)
178*5d9d9091SRichard Lowe
179