pal.S revision 117161
1/*-
2 * Copyright (c) 2000-2001 Doug Rabson
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 *	$FreeBSD: head/sys/ia64/ia64/pal.S 110211 2003-02-01 22:50:09Z marcel $
27 */
28
29#include <machine/asm.h>
30
31	.data
32	.global ia64_pal_entry
33ia64_pal_entry:	.quad 0
34	.text
35
36/*
37 * struct ia64_pal_result ia64_call_pal_static(u_int64_t proc,
38 *	u_int64_t arg1, u_int64_t arg2, u_int64_t arg3)
39 */
40ENTRY(ia64_call_pal_static, 4)
41
42	.regstk	4,5,0,0
43palret	=	loc0
44entry	=	loc1
45rpsave	=	loc2
46pfssave =	loc3
47psrsave	=	loc4
48
49	alloc	pfssave=ar.pfs,4,5,0,0
50	;;
51	mov	rpsave=rp
52
53	movl	entry=@gprel(ia64_pal_entry)
541:	mov	palret=ip		// for return address
55	;;
56	add	entry=entry,gp
57	mov	psrsave=psr
58	mov	r28=in0			// procedure number
59	;;
60	ld8	entry=[entry]		// read entry point
61	mov	r29=in1			// copy arguments
62	mov	r30=in2
63	mov	r31=in3
64	;;
65	mov	b6=entry
66	add	palret=2f-1b,palret	// calculate return address
67	;;
68	mov	b0=palret
69	rsm	psr.i			// disable interrupts
70	;;
71	br.cond.sptk b6			// call into firmware
722:	mov	psr.l=psrsave
73	mov	rp=rpsave
74	mov	ar.pfs=pfssave
75	;;
76	srlz.d
77	br.ret.sptk rp
78
79END(ia64_call_pal_static)
80
81#ifdef _KERNEL
82
83/*
84 * struct ia64_pal_result ia64_call_pal_static_physical(u_int64_t proc,
85 *	u_int64_t arg1, u_int64_t arg2, u_int64_t arg3)
86 */
87ENTRY(ia64_call_pal_static_physical, 4)
88
89	.regstk	4,5,0,0
90palret	=	loc0
91entry	=	loc1
92rpsave	=	loc2
93pfssave =	loc3
94psrsave	=	loc4
95
96	alloc	pfssave=ar.pfs,4,5,0,0
97	;;
98	mov	rpsave=rp
99
100	movl	entry=@gprel(ia64_pal_entry)
1011:	mov	palret=ip		// for return address
102	;;
103	add	entry=entry,gp
104	mov	r28=in0			// procedure number
105	;;
106	ld8	entry=[entry]		// read entry point
107	mov	r29=in1			// copy arguments
108	mov	r30=in2
109	mov	r31=in3
110	;;
111	dep	entry=0,entry,61,3	// physical address
112	dep	palret=0,palret,61,3	// physical address
113	br.call.sptk.many rp=ia64_physical_mode
114	mov	psrsave=ret0
115	;;
116	mov	b6=entry
117	add	palret=2f-1b,palret	// calculate return address
118	;;
119	mov	b0=palret
120	br.cond.sptk b6			// call into firmware
121	;;
1222:	mov	r14=psrsave
123	;;
124	br.call.sptk.many rp=ia64_change_mode
125	;;
126	mov	rp=rpsave
127	mov	ar.pfs=pfssave
128	;;
129	br.ret.sptk rp
130
131END(ia64_call_pal_static_physical)
132
133#endif
134
135/*
136 * struct ia64_pal_result ia64_call_pal_stacked(u_int64_t proc,
137 *	u_int64_t arg1, u_int64_t arg2, u_int64_t arg3)
138 */
139ENTRY(ia64_call_pal_stacked, 4)
140
141	.regstk	4,4,4,0
142entry	=	loc0
143rpsave	=	loc1
144pfssave =	loc2
145psrsave	=	loc3
146
147	alloc	pfssave=ar.pfs,4,4,4,0
148	;;
149	mov	rpsave=rp
150	movl	entry=@gprel(ia64_pal_entry)
151	;;
152	add	entry=entry,gp
153	mov	psrsave=psr
154	mov	r28=in0			// procedure number
155	mov	out0=in0
156	;;
157	ld8	entry=[entry]		// read entry point
158	mov	out1=in1		// copy arguments
159	mov	out2=in2
160	mov	out3=in3
161	;;
162	mov	b6=entry
163	;;
164	rsm	psr.i			// disable interrupts
165	;;
166	br.call.sptk.many rp=b6		// call into firmware
167	mov	psr.l=psrsave
168	mov	rp=rpsave
169	mov	ar.pfs=pfssave
170	;;
171	srlz.d
172	br.ret.sptk rp
173
174END(ia64_call_pal_stacked)
175
176#ifdef _KERNEL
177
178/*
179 * struct ia64_pal_result ia64_call_pal_stacked_physical(u_int64_t proc,
180 *	u_int64_t arg1, u_int64_t arg2, u_int64_t arg3)
181 */
182ENTRY(ia64_call_pal_stacked_physical, 4)
183
184	.regstk	4,4,4,0
185entry	=	loc0
186rpsave	=	loc1
187pfssave =	loc2
188psrsave	=	loc3
189
190	alloc	pfssave=ar.pfs,4,4,4,0
191	;;
192	mov	rpsave=rp
193	movl	entry=@gprel(ia64_pal_entry)
194	;;
195	add	entry=entry,gp
196	mov	r28=in0			// procedure number
197	mov	out0=in0
198	;;
199	ld8	entry=[entry]		// read entry point
200	mov	out1=in1		// copy arguments
201	mov	out2=in2
202	mov	out3=in3
203	;;
204	dep	entry=0,entry,61,3	// physical address
205	br.call.sptk.many rp=ia64_physical_mode
206	mov	psrsave=ret0
207	;;
208	mov	b6=entry
209	;;
210	br.call.sptk.many rp=b6		// call into firmware
211	;;
212	mov	r14=psrsave
213	;;
214	br.call.sptk.many rp=ia64_change_mode
215	;;
216	mov	rp=rpsave
217	mov	ar.pfs=pfssave
218	;;
219	br.ret.sptk rp
220
221END(ia64_call_pal_stacked_physical)
222
223#endif
224