xref: /netbsd-src/sys/arch/ia64/ia64/pal.S (revision 6ec65fcfd4fc14dd006a1488ebb10c8b067ba270)
1/*	$NetBSD: pal.S,v 1.2 2023/10/06 11:45:16 skrll Exp $	*/
2
3/*-
4 * Copyright (c) 2000-2001 Doug Rabson
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 *	$FreeBSD$
29 */
30
31#include <machine/asm.h>
32
33	.data
34	.global ia64_pal_entry
35ia64_pal_entry:	.quad 0
36	.text
37
38/*
39 * struct ia64_pal_result ia64_call_pal_static(u_int64_t proc,
40 *	u_int64_t arg1, u_int64_t arg2, u_int64_t arg3)
41 */
42ENTRY(ia64_call_pal_static, 4)
43
44	.regstk	4,5,0,0
45palret	=	loc0
46entry	=	loc1
47rpsave	=	loc2
48pfssave =	loc3
49psrsave	=	loc4
50
51	alloc	pfssave=ar.pfs,4,5,0,0
52	;;
53	mov	rpsave=rp
54
55	movl	entry=@gprel(ia64_pal_entry)
561:	mov	palret=ip		// for return address
57	;;
58	add	entry=entry,gp
59	mov	psrsave=psr
60	mov	r28=in0			// procedure number
61	;;
62	ld8	entry=[entry]		// read entry point
63	mov	r29=in1			// copy arguments
64	mov	r30=in2
65	mov	r31=in3
66	;;
67	mov	b6=entry
68	add	palret=2f-1b,palret	// calculate return address
69	;;
70	mov	b0=palret
71	rsm	psr.i			// disable interrupts
72	;;
73	br.cond.sptk b6			// call into firmware
742:	mov	psr.l=psrsave
75	mov	rp=rpsave
76	mov	ar.pfs=pfssave
77	;;
78	srlz.d
79	br.ret.sptk rp
80
81END(ia64_call_pal_static)
82
83#ifdef _KERNEL
84
85/*
86 * struct ia64_pal_result ia64_call_pal_static_physical(u_int64_t proc,
87 *	u_int64_t arg1, u_int64_t arg2, u_int64_t arg3)
88 */
89ENTRY(ia64_call_pal_static_physical, 4)
90
91	.regstk	4,5,0,0
92palret	=	loc0
93entry	=	loc1
94rpsave	=	loc2
95pfssave =	loc3
96psrsave	=	loc4
97
98	alloc	pfssave=ar.pfs,4,5,0,0
99	;;
100	mov	rpsave=rp
101
102	movl	entry=@gprel(ia64_pal_entry)
1031:	mov	palret=ip		// for return address
104	;;
105	add	entry=entry,gp
106	mov	r28=in0			// procedure number
107	;;
108	ld8	entry=[entry]		// read entry point
109	mov	r29=in1			// copy arguments
110	mov	r30=in2
111	mov	r31=in3
112	;;
113	dep	entry=0,entry,61,3	// physical address
114	dep	palret=0,palret,61,3	// physical address
115	br.call.sptk.many rp=ia64_physical_mode
116	mov	psrsave=ret0
117	;;
118	mov	b6=entry
119	add	palret=2f-1b,palret	// calculate return address
120	;;
121	mov	b0=palret
122	br.cond.sptk b6			// call into firmware
123	;;
1242:	mov	r14=psrsave
125	;;
126	br.call.sptk.many rp=ia64_change_mode
127	;;
128	mov	rp=rpsave
129	mov	ar.pfs=pfssave
130	;;
131	br.ret.sptk rp
132
133END(ia64_call_pal_static_physical)
134
135#endif
136
137/*
138 * struct ia64_pal_result ia64_call_pal_stacked(u_int64_t proc,
139 *	u_int64_t arg1, u_int64_t arg2, u_int64_t arg3)
140 */
141ENTRY(ia64_call_pal_stacked, 4)
142
143	.regstk	4,4,4,0
144entry	=	loc0
145rpsave	=	loc1
146pfssave =	loc2
147psrsave	=	loc3
148
149	alloc	pfssave=ar.pfs,4,4,4,0
150	;;
151	mov	rpsave=rp
152	movl	entry=@gprel(ia64_pal_entry)
153	;;
154	add	entry=entry,gp
155	mov	psrsave=psr
156	mov	r28=in0			// procedure number
157	mov	out0=in0
158	;;
159	ld8	entry=[entry]		// read entry point
160	mov	out1=in1		// copy arguments
161	mov	out2=in2
162	mov	out3=in3
163	;;
164	mov	b6=entry
165	;;
166	rsm	psr.i			// disable interrupts
167	;;
168	br.call.sptk.many rp=b6		// call into firmware
169	mov	psr.l=psrsave
170	mov	rp=rpsave
171	mov	ar.pfs=pfssave
172	;;
173	srlz.d
174	br.ret.sptk rp
175
176END(ia64_call_pal_stacked)
177
178#ifdef _KERNEL
179
180/*
181 * struct ia64_pal_result ia64_call_pal_stacked_physical(u_int64_t proc,
182 *	u_int64_t arg1, u_int64_t arg2, u_int64_t arg3)
183 */
184ENTRY(ia64_call_pal_stacked_physical, 4)
185
186	.regstk	4,4,4,0
187entry	=	loc0
188rpsave	=	loc1
189pfssave =	loc2
190psrsave	=	loc3
191
192	alloc	pfssave=ar.pfs,4,4,4,0
193	;;
194	mov	rpsave=rp
195	movl	entry=@gprel(ia64_pal_entry)
196	;;
197	add	entry=entry,gp
198	mov	r28=in0			// procedure number
199	mov	out0=in0
200	;;
201	ld8	entry=[entry]		// read entry point
202	mov	out1=in1		// copy arguments
203	mov	out2=in2
204	mov	out3=in3
205	;;
206	dep	entry=0,entry,61,3	// physical address
207	br.call.sptk.many rp=ia64_physical_mode
208	mov	psrsave=ret0
209	;;
210	mov	b6=entry
211	;;
212	br.call.sptk.many rp=b6		// call into firmware
213	;;
214	mov	r14=psrsave
215	;;
216	br.call.sptk.many rp=ia64_change_mode
217	;;
218	mov	rp=rpsave
219	mov	ar.pfs=pfssave
220	;;
221	br.ret.sptk rp
222
223END(ia64_call_pal_stacked_physical)
224
225#endif
226