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