Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * Hypervisor Software File: intr.s | |
5 | * | |
6 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
7 | * | |
8 | * - Do no alter or remove copyright notices | |
9 | * | |
10 | * - Redistribution and use of this software in source and binary forms, with | |
11 | * or without modification, are permitted provided that the following | |
12 | * conditions are met: | |
13 | * | |
14 | * - Redistribution of source code must retain the above copyright notice, | |
15 | * this list of conditions and the following disclaimer. | |
16 | * | |
17 | * - Redistribution in binary form must reproduce the above copyright notice, | |
18 | * this list of conditions and the following disclaimer in the | |
19 | * documentation and/or other materials provided with the distribution. | |
20 | * | |
21 | * Neither the name of Sun Microsystems, Inc. or the names of contributors | |
22 | * may be used to endorse or promote products derived from this software | |
23 | * without specific prior written permission. | |
24 | * | |
25 | * This software is provided "AS IS," without a warranty of any kind. | |
26 | * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
27 | * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
28 | * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
29 | * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
30 | * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
31 | * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN | |
32 | * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR | |
33 | * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
34 | * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
35 | * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
36 | * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
37 | * | |
38 | * You acknowledge that this software is not designed, licensed or | |
39 | * intended for use in the design, construction, operation or maintenance of | |
40 | * any nuclear facility. | |
41 | * | |
42 | * ========== Copyright Header End ============================================ | |
43 | */ | |
44 | /* | |
45 | * Copyright 2007 Sun Microsystems, Inc. All rights reserved. | |
46 | * Use is subject to license terms. | |
47 | */ | |
48 | ||
49 | .ident "@(#)intr.s 1.43 07/05/03 SMI" | |
50 | ||
51 | #include <sys/asm_linkage.h> | |
52 | #include <sys/htypes.h> | |
53 | #include <asi.h> | |
54 | #include <hprivregs.h> | |
55 | #include <sun4v/asi.h> | |
56 | #include <offsets.h> | |
57 | #include <guest.h> | |
58 | #include <intr.h> | |
59 | #include <vdev_intr.h> | |
60 | #include <util.h> | |
61 | #include <debug.h> | |
62 | ||
63 | /* | |
64 | * cpu_mondo - | |
65 | * | |
66 | * handles an incoming cpu_mondo x-call from another | |
67 | * strand hosting a vcpu in the same domain as the current vcpu | |
68 | * on this strand. | |
69 | * | |
70 | * On entry: | |
71 | * %g1 = vcpup | |
72 | * %g2 = intr-type | |
73 | * | |
74 | * On exit: | |
75 | * retry trapped instruction | |
76 | */ | |
77 | ENTRY(cpu_mondo) | |
78 | ||
79 | /* | |
80 | * Update when we were called last | |
81 | */ | |
82 | rd %tick, %g6 | |
83 | stx %g6, [%g1 + CPU_CMD_LASTPOKE] | |
84 | ||
85 | /* | |
86 | * Wait for mailbox to not be busy | |
87 | */ | |
88 | 1: ldx [%g1 + CPU_COMMAND], %g6 | |
89 | cmp %g6, CPU_CMD_BUSY | |
90 | be,pn %xcc, 1b | |
91 | cmp %g6, CPU_CMD_GUESTMONDO_READY | |
92 | bne,pn %xcc, .cpu_mondo_return | |
93 | .empty | |
94 | ||
95 | mov CPU_MONDO_QUEUE_TAIL, %g2 | |
96 | ldxa [%g2]ASI_QUEUE, %g3 | |
97 | add %g3, Q_EL_SIZE, %g5 | |
98 | ldx [%g1 + CPU_CPUQ_MASK], %g6 | |
99 | and %g5, %g6, %g5 | |
100 | mov CPU_MONDO_QUEUE_HEAD, %g2 | |
101 | ldxa [%g2]ASI_QUEUE, %g4 | |
102 | cmp %g5, %g4 | |
103 | be,pn %xcc, .cpu_mondo_return ! queue is full | |
104 | ldx [%g1 + CPU_CPUQ_BASE], %g6 | |
105 | ||
106 | ! Simply return and drop mondo if Q was unconfigured from under us | |
107 | brz %g6, .cpu_mondo_return | |
108 | mov CPU_MONDO_QUEUE_TAIL, %g2 | |
109 | stxa %g5, [%g2]ASI_QUEUE ! new tail pointer | |
110 | add %g3, %g6, %g5 | |
111 | ||
112 | /* Fill in newly-allocated cpu mondo entry */ | |
113 | ldx [%g1 + CPU_CMD_ARG0], %g6 | |
114 | stxa %g6, [%g5]ASI_BLK_INIT_P | |
115 | ldx [%g1 + CPU_CMD_ARG1], %g6 | |
116 | stx %g6, [%g5 + 0x8] | |
117 | ldx [%g1 + CPU_CMD_ARG2], %g6 | |
118 | stx %g6, [%g5 + 0x10] | |
119 | ldx [%g1 + CPU_CMD_ARG3], %g6 | |
120 | stx %g6, [%g5 + 0x18] | |
121 | ldx [%g1 + CPU_CMD_ARG4], %g6 | |
122 | stx %g6, [%g5 + 0x20] | |
123 | ldx [%g1 + CPU_CMD_ARG5], %g6 | |
124 | stx %g6, [%g5 + 0x28] | |
125 | ldx [%g1 + CPU_CMD_ARG6], %g6 | |
126 | stx %g6, [%g5 + 0x30] | |
127 | ldx [%g1 + CPU_CMD_ARG7], %g6 | |
128 | stx %g6, [%g5 + 0x38] | |
129 | membar #Sync ! make sure stores visible | |
130 | stx %g0, [%g1 + CPU_COMMAND] ! clear for next xcall | |
131 | .cpu_mondo_return: | |
132 | retry | |
133 | SET_SIZE(cpu_mondo) | |
134 | ||
135 | ||
136 | /* | |
137 | * insert_device_mondo_r | |
138 | * | |
139 | * %g2 = data0 | |
140 | * %g7 + 4 = return address | |
141 | * | |
142 | * %g1 - %g6 trashed | |
143 | */ | |
144 | /* | |
145 | * FIXME: This should probably arrive with a pointer to the | |
146 | * vcpu the mondo is targeted at | |
147 | */ | |
148 | ENTRY_NP(insert_device_mondo_r) | |
149 | ||
150 | VCPU_STRUCT(%g1) /* FIXME ! */ | |
151 | mov %g2, %g3 | |
152 | ba send_dev_mondo ! tail call returns to caller | |
153 | set 1, %g2 | |
154 | ||
155 | SET_SIZE(insert_device_mondo_r) | |
156 | ||
157 | ||
158 | /* | |
159 | * insert_device_mondo_p | |
160 | * | |
161 | * %g1 = datap | |
162 | * %g7 + 4 = return address | |
163 | * | |
164 | * %g1 - %g6 trashed | |
165 | */ | |
166 | ENTRY_NP(insert_device_mondo_p) | |
167 | ||
168 | mov %g1, %g3 | |
169 | VCPU_STRUCT(%g1) | |
170 | ba send_dev_mondo ! tail call returns to caller | |
171 | mov %g0, %g2 | |
172 | .no_devmondo_q: | |
173 | mov %g7, %g5 | |
174 | PRINT("dev q unconfigured\r\n"); | |
175 | mov %g5, %g7 | |
176 | SET_SIZE(insert_device_mondo_p) | |
177 | ||
178 | ||
179 | /* | |
180 | * send_dev_mondo | |
181 | * | |
182 | * %g1 = vcpup | |
183 | * %g2 = flag (0 = pointer to data, 1 = mondo) | |
184 | * %g3 = data (depending on value of flag) | |
185 | * %g7 + 4 = return address | |
186 | * | |
187 | * %g2 - %g6 trashed | |
188 | */ | |
189 | ENTRY_NP(send_dev_mondo) | |
190 | ||
191 | add %g1, CPU_DEVQ_LOCK, %g4 | |
192 | SPINLOCK_ENTER(%g4, %g5, %g6) | |
193 | ||
194 | ldx [ %g1 + CPU_DEVQ_BASE ], %g4 | |
195 | brz,a %g4, 4f ! Queue not configured exit! | |
196 | nop | |
197 | ||
198 | ldx [ %g1 + CPU_DEVQ_SHDW_TAIL ], %g5 | |
199 | add %g5, Q_EL_SIZE, %g6 | |
200 | ldx [%g1 + CPU_DEVQ_MASK ], %g4 | |
201 | and %g6, %g4, %g6 | |
202 | !! %g1 = vcpup | |
203 | !! %g6 = new shadow tail | |
204 | !! %g5 = shadow tail | |
205 | ||
206 | stx %g6, [ %g1 + CPU_DEVQ_SHDW_TAIL ] | |
207 | ||
208 | ldx [ %g1 + CPU_DEVQ_BASE ], %g4 | |
209 | add %g5, %g4, %g5 ! pointer to stuff mondo | |
210 | ||
211 | brz %g2, 1f ! data or pointer in %g3? | |
212 | nop | |
213 | ||
214 | stx %g3, [ %g5 + 0x00 ] | |
215 | ba,a 2f | |
216 | ||
217 | 1: | |
218 | ldx [ %g3 + 0x00 ], %g2 | |
219 | stx %g2, [%g5 + 0x00] | |
220 | ldx [%g3 + 0x08], %g2 | |
221 | stx %g2, [%g5 + 0x08] | |
222 | ldx [%g3 + 0x10], %g2 | |
223 | stx %g2, [%g5 + 0x10] | |
224 | ldx [%g3 + 0x18], %g2 | |
225 | stx %g2, [%g5 + 0x18] | |
226 | ldx [%g3 + 0x20], %g2 | |
227 | stx %g2, [%g5 + 0x20] | |
228 | ldx [%g3 + 0x28], %g2 | |
229 | stx %g2, [%g5 + 0x28] | |
230 | ldx [%g3 + 0x30], %g2 | |
231 | stx %g2, [%g5 + 0x30] | |
232 | ldx [%g3 + 0x38], %g2 | |
233 | stx %g2, [%g5 + 0x38] | |
234 | ||
235 | 2: | |
236 | ! is local the target? | |
237 | VCPU_STRUCT(%g3) | |
238 | ||
239 | cmp %g3, %g1 | |
240 | bne %xcc, 3f | |
241 | nop | |
242 | ||
243 | ! Just update the local cpu's devq since it is the target. | |
244 | ! %g6 = new shadow tail. | |
245 | ||
246 | /* | |
247 | * XXX Sanity test that new tail does not corrupt head of queue | |
248 | */ | |
249 | set DEV_MONDO_QUEUE_TAIL, %g4 | |
250 | ba 4f | |
251 | stxa %g6, [%g4] ASI_QUEUE | |
252 | 3: | |
253 | /* | |
254 | * Poke target to update DevQ | |
255 | * %g2 = target strand id | |
256 | */ | |
257 | VCPU2STRAND_STRUCT(%g1, %g2) | |
258 | ldub [%g2 + STRAND_ID], %g2 | |
259 | ||
260 | ! %g2 = target strand | |
261 | ||
262 | sllx %g2, INT_VEC_DIS_VCID_SHIFT, %g3 | |
263 | or %g3, VECINTR_VDEV, %g3 | |
264 | stxa %g3, [%g0]ASI_INTR_UDB_W | |
265 | ||
266 | 4: | |
267 | add %g1, CPU_DEVQ_LOCK, %g4 | |
268 | SPINLOCK_EXIT(%g4) | |
269 | ||
270 | HVRET | |
271 | SET_SIZE(send_dev_mondo) | |
272 | ||
273 | ||
274 | /* | |
275 | * vdev_mondo | |
276 | * | |
277 | * %g1 = vcpup | |
278 | * %g2-%g4 clobbered. | |
279 | */ | |
280 | ENTRY_NP(vdev_mondo) | |
281 | ||
282 | add %g1, CPU_DEVQ_LOCK, %g2 | |
283 | SPINLOCK_ENTER(%g2, %g3, %g4) | |
284 | ||
285 | ldx [ %g1 + CPU_DEVQ_SHDW_TAIL], %g3 | |
286 | ||
287 | set DEV_MONDO_QUEUE_TAIL, %g4 | |
288 | stxa %g3, [ %g4 ] ASI_QUEUE | |
289 | ||
290 | add %g1, CPU_DEVQ_LOCK, %g2 | |
291 | SPINLOCK_EXIT(%g2) | |
292 | ||
293 | HVRET | |
294 | SET_SIZE(vdev_mondo) | |
295 | ||
296 | ||
297 | /* | |
298 | * dev_mondo - handle an incoming JBus mondo | |
299 | * | |
300 | * %g1 = cpup | |
301 | * %g7 + 4 = return address | |
302 | */ | |
303 | ENTRY(dev_mondo) | |
304 | ! XXX Check BUSY bit and ignore the dev mondo if it is not set | |
305 | setx DEV_MONDO_INT, %g4, %g6 | |
306 | ldx [%g6 + DEV_MONDO_INT_ABUSY], %g4 | |
307 | btst DEV_MONDO_INT_ABUSY_BUSY, %g4 | |
308 | bz,pn %xcc, 2f ! Not BUSY .. just ignore | |
309 | ldx [%g6 + DEV_MONDO_INT_DATA0], %g2 ! THREADID[5:0],INO[5:0] | |
310 | ldx [%g6 + DEV_MONDO_INT_DATA1], %g3 ! IGN[5:0],ZERO[5:0] | |
311 | stx %g0, [%g6 + DEV_MONDO_INT_ABUSY] ! Clear BUSY bit | |
312 | ||
313 | ! vINOs and what I/O bridge puts into DATA0 are | |
314 | ! the same therefore we don't need to translate | |
315 | ! anything here | |
316 | ||
317 | and %g2, NINOSPERDEV - 1 , %g4 | |
318 | or %g4, %g3, %g2 | |
319 | srlx %g3, DEV_DEVINO_SHIFT, %g3 | |
320 | ! %g1 = cpup | |
321 | ! %g2 = IGN,INO | |
322 | ! %g3 = IGN | |
323 | ! %g4 = INO | |
324 | JMPL_VINO2DEVOP(%g2, DEVOPSVEC_MONDO_RECEIVE, %g1, %g6, 2f) | |
325 | 2: | |
326 | retry | |
327 | SET_SIZE(dev_mondo) | |
328 | ||
329 | ||
330 | /* | |
331 | * We were interrupted for a x-call mondo for something. | |
332 | * so we stash the state of the current vcpu and | |
333 | * jump to the main handler/scheduler function | |
334 | */ | |
335 | ENTRY_NP(hvxcall_mondo) | |
336 | ||
337 | VCPU_STRUCT(%g2) | |
338 | set CPU_LAUNCH_WITH_RETRY, %g3 | |
339 | mov 1, %g1 | |
340 | stb %g1, [%g2 + %g3] | |
341 | ||
342 | HVCALL(vcpu_state_save) | |
343 | ||
344 | ba,pt %xcc, handle_hvmondo | |
345 | nop | |
346 | SET_SIZE(hvxcall_mondo) |