Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / hypervisor / src / greatlakes / common / src / svc_vbsc.s
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* Hypervisor Software File: svc_vbsc.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 "@(#)svc_vbsc.s 1.28 07/05/29 SMI"
50
51 .file "svc_vbsc.s"
52
53#if defined(CONFIG_SVC) && defined(CONFIG_VBSC_SVC)
54
55#include <sys/asm_linkage.h>
56#include <sys/htypes.h>
57#include <hypervisor.h>
58#include <sparcv9/misc.h>
59#include <asi.h>
60#include <mmu.h>
61#include <fpga.h>
62#include <sun4v/traps.h>
63#include <sun4v/asi.h>
64#include <sun4v/mmu.h>
65#include <sun4v/errs_defs.h>
66
67#include <config.h>
68#include <guest.h>
69#include <strand.h>
70#include <offsets.h>
71#include <svc.h>
72#include <svc_vbsc.h>
73#include <errs_common.h>
74#include <util.h>
75#include <abort.h>
76#include <debug.h>
77
78/*
79 * vbsc_send_polled - send a command to vbsc using polled I/O
80 *
81 * If VBSC does not accept the packet then
82 *
83 * %g1 - cmd[0]
84 * %g2 - cmd[1]
85 * %g3 - cmd[2]
86 * %g7 - return address
87 */
88 ENTRY_NP(vbsc_send_polled)
89.vbsc_send_polled_resend:
90 setx FPGA_Q3OUT_BASE, %g4, %g5
91 setx FPGA_BASE + FPGA_SRAM_BASE, %g4, %g6
92
93 lduh [%g5 + FPGA_Q_BASE], %g4
94 add %g4, %g6, %g6
95 !! %g6 = sram buffer words
96
97 stx %g3, [%g6 + (2 * 8)]
98 stx %g2, [%g6 + (1 * 8)]
99 stx %g1, [%g6 + (0 * 8)]
100 mov 1, %g4
101 stb %g4, [%g5 + FPGA_Q_SEND]
102
103 /*
104 * Wait for a non-zero status. If we get an ACK then we're done.
105 * Otherwise re-send the packet. Failure is not an option, even
106 * to hv_abort we need to send a message to vbsc. So keep trying.
107 */
108.vbsc_send_polled_wait_for_ack:
109 ldub [%g5 + FPGA_Q_STATUS], %g4
110 andcc %g4, (QINTR_ACK | QINTR_NACK | QINTR_BUSY | QINTR_ABORT), %g4
111 bz,pn %xcc, .vbsc_send_polled_wait_for_ack
112 nop
113 btst QINTR_ACK, %g4
114 bz,pt %xcc, .vbsc_send_polled_resend
115 nop
116
117 stb %g4, [%g5 + FPGA_Q_STATUS] ! clear status bits
118 HVRET
119 SET_SIZE(vbsc_send_polled)
120
121
122/*
123 * vbsc_hv_start - notify VBSC that the hypervisor has started
124 *
125 * %g7 return address
126 *
127 * Called from setup environment
128 */
129 ENTRY_NP(vbsc_hv_start)
130 mov %g7, %o3
131
132 setx VBSC_HV_START, %g2, %g1
133 mov 0, %g2
134 mov 0, %g3
135 HVCALL(vbsc_send_polled)
136
137 mov %o3, %g7
138 HVRET
139 SET_SIZE(vbsc_hv_start)
140
141
142/*
143 * vbsc_hv_abort - notify VBSC that hv has aborted
144 *
145 * %g1 contains reason for the abort
146 * %g7 return address
147 */
148 ENTRY_NP(vbsc_hv_abort)
149 mov %g1, %g2
150 setx VBSC_HV_ABORT, %g3, %g1
151 mov 0, %g3
152 HVCALL(vbsc_send_polled)
153
154 /* spin until the vbsc powers us down */
155 ba .
156 nop
157 SET_SIZE(vbsc_hv_abort)
158
159
160/*
161 * vbsc_hv_plxreset - notify VBSC that the hypervisor has requested
162 * a special reset due to PLX link training problems. VBSC knows to
163 * do this quietly and prevent it from looping forever.
164 *
165 * %g1 plx link failure bitmask
166 * %g7 return address
167 *
168 * Called from setup environment
169 */
170 ENTRY_NP(vbsc_hv_plxreset)
171 mov %g7, %o3
172
173 mov %g1, %g2
174 setx VBSC_HV_PLXRESET, %g3, %g1
175 mov 0, %g3
176 HVCALL(vbsc_send_polled)
177
178 mov %o3, %g7
179 HVRET
180 SET_SIZE(vbsc_hv_plxreset)
181
182
183/*
184 * vbsc_guest_start - notify VBSC that a guest has started
185 *
186 * %g7 return address
187 */
188 ENTRY_NP(vbsc_guest_start)
189 mov %g7, %o3
190
191 setx VBSC_GUEST_ON, %g2, %g1
192 GUEST_STRUCT(%o2)
193 set GUEST_GID, %o4
194 ldx [%o2 + %o4], %g2
195 add %g2, XPID_GUESTBASE, %g2
196 mov 0, %g3
197 HVCALL(vbsc_send_polled)
198
199 mov %o3, %g7
200 HVRET
201 SET_SIZE(vbsc_guest_start)
202
203
204/*
205 * vbsc_guest_exit - notify VBSC that a guest has exited
206 *
207 * arg0 exit code (%o0)
208 * --
209 * does not return
210 */
211 ENTRY_NP(vbsc_guest_exit)
212 setx VBSC_GUEST_OFF, %g2, %g1
213 GUEST_STRUCT(%o2)
214 set GUEST_GID, %o4
215 ldx [%o2 + %o4], %g2
216 add %g2, XPID_GUESTBASE, %g2
217 ldx [%o2 + GUEST_TOD_OFFSET], %g3
218 HVCALL(vbsc_send_polled)
219
220 /* spin until the vbsc powers us down */
221 ba .
222 nop
223 SET_SIZE(vbsc_guest_exit)
224
225
226/*
227 * vbsc_guest_sir - notify vbsc that a guest requested a reset
228 *
229 * --
230 * does not return
231 */
232 ENTRY_NP(vbsc_guest_sir)
233 setx VBSC_GUEST_RESET, %g2, %g1
234 GUEST_STRUCT(%o2)
235 set GUEST_GID, %o4
236 ldx [%o2 + %o4], %g2
237 add %g2, XPID_GUESTBASE, %g2
238 ldx [%o2 + GUEST_TOD_OFFSET], %g3
239 HVCALL(vbsc_send_polled)
240
241 /* spin until the vbsc powers us down */
242 ba .
243 nop
244 SET_SIZE(vbsc_guest_sir)
245
246/*
247 * vbsc_guest_wdexpire - notify vbsc that a guest's watchdog timer expired
248 * Service Processor policy dictates what happens next.
249 *
250 * %g1: guestp
251 * %g7: return address
252 * --
253 */
254 ENTRY_NP(vbsc_guest_wdexpire)
255 mov %g1, %g6
256 setx VBSC_GUEST_WDEXPIRE, %g2, %g1
257 set GUEST_GID, %g5
258 ldx [%g6 + %g5], %g2
259 add %g2, XPID_GUESTBASE, %g2
260 ldx [%g6 + GUEST_TOD_OFFSET], %g3
261 ba,a vbsc_send_polled ! tail call, returns to caller
262 SET_SIZE(vbsc_guest_wdexpire)
263
264
265/*
266 * vbsc_guest_tod_offset - notify VBSC of a guest's TOD offset
267 * We don't retry here, failures are ignored.
268 *
269 * %g1 guestp
270 * %g7 return address
271 *
272 * Clobbers %g1-6
273 * Called from guest hcall environment
274 */
275
276/* FIXME: Use a better buffer to send from ... */
277/* Better yet this function / operation goes away entirely for LDoms */
278
279 ENTRY_NP(vbsc_guest_tod_offset)
280 VCPU_STRUCT(%g2)
281 inc CPU_SCR0, %g2
282
283 set GUEST_GID, %g3
284 ldx [%g1 + %g3], %g3
285 add %g3, XPID_GUESTBASE, %g3
286 stx %g3, [%g2 + 0x8]
287
288 ldx [%g1 + GUEST_TOD_OFFSET], %g3
289 stx %g3, [%g2 + 0x10]
290
291 setx VBSC_GUEST_TODOFFSET, %g4, %g3
292 stx %g3, [%g2 + 0x0]
293
294 ROOT_STRUCT(%g1)
295 ldx [%g1 + CONFIG_VBSC_SVCH], %g1
296
297 mov 8 * 3, %g3
298
299 !! %g1 svch
300 !! %g2 buf
301 !! %g3 length
302 ba,pt %xcc, svc_internal_send ! tail call, returns to caller
303 nop
304 SET_SIZE(vbsc_guest_tod_offset)
305
306
307
308#define SIM_IRU_DIAG_ERPT(erpt_vbsc, reg1, reg2) \
309 set ERPT_TYPE_CPU, reg1 ;\
310 stx reg1, [erpt_vbsc + EVBSC_REPORT_TYPE] ;\
311 setx 0x10000000000001, reg2, reg1 ;\
312 stx reg1, [erpt_vbsc + EVBSC_EHDL] ;\
313 setx 0x002a372a4, reg2, reg1 ;\
314 stx reg1, [erpt_vbsc + EVBSC_STICK] ;\
315 setx 0x3e002310000607, reg2, reg1 ;\
316 stx reg1, [erpt_vbsc + EVBSC_CPUVER] ;\
317 setx 0x000000000, reg2, reg1 ;\
318 stx reg1, [erpt_vbsc + EVBSC_CPUSERIAL] ;\
319 setx 0x000010000, reg2, reg1 ;\
320 stx reg1, [erpt_vbsc + EVBSC_SPARC_AFSR] ;\
321 setx 0x000830550, reg2, reg1 ;\
322 stx reg1, [erpt_vbsc + EVBSC_SPARC_AFAR] ;\
323 setx 0x400000402, reg2, reg1 ;\
324 stx reg1, [erpt_vbsc + EVBSC_TSTATE] ;\
325 setx 0x000000800, reg2, reg1 ;\
326 stx reg1, [erpt_vbsc + EVBSC_HTSTATE] ;\
327 setx 0x000800610, reg2, reg1 ;\
328 stx reg1, [erpt_vbsc + EVBSC_TPC] ;\
329 set 0x0, reg1 ;\
330 stuh reg1, [erpt_vbsc + EVBSC_CPUID] ;\
331 set 0x63, reg1 ;\
332 stuh reg1, [erpt_vbsc + EVBSC_TT] ;\
333 set 0x1, reg1 ;\
334 stub reg1, [erpt_vbsc + EVBSC_TL] ;\
335 set 0x3, reg1 ;\
336 stub reg1, [erpt_vbsc + EVBSC_ERREN]
337
338#define SIM_IRC_DIAG_ERPT(erpt_vbsc, reg1, reg2) \
339 set ERPT_TYPE_CPU, reg1 ;\
340 stx reg1, [erpt_vbsc + EVBSC_REPORT_TYPE] ;\
341 setx 0x10000000000002, reg2, reg1 ;\
342 stx reg1, [erpt_vbsc + EVBSC_EHDL] ;\
343 setx 0x002a372a4, reg2, reg1 ;\
344 stx reg1, [erpt_vbsc + EVBSC_STICK] ;\
345 setx 0x3e002310000607, reg2, reg1 ;\
346 stx reg1, [erpt_vbsc + EVBSC_CPUVER] ;\
347 setx 0x000000000, reg2, reg1 ;\
348 stx reg1, [erpt_vbsc + EVBSC_CPUSERIAL] ;\
349 setx 0x000020000, reg2, reg1 ;\
350 stx reg1, [erpt_vbsc + EVBSC_SPARC_AFSR] ;\
351 setx 0x000830550, reg2, reg1 ;\
352 stx reg1, [erpt_vbsc + EVBSC_SPARC_AFAR] ;\
353 setx 0x400000402, reg2, reg1 ;\
354 stx reg1, [erpt_vbsc + EVBSC_TSTATE] ;\
355 setx 0x000000800, reg2, reg1 ;\
356 stx reg1, [erpt_vbsc + EVBSC_HTSTATE] ;\
357 setx 0x000800610, reg2, reg1 ;\
358 stx reg1, [erpt_vbsc + EVBSC_TPC] ;\
359 set 0x0, reg1 ;\
360 stuh reg1, [erpt_vbsc + EVBSC_CPUID] ;\
361 set 0x63, reg1 ;\
362 stuh reg1, [erpt_vbsc + EVBSC_TT] ;\
363 set 0x1, reg1 ;\
364 stub reg1, [erpt_vbsc + EVBSC_TL] ;\
365 set 0x3, reg1 ;\
366 stub reg1, [erpt_vbsc + EVBSC_ERREN]
367
368
369/*
370 * vbsc_rx
371 *
372 * %g1 callback cookie (guest struct?XXX)
373 * %g2 svc pointer
374 * %g7 return address
375 */
376 ENTRY(vbsc_rx)
377 ROOT_STRUCT(%g1)
378 ldx [%g1 + CONFIG_VBSC_SVCH], %g1
379
380 mov %g7, %g6
381 PRINT("vbsc_rx: "); PRINTX(%g1); PRINT("\r\n");
382 mov %g6, %g7
383
384 /*
385 * We don't defer packets so clear the recv pending flag.
386 * This is called on the cpu handling the interrupts so
387 * the contents of the buffer will not get clobbered until
388 * we return.
389 */
390 ld [%g2 + SVC_CTRL_STATE], %g3
391 andn %g3, SVC_FLAGS_RI, %g3
392 st %g3, [%g2 + SVC_CTRL_STATE] ! clear RECV pending
393
394 ldx [%g2 + SVC_CTRL_RECV + SVC_LINK_PA], %g2
395 inc SVC_PKT_SIZE, %g2 ! skip the header
396
397 /*
398 * Dispatch command
399 */
400 ldub [%g2 + 6], %g4
401 cmp %g4, VBSC_CMD_GUEST_STATE
402 be,pn %xcc, gueststatecmd
403 cmp %g4, VBSC_CMD_HV
404 be,pn %xcc, hvcmd
405 cmp %g4, VBSC_CMD_READMEM
406 be,pn %xcc, dbgrd
407 cmp %g4, VBSC_CMD_WRITEMEM
408 be,pn %xcc, dbgwr
409 cmp %g4, VBSC_CMD_SENDERR
410 be,pn %xcc, dbg_send_error
411 nop
412vbsc_rx_finished:
413 HVRET
414
415
416/*
417 * hvcmd - Hypervisor Command
418 */
419hvcmd:
420 ldub [%g2 + 7], %g4
421 cmp %g4, 'I'
422 be,pn %xcc, hvcmd_ping
423 nop
424 ba,a vbsc_rx_finished
425
426 /*
427 * hvcmd_ping - nop, just respond
428 */
429hvcmd_ping:
430 /* FIXME: find better scratch buffer */
431 VCPU_STRUCT(%g2)
432 inc CPU_SCR0, %g2
433 setx VBSC_ACK(VBSC_CMD_HV, 'I'), %g4, %g3
434 stx %g3, [%g2 + 0x0]
435 rdpr %tpc, %g3
436 st %g3, [%g2 + 0xc]
437 srlx %g3, 32, %g3
438 st %g3, [%g2 + 0x8]
439 ba,pt %xcc, svc_internal_send ! returns to caller!!!!
440 mov 16, %g3 ! len
441
442/*
443 * gueststatecmd - Request from VBSC to change guest state
444 */
445gueststatecmd:
446 !! %g2 = incoming packet
447
448 ldub [%g2 + 7], %g4
449 cmp %g4, GUEST_STATE_CMD_SHUTREQ
450 be,pn %xcc, 1f
451 cmp %g4, GUEST_STATE_CMD_DCOREREQ
452 be,pn %xcc, 1f
453 nop
454 ba,a vbsc_rx_finished
455
4561:
457 /*
458 * The use of XID is deprecated. The target of
459 * the request is always the control domain.
460 */
461 CTRL_DOMAIN(%g1, %g3, %g4)
462 cmp %g1, 0
463 be,pn %xcc, vbsc_rx_finished
464 nop
465
466 /*
467 * Check if the current vcpu is in the control
468 * domain and running. If so, the state command
469 * can be executed on the local strand.
470 */
471 VCPU_STRUCT(%g3)
472
473 !! %g1 = control domain guestp
474 !! %g2 = incoming packet
475 !! %g3 = current vcpup
476
477 ldx [%g3 + CPU_GUEST], %g4
478 cmp %g1, %g4
479 bne,pn %xcc, reroutecmd
480 nop
481
482 ldx [%g3 + CPU_STATUS], %g4
483 cmp %g4, CPU_STATE_RUNNING
484 bne,pn %xcc, reroutecmd
485 nop
486
487 ba,a executecmd
488
489reroutecmd:
490
491 !! %g1 = control domain guestp
492 !! %g2 = incoming packet
493
494 /*
495 * Loop through the vcpus in the control domain
496 * until one is found that is running. If none
497 * are found, the domain is not in an appropriate
498 * state for the request so the request is dropped.
499 */
500
501 mov 0, %g4
502 !! %g4 = current index
5031:
504 cmp %g4, (NVCPUS - 1)
505 bgu,pn %xcc, vbsc_rx_finished ! no appropriate vcpu, ignore request
506 nop
507 sllx %g4, GUEST_VCPUS_SHIFT, %g3
508 add %g1, %g3, %g3
509 add %g3, GUEST_VCPUS, %g3
510 ldx [%g3], %g3
511 brz,a %g3, 1b ! skip any empty entries
512 inc %g4
513 !! %g3 = current vcpup
514
515 ! check the vcpu state
516 ldx [%g3 + CPU_STATUS], %g5
517 cmp %g5, CPU_STATE_RUNNING
518 bne,a %xcc, 1b
519 inc %g4
520
521executecmd:
522
523 !! %g2 = incoming packet
524 !! %g3 = target vcpup
525
526 VCPU2STRAND_STRUCT(%g3, %g4)
527 !! %g4 = target strandp
528
529 ldub [%g2 + 7], %g5
530 cmp %g5, GUEST_STATE_CMD_SHUTREQ
531 be,pn %xcc, hvcmd_guest_shutdown_request
532 cmp %g5, GUEST_STATE_CMD_DCOREREQ
533 be,pn %xcc, hvcmd_guest_dcore_request
534 nop
535 ba,a vbsc_rx_finished
536
537hvcmd_guest_shutdown_request:
538
539 !! %g2 = incoming packet
540 !! %g3 = target vcpup
541 !! %g4 = target strandp
542
543#ifdef DEBUG
544 mov %g7, %g5
545 PRINT("Control Domain shutdown request, target strand=0x")
546 ldub [%g4 + STRAND_ID], %g6
547 PRINTX(%g6)
548 PRINT("\r\n")
549 mov %g5, %g7
550#endif /* DEBUG */
551
552 ! retrieve the command argument from the packet
553 ldx [%g2 + 0x10], %g2
554 !! %g2 = command argument (grace period in seconds)
555
556 /*
557 * Perform the action locally if the current
558 * strand is the specified target.
559 */
560
561 STRAND_STRUCT(%g5)
562 cmp %g4, %g5
563 be,a,pt %xcc, guest_shutdown ! tail call, does not return here
564 mov %g2, %g1 ! the required argument
565
566 /*
567 * Send a mondo to the specified strand to
568 * perform the action.
569 */
570
571 add %g4, STRAND_HV_TXMONDO, %g5
572 !! %g5 = strand mondop
573
574 ! setup mondo structure
575 mov HXCMD_GUEST_SHUTDOWN, %g6
576 stx %g6, [%g5 + HVM_CMD]
577 STRAND_STRUCT(%g6)
578 stx %g6, [%g5 + HVM_FROM_STRANDP]
579 stx %g3, [%g5 + HVM_ARGS + HVM_GUESTCMD_VCPUP]
580 stx %g2, [%g5 + HVM_ARGS + HVM_GUESTCMD_ARG]
581
582 ! send the mondo
583 mov %g4, %g1 ! arg1 = target strandp
584 mov %g5, %g2 ! arg2 = strand mondop
585 STRAND_PUSH(%g7, %g3, %g4)
586 HVCALL(hvmondo_send)
587 STRAND_POP(%g7, %g3)
588
589 ba,a vbsc_rx_finished
590
591hvcmd_guest_dcore_request:
592
593 !! %g2 = incoming packet
594 !! %g3 = target vcpup
595 !! %g4 = target strandp
596
597#ifdef DEBUG
598 mov %g7, %g5
599 PRINT("Control Domain panic request, target strand=0x")
600 ldub [%g4 + STRAND_ID], %g6
601 PRINTX(%g6)
602 PRINT("\r\n")
603 mov %g5, %g7
604#endif /* DEBUG */
605
606 /*
607 * Perform the action locally if the current
608 * strand is the specified target.
609 */
610
611 STRAND_STRUCT(%g5)
612 cmp %g4, %g5
613 be,a,pt %xcc, guest_panic ! tail call, does not return here
614 nop
615
616 /*
617 * Send a mondo to the specified strand to
618 * perform the action.
619 */
620
621 add %g4, STRAND_HV_TXMONDO, %g5
622 !! %g5 = strand mondop
623
624 ! setup mondo structure
625 mov HXCMD_GUEST_PANIC, %g6
626 stx %g6, [%g5 + HVM_CMD]
627 STRAND_STRUCT(%g6)
628 stx %g6, [%g5 + HVM_FROM_STRANDP]
629 stx %g3, [%g5 + HVM_ARGS + HVM_GUESTCMD_VCPUP]
630
631 ! send the mondo
632 mov %g4, %g1 ! arg1 = target strandp
633 mov %g5, %g2 ! arg2 = strand mondop
634 STRAND_PUSH(%g7, %g3, %g4)
635 HVCALL(hvmondo_send)
636 STRAND_POP(%g7, %g3)
637
638 ba,a vbsc_rx_finished
639
640 /*
641 * dbgrd - perform read transaction on behalf of vbsc
642 */
643dbgrd:
644 ldx [%g2 + 8], %g3 ! ADDR
645 ldub [%g2 + 7], %g6 ! size
646 sub %g6, '0', %g6
647 ldub [%g2 + 5], %g4 ! asi?
648 cmp %g4, 'A'
649 bne,pt %xcc, 1f
650 sllx %g6, 2, %g6 ! offset
651 add %g6, 4*4, %g6 ! offset of ASIs
652 srlx %g3, 56, %g4
653 and %g4, 0xff, %g4
654 wr %g4, %asi
655 sllx %g3, 8, %g3
656 srlx %g3, 8, %g3 ! bits 0-56
6571: ba 1f
658 rd %pc, %g4
659 ldub [%g3], %g6
660 lduh [%g3], %g6
661 ld [%g3], %g6
662 ldx [%g3], %g6
663 lduba [%g3] %asi, %g6
664 lduha [%g3] %asi, %g6
665 lda [%g3] %asi, %g6
666 ldxa [%g3] %asi, %g6
6671: add %g4, 4, %g4
668 jmp %g4 + %g6 ! CTI COUPLE!!
669 ba 1f ! CTI COUPLE!!
670 nop ! NEVER EXECUTED!! DONT DELETE
6711: ba 1f
672 rd %pc, %g2
673.word 0 ! data buffer - upper 32 bits
674.word 0 ! data buffer - lower 32 bits
6751: add %g2, 4, %g2 ! buf
676 st %g6, [%g2 + 4] ! low bits
677 srlx %g6, 32, %g6
678 st %g6, [%g2 + 0] ! upper bits
679 ba svc_internal_send ! returns to caller!!!!
680 mov 8, %g3 ! len
681
682 /*
683 * dbgwr - perform write transaction on behalf of vbsc
684 */
685dbgwr:
686 ldx [%g2 + 0x10], %g3 ! ADDR
687 ldub [%g2 + 7], %g6 ! size
688 sub %g6, '0', %g6
689 ldub [%g2 + 5], %g1 ! asi?
690 cmp %g1, 'A'
691 bne,pt %xcc, 1f
692 sllx %g6, 2, %g6 ! offset
693 add %g6, 4*4, %g6 ! offset of ASIs
694 srlx %g3, 56, %g4
695 and %g4, 0xff, %g4
696 wr %g4, %asi
697 sllx %g3, 8, %g3
698 srlx %g3, 8, %g3 ! bits0-56
6991: ba 1f
700 rd %pc, %g4
701 stb %g1, [%g3]
702 sth %g1, [%g3]
703 st %g1, [%g3]
704 stx %g1, [%g3]
705 stba %g1, [%g3] %asi
706 stha %g1, [%g3] %asi
707 sta %g1, [%g3] %asi
708 stxa %g1, [%g3] %asi
7091: add %g4, 4, %g4
710 ldx [%g2 + 8], %g1 ! get data
711 jmp %g4 + %g6 ! CTI COUPLE!!
712 jmp %g7 + 4 ! All done.
713 nop ! NEVER EXECUTED!!!
714
715 /*
716 * dbg_send_error - send a fake error transaction back to vbsc
717 */
718dbg_send_error:
719#if 0
720#ifdef DEBUG
721 /*
722 * Fill the error reports with valid information to
723 * help test interaction with the FERG on the vbsc
724 */
725 mov %g7, %g6
726 STRAND_STRUCT(%g3)
727 add %g3, STRAND_CE_RPT + STRAND_VBSC_ERPT, %g4
728 SIM_IRC_DIAG_ERPT(%g4, %g5, %g7)
729 add %g3, STRAND_UE_RPT + STRAND_VBSC_ERPT, %g4
730 SIM_IRU_DIAG_ERPT(%g4, %g5, %g7)
731 PRINT("\r\n")
732 mov %g6, %g7
733#endif
734
735 CPU_PUSH(%g7, %g1, %g2, %g3)
736 STRAND_STRUCT(%g1)
737 add %g1, STRAND_CE_RPT + STRAND_UNSENT_PKT, %g2
738 ldx [%g1 + STRAND_CONFIGP], %g6
739
740#ifdef DEBUG
741 /*
742 * Send one error and mark another buffer to be
743 * sent
744 */
745 mov 1, %g7
746 stx %g7, [%g6 + CONFIG_ERRS_TO_SEND]
747 set STRAND_UE_RPT + STRAND_UNSENT_PKT, %g3
748 add %g1, %g3, %g3
749 stx %g7, [%g3]
750#endif
751 add %g1, STRAND_CE_RPT + STRAND_VBSC_ERPT, %g1
752 mov EVBSC_SIZE, %g3
753 HVCALL(send_diag_erpt)
754 CPU_POP(%g7, %g1, %g2, %g3)
755#endif
756 HVRET
757 SET_SIZE(vbsc_rx)
758
759/*
760 * vbsc_tx
761 *
762 * %g1 callback cookie
763 * %g2 packet
764 * %g7 return address
765 */
766 ENTRY(vbsc_tx)
767 mov %g7, %g6
768 PRINT("vbsc_tx: ")
769 PRINTX(%g1)
770 PRINT("\r\n")
771 mov %g6, %g7
772
773 HVRET
774 SET_SIZE(vbsc_tx)
775
776
777
778
779/*
780 * vbsc_puts - print string on hypervisor console
781 *
782 * %g1 string pointer
783 * %g7 return address
784 */
785 ENTRY_NP(vbsc_puts)
786
787 CPU_PUSH(%g7, %g2, %g3, %g4)
788 CPU_PUSH(%g6, %g2, %g3, %g4)
789 CPU_PUSH(%g5, %g2, %g3, %g4)
790 CPU_PUSH(%l0, %g2, %g3, %g4)
791
792 mov %g1, %l0
793 !! %l0 = string pointer
794
7951: mov 8, %g5
796 mov 0, %g2
797 !! %g5 = loop count
798 !! %g2 = debug-puthex arg1
799
8002: ldub [%l0], %g3
801 brz,pn %g3, .sendndone
802 nop
803 sllx %g2, 8, %g2
804 or %g2, %g3, %g2 ! arg1 = (arg1 << 8) | char
805 deccc %g5
806 bnz,pt %xcc, 2b
807 inc %l0
808
8093:
810 setx VBSC_HV_PUTCHARS, %g3, %g1
811 HVCALL(vbsc_send_polled)
812
813 ba,pt %xcc, 1b
814 nop
815
816.sendndone:
817 setx VBSC_HV_PUTCHARS, %g3, %g1
818 HVCALL(vbsc_send_polled)
819
820 CPU_POP(%l0, %g1, %g2, %g3)
821 CPU_POP(%g5, %g1, %g2, %g3)
822 CPU_POP(%g6, %g1, %g2, %g3)
823 CPU_POP(%g7, %g1, %g2, %g3)
824
825 HVRET
826 SET_SIZE(vbsc_puts)
827
828
829/*
830 * vbsc_putx - print hex number on hypervisor console
831 *
832 * %g1 number
833 * %g7 return address
834 */
835 ENTRY_NP(vbsc_putx)
836 mov %g1, %g2
837 setx VBSC_HV_PUTHEX, %g3, %g1
838 ba,a vbsc_send_polled
839 /* tail call, returns directly to caller */
840 SET_SIZE(vbsc_putx)
841
842#endif /* CONFIG_SVC && CONFIG_VBSC_SVC */