Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / hypervisor / src / greatlakes / common / src / intr.s
CommitLineData
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 */
881: 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
2171:
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
2352:
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
2523:
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
2664:
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)
3252:
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)