support.S revision 101955
180709Sjake/*-
280709Sjake * Copyright (c) 2001 Jake Burkholder.
380709Sjake * All rights reserved.
480709Sjake *
580709Sjake * Redistribution and use in source and binary forms, with or without
680709Sjake * modification, are permitted provided that the following conditions
780709Sjake * are met:
880709Sjake * 1. Redistributions of source code must retain the above copyright
980709Sjake *    notice, this list of conditions and the following disclaimer.
1080709Sjake * 2. Redistributions in binary form must reproduce the above copyright
1180709Sjake *    notice, this list of conditions and the following disclaimer in the
1280709Sjake *    documentation and/or other materials provided with the distribution.
1380709Sjake *
1481337Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1580709Sjake * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1680709Sjake * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1781337Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1880709Sjake * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1980709Sjake * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2080709Sjake * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2180709Sjake * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2280709Sjake * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2380709Sjake * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2480709Sjake * SUCH DAMAGE.
2580709Sjake *
2680709Sjake * $FreeBSD: head/sys/sparc64/sparc64/support.S 101955 2002-08-16 00:57:37Z jake $
2780709Sjake */
2880709Sjake
2980709Sjake#include <machine/asi.h>
3080709Sjake#include <machine/asmacros.h>
3182909Sjake#include <machine/ktr.h>
3282909Sjake#include <machine/pstate.h>
3380709Sjake
3480709Sjake#include "assym.s"
3580709Sjake
3688641Sjake	.register %g2, #ignore
3788641Sjake	.register %g3, #ignore
3888641Sjake	.register %g6, #ignore
3988641Sjake
4084193Sjake#define	E	/* empty */
4180709Sjake
4284193Sjake/*
4384193Sjake * Generate load and store instructions for the corresponding width and asi
4484193Sjake * (or not).  Note that we want to evaluate the macro args before
4584193Sjake * concatenating, so that E really turns into nothing.
4684193Sjake */
4780709Sjake#define	_LD(w, a)	ld ## w ## a
4880709Sjake#define	_ST(w, a)	st ## w ## a
4980709Sjake
5080709Sjake#define	LD(w, a)	_LD(w, a)
5180709Sjake#define	ST(w, a)	_ST(w, a)
5280709Sjake
5384193Sjake/*
5484193Sjake * Common code for copy routines.
5584193Sjake *
5684193Sjake * We use large macros to generate functions for each of the copy routines.
5784193Sjake * This allows the load and store instructions to be generated for the right
5884193Sjake * operation, asi or not.  It is possible to write an asi independent function
5984193Sjake * but this would require 2 expensive wrs in the main loop to switch %asi.
6084193Sjake * It would also screw up profiling (if we ever get it), but may save some I$.
6184193Sjake * We assume that either one of dasi and sasi is empty, or that they are both
6284193Sjake * the same (empty or non-empty).  It is up to the caller to set %asi.
6384193Sjake */
6484193Sjake
6584193Sjake/*
6684193Sjake * ASI independent implementation of copystr(9).
6784193Sjake * Used to implement copyinstr() and copystr().
6884193Sjake *
6984193Sjake * Return value is in %g1.
7084193Sjake */
7184193Sjake#define	_COPYSTR(src, dst, len, done, sa, sasi, da, dasi) \
7284193Sjake	brz	len, 4f ; \
7384193Sjake	 mov	src, %g2 ; \
7484193Sjake1:	deccc	1, len ; \
7584193Sjake	bl,a,pn	%xcc, 3f ; \
7684193Sjake	 nop ; \
7784193Sjake	LD(ub, sa) [src] sasi, %g1 ; \
7884193Sjake	ST(b, da) %g1, [dst] dasi ; \
7984193Sjake	brz,pn	%g1, 3f ; \
8084193Sjake	 inc	src ; \
8184193Sjake	b	%xcc, 1b ; \
8280709Sjake	 inc	dst ; \
8384193Sjake2:	mov	ENAMETOOLONG, %g1 ; \
8484193Sjake3:	sub	src, %g2, %g2 ; \
8584193Sjake	brnz,a	done, 4f ; \
8684193Sjake	 stx	%g2, [done] ; \
8784193Sjake4:
8880709Sjake
8984193Sjake/*
9084193Sjake * ASI independent implementation of memset(3).
9186520Sjake * Used to implement bzero(), memset() and aszero().
9284193Sjake *
9384193Sjake * If the pattern is non-zero, duplicate it to fill 64 bits.
9484193Sjake * Store bytes until dst is 8-byte aligned, then store 8 bytes.
9584193Sjake * It has yet to be determined how much unrolling is beneficial.
9684193Sjake * Could also read and compare before writing to minimize snoop traffic.
9784193Sjake *
9884193Sjake * XXX bzero() should be implemented as
9984193Sjake * #define bzero(dst, len) (void)memset((dst), 0, (len))
10084193Sjake * if at all.
10184193Sjake */
10284193Sjake#define	_MEMSET(dst, pat, len, da, dasi) \
10384193Sjake	brlez,pn len, 5f ; \
10484193Sjake	 and	pat, 0xff, pat ; \
10584193Sjake	brz,pt	pat, 1f ; \
10684193Sjake	 sllx	pat, 8, %g1 ; \
10784193Sjake	or	pat, %g1, pat ; \
10884193Sjake	sllx	pat, 16, %g1 ; \
10984193Sjake	or	pat, %g1, pat ; \
11084193Sjake	sllx	pat, 32, %g1 ; \
11184193Sjake	or	pat, %g1, pat ; \
112100841Sjake	_ALIGN_TEXT ; \
11384193Sjake1:	deccc	1, len ; \
11484193Sjake	bl,pn	%xcc, 5f ; \
11584193Sjake	 btst	7, dst ; \
11684193Sjake	bz,a,pt	%xcc, 2f ; \
11784193Sjake	 inc	1, len ; \
11884193Sjake	ST(b, da) pat, [dst] dasi ; \
11984193Sjake	b	%xcc, 1b ; \
12084193Sjake	 inc	dst ; \
121100841Sjake	_ALIGN_TEXT ; \
12284193Sjake2:	deccc	32, len ; \
12384193Sjake	bl,a,pn	%xcc, 3f ; \
12484193Sjake	 inc	32, len ; \
12584193Sjake	ST(x, da) pat, [dst] dasi ; \
12684193Sjake	ST(x, da) pat, [dst + 8] dasi ; \
12784193Sjake	ST(x, da) pat, [dst + 16] dasi ; \
12884193Sjake	ST(x, da) pat, [dst + 24] dasi ; \
12984193Sjake	b	%xcc, 2b ; \
13084193Sjake	 inc	32, dst ; \
131100841Sjake	_ALIGN_TEXT ; \
13284193Sjake3:	deccc	8, len ; \
13384193Sjake	bl,a,pn	%xcc, 4f ; \
13484193Sjake	 inc	8, len ; \
13584193Sjake	ST(x, da) pat, [dst] dasi ; \
13684193Sjake	b	%xcc, 3b ; \
13784193Sjake	 inc	8, dst ; \
138100841Sjake	_ALIGN_TEXT ; \
13984193Sjake4:	deccc	1, len ; \
14084193Sjake	bl,a,pn	%xcc, 5f ; \
14184193Sjake	 nop ; \
14284193Sjake	ST(b, da) pat, [dst] dasi ; \
14384193Sjake	b	%xcc, 4b ; \
14484193Sjake	 inc	1, dst ; \
14584193Sjake5:
14680709Sjake
14784193Sjake/*
14884193Sjake * ASI independent implementation of memcpy(3).
14986520Sjake * Used to implement bcopy(), copyin(), copyout(), memcpy(), ascopy(),
15086520Sjake * ascopyfrom() and ascopyto().
15184193Sjake *
15284193Sjake * Transfer bytes until dst is 8-byte aligned.  If src is then also 8 byte
15384193Sjake * aligned, transfer 8 bytes, otherwise finish with bytes.  The unaligned
15484193Sjake * case could be optimized, but it is expected that this is the uncommon
15584193Sjake * case and of questionable value.  The code to do so is also rather large
15688641Sjake * and ugly.  It has yet to be determined how much unrolling is beneficial.
15784193Sjake *
15884193Sjake * XXX bcopy() must also check for overlap.  This is stupid.
15984193Sjake * XXX bcopy() should be implemented as
16084193Sjake * #define bcopy(src, dst, len) (void)memcpy((dst), (src), (len))
16184193Sjake * if at all.
16284193Sjake */
16384193Sjake#define	_MEMCPY(dst, src, len, da, dasi, sa, sasi) \
16484193Sjake1:	deccc	1, len ; \
16584193Sjake	bl,pn	%xcc, 6f ; \
16684193Sjake	 btst	7, dst ; \
16784193Sjake	bz,a,pt	%xcc, 2f ; \
16884193Sjake	 inc	1, len ; \
16984193Sjake	LD(ub, sa) [src] sasi, %g1 ; \
17080709Sjake	ST(b, da) %g1, [dst] dasi ; \
17184193Sjake	inc	1, src ; \
17284193Sjake	b	%xcc, 1b ; \
17384193Sjake	 inc	1, dst ; \
174100841Sjake	_ALIGN_TEXT ; \
17584193Sjake2:	btst	7, src ; \
17684193Sjake	bz,a,pt	%xcc, 3f ; \
17784193Sjake	 nop ; \
17884193Sjake	b,a	%xcc, 5f ; \
179100841Sjake	_ALIGN_TEXT ; \
18084193Sjake3:	deccc	32, len ; \
18184193Sjake	bl,a,pn	%xcc, 4f ; \
18284193Sjake	 inc	32, len ; \
18384193Sjake	LD(x, sa) [src] sasi, %g1 ; \
18484193Sjake	LD(x, sa) [src + 8] sasi, %g2 ; \
18584193Sjake	LD(x, sa) [src + 16] sasi, %g3 ; \
18684193Sjake	LD(x, sa) [src + 24] sasi, %g4 ; \
18784193Sjake	ST(x, da) %g1, [dst] dasi ; \
18884193Sjake	ST(x, da) %g2, [dst + 8] dasi ; \
18984193Sjake	ST(x, da) %g3, [dst + 16] dasi ; \
19084193Sjake	ST(x, da) %g4, [dst + 24] dasi ; \
19184193Sjake	inc	32, src ; \
19284193Sjake	b	%xcc, 3b ; \
19384193Sjake	 inc	32, dst ; \
194100841Sjake	_ALIGN_TEXT ; \
19584193Sjake4:	deccc	8, len ; \
19684193Sjake	bl,a,pn	%xcc, 5f ; \
19784193Sjake	 inc	8, len ; \
19884193Sjake	LD(x, sa) [src] sasi, %g1 ; \
19984193Sjake	ST(x, da) %g1, [dst] dasi ; \
20084193Sjake	inc	8, src ; \
20184193Sjake	b	%xcc, 4b ; \
20284193Sjake	 inc	8, dst ; \
203100841Sjake	_ALIGN_TEXT ; \
20484193Sjake5:	deccc	1, len ; \
20584193Sjake	bl,a,pn	%xcc, 6f ; \
20684193Sjake	 nop ; \
20784193Sjake	LD(ub, sa) [src] sasi, %g1 ; \
20884193Sjake	ST(b, da) %g1, [dst] dasi ; \
20980709Sjake	inc	src ; \
21084193Sjake	b	%xcc, 5b ; \
21180709Sjake	 inc	dst ; \
21284193Sjake6:
21380709Sjake
214101955Sjake/*
215101955Sjake * void ascopy(u_long asi, vm_offset_t src, vm_offset_t dst, size_t len)
216101955Sjake */
217101955SjakeENTRY(ascopy)
218101955Sjake	wr	%o0, 0, %asi
219101955Sjake	_MEMCPY(%o2, %o1, %o3, a, %asi, a, %asi)
220101955Sjake	retl
221101955Sjake	 nop
222101955SjakeEND(ascopy)
22380709Sjake
224101955Sjake/*
225101955Sjake * void ascopyfrom(u_long sasi, vm_offset_t src, caddr_t dst, size_t len)
226101955Sjake */
227101955SjakeENTRY(ascopyfrom)
228101955Sjake	wr	%o0, 0, %asi
229101955Sjake	_MEMCPY(%o2, %o1, %o3, E, E, a, %asi)
230101955Sjake	retl
231101955Sjake	 nop
232101955SjakeEND(ascopyfrom)
23380709Sjake
234101955Sjake/*
235101955Sjake * void ascopyto(caddr_t src, u_long dasi, vm_offset_t dst, size_t len)
236101955Sjake */
237101955SjakeENTRY(ascopyto)
238101955Sjake	wr	%o1, 0, %asi
239101955Sjake	_MEMCPY(%o2, %o0, %o3, a, %asi, E, E)
240101955Sjake	retl
241101955Sjake	 nop
242101955SjakeEND(ascopyto)
24380709Sjake
244101955Sjake/*
245101955Sjake * void aszero(u_long asi, vm_offset_t pa, size_t len)
246101955Sjake */
247101955SjakeENTRY(aszero)
248101955Sjake	wr	%o0, 0, %asi
249101955Sjake	_MEMSET(%o1, %g0, %o2, a, %asi)
250101955Sjake	retl
251101955Sjake	 nop
252101955SjakeEND(aszero)
25380709Sjake
25480709Sjake/*
25584193Sjake * int bcmp(const void *b1, const void *b2, size_t len)
25680709Sjake */
25780709SjakeENTRY(bcmp)
25880709Sjake	brz,pn	%o2, 2f
25980709Sjake	 clr	%o3
26080709Sjake1:	ldub	[%o0 + %o3], %o4
26180709Sjake	ldub	[%o1 + %o3], %o5
26280709Sjake	cmp	%o4, %o5
26384193Sjake	bne,pn	%xcc, 2f
26480709Sjake	 inc	%o3
26580709Sjake	deccc	%o2
26680709Sjake	bne,pt	%xcc, 1b
26780709Sjake	 nop
26880709Sjake2:	retl
26980709Sjake	 mov	%o2, %o0
27080709SjakeEND(bcmp)
27180709Sjake
27280709Sjake/*
27380709Sjake * void bcopy(const void *src, void *dst, size_t len)
27480709Sjake */
27586520SjakeENTRY(bcopy)
27684193SjakeENTRY(ovbcopy)
27784193Sjake	/*
27884193Sjake	 * Check for overlap, and copy backwards if so.
27984193Sjake	 */
28084193Sjake	sub	%o1, %o0, %g1
28184193Sjake	cmp	%g1, %o2
28284193Sjake	bgeu,a,pt %xcc, 3f
28384193Sjake	 nop
28484193Sjake
28584193Sjake	/*
28684193Sjake	 * Copy backwards.
28784193Sjake	 */
28884193Sjake	add	%o0, %o2, %o0
28984193Sjake	add	%o1, %o2, %o1
29084193Sjake1:	deccc	1, %o2
29184193Sjake	bl,a,pn	%xcc, 2f
29284193Sjake	 nop
29384193Sjake	dec	1, %o0
29484193Sjake	ldub	[%o0], %g1
29584193Sjake	dec	1, %o1
29684193Sjake	b	%xcc, 1b
29784193Sjake	 stb	%g1, [%o1]
29884193Sjake2:	retl
29984193Sjake	 nop
30084193Sjake
30184193Sjake	/*
30284193Sjake	 * Do the fast version.
30384193Sjake	 */
30484193Sjake3:	_MEMCPY(%o1, %o0, %o2, E, E, E, E)
30580709Sjake	retl
30680709Sjake	 nop
30780709SjakeEND(bcopy)
30880709Sjake
30980709Sjake/*
31084193Sjake * void bzero(void *b, size_t len)
31180709Sjake */
31284193SjakeENTRY(bzero)
31384193Sjake	_MEMSET(%o0, %g0, %o1, E, E)
31480709Sjake	retl
31580709Sjake	 nop
31684193SjakeEND(bzero)
31780709Sjake
31880709Sjake/*
319101955Sjake * int copystr(const void *src, void *dst, size_t len, size_t *done)
32080709Sjake */
321101955SjakeENTRY(copystr)
322101955Sjake	_COPYSTR(%o0, %o1, %o2, %o3, E, E, E, E)
32384193Sjake	retl
324101955Sjake	 mov	%g1, %o0
325101955SjakeEND(copystr)
32684193Sjake
32784193Sjake/*
32880709Sjake * void *memcpy(void *dst, const void *src, size_t len)
32980709Sjake */
33080709SjakeENTRY(memcpy)
33184193Sjake	mov	%o0, %o3
33284193Sjake	_MEMCPY(%o3, %o1, %o2, E, E, E, E)
33380709Sjake	retl
33480709Sjake	 nop
33580709SjakeEND(memcpy)
33680709Sjake
33780709Sjake/*
33884193Sjake * void *memset(void *b, int c, size_t len)
33984193Sjake */
34084193SjakeENTRY(memset)
34184193Sjake	mov	%o0, %o3
34284193Sjake	_MEMSET(%o3, %o1, %o2, E, E)
34384193Sjake	retl
34484193Sjake	 nop
34584193SjakeEND(memset)
34684193Sjake
347101955Sjake	.globl	copy_nofault_begin
348101955Sjakecopy_nofault_begin:
349101955Sjake	nop
350101955Sjake
35184193Sjake/*
35280709Sjake * int copyin(const void *uaddr, void *kaddr, size_t len)
35380709Sjake */
35480709SjakeENTRY(copyin)
35584193Sjake	wr	%g0, ASI_AIUP, %asi
35684193Sjake	_MEMCPY(%o1, %o0, %o2, E, E, a, %asi)
35780709Sjake	retl
35880709Sjake	 clr	%o0
35980709SjakeEND(copyin)
36080709Sjake
36180709Sjake/*
36280709Sjake * int copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done)
36380709Sjake */
36480709SjakeENTRY(copyinstr)
36584193Sjake	wr	%g0, ASI_AIUP, %asi
36684193Sjake	_COPYSTR(%o0, %o1, %o2, %o3, a, %asi, E, E)
36780709Sjake	retl
36884193Sjake	 mov	%g1, %o0
36980709SjakeEND(copyinstr)
37080709Sjake
37180709Sjake/*
37280709Sjake * int copyout(const void *kaddr, void *uaddr, size_t len)
37380709Sjake */
37480709SjakeENTRY(copyout)
37584193Sjake	wr	%g0, ASI_AIUP, %asi
37684193Sjake	_MEMCPY(%o1, %o0, %o2, a, %asi, E, E)
37780709Sjake	retl
37880709Sjake	 clr	%o0
37980709SjakeEND(copyout)
38080709Sjake
381101955Sjake	.globl	copy_nofault_end
382101955Sjakecopy_nofault_end:
383101955Sjake	nop
384101955Sjake
385101955SjakeENTRY(copy_fault)
38680709Sjake	retl
38780709Sjake	 mov	EFAULT, %o0
388101955SjakeEND(copy_fault)
38980709Sjake
390101955Sjake	.globl	fs_nofault_begin
391101955Sjakefs_nofault_begin:
392101955Sjake	nop
39380709Sjake
39480709Sjake/*
395101955Sjake * Chatty aliases for fetch, store functions.
39680709Sjake */
397101955Sjake	.globl	fubyte, fusword, fuword, subyte, susword, suword
398101955Sjake	.set	fubyte, fuword8
399101955Sjake	.set	fusword, fuword16
400101955Sjake	.set	fuword, fuword64
401101955Sjake	.set	subyte, suword8
402101955Sjake	.set	susword, suword16
403101955Sjake	.set	suword, suword64
40480709Sjake
40580709Sjake/*
406101955Sjake * int fuword8(const void *base)
40780709Sjake */
408101955SjakeENTRY(fuword8)
409101955Sjake	retl
410101955Sjake	 lduba	[%o0] ASI_AIUP, %o0
411101955SjakeEND(fuword8)
41280709Sjake
41380709Sjake/*
414101955Sjake * int fuword16(const void *base)
41580709Sjake */
41698511SjakeENTRY(fuword16)
417101955Sjake	retl
418101955Sjake	 lduha	[%o0] ASI_AIUP, %o0
41998511SjakeEND(fuword16)
42080709Sjake
42180709Sjake/*
42298511Sjake * int32_t fuword32(const void *base)
42397307Sdfr */
42498511SjakeENTRY(fuword32)
425101955Sjake	retl
426101955Sjake	 lduwa	[%o0] ASI_AIUP, %o0
42798511SjakeEND(fuword32)
42898511Sjake
42998511Sjake/*
43098511Sjake * int64_t fuword64(const void *base)
43198511Sjake */
43297307SdfrENTRY(fuword64)
433101955Sjake	retl
434101955Sjake	 ldxa	[%o0] ASI_AIUP, %o0
43597307SdfrEND(fuword64)
43697307Sdfr
43797307Sdfr/*
438101955Sjake * int suword8(const void *base, int word)
43980709Sjake */
440101955SjakeENTRY(suword8)
441101955Sjake	stba	%o1, [%o0] ASI_AIUP
442101955Sjake	retl
443101955Sjake	 clr	%o0
444101955SjakeEND(suword8)
44580709Sjake
44680709Sjake/*
447101955Sjake * int suword16(const void *base, int word)
44880709Sjake */
44998511SjakeENTRY(suword16)
450101955Sjake	stha	%o1, [%o0] ASI_AIUP
451101955Sjake	retl
452101955Sjake	 clr	%o0
45398511SjakeEND(suword16)
45480709Sjake
45597307Sdfr/*
45698511Sjake * int suword32(const void *base, int32_t word)
45797307Sdfr */
45898511SjakeENTRY(suword32)
459101955Sjake	stwa	%o1, [%o0] ASI_AIUP
460101955Sjake	retl
461101955Sjake	 clr	%o0
46298511SjakeEND(suword32)
46398511Sjake
46498511Sjake/*
46598511Sjake * int suword64(const void *base, int64_t word)
46698511Sjake */
46797307SdfrENTRY(suword64)
468101955Sjake	stxa	%o1, [%o0] ASI_AIUP
469101955Sjake	retl
470101955Sjake	 clr	%o0
47197307SdfrEND(suword64)
47297307Sdfr
473101955Sjake	.globl	fs_nofault_intr_begin
474101955Sjakefs_nofault_intr_begin:
475101955Sjake	nop
476101955Sjake
477101955Sjake/*
478101955Sjake * int fuswintr(const void *base)
479101955Sjake */
480101955SjakeENTRY(fuswintr)
48185238Sjake	retl
482101955Sjake	 lduha	[%o0] ASI_AIUP, %o0
483101955SjakeEND(fuswintr)
48485238Sjake
485101955Sjake/*
486101955Sjake * int suswintr(const void *base, int word)
487101955Sjake */
488101955SjakeENTRY(suswintr)
489101955Sjake	stha	%o1, [%o0] ASI_AIUP
49080709Sjake	retl
491101955Sjake	 clr	%o0
492101955SjakeEND(suswintr)
49380709Sjake
494101955Sjake	.globl	fs_nofault_intr_end
495101955Sjakefs_nofault_intr_end:
496101955Sjake	nop
497101955Sjake
498101955Sjake	.globl	fs_nofault_end
499101955Sjakefs_nofault_end:
500101955Sjake	nop
501101955Sjake
502101955SjakeENTRY(fs_fault)
50385238Sjake	retl
50485238Sjake	 mov	-1, %o0
505101955SjakeEND(fsfault)
50685238Sjake
50780709SjakeENTRY(longjmp)
50880709Sjake	set	1, %g3
50980709Sjake	movrz	%o1, %o1, %g3
51080709Sjake	mov	%o0, %g1
51188641Sjake	ldx	[%g1 + _JB_FP], %g2
51280709Sjake1:	cmp	%fp, %g2
51380709Sjake	bl,a,pt	%xcc, 1b
51480709Sjake	 restore
51580709Sjake	bne,pn	%xcc, 2f
51688641Sjake	 ldx	[%g1 + _JB_SP], %o2
51780709Sjake	cmp	%o2, %sp
51880709Sjake	blt,pn	%xcc, 2f
51980709Sjake	 movge	%xcc, %o2, %sp
52088641Sjake	ldx	[%g1 + _JB_PC], %o7
52188641Sjake	retl
52280709Sjake	 mov	%g3, %o0
52380709Sjake2:	PANIC("longjmp botch", %l1)
52480709SjakeEND(longjmp)
52580709Sjake
52680709SjakeENTRY(setjmp)
52788641Sjake	stx	%sp, [%o0 + _JB_SP]
52888641Sjake	stx	%o7, [%o0 + _JB_PC]
52988641Sjake	stx	%fp, [%o0 + _JB_FP]
53080709Sjake	retl
53180709Sjake	 clr	%o0
53280709SjakeEND(setjmp)
53380709Sjake
53480709Sjake/*
53580709Sjake * void openfirmware(cell_t args[])
53680709Sjake */
53780709SjakeENTRY(openfirmware)
53884193Sjake	save	%sp, -CCFSZ, %sp
53986520Sjake	SET(ofw_vec, %l7, %l6)
54081183Sjake	ldx	[%l6], %l6
54181386Sjake	rdpr	%pil, %l7
54284193Sjake	wrpr	%g0, PIL_TICK, %pil
54381183Sjake	call	%l6
54480709Sjake	 mov	%i0, %o0
54581386Sjake	wrpr	%l7, 0, %pil
54684193Sjake	ret
54784193Sjake	 restore %o0, %g0, %o0
54880709SjakeEND(openfirmware)
54986147Stmm
55086147Stmm/*
55186147Stmm * void ofw_exit(cell_t args[])
55286147Stmm */
55386147StmmENTRY(openfirmware_exit)
55486147Stmm	save	%sp, -CCFSZ, %sp
55586147Stmm	flushw
55686147Stmm	wrpr	%g0, PIL_TICK, %pil
55786520Sjake	SET(ofw_tba, %l7, %l5)
55886147Stmm	ldx	[%l5], %l5
55986147Stmm	wrpr	%l5, 0, %tba			! restore the ofw trap table
56086520Sjake	SET(ofw_vec, %l7, %l6)
56186147Stmm	ldx	[%l6], %l6
56286520Sjake	SET(kstack0 + KSTACK_PAGES * PAGE_SIZE - PCB_SIZEOF, %l7, %l0)
56386147Stmm	sub	%l0, SPOFF, %fp			! setup a stack in a locked page
56486147Stmm	sub	%l0, SPOFF + CCFSZ, %sp
56586147Stmm	mov     AA_DMMU_PCXR, %l3		! set context 0
56686147Stmm	stxa    %g0, [%l3] ASI_DMMU
56788641Sjake	membar	#Sync
56886147Stmm	wrpr	%g0, 0, %tl			! force trap level 0
56986147Stmm	call	%l6
57086147Stmm	 mov	%i0, %o0
57186147Stmm	! never to return
57286147StmmEND(openfirmware_exit)
573100841Sjake
574100910Sjake#ifdef GPROF
575100841Sjake
576100910SjakeENTRY(user)
577100910Sjake	nop
578100910Sjake
579100910SjakeENTRY(btrap)
580100910Sjake	nop
581100910Sjake
582100910SjakeENTRY(etrap)
583100910Sjake	nop
584100910Sjake
585100910SjakeENTRY(bintr)
586100910Sjake	nop
587100910Sjake
588100910SjakeENTRY(eintr)
589100910Sjake	nop
590100910Sjake
591100910Sjake
592100841Sjake/*
593100841Sjake * XXX including sys/gmon.h in genassym.c is not possible due to uintfptr_t
594100841Sjake * badness.
595100841Sjake */
596100841Sjake#define	GM_STATE	0x0
597100841Sjake#define	GMON_PROF_OFF	3
598100841Sjake#define	GMON_PROF_HIRES	4
599100841Sjake
600100910Sjake	.globl	_mcount
601100910Sjake	.set	_mcount, __cyg_profile_func_enter
602100910Sjake
603100910SjakeENTRY(__cyg_profile_func_enter)
604100841Sjake	SET(_gmonparam, %o3, %o2)
605100841Sjake	lduw    [%o2 + GM_STATE], %o3
606100841Sjake	cmp     %o3, GMON_PROF_OFF
607100841Sjake	be,a,pn %icc, 1f
608100841Sjake	 nop
609100841Sjake	SET(mcount, %o3, %o2)
610100841Sjake	jmpl	%o2, %g0
611100841Sjake	 nop
612100841Sjake1:      retl
613100841Sjake	 nop
614100910SjakeEND(__cyg_profile_func_enter)
615100841Sjake
616100910Sjake#ifdef GUPROF
617100910Sjake
618100910SjakeENTRY(__cyg_profile_func_exit)
619100841Sjake	SET(_gmonparam, %o3, %o2)
620100841Sjake	lduw    [%o2 + GM_STATE], %o3
621100841Sjake	cmp     %o3, GMON_PROF_HIRES
622100841Sjake	be,a,pn %icc, 1f
623100841Sjake	 nop
624100841Sjake	SET(mexitcount, %o3, %o2)
625100841Sjake	jmpl	%o2, %g0
626100841Sjake	 nop
627100841Sjake1:      retl
628100841Sjake	 nop
629100910SjakeEND(__cyg_profile_func_exit)
630100841Sjake
631100910Sjake#endif /* GUPROF */
632100841Sjake
633100910Sjake#endif /* GPROF */
634