Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / hypervisor / src / greatlakes / common / src / chipsubr.s
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* Hypervisor Software File: chipsubr.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 "@(#)chipsubr.s 1.8 07/05/04 SMI"
50
51/*
52 * Routines that are specific to this chipset
53 */
54
55#include <sys/asm_linkage.h>
56#include <sys/htypes.h>
57#include <hprivregs.h>
58#include <asi.h>
59#include <sun4v/traps.h>
60#include <sun4v/asi.h>
61#include <sparcv9/asi.h>
62#include <offsets.h>
63#include <guest.h>
64#include <abort.h>
65#include <util.h>
66#include <intr.h>
67#include <fpga.h>
68#include <debug.h>
69
70
71/*
72 * halt_strand - stop the current running strand while there are
73 * no interrupts of any kind pending.
74 *
75 * %g7 = return address
76 *
77 * Clobbers:
78 * %g1
79 */
80
81 ENTRY(halt_strand)
82
83 mov %g7, %g6 ! preserve return address
84 HALT_STRAND()
85 mov %g6, %g7
86
87 HVRET
88 SET_SIZE(halt_strand)
89
90
91/*
92 * hvmondo_send - send a HV mondo to another specified strand
93 * NOTE: blocks for the moment
94 *
95 * %g1 - target strandp
96 * %g2 - mondo ptr
97 * %g7 - return addr
98 *
99 * Clobbers:
100 * %g1 - %g7
101 */
102 ENTRY(hvmondo_send)
103 /* Try and grab the target mondo mailbox */
104 add %g1, STRAND_XCALL_MBOX + XCMB_COMMAND, %g5
1051:
106 mov HXMB_BUSY, %g4
107 casxa [%g5]ASI_P, %g0, %g4
108 brnz,pn %g4, 1b
109 nop
110 membar #StoreStore /* ensure all our stores are done */
111
112 /* Copy the mondo to the mailbox */
113 add %g1, STRAND_XCALL_MBOX + XCMB_MONDOBUF, %g4
114
115#define MV(_o) \
116 ldx [%g2 + (_o)*8], %g3 ;\
117 stx %g3, [%g4 + (_o)*8]
118
119 MV(0)
120 MV(1)
121 MV(2)
122 MV(3)
123 MV(4)
124 MV(5)
125 MV(6)
126 MV(7)
127#undef MV
128
129 /* signal the MB command */
130 mov HXMB_NEWMONDO, %g3
131 stx %g3, [%g5]
132
133 /* now poke the target strand */
134 ldub [%g1 + STRAND_ID], %g3
135 sllx %g3, INT_VEC_DIS_VCID_SHIFT, %g3
136 mov VECINTR_HVXCALL, %g4
137 or %g3, %g4, %g3
138 stxa %g3, [%g0]ASI_INTR_UDB_W
139 HVRET
140 SET_SIZE(hvmondo_send)
141
142
143/*
144 * Wrapper around hvmondo_send, so it can be called from C
145 * SPARC ABI requries only that g2,g3,g4 are preserved across
146 * function calls.
147 * %o0 = target strandp
148 * %o1 = mondo ptr
149 *
150 * void c_hvmondo_send(strand_t targetp, hvm_t *msgp)
151 */
152 ENTRY(c_hvmondo_send)
153
154 STRAND_PUSH(%g2, %g6, %g7)
155 STRAND_PUSH(%g3, %g6, %g7)
156 STRAND_PUSH(%g4, %g6, %g7)
157
158 mov %o0, %g1
159 mov %o1, %g2
160 HVCALL(hvmondo_send)
161
162 STRAND_POP(%g4, %g6)
163 STRAND_POP(%g3, %g6)
164 STRAND_POP(%g2, %g6)
165
166 retl
167 nop
168 SET_SIZE(c_hvmondo_send)
169
170
171/*
172 * Stall waiting for a hv mondo interrupt.
173 * We wait for the X-call interrupt ; not the CMD word
174 * A send *must* sent the PYN interrupt bit
175 */
176 ENTRY(hvmondo_wait)
1771:
178 membar #Sync /* ERRATUM 43 */
179 ldxa [%g0]ASI_INTR_UDB_R, %g1
180 brnz,pn %g1, 2f
181 nop
182
183 mov %g7, %g6
184 HALT_STRAND()
185 mov %g6, %g7
186
187 ba,pt %xcc, 1b
188 nop
1892:
190 cmp %g1, VECINTR_HVXCALL
191 beq,pt %xcc, 4f
192 cmp %g1, VECINTR_DEV
193 beq %xcc, .dev_intr
194 cmp %g1, VECINTR_FPGA
195 beq %xcc, .fpga_intr
196 nop
197
198 /*
199 * Ignore any interrupts that do not
200 * require additional handling.
201 */
202#ifdef DEBUG
203 mov %g7, %g2 ! print clobbers %g7
204 PRINT("hvmondo_wait: ignoring interrupt type 0x")
205 PRINTX(%g1)
206 PRINT("\r\n")
207 mov %g2, %g7
208#endif
209
210 ba,pt %xcc, 1b
211 nop
212
213.dev_intr:
214#if defined(CONFIG_PCIE)
215 setx DEV_MONDO_INT, %g4, %g6
216 ldx [%g6 + DEV_MONDO_INT_ABUSY], %g4
217 btst DEV_MONDO_INT_ABUSY_BUSY, %g4
218 bz,pn %xcc, 1b ! Not BUSY .. just ignore
219 nop ! block waiting for next xcall
220 stx %g0, [%g6 + DEV_MONDO_INT_ABUSY] ! Clear BUSY bit
221#endif
222 ba,pt %xcc, 1b ! block waiting for next xcall
223 nop
224
225
226.fpga_intr:
227#if CONFIG_FPGA
228
229 !! Disable FPGA interrupts
230 !!
231 FPGA_MBOX_INT_DISABLE(IRQ_QUEUE_IN|IRQ_QUEUE_OUT|IRQ_LDC_OUT, %g2, %g3)
232
233 CLEAR_INT_CTL_PEND(%g2, %g3)
234
235.chk_fpga_intr_type:
236 ! check to see the type of interrupt
237 setx FPGA_INTR_BASE, %g3, %g2
238 ldub [%g2 + FPGA_MBOX_INTR_STATUS], %g4
239
240 btst IRQ_QUEUE_IN, %g4
241 bz,pt %xcc, .check_queue_out
242 nop
243
244 ! Mark it done
245 ROOT_STRUCT(%g5)
246 ldx [%g5 + CONFIG_SVCS], %g5
247 ldx [%g5 + HV_SVC_DATA_RXCHANNEL], %g5
248 set QINTR_ACK, %g4
249 stub %g4, [%g5 + FPGA_Q_STATUS]
250
251 ba,pt %xcc, .chk_fpga_intr_type
252 nop
253
254.check_queue_out:
255 btst IRQ_QUEUE_OUT, %g4
256 bz,pt %xcc, .check_ldc_out
257 nop
258
259 ! Mark it done
260 ROOT_STRUCT(%g5)
261 ldx [%g5 + CONFIG_SVCS], %g5
262 ldx [%g5 + HV_SVC_DATA_TXCHANNEL], %g5
263 ldub [%g5 + FPGA_Q_STATUS], %g6
264 sth %g0, [%g5 + FPGA_Q_SIZE] ! len = 0
265 stub %g6, [%g5 + FPGA_Q_STATUS] ! clear status
266
267 ba,pt %xcc, .chk_fpga_intr_type
268 nop
269
270.check_ldc_out:
271 btst IRQ_LDC_OUT, %g4
272 bz,pt %xcc, .enable_fpga_mbox_intr
273 nop
274
275 FPGA_CLEAR_LDC_INTERRUPTS(%g3, %g5)
276
277 ba,pt %xcc, .chk_fpga_intr_type
278 nop
279
280.enable_fpga_mbox_intr:
281 ! Enable FPGA interrupts
282 setx FPGA_INTR_BASE, %g2, %g3
283 mov IRQ_QUEUE_IN|IRQ_QUEUE_OUT|IRQ_LDC_OUT, %g2
284 stub %g2, [%g3 + FPGA_MBOX_INTR_ENABLE]
285
286#endif /* } */
287 ba,pt %xcc, 1b ! block waiting for next xcall
288 nop
289
2904:
291 HVRET
292 SET_SIZE(hvmondo_wait)
293
294
295
296/*
297 * Should really only call this when you know an interrupt has been
298 * delivered. Use hvmondo_wait to block on that event.
299 */
300/*
301 * Semi-busy wait for a HV mondo to turn up.
302 * We improve performance of the other strands by turning this one off
303 * until the x-call mondo shows up.
304 * Uses a subroutine - so g7 also gets clobbered.
305 *
306 * This macro allows for polling for a x-call mondo. Really this shouldn't
307 * happen, but we do it for now until we setup guest0.
308 *
309 * Other interrupts sources should be disabled before this gets called, but
310 * for now we just print warnings.
311 *
312 * accepts:
313 * %g7 - return address
314 *
315 * returns:
316 * %g1 - recv command
317 *
318 * clobbers:
319 * %g1, %g2, %g7
320 *
321 */
322 ENTRY(hvmondo_recv)
323
324 /*
325 * Grab the mondo from the mailbox
326 * then release the mail box - unnecessary extra copying
327 * that all goes away with a LDC style receive queue for this
328 * stuff.
329 */
330 STRAND_STRUCT(%g1)
331
332 /*
333 * We'll be paranoid to make sure the command is complete
334 * this shouldn't be necessary, but leave it for now until
335 * a proper Q arrives.
336 */
3371:
338 membar #StoreLoad
339 ldx [%g1 + STRAND_XCALL_MBOX + XCMB_COMMAND], %g3
340 cmp %g3, HXMB_BUSY
341 be,pn %xcc, 1b
342 cmp %g3, HXMB_NEWMONDO
343 be,pt %xcc, 2f
344 nop
345
346 HVABORT(-1, "mbox idle or non-mondo command")
347
3482:
349 add %g1, STRAND_XCALL_MBOX + XCMB_MONDOBUF, %g2
350 add %g1, STRAND_HV_RXMONDO, %g4
351
352#define MV(_o) \
353 ldx [%g2 + (_o)*8], %g3 ;\
354 stx %g3, [%g4 + (_o)*8]
355
356 MV(0)
357 MV(1)
358 MV(2)
359 MV(3)
360 MV(4)
361 MV(5)
362 MV(6)
363 MV(7)
364#undef MV
365
366 /* release the mail box for the next on */
367 stx %g0, [%g1 + STRAND_XCALL_MBOX + XCMB_COMMAND]
368 add %g1, STRAND_HV_RXMONDO, %g1 ! returns ptr to buffer
369 HVRET
370 SET_SIZE(hvmondo_recv)