xref: /illumos-gate/usr/src/uts/sun4u/ml/mach_xc.S (revision 44749cf0c208741d3c37035731688216f5517f58)
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#include "assym.h"
27
28#include <sys/asm_linkage.h>
29#include <sys/privregs.h>
30#include <sys/x_call.h>
31#include <sys/xc_impl.h>
32
33#ifdef TRAPTRACE
34#include <sys/traptrace.h>
35#endif /* TRAPTRACE */
36
37
38/*
39 * Entered by the software trap (TT=ST_SELFXCALL, TL>0) thru send_self_xcall().
40 * Emulate the mondo handler - vec_interrupt().
41 *
42 * Global registers are the Alternate Globals.
43 * Arguments:
44 * 	%o0 - CPU
45 * 	ILP32 kernel:
46 * 		%o5 - function to call
47 * 		%o1, %o2, %o3, %o4  - arguments
48 * 	LP64 kernel:
49 * 		%o3 - function to call
50 * 		%o1, %o2 - arguments
51 */
52	ENTRY_NP(self_xcall)
53	!
54	! TL>0 handlers are expected to do "retry"
55	! prepare their return PC and nPC now
56	!
57	rdpr	%tnpc, %g1
58	wrpr	%g1, %tpc			!  PC <- TNPC[TL]
59 	add	%g1, 4, %g1
60	wrpr	%g1, %tnpc			! nPC <- TNPC[TL] + 4
61
62#ifdef TRAPTRACE
63	TRACE_PTR(%g4, %g6)
64	GET_TRACE_TICK(%g6, %g3)
65	stxa	%g6, [%g4 + TRAP_ENT_TICK]%asi
66	rdpr	%tl, %g6
67	stha	%g6, [%g4 + TRAP_ENT_TL]%asi
68	rdpr	%tt, %g6
69	stha	%g6, [%g4 + TRAP_ENT_TT]%asi
70	stna	%o3, [%g4 + TRAP_ENT_TR]%asi ! pc of the TL>0 handler
71	rdpr	%tpc, %g6
72	stna	%g6, [%g4 + TRAP_ENT_TPC]%asi
73	rdpr	%tstate, %g6
74	stxa	%g6, [%g4 + TRAP_ENT_TSTATE]%asi
75	stna	%sp, [%g4 + TRAP_ENT_SP]%asi
76	stna	%o1, [%g4 + TRAP_ENT_F1]%asi ! arg 1
77	stna	%o2, [%g4 + TRAP_ENT_F2]%asi ! arg 2
78	stna	%g0, [%g4 + TRAP_ENT_F3]%asi
79	stna	%g0, [%g4 + TRAP_ENT_F4]%asi
80	TRACE_NEXT(%g4, %g6, %g3)
81#endif /* TRAPTRACE */
82	!
83	! Load the arguments for the fast trap handler.
84	!
85	mov	%o1, %g1
86	jmp	%o3				! call the fast trap handler
87	mov	%o2, %g2
88	/* Not Reached */
89	SET_SIZE(self_xcall)
90
91#ifdef  TRAPTRACE
92	ENTRY(xc_trace)
93	rdpr	%pstate, %g1
94	andn	%g1, PSTATE_IE | PSTATE_AM, %g2
95	wrpr	%g0, %g2, %pstate			/* disable interrupts */
96	TRACE_PTR(%g3, %g4)
97	GET_TRACE_TICK(%g6, %g4)
98	stxa	%g6, [%g3 + TRAP_ENT_TICK]%asi
99	stha	%g0, [%g3 + TRAP_ENT_TL]%asi
100	set	TT_XCALL, %g2
101	or	%o0, %g2, %g4
102	stha	%g4, [%g3 + TRAP_ENT_TT]%asi
103	stna	%o7, [%g3 + TRAP_ENT_TPC]%asi
104	ldn	[%o1], %g2
105	stna	%g2, [%g3 + TRAP_ENT_SP]%asi		/* sp = cpuset */
106	stna	%o2, [%g3 + TRAP_ENT_TR]%asi		/* tr = func */
107	stna	%o3, [%g3 + TRAP_ENT_F1]%asi		/* f1 = arg1 */
108	stna	%o4, [%g3 + TRAP_ENT_F2]%asi		/* f2 = arg2 */
109	stna	%g0, [%g3 + TRAP_ENT_F3]%asi		/* f3 = 0 */
110	stna	%i7, [%g3 + TRAP_ENT_F4]%asi		/* f4 = xcall caller */
111	stxa	%g1, [%g3 + TRAP_ENT_TSTATE]%asi	/* tstate = pstate */
112	TRACE_NEXT(%g2, %g3, %g4)
113/*
114 * In the case of a cpuset of greater size than a long we
115 * grab extra trace buffers just to store the cpuset.
116 * Seems like a waste but popular opinion opted for this
117 * rather than increase the size of the buffer.
118 */
119#if CPUSET_SIZE > CLONGSIZE
120	add	%o1, CPUSET_SIZE, %g5			/* end of cpuset */
121	clr	%o2
1221:
123	TRACE_PTR(%g3, %g4)
124	stha	%g0, [%g3 + TRAP_ENT_TL]%asi
125	set	TT_XCALL_CONT, %g2
126	or	%g2, %o2, %g2				/* continuation # */
127	stha	%g2, [%g3 + TRAP_ENT_TT]%asi
128	stxa	%g6, [%g3 + TRAP_ENT_TICK]%asi		/* same tick */
129	stna	%g0, [%g3 + TRAP_ENT_TPC]%asi		/* clr unused fields */
130	stna	%g0, [%g3 + TRAP_ENT_SP]%asi
131	stna	%g0, [%g3 + TRAP_ENT_TR]%asi
132	stxa	%g0, [%g3 + TRAP_ENT_TSTATE]%asi
133	stna	%g0, [%g3 + TRAP_ENT_F2]%asi
134	stna	%g0, [%g3 + TRAP_ENT_F3]%asi
135	stna	%g0, [%g3 + TRAP_ENT_F4]%asi
136	ldn	[%o1], %g2
137	stna	%g2, [%g3 + TRAP_ENT_F1]%asi
138	add	%o1, CLONGSIZE, %o1
139	cmp	%o1, %g5
140	bge	2f
141	ldn	[%o1], %g2
142	stna	%g2, [%g3 + TRAP_ENT_F2]%asi
143	add	%o1, CLONGSIZE, %o1
144	cmp	%o1, %g5
145	bge	2f
146	ldn	[%o1], %g2
147	stna	%g2, [%g3 + TRAP_ENT_F3]%asi
148	add	%o1, CLONGSIZE, %o1
149	cmp	%o1, %g5
150	bge	2f
151	ldn	[%o1], %g2
152	stna	%g2, [%g3 + TRAP_ENT_F4]%asi
153	add	%o1, CLONGSIZE, %o1
1542:
155	TRACE_NEXT(%g2, %g3, %g4)
156	cmp	%o1, %g5
157	bl	1b
158	inc	%o2
159#endif	/* CPUSET_SIZE */
160	retl
161	wrpr	%g0, %g1, %pstate			/* enable interrupts */
162	SET_SIZE(xc_trace)
163
164#endif	/* TRAPTRACE */
165
166/*
167 * This dummy tl1 function is there to ensure that previously called
168 * xtrap handlers have exececuted. The hardware (mondo dispatch
169 * mechanism) is such that return from xtrap doesn't guarantee execution
170 * of xtrap handler. So, callers can call this xtrap-handler to ensure
171 * that the previous one is complete. This is because the hardware only
172 * can handle 1 mondo at a time - when this mondo is handled, we are sure
173 * that the mondo for the previous xtrap must have been handled.
174 */
175	ENTRY_NP(xt_sync_tl1)
176	retry
177	SET_SIZE(xt_sync_tl1)
178
179