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