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 #include <sys/machthread.h>
38 #include <sys/hypervisor_api.h>
39
40 #ifdef TRAPTRACE
41 #include <sys/traptrace.h>
42 #endif /* TRAPTRACE */
43
44
45 #if defined(lint)
46
47 /* ARGSUSED */
48 void
49 self_xcall(struct cpu *cpu, uint64_t arg1, uint64_t arg2, xcfunc_t *func)
50 {}
51
52 #else
53
54 /*
55 * Entered by the software trap (TT=ST_SELFXCALL, TL>0) thru send_self_xcall().
56 * Emulate the mondo handler - vec_interrupt().
57 *
58 * Global registers are the Alternate Globals.
59 * Arguments:
60 * %o0 - CPU
61 * ILP32 kernel:
62 * %o5 - function to call
63 * %o1, %o2, %o3, %o4 - arguments
64 * LP64 kernel:
65 * %o3 - function to call
66 * %o1, %o2 - arguments
67 */
68 ENTRY_NP(self_xcall)
69 !
70 ! TL>0 handlers are expected to do "retry"
71 ! prepare their return PC and nPC now
72 !
73 rdpr %tnpc, %g1
87 rdpr %tpc, %g6
88 stna %g6, [%g4 + TRAP_ENT_TPC]%asi
89 rdpr %tstate, %g6
90 stxa %g6, [%g4 + TRAP_ENT_TSTATE]%asi
91 stna %sp, [%g4 + TRAP_ENT_SP]%asi
92 stna %o1, [%g4 + TRAP_ENT_F1]%asi ! arg 1
93 stna %o2, [%g4 + TRAP_ENT_F2]%asi ! arg 2
94 stna %g0, [%g4 + TRAP_ENT_F3]%asi
95 stna %g0, [%g4 + TRAP_ENT_F4]%asi
96 TRACE_NEXT(%g4, %g6, %g3)
97 #endif /* TRAPTRACE */
98 !
99 ! Load the arguments for the fast trap handler.
100 !
101 mov %o1, %g1
102 jmp %o3 ! call the fast trap handler
103 mov %o2, %g2
104 /* Not Reached */
105 SET_SIZE(self_xcall)
106
107 #endif /* lint */
108
109 #ifdef TRAPTRACE
110 #if defined(lint)
111
112 /* ARGSUSED */
113 void
114 xc_trace(u_int traptype, cpuset_t *cpu_set, xcfunc_t *func,
115 uint64_t arg1, uint64_t arg2)
116 {}
117
118 #else /* lint */
119 ENTRY(xc_trace)
120 rdpr %pstate, %g1
121 andn %g1, PSTATE_IE | PSTATE_AM, %g2
122 wrpr %g0, %g2, %pstate /* disable interrupts */
123 TRACE_PTR(%g3, %g4)
124 GET_TRACE_TICK(%g6, %g4)
125 stxa %g6, [%g3 + TRAP_ENT_TICK]%asi
126 stha %g0, [%g3 + TRAP_ENT_TL]%asi
127 set TT_XCALL, %g2
128 or %o0, %g2, %g4
129 stha %g4, [%g3 + TRAP_ENT_TT]%asi
130 stna %o7, [%g3 + TRAP_ENT_TPC]%asi
131 ldn [%o1], %g2
132 stna %g2, [%g3 + TRAP_ENT_SP]%asi /* sp = cpuset */
133 stna %o2, [%g3 + TRAP_ENT_TR]%asi /* tr = func */
134 stna %o3, [%g3 + TRAP_ENT_F1]%asi /* f1 = arg1 */
135 stna %o4, [%g3 + TRAP_ENT_F2]%asi /* f2 = arg2 */
136 stna %g0, [%g3 + TRAP_ENT_F3]%asi /* f3 = 0 */
137 stna %i7, [%g3 + TRAP_ENT_F4]%asi /* f4 = xcall caller */
138 stxa %g1, [%g3 + TRAP_ENT_TSTATE]%asi /* tstate = pstate */
171 cmp %o1, %g5
172 bge 2f
173 ldn [%o1], %g2
174 stna %g2, [%g3 + TRAP_ENT_F3]%asi
175 add %o1, CLONGSIZE, %o1
176 cmp %o1, %g5
177 bge 2f
178 ldn [%o1], %g2
179 stna %g2, [%g3 + TRAP_ENT_F4]%asi
180 add %o1, CLONGSIZE, %o1
181 2:
182 TRACE_NEXT(%g2, %g3, %g4)
183 cmp %o1, %g5
184 bl 1b
185 inc %o2
186 #endif /* CPUSET_SIZE */
187 retl
188 wrpr %g0, %g1, %pstate /* enable interrupts */
189 SET_SIZE(xc_trace)
190
191 #endif /* lint */
192 #endif /* TRAPTRACE */
193
194 #if defined(lint)
195
196 /*ARGSUSED*/
197 void
198 init_mondo(xcfunc_t *func, uint64_t arg1, uint64_t arg2)
199 {}
200
201 /*ARGSUSED*/
202 int
203 shipit(int n, uint64_t cpuid)
204 { return(0); }
205
206 #else /* lint */
207 /*
208 * Setup interrupt dispatch data registers
209 * Entry:
210 * %o0 - function or inumber to call
211 * %o1, %o2 - arguments (2 uint64_t's)
212 */
213 ENTRY(init_mondo)
214 ALTENTRY(init_mondo_nocheck)
215 CPU_ADDR(%g1, %g4) ! load CPU struct addr
216 add %g1, CPU_MCPU, %g1
217 ldx [%g1 + MCPU_MONDO_DATA], %g1
218 stx %o0, [%g1]
219 stx %o1, [%g1+8]
220 stx %o2, [%g1+0x10]
221 stx %g0, [%g1+0x18]
222 stx %g0, [%g1+0x20]
223 stx %g0, [%g1+0x28]
224 stx %g0, [%g1+0x30]
225 stx %g0, [%g1+0x38]
226 retl
227 membar #Sync ! allowed to be in the delay slot
228 SET_SIZE(init_mondo)
229
230 /*
231 * Ship mondo to cpuid
232 */
233 ENTRY_NP(shipit)
234 /* For now use dummy interface: cpu# func arg1 arg2 */
235 CPU_ADDR(%g1, %g4)
236 add %g1, CPU_MCPU, %g1
237 ldx [%g1 + MCPU_MONDO_DATA_RA], %o2
238 mov HV_INTR_SEND, %o5
239 ta FAST_TRAP
240 retl
241 membar #Sync
242 SET_SIZE(shipit)
243
244 #endif /* lint */
245
246 #if defined(lint)
247
248 /*ARGSUSED*/
249 uint64_t
250 get_cpuaddr(uint64_t reg, uint64_t scr)
251 { return (0);}
252
253 #else /* lint */
254 /*
255 * Get cpu structure
256 * Entry:
257 * %o0 - register for CPU_ADDR macro
258 * %o1 - scratch for CPU_ADDR macro
259 */
260 ENTRY(get_cpuaddr)
261 CPU_ADDR(%o0, %o1) ! %o0 == CPU struct addr
262 retl
263 nop
264 SET_SIZE(get_cpuaddr)
265
266 #endif /* lint */
267
268 #if defined(lint)
269 /* ARGSUSED */
270 void
271 xt_sync_tl1(uint64_t *cpu_sync_addr)
272 {}
273
274 #else /* lint */
275 /*
276 * This is to ensure that previously called xtrap handlers have executed on
277 * sun4v. We zero out the byte corresponding to its cpuid in the
278 * array passed to us from xt_sync(), so the sender knows the previous
279 * mondo has been executed.
280 * Register:
281 * %g1 - Addr of the cpu_sync array.
282 */
283 ENTRY_NP(xt_sync_tl1)
284 CPU_INDEX(%g3, %g4) /* %g3 = cpu id */
285 stb %g0, [%g1 + %g3]
286 retry
287 SET_SIZE(xt_sync_tl1)
288
289 #endif /* lint */
|
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 #include <sys/machthread.h>
33 #include <sys/hypervisor_api.h>
34
35 #ifdef TRAPTRACE
36 #include <sys/traptrace.h>
37 #endif /* TRAPTRACE */
38
39
40 /*
41 * Entered by the software trap (TT=ST_SELFXCALL, TL>0) thru send_self_xcall().
42 * Emulate the mondo handler - vec_interrupt().
43 *
44 * Global registers are the Alternate Globals.
45 * Arguments:
46 * %o0 - CPU
47 * ILP32 kernel:
48 * %o5 - function to call
49 * %o1, %o2, %o3, %o4 - arguments
50 * LP64 kernel:
51 * %o3 - function to call
52 * %o1, %o2 - arguments
53 */
54 ENTRY_NP(self_xcall)
55 !
56 ! TL>0 handlers are expected to do "retry"
57 ! prepare their return PC and nPC now
58 !
59 rdpr %tnpc, %g1
73 rdpr %tpc, %g6
74 stna %g6, [%g4 + TRAP_ENT_TPC]%asi
75 rdpr %tstate, %g6
76 stxa %g6, [%g4 + TRAP_ENT_TSTATE]%asi
77 stna %sp, [%g4 + TRAP_ENT_SP]%asi
78 stna %o1, [%g4 + TRAP_ENT_F1]%asi ! arg 1
79 stna %o2, [%g4 + TRAP_ENT_F2]%asi ! arg 2
80 stna %g0, [%g4 + TRAP_ENT_F3]%asi
81 stna %g0, [%g4 + TRAP_ENT_F4]%asi
82 TRACE_NEXT(%g4, %g6, %g3)
83 #endif /* TRAPTRACE */
84 !
85 ! Load the arguments for the fast trap handler.
86 !
87 mov %o1, %g1
88 jmp %o3 ! call the fast trap handler
89 mov %o2, %g2
90 /* Not Reached */
91 SET_SIZE(self_xcall)
92
93 #ifdef TRAPTRACE
94 ENTRY(xc_trace)
95 rdpr %pstate, %g1
96 andn %g1, PSTATE_IE | PSTATE_AM, %g2
97 wrpr %g0, %g2, %pstate /* disable interrupts */
98 TRACE_PTR(%g3, %g4)
99 GET_TRACE_TICK(%g6, %g4)
100 stxa %g6, [%g3 + TRAP_ENT_TICK]%asi
101 stha %g0, [%g3 + TRAP_ENT_TL]%asi
102 set TT_XCALL, %g2
103 or %o0, %g2, %g4
104 stha %g4, [%g3 + TRAP_ENT_TT]%asi
105 stna %o7, [%g3 + TRAP_ENT_TPC]%asi
106 ldn [%o1], %g2
107 stna %g2, [%g3 + TRAP_ENT_SP]%asi /* sp = cpuset */
108 stna %o2, [%g3 + TRAP_ENT_TR]%asi /* tr = func */
109 stna %o3, [%g3 + TRAP_ENT_F1]%asi /* f1 = arg1 */
110 stna %o4, [%g3 + TRAP_ENT_F2]%asi /* f2 = arg2 */
111 stna %g0, [%g3 + TRAP_ENT_F3]%asi /* f3 = 0 */
112 stna %i7, [%g3 + TRAP_ENT_F4]%asi /* f4 = xcall caller */
113 stxa %g1, [%g3 + TRAP_ENT_TSTATE]%asi /* tstate = pstate */
146 cmp %o1, %g5
147 bge 2f
148 ldn [%o1], %g2
149 stna %g2, [%g3 + TRAP_ENT_F3]%asi
150 add %o1, CLONGSIZE, %o1
151 cmp %o1, %g5
152 bge 2f
153 ldn [%o1], %g2
154 stna %g2, [%g3 + TRAP_ENT_F4]%asi
155 add %o1, CLONGSIZE, %o1
156 2:
157 TRACE_NEXT(%g2, %g3, %g4)
158 cmp %o1, %g5
159 bl 1b
160 inc %o2
161 #endif /* CPUSET_SIZE */
162 retl
163 wrpr %g0, %g1, %pstate /* enable interrupts */
164 SET_SIZE(xc_trace)
165
166 #endif /* TRAPTRACE */
167
168 /*
169 * Setup interrupt dispatch data registers
170 * Entry:
171 * %o0 - function or inumber to call
172 * %o1, %o2 - arguments (2 uint64_t's)
173 */
174 ENTRY(init_mondo)
175 ALTENTRY(init_mondo_nocheck)
176 CPU_ADDR(%g1, %g4) ! load CPU struct addr
177 add %g1, CPU_MCPU, %g1
178 ldx [%g1 + MCPU_MONDO_DATA], %g1
179 stx %o0, [%g1]
180 stx %o1, [%g1+8]
181 stx %o2, [%g1+0x10]
182 stx %g0, [%g1+0x18]
183 stx %g0, [%g1+0x20]
184 stx %g0, [%g1+0x28]
185 stx %g0, [%g1+0x30]
186 stx %g0, [%g1+0x38]
187 retl
188 membar #Sync ! allowed to be in the delay slot
189 SET_SIZE(init_mondo)
190
191 /*
192 * Ship mondo to cpuid
193 */
194 ENTRY_NP(shipit)
195 /* For now use dummy interface: cpu# func arg1 arg2 */
196 CPU_ADDR(%g1, %g4)
197 add %g1, CPU_MCPU, %g1
198 ldx [%g1 + MCPU_MONDO_DATA_RA], %o2
199 mov HV_INTR_SEND, %o5
200 ta FAST_TRAP
201 retl
202 membar #Sync
203 SET_SIZE(shipit)
204
205 /*
206 * Get cpu structure
207 * Entry:
208 * %o0 - register for CPU_ADDR macro
209 * %o1 - scratch for CPU_ADDR macro
210 */
211 ENTRY(get_cpuaddr)
212 CPU_ADDR(%o0, %o1) ! %o0 == CPU struct addr
213 retl
214 nop
215 SET_SIZE(get_cpuaddr)
216
217 /*
218 * This is to ensure that previously called xtrap handlers have executed on
219 * sun4v. We zero out the byte corresponding to its cpuid in the
220 * array passed to us from xt_sync(), so the sender knows the previous
221 * mondo has been executed.
222 * Register:
223 * %g1 - Addr of the cpu_sync array.
224 */
225 ENTRY_NP(xt_sync_tl1)
226 CPU_INDEX(%g3, %g4) /* %g3 = cpu id */
227 stb %g0, [%g1 + %g3]
228 retry
229 SET_SIZE(xt_sync_tl1)
230
|