]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/sun4v/sun4v/support.S
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / sun4v / sun4v / support.S
1 /*-
2  * Copyright (c) 2001 Jake Burkholder.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #include <machine/asm.h>
28 __FBSDID("$FreeBSD$");
29
30 #include <sys/errno.h>
31
32 #include <machine/asi.h>
33 #include <machine/asmacros.h>
34 #include <machine/hypervisorvar.h>
35 #include <machine/intr_machdep.h>
36 #include <machine/ktr.h>
37 #include <machine/pstate.h>
38
39 #include "assym.s"
40
41         .register %g2, #ignore
42         .register %g3, #ignore
43         .register %g6, #ignore
44
45 #define E       /* empty */
46
47 /*
48  * Generate load and store instructions for the corresponding width and asi
49  * (or not).  Note that we want to evaluate the macro args before
50  * concatenating, so that E really turns into nothing.
51  */
52 #define _LD(w, a)       ld ## w ## a
53 #define _ST(w, a)       st ## w ## a
54
55 #define LD(w, a)        _LD(w, a)
56 #define ST(w, a)        _ST(w, a)
57
58 /*
59  * Common code for copy routines.
60  *
61  * We use large macros to generate functions for each of the copy routines.
62  * This allows the load and store instructions to be generated for the right
63  * operation, asi or not.  It is possible to write an asi independent function
64  * but this would require 2 expensive wrs in the main loop to switch %asi.
65  * It would also screw up profiling (if we ever get it), but may save some I$.
66  * We assume that either one of dasi and sasi is empty, or that they are both
67  * the same (empty or non-empty).  It is up to the caller to set %asi.
68  */
69
70 /*
71  * ASI independent implementation of copystr(9).
72  * Used to implement copyinstr() and copystr().
73  *
74  * Return value is in %g1.
75  */
76 #define _COPYSTR(src, dst, len, done, sa, sasi, da, dasi) \
77         brz     len, 4f ; \
78          mov    src, %g2 ; \
79 1:      deccc   1, len ; \
80         bl,a,pn %xcc, 3f ; \
81          nop ; \
82         LD(ub, sa) [src] sasi, %g1 ; \
83         ST(b, da) %g1, [dst] dasi ; \
84         brz,pn  %g1, 3f ; \
85          inc    src ; \
86         ba      %xcc, 1b ; \
87          inc    dst ; \
88 2:      mov     ENAMETOOLONG, %g1 ; \
89 3:      sub     src, %g2, %g2 ; \
90         brnz,a  done, 4f ; \
91          stx    %g2, [done] ; \
92 4:
93
94 /*
95  * ASI independent implementation of memset(3).
96  * Used to implement bzero(), memset() and aszero().
97  *
98  * If the pattern is non-zero, duplicate it to fill 64 bits.
99  * Store bytes until dst is 8-byte aligned, then store 8 bytes.
100  * It has yet to be determined how much unrolling is beneficial.
101  * Could also read and compare before writing to minimize snoop traffic.
102  *
103  * XXX bzero() should be implemented as
104  * #define bzero(dst, len) (void)memset((dst), 0, (len))
105  * if at all.
106  */
107 #define _MEMSET(dst, pat, len, da, dasi) \
108         brlez,pn len, 5f ; \
109          and    pat, 0xff, pat ; \
110         brz,pt  pat, 1f ; \
111          sllx   pat, 8, %g1 ; \
112         or      pat, %g1, pat ; \
113         sllx    pat, 16, %g1 ; \
114         or      pat, %g1, pat ; \
115         sllx    pat, 32, %g1 ; \
116         or      pat, %g1, pat ; \
117         .align 16 ; \
118 1:      deccc   1, len ; \
119         bl,pn   %xcc, 5f ; \
120          btst   7, dst ; \
121         bz,a,pt %xcc, 2f ; \
122          inc    1, len ; \
123         ST(b, da) pat, [dst] dasi ; \
124         ba      %xcc, 1b ; \
125          inc    dst ; \
126         .align 16 ; \
127 2:      deccc   32, len ; \
128         bl,a,pn %xcc, 3f ; \
129          inc    32, len ; \
130         ST(x, da) pat, [dst] dasi ; \
131         ST(x, da) pat, [dst + 8] dasi ; \
132         ST(x, da) pat, [dst + 16] dasi ; \
133         ST(x, da) pat, [dst + 24] dasi ; \
134         ba      %xcc, 2b ; \
135          inc    32, dst ; \
136         .align 16 ; \
137 3:      deccc   8, len ; \
138         bl,a,pn %xcc, 4f ; \
139          inc    8, len ; \
140         ST(x, da) pat, [dst] dasi ; \
141         ba      %xcc, 3b ; \
142          inc    8, dst ; \
143         .align 16 ; \
144 4:      deccc   1, len ; \
145         bl,a,pn %xcc, 5f ; \
146          nop ; \
147         ST(b, da) pat, [dst] dasi ; \
148         ba      %xcc, 4b ; \
149          inc    1, dst ; \
150 5:
151
152 /*
153  * ASI independent implementation of memcpy(3).
154  * Used to implement bcopy(), copyin(), copyout(), memcpy(), ascopy(),
155  * ascopyfrom() and ascopyto().
156  *
157  * Transfer bytes until dst is 8-byte aligned.  If src is then also 8 byte
158  * aligned, transfer 8 bytes, otherwise finish with bytes.  The unaligned
159  * case could be optimized, but it is expected that this is the uncommon
160  * case and of questionable value.  The code to do so is also rather large
161  * and ugly.  It has yet to be determined how much unrolling is beneficial.
162  *
163  * XXX bcopy() must also check for overlap.  This is stupid.
164  * XXX bcopy() should be implemented as
165  * #define bcopy(src, dst, len) (void)memcpy((dst), (src), (len))
166  * if at all.
167  */
168 #define _MEMCPY(dst, src, len, da, dasi, sa, sasi) \
169 1:      deccc   1, len ; \
170         bl,pn   %xcc, 6f ; \
171          btst   7, dst ; \
172         bz,a,pt %xcc, 2f ; \
173          inc    1, len ; \
174         LD(ub, sa) [src] sasi, %g1 ; \
175         ST(b, da) %g1, [dst] dasi ; \
176         inc     1, src ; \
177         ba      %xcc, 1b ; \
178          inc    1, dst ; \
179         .align 16 ; \
180 2:      btst    7, src ; \
181         bz,a,pt %xcc, 3f ; \
182          nop ; \
183         ba,a    %xcc, 5f ; \
184         .align 16 ; \
185 3:      deccc   32, len ; \
186         bl,a,pn %xcc, 4f ; \
187          inc    32, len ; \
188         LD(x, sa) [src] sasi, %g1 ; \
189         LD(x, sa) [src + 8] sasi, %g2 ; \
190         LD(x, sa) [src + 16] sasi, %g3 ; \
191         LD(x, sa) [src + 24] sasi, %g4 ; \
192         ST(x, da) %g1, [dst] dasi ; \
193         ST(x, da) %g2, [dst + 8] dasi ; \
194         ST(x, da) %g3, [dst + 16] dasi ; \
195         ST(x, da) %g4, [dst + 24] dasi ; \
196         inc     32, src ; \
197         ba      %xcc, 3b ; \
198          inc    32, dst ; \
199         .align 16 ; \
200 4:      deccc   8, len ; \
201         bl,a,pn %xcc, 5f ; \
202          inc    8, len ; \
203         LD(x, sa) [src] sasi, %g1 ; \
204         ST(x, da) %g1, [dst] dasi ; \
205         inc     8, src ; \
206         ba      %xcc, 4b ; \
207          inc    8, dst ; \
208         .align 16 ; \
209 5:      deccc   1, len ; \
210         bl,a,pn %xcc, 6f ; \
211          nop ; \
212         LD(ub, sa) [src] sasi, %g1 ; \
213         ST(b, da) %g1, [dst] dasi ; \
214         inc     src ; \
215         ba      %xcc, 5b ; \
216          inc    dst ; \
217 6:
218
219 /*
220  * void ascopy(u_long asi, vm_offset_t src, vm_offset_t dst, size_t len)
221  */
222 ENTRY(ascopy)
223         wr      %o0, 0, %asi
224         _MEMCPY(%o2, %o1, %o3, a, %asi, a, %asi)
225         retl
226          nop
227 END(ascopy)
228
229 /*
230  * void ascopyfrom(u_long sasi, vm_offset_t src, caddr_t dst, size_t len)
231  */
232 ENTRY(ascopyfrom)
233         wr      %o0, 0, %asi
234         _MEMCPY(%o2, %o1, %o3, E, E, a, %asi)
235         retl
236          nop
237 END(ascopyfrom)
238
239 /*
240  * void ascopyto(caddr_t src, u_long dasi, vm_offset_t dst, size_t len)
241  */
242 ENTRY(ascopyto)
243         wr      %o1, 0, %asi
244         _MEMCPY(%o2, %o0, %o3, a, %asi, E, E)
245         retl
246          nop
247 END(ascopyto)
248
249 /*
250  * void aszero(u_long asi, vm_offset_t pa, size_t len)
251  */
252 ENTRY(aszero)
253         wr      %o0, 0, %asi
254         _MEMSET(%o1, %g0, %o2, a, %asi)
255         retl
256          nop
257 END(aszero)
258
259 /*
260  * int bcmp(const void *b1, const void *b2, size_t len)
261  */
262 ENTRY(bcmp)
263         brz,pn  %o2, 2f
264          clr    %o3
265 1:      ldub    [%o0 + %o3], %o4
266         ldub    [%o1 + %o3], %o5
267         cmp     %o4, %o5
268         bne,pn  %xcc, 2f
269          inc    %o3
270         deccc   %o2
271         bne,pt  %xcc, 1b
272          nop
273 2:      retl
274          mov    %o2, %o0
275 END(bcmp)
276 #if 0
277 /*
278  * void bcopy(const void *src, void *dst, size_t len)
279  */
280 ENTRY(bcopy)
281         /*
282          * Check for overlap, and copy backwards if so.
283          */
284         sub     %o1, %o0, %g1
285         cmp     %g1, %o2
286         bgeu,a,pt %xcc, 3f
287          nop
288
289         /*
290          * Copy backwards.
291          */
292         add     %o0, %o2, %o0
293         add     %o1, %o2, %o1
294 1:      deccc   1, %o2
295         bl,a,pn %xcc, 2f
296          nop
297         dec     1, %o0
298         ldub    [%o0], %g1
299         dec     1, %o1
300         ba      %xcc, 1b
301          stb    %g1, [%o1]
302 2:      retl
303          nop
304
305         /*
306          * Do the fast version.
307          */
308 3:      _MEMCPY(%o1, %o0, %o2, E, E, E, E)
309         retl
310          nop
311 END(bcopy)
312
313 /*
314  * void bzero(void *b, size_t len)
315  */
316 ENTRY(bzero)
317         _MEMSET(%o0, %g0, %o1, E, E)
318         retl
319          nop
320 END(bzero)
321 #endif
322 /*
323  * int copystr(const void *src, void *dst, size_t len, size_t *done)
324  */
325 ENTRY(copystr)
326         _COPYSTR(%o0, %o1, %o2, %o3, E, E, E, E)
327         retl
328          mov    %g1, %o0
329 END(copystr)
330
331 /*
332  * void *memcpy(void *dst, const void *src, size_t len)
333  */
334 ENTRY(memcpy)
335         mov     %o0, %o3
336         _MEMCPY(%o3, %o1, %o2, E, E, E, E)
337         retl
338          nop
339 END(memcpy)
340
341 /*
342  * void *memset(void *b, int c, size_t len)
343  */
344 ENTRY(memset)
345         mov     %o0, %o3
346         _MEMSET(%o3, %o1, %o2, E, E)
347         retl
348          nop
349 END(memset)
350
351         .globl  copy_nofault_begin
352 copy_nofault_begin:
353         nop
354 #if 1
355 /*
356  * int copyin(const void *uaddr, void *kaddr, size_t len)
357  */
358 ENTRY(copyin)
359         wr      %g0, ASI_AIUS, %asi
360         _MEMCPY(%o1, %o0, %o2, E, E, a, %asi)
361         retl
362          clr    %o0
363 END(copyin)
364 #endif
365 /*
366  * int copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done)
367  */
368 ENTRY(copyinstr)
369         wr      %g0, ASI_AIUS, %asi
370         _COPYSTR(%o0, %o1, %o2, %o3, a, %asi, E, E)
371         retl
372          mov    %g1, %o0
373 END(copyinstr)
374
375 /*
376  * int copyout(const void *kaddr, void *uaddr, size_t len)
377  */
378 ENTRY(copyout)
379         wr      %g0, ASI_AIUS, %asi
380         _MEMCPY(%o1, %o0, %o2, a, %asi, E, E)
381         retl
382          clr    %o0
383 END(copyout)
384
385         .globl  copy_nofault_end
386 copy_nofault_end:
387         nop
388
389 ENTRY(copy_fault)
390         retl
391          mov    EFAULT, %o0
392 END(copy_fault)
393
394         .globl  fs_nofault_begin
395 fs_nofault_begin:
396         nop
397
398 /*
399  * Chatty aliases for fetch, store functions.
400  */
401         .globl  fubyte, fusword, fuword, subyte, susword, suword
402         .set    fubyte, fuword8
403         .set    fusword, fuword16
404         .set    fuword, fuword64
405         .set    subyte, suword8
406         .set    susword, suword16
407         .set    suword, suword64
408
409         .globl  casuword, fuptr, suptr
410         .set    casuword, casuword64
411         .set    fuptr, fuword64
412         .set    suptr, suword64
413
414 /*
415  * int32_t casuword32(volatile int32_t *p, int32_t e, int32_t s)
416  */
417 ENTRY(casuword32)
418         casa    [%o0] ASI_AIUS, %o1, %o2
419         retl
420          mov    %o2, %o0
421 END(casuword32)
422
423 /*
424  * int64_t casuword64(volatile int64_t *p, int64_t e, int64_t s)
425  */
426 ENTRY(casuword64)
427         casxa   [%o0] ASI_AIUS, %o1, %o2
428         retl
429          mov    %o2, %o0
430 END(casuword64)
431
432 /*
433  * int fuword8(const void *base)
434  */
435 ENTRY(fuword8)
436         retl
437          lduba  [%o0] ASI_AIUS, %o0
438 END(fuword8)
439
440 /*
441  * int fuword16(const void *base)
442  */
443 ENTRY(fuword16)
444         retl
445          lduha  [%o0] ASI_AIUS, %o0
446 END(fuword16)
447
448 /*
449  * int32_t fuword32(const void *base)
450  */
451 ENTRY(fuword32)
452         retl
453          lduwa  [%o0] ASI_AIUS, %o0
454 END(fuword32)
455
456 /*
457  * int64_t fuword64(const void *base)
458  */
459 ENTRY(fuword64)
460         retl
461          ldxa   [%o0] ASI_AIUS, %o0
462 END(fuword64)
463
464 /*
465  * int suword8(const void *base, int word)
466  */
467 ENTRY(suword8)
468         stba    %o1, [%o0] ASI_AIUS
469         retl
470          clr    %o0
471 END(suword8)
472
473 /*
474  * int suword16(const void *base, int word)
475  */
476 ENTRY(suword16)
477         stha    %o1, [%o0] ASI_AIUS
478         retl
479          clr    %o0
480 END(suword16)
481
482 /*
483  * int suword32(const void *base, int32_t word)
484  */
485 ENTRY(suword32)
486         stwa    %o1, [%o0] ASI_AIUS
487         retl
488          clr    %o0
489 END(suword32)
490
491 /*
492  * int suword64(const void *base, int64_t word)
493  */
494 ENTRY(suword64)
495         stxa    %o1, [%o0] ASI_AIUS
496         retl
497          clr    %o0
498 END(suword64)
499
500         .globl  fs_nofault_intr_begin
501 fs_nofault_intr_begin:
502         nop
503
504 /*
505  * int fuswintr(const void *base)
506  */
507 ENTRY(fuswintr)
508         retl
509          lduha  [%o0] ASI_AIUS, %o0
510 END(fuswintr)
511
512 /*
513  * int suswintr(const void *base, int word)
514  */
515 ENTRY(suswintr)
516         stha    %o1, [%o0] ASI_AIUS
517         retl
518          clr    %o0
519 END(suswintr)
520
521         .globl  fs_nofault_intr_end
522 fs_nofault_intr_end:
523         nop
524
525         .globl  fs_nofault_end
526 fs_nofault_end:
527         nop
528
529 ENTRY(fs_fault)
530         retl
531          mov    -1, %o0
532 END(fsfault)
533
534         .globl  fas_nofault_begin
535 fas_nofault_begin:
536
537 /*
538  * int fasword8(u_long asi, uint64_t addr, uint8_t *val)
539  */
540 ENTRY(fasword8)
541         wr      %o0, 0, %asi
542         membar  #Sync
543         lduba   [%o1] %asi, %o3
544         membar  #Sync
545         stb     %o3, [%o2]
546         retl
547          clr    %o0
548 END(fasword8)
549
550 /*
551  * int fasword16(u_long asi, uint64_t addr, uint16_t *val)
552  */
553 ENTRY(fasword16)
554         wr      %o0, 0, %asi
555         membar  #Sync
556         lduha   [%o1] %asi, %o3
557         membar  #Sync
558         sth     %o3, [%o2]
559         retl
560          clr    %o0
561 END(fasword16)
562
563 /*
564  * int fasword32(u_long asi, uint64_t addr, uint32_t *val)
565  */
566 ENTRY(fasword32)
567         wr      %o0, 0, %asi
568         membar  #Sync
569         lduwa   [%o1] %asi, %o3
570         membar  #Sync
571         stw     %o3, [%o2]
572         retl
573          clr    %o0
574 END(fasword32)
575
576         .globl  fas_nofault_end
577 fas_nofault_end:
578         nop
579
580         .globl  fas_fault
581 ENTRY(fas_fault)
582         retl
583          mov    -1, %o0
584 END(fas_fault)
585
586         .globl  fpu_fault_begin
587 fpu_fault_begin:
588         nop
589
590         .globl  fpu_fault_end
591 fpu_fault_end:
592         nop
593
594         .globl  fpu_fault_size
595         .set    fpu_fault_size, fpu_fault_end - fpu_fault_begin
596
597 ENTRY(longjmp)
598         set     1, %g3
599         movrz   %o1, %o1, %g3
600         mov     %o0, %g1
601         ldx     [%g1 + _JB_FP], %g2
602 1:      cmp     %fp, %g2
603         bl,a,pt %xcc, 1b
604          restore
605         bne,pn  %xcc, 2f
606          ldx    [%g1 + _JB_SP], %o2
607         cmp     %o2, %sp
608         blt,pn  %xcc, 2f
609          movge  %xcc, %o2, %sp
610         ldx     [%g1 + _JB_PC], %o7
611         retl
612          mov    %g3, %o0
613 2:      PANIC("longjmp botch", %l1)
614 END(longjmp)
615
616 ENTRY(setjmp)
617         stx     %sp, [%o0 + _JB_SP]
618         stx     %o7, [%o0 + _JB_PC]
619         stx     %fp, [%o0 + _JB_FP]
620         retl
621          clr    %o0
622 END(setjmp)
623
624 /*
625  * void ofw_entry(cell_t args[])
626  */
627 ENTRY(ofw_entry)
628         save    %sp, -CCFSZ, %sp
629         SET(ofw_vec, %l7, %l6)
630         ldx     [%l6], %l6
631         rdpr    %pil, %l7
632         wrpr    %g0, PIL_TICK, %pil
633         call    %l6
634          mov    %i0, %o0
635         wrpr    %l7, 0, %pil
636         ret
637          restore %o0, %g0, %o0
638 END(ofw_entry)
639
640 #ifdef notyet
641 /* SUN4V_FIXME - uses a now illegal ASI */
642 /*
643  * void ofw_exit(cell_t args[])
644  */
645 ENTRY(ofw_exit)
646         save    %sp, -CCFSZ, %sp
647         flushw
648         wrpr    %g0, PIL_TICK, %pil
649         SET(ofw_tba, %l7, %l5)
650         ldx     [%l5], %l5
651         wrpr    %l5, 0, %tba                    ! restore the ofw trap table
652         SET(ofw_vec, %l7, %l6)
653         ldx     [%l6], %l6
654         SET(kstack0 + KSTACK_PAGES * PAGE_SIZE - PCB_SIZEOF, %l7, %l0)
655         sub     %l0, SPOFF, %fp                 ! setup a stack in a locked page
656         sub     %l0, SPOFF + CCFSZ, %sp
657         mov     AA_DMMU_PCXR, %l3               ! set context 0
658         stxa    %g0, [%l3] ASI_DMMU
659         membar  #Sync
660         wrpr    %g0, 0, %tl                     ! force trap level 0
661         call    %l6
662          mov    %i0, %o0
663         ! never to return
664 END(ofw_exit)
665
666 #endif
667 ENTRY(set_mmfsa_scratchpad)
668         stxa    %o0, [%g0]ASI_SCRATCHPAD
669         retl
670           nop
671 END(set_mmfsa_scratchpad)
672 ENTRY(set_pcpu_scratchpad)
673         mov     SCRATCH_REG_PCPU, %g2
674         stxa    %o0, [%g0 + %g2]ASI_SCRATCHPAD
675         retl
676           nop
677 END(set_pcpu_scratchpad)
678 ENTRY(set_hash_kernel_scratchpad)
679         mov     SCRATCH_REG_HASH_KERNEL, %g2
680         stxa    %o0, [%g0 + %g2]ASI_SCRATCHPAD
681         retl
682           nop
683 END(set_hash_kernel_scratchpad)
684 ENTRY(set_tsb_kernel_scratchpad)
685         mov     SCRATCH_REG_TSB_KERNEL, %g2
686         stxa    %o0, [%g0 + %g2]ASI_SCRATCHPAD
687         retl
688           nop
689 END(set_tsb_kernel_scratchpad)
690
691 ENTRY(set_hash_user_scratchpad)
692         mov     SCRATCH_REG_HASH_USER, %g2
693         stxa    %o0, [%g0 + %g2]ASI_SCRATCHPAD
694         retl
695           nop
696 END(set_hash_user_scratchpad)
697 ENTRY(set_tsb_user_scratchpad)
698         mov     SCRATCH_REG_TSB_USER, %g2
699         stxa    %o0, [%g0 + %g2]ASI_SCRATCHPAD
700         retl
701           nop
702 END(set_tsb_user_scratchpad)
703         
704                 
705 /*
706  * %o0 ra - real address
707  * [%o1] lo - lower 64-bits
708  * [%o2] hi - upper 64-bits
709  */
710         
711 ENTRY(load_real_dw)
712         save    %sp, -SA(MINFRAME64), %sp
713         ldda [%g0 + %i0]ASI_LDTD_REAL, %l0
714         stx %l0, [%i1]
715         stx %l1, [%i2]
716         restore
717         retl
718           nop
719 END(load_real_dw)
720
721 /*
722  * %o0 = vaddr
723  * %o1 = ctxnum
724  */             
725 ENTRY(invlpg)
726         mov     %o0, %o2
727         mov     %o1, %o3
728         mov     %g0, %o0
729         mov     %g0, %o1
730         mov     MAP_ITLB | MAP_DTLB, %o4
731         mov     MMU_DEMAP_PAGE, %o5
732         ta      FAST_TRAP
733         brz,pt  %o0, 1f
734           nop
735         ba,pt   %xcc, panic_bad_hcall
736           mov   MMU_DEMAP_PAGE, %o1
737 1:
738         retl
739           nop
740 END(invlpg)
741
742
743 /*
744  * %o0 = ctxnum
745  * 
746  */             
747 ENTRY(invlctx)
748         cmp     %o0, %g0
749         bne     %xcc, 2f
750           nop
751         MAGIC_TRAP_ON
752         MAGIC_EXIT
753 2:              
754         mov     %o0, %o2
755         mov     %g0, %o0
756         mov     %g0, %o1
757         mov     MAP_ITLB | MAP_DTLB, %o3
758         mov     MMU_DEMAP_CTX, %o5
759         ta      FAST_TRAP
760         brz,pt  %o0, 1f
761           nop
762         ba,pt   %xcc, panic_bad_hcall
763           mov   MMU_DEMAP_CTX, %o1
764 1:
765         retl
766           nop
767 END(invlctx)
768
769 ENTRY(invltlb)
770         mov     %g0, %o0
771         mov     %g0, %o1
772         mov     MAP_ITLB | MAP_DTLB, %o2
773         mov     MMU_DEMAP_ALL, %o5
774         ta      FAST_TRAP
775         brz,pt  %o0, 1f
776           nop
777         ba,pt   %xcc, panic_bad_hcall
778           mov   MMU_DEMAP_ALL, %o1
779 1:
780         retl
781           nop
782 END(invltlb)
783
784
785         /*
786          * panic_bad_hcall is called when a hcall returns
787          * unexpected error
788          * %o0 error number
789          * %o1 hcall number
790          */
791
792         .text
793 bad_hcall_error:
794         .asciz  "hypervisor call 0x%x returned an unexpected error %d"
795
796         
797 ENTRY(panic_bad_hcall)
798         mov     %o0, %o2
799         sethi   %hi(bad_hcall_error), %o0
800         or      %o0, %lo(bad_hcall_error), %o0
801         mov     %o7, %o3
802         call    panic
803           mov   %o3, %o7
804 END(panic_bad_hcall)
805
806
807         
808 ! %o0 = pa
809 ! %o1 = size
810         
811 ENTRY(bzerophyspage)
812         save    %sp, -SA(MINFRAME64), %sp
813         mov     8, %l1
814         mov     16, %l2
815         mov     24, %l3
816         mov     32, %l4
817         mov     40, %l5
818         mov     48, %l6
819         mov     56, %l7
820 1:      stxa    %g0, [%i0]ASI_REAL
821         stxa    %g0, [%i0 + %l1]ASI_REAL
822         stxa    %g0, [%i0 + %l2]ASI_REAL
823         stxa    %g0, [%i0 + %l3]ASI_REAL
824         stxa    %g0, [%i0 + %l4]ASI_REAL
825         stxa    %g0, [%i0 + %l5]ASI_REAL
826         stxa    %g0, [%i0 + %l6]ASI_REAL
827         stxa    %g0, [%i0 + %l7]ASI_REAL
828         sub     %i1, 64, %i1
829         brnz,pt %i1, 1b
830           add   %i0, 64, %i0
831         membar #Sync
832         ret
833           restore
834
835 END(bzerophyspage)
836
837 ENTRY(init_mondo)
838         ldx     [PCPU(MONDO_DATA)], %g2
839         stx     %o0, [%g2]
840         stx     %o1, [%g2+8]
841         stx     %o2, [%g2+0x10]
842         stx     %o3, [%g2+0x18]
843         stx     %g0, [%g2+0x20]
844         stx     %g0, [%g2+0x28]
845         stx     %g0, [%g2+0x30]
846         stx     %g0, [%g2+0x38]
847         retl
848          membar #Sync 
849 END(init_mondo)
850
851
852 ENTRY(init_mondo_queue)                 
853         mov     CPU_MONDO_QUEUE_TAIL, %g2     
854         ldxa    [%g2]ASI_QUEUE, %g2     
855         mov     CPU_MONDO_QUEUE_HEAD, %g6     
856         stxa    %g2, [%g6]ASI_QUEUE
857         mov     DEV_MONDO_QUEUE_TAIL, %g2     
858         ldxa    [%g2]ASI_QUEUE, %g2     
859         mov     DEV_MONDO_QUEUE_HEAD, %g6     
860         stxa    %g2, [%g6]ASI_QUEUE 
861         retl
862           membar #Sync    
863 END(init_mondo_queue)
864         
865 #ifdef GPROF
866
867 ENTRY(user)
868         nop
869
870 ENTRY(btrap)
871         nop
872
873 ENTRY(etrap)
874         nop
875
876 ENTRY(bintr)
877         nop
878
879 ENTRY(eintr)
880         nop
881
882
883 /*
884  * XXX including sys/gmon.h in genassym.c is not possible due to uintfptr_t
885  * badness.
886  */
887 #define GM_STATE        0x0
888 #define GMON_PROF_OFF   3
889 #define GMON_PROF_HIRES 4
890
891         .globl  _mcount
892         .set    _mcount, __cyg_profile_func_enter
893
894 ENTRY(__cyg_profile_func_enter)
895         SET(_gmonparam, %o3, %o2)
896         lduw    [%o2 + GM_STATE], %o3
897         cmp     %o3, GMON_PROF_OFF
898         be,a,pn %icc, 1f
899          nop
900         SET(mcount, %o3, %o2)
901         jmpl    %o2, %g0
902          nop
903 1:      retl
904          nop
905 END(__cyg_profile_func_enter)
906
907 #ifdef GUPROF
908
909 ENTRY(__cyg_profile_func_exit)
910         SET(_gmonparam, %o3, %o2)
911         lduw    [%o2 + GM_STATE], %o3
912         cmp     %o3, GMON_PROF_HIRES
913         be,a,pn %icc, 1f
914          nop
915         SET(mexitcount, %o3, %o2)
916         jmpl    %o2, %g0
917          nop
918 1:      retl
919          nop
920 END(__cyg_profile_func_exit)
921
922 #endif /* GUPROF */
923
924 #endif /* GPROF */