3 * IA-64 Processor Programmers Reference Vol 2
5 * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
6 * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
7 * Copyright (C) 1999-2001, 2003 Hewlett-Packard Co
8 * David Mosberger <davidm@hpl.hp.com>
9 * Stephane Eranian <eranian@hpl.hp.com>
11 * 05/22/2000 eranian Added support for stacked register calls
12 * 05/24/2000 eranian Added support for physical mode static calls
15 #include <asm/asmmacro.h>
16 #include <asm/processor.h>
20 data8 ia64_pal_default_handler
24 * Set the PAL entry point address. This could be written in C code, but we do it here
25 * to keep it all in one module (besides, it's so trivial that it's
28 * in0 Address of the PAL entry point (text address, NOT a function descriptor).
30 GLOBAL_ENTRY(ia64_pal_handler_init)
31 alloc r3=ar.pfs,1,0,0,0
32 movl r2=pal_entry_point
36 END(ia64_pal_handler_init)
39 * Default PAL call handler. This needs to be coded in assembly because it uses
40 * the static calling convention, i.e., the RSE may not be used and calls are
41 * done via "br.cond" (not "br.call").
43 GLOBAL_ENTRY(ia64_pal_default_handler)
46 END(ia64_pal_default_handler)
49 * Make a PAL call using the static calling convention.
51 * in0 Index of PAL service
52 * in1 - in3 Remaining PAL arguments
53 * in4 1 ==> clear psr.ic, 0 ==> don't clear psr.ic
56 GLOBAL_ENTRY(ia64_pal_call_static)
57 .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(6)
58 alloc loc1 = ar.pfs,6,90,0,0
59 movl loc2 = pal_entry_point
66 ld8 loc2 = [loc2] // loc2 <- entry point
67 tbit.nz p6,p7 = in4, 0
75 (p6) rsm psr.i | psr.ic
88 srlz.d // seralize restoration of psr.l
90 END(ia64_pal_call_static)
93 * Make a PAL call using the stacked registers calling convention.
96 * in0 Index of PAL service
97 * in2 - in3 Remaning PAL arguments
99 GLOBAL_ENTRY(ia64_pal_call_stacked)
100 .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
101 alloc loc1 = ar.pfs,5,4,87,0
102 movl loc2 = pal_entry_point
104 mov r28 = in0 // Index MUST be copied to r28
105 mov out0 = in0 // AND in0 of PAL function
109 ld8 loc2 = [loc2] // loc2 <- entry point
118 br.call.sptk.many rp=b7 // now make the call
119 .ret0: mov psr.l = loc3
123 srlz.d // serialize restoration of psr.l
125 END(ia64_pal_call_stacked)
128 * Make a physical mode PAL call using the static registers calling convention.
131 * in0 Index of PAL service
132 * in2 - in3 Remaning PAL arguments
134 * PSR_LP, PSR_TB, PSR_ID, PSR_DA are never set by the kernel.
135 * So we don't need to clear them.
137 #define PAL_PSR_BITS_TO_CLEAR \
138 (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_DB | IA64_PSR_RT | \
139 IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | \
140 IA64_PSR_DFL | IA64_PSR_DFH)
142 #define PAL_PSR_BITS_TO_SET \
146 GLOBAL_ENTRY(ia64_pal_call_phys_static)
147 .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(6)
148 alloc loc1 = ar.pfs,6,90,0,0
149 movl loc2 = pal_entry_point
151 mov r28 = in0 // copy procedure index
152 mov r8 = ip // save ip to compute branch
153 mov loc0 = rp // save rp
157 ld8 loc2 = [loc2] // loc2 <- entry point
158 mov r29 = in1 // first argument
159 mov r30 = in2 // copy arg2
160 mov r31 = in3 // copy arg3
162 mov loc3 = psr // save psr
163 adds r8 = 1f-1b,r8 // calculate return address for call
165 mov loc4=ar.rsc // save RSE configuration
166 dep.z loc2=loc2,0,61 // convert pal entry point to physical
167 tpa r8=r8 // convert rp to physical
169 mov b7 = loc2 // install target to branch reg
170 mov ar.rsc=0 // put RSE in enforced lazy, LE mode
171 movl r16=PAL_PSR_BITS_TO_CLEAR
172 movl r17=PAL_PSR_BITS_TO_SET
174 or loc3=loc3,r17 // add in psr the bits to set
176 andcm r16=loc3,r16 // removes bits to clear from psr
177 br.call.sptk.many rp=ia64_switch_mode_phys
178 .ret1: mov rp = r8 // install return address (physical)
181 mov ar.rsc=0 // put RSE in enforced lazy, LE mode
182 mov r16=loc3 // r16= original psr
183 br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
185 mov psr.l = loc3 // restore init PSR
190 mov ar.rsc=loc4 // restore RSE configuration
191 srlz.d // seralize restoration of psr.l
193 END(ia64_pal_call_phys_static)
196 * Make a PAL call using the stacked registers in physical mode.
199 * in0 Index of PAL service
200 * in2 - in3 Remaning PAL arguments
202 GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
203 .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
204 alloc loc1 = ar.pfs,5,5,86,0
205 movl loc2 = pal_entry_point
207 mov r28 = in0 // copy procedure index
208 mov loc0 = rp // save rp
212 ld8 loc2 = [loc2] // loc2 <- entry point
213 mov out0 = in0 // first argument
214 mov out1 = in1 // copy arg2
215 mov out2 = in2 // copy arg3
216 mov out3 = in3 // copy arg3
218 mov loc3 = psr // save psr
220 mov loc4=ar.rsc // save RSE configuration
221 dep.z loc2=loc2,0,61 // convert pal entry point to physical
223 mov ar.rsc=0 // put RSE in enforced lazy, LE mode
224 movl r16=PAL_PSR_BITS_TO_CLEAR
225 movl r17=PAL_PSR_BITS_TO_SET
227 or loc3=loc3,r17 // add in psr the bits to set
228 mov b7 = loc2 // install target to branch reg
230 andcm r16=loc3,r16 // removes bits to clear from psr
231 br.call.sptk.many rp=ia64_switch_mode_phys
233 br.call.sptk.many rp=b7 // now make the call
235 mov ar.rsc=0 // put RSE in enforced lazy, LE mode
236 mov r16=loc3 // r16= original psr
237 br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
239 .ret8: mov psr.l = loc3 // restore init PSR
243 mov ar.rsc=loc4 // restore RSE configuration
244 srlz.d // seralize restoration of psr.l
246 END(ia64_pal_call_phys_stacked)
249 * Save scratch fp scratch regs which aren't saved in pt_regs already (fp10-fp15).
251 * NOTE: We need to do this since firmware (SAL and PAL) may use any of the scratch
252 * regs fp-low partition.
255 * in0 Address of stack storage for fp regs
257 GLOBAL_ENTRY(ia64_save_scratch_fpregs)
258 alloc r3=ar.pfs,1,0,0,0
261 stf.spill [in0] = f10,32
262 stf.spill [r2] = f11,32
264 stf.spill [in0] = f12,32
265 stf.spill [r2] = f13,32
267 stf.spill [in0] = f14,32
268 stf.spill [r2] = f15,32
270 END(ia64_save_scratch_fpregs)
273 * Load scratch fp scratch regs (fp10-fp15)
276 * in0 Address of stack storage for fp regs
278 GLOBAL_ENTRY(ia64_load_scratch_fpregs)
279 alloc r3=ar.pfs,1,0,0,0
282 ldf.fill f10 = [in0],32
283 ldf.fill f11 = [r2],32
285 ldf.fill f12 = [in0],32
286 ldf.fill f13 = [r2],32
288 ldf.fill f14 = [in0],32
289 ldf.fill f15 = [r2],32
291 END(ia64_load_scratch_fpregs)