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
25 * do it here 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
31 GLOBAL_ENTRY(ia64_pal_handler_init)
32 alloc r3=ar.pfs,1,0,0,0
33 movl r2=pal_entry_point
37 END(ia64_pal_handler_init)
40 * Default PAL call handler. This needs to be coded in assembly because it
41 * uses the static calling convention, i.e., the RSE may not be used and
42 * calls are done via "br.cond" (not "br.call").
44 GLOBAL_ENTRY(ia64_pal_default_handler)
47 END(ia64_pal_default_handler)
50 * Make a PAL call using the static calling convention.
52 * in0 Index of PAL service
53 * in1 - in3 Remaining PAL arguments
55 GLOBAL_ENTRY(ia64_pal_call_static)
56 .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
57 alloc loc1 = ar.pfs,4,5,0,0
58 movl loc2 = pal_entry_point
65 ld8 loc2 = [loc2] // loc2 <- entry point
67 mov loc4=ar.rsc // save RSE configuration
69 mov ar.rsc=0 // put RSE in enforced lazy, LE mode
83 mov ar.rsc = loc4 // restore RSE configuration
87 srlz.d // seralize restoration of psr.l
89 END(ia64_pal_call_static)
92 * Make a PAL call using the stacked registers calling convention.
95 * in0 Index of PAL service
96 * in2 - in3 Remaining PAL arguments
98 GLOBAL_ENTRY(ia64_pal_call_stacked)
99 .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
100 alloc loc1 = ar.pfs,4,4,4,0
101 movl loc2 = pal_entry_point
103 mov r28 = in0 // Index MUST be copied to r28
104 mov out0 = in0 // AND in0 of PAL function
108 ld8 loc2 = [loc2] // loc2 <- entry point
117 br.call.sptk.many rp=b7 // now make the call
118 .ret0: mov psr.l = loc3
122 srlz.d // serialize restoration of psr.l
124 END(ia64_pal_call_stacked)
127 * Make a physical mode PAL call using the static registers calling convention.
130 * in0 Index of PAL service
131 * in2 - in3 Remaining PAL arguments
133 * PSR_LP, PSR_TB, PSR_ID, PSR_DA are never set by the kernel.
134 * So we don't need to clear them.
136 #define PAL_PSR_BITS_TO_CLEAR \
137 (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_DB | IA64_PSR_RT |\
138 IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | \
139 IA64_PSR_DFL | IA64_PSR_DFH)
141 #define PAL_PSR_BITS_TO_SET \
145 GLOBAL_ENTRY(ia64_pal_call_phys_static)
146 .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
147 alloc loc1 = ar.pfs,4,7,0,0
148 movl loc2 = pal_entry_point
150 mov r28 = in0 // copy procedure index
151 mov r8 = ip // save ip to compute branch
152 mov loc0 = rp // save rp
156 ld8 loc2 = [loc2] // loc2 <- entry point
157 mov r29 = in1 // first argument
158 mov r30 = in2 // copy arg2
159 mov r31 = in3 // copy arg3
161 mov loc3 = psr // save psr
162 adds r8 = 1f-1b,r8 // calculate return address for call
164 mov loc4=ar.rsc // save RSE configuration
165 dep.z loc2=loc2,0,61 // convert pal entry point to physical
166 tpa r8=r8 // convert rp to physical
168 mov b7 = loc2 // install target to branch reg
169 mov ar.rsc=0 // put RSE in enforced lazy, LE mode
170 movl r16=PAL_PSR_BITS_TO_CLEAR
171 movl r17=PAL_PSR_BITS_TO_SET
173 or loc3=loc3,r17 // add in psr the bits to set
175 andcm r16=loc3,r16 // removes bits to clear from psr
176 br.call.sptk.many rp=ia64_switch_mode_phys
177 mov rp = r8 // install return address (physical)
182 mov ar.rsc=0 // put RSE in enforced lazy, LE mode
183 mov r16=loc3 // r16= original psr
186 br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
187 mov psr.l = loc3 // restore init PSR
192 mov ar.rsc=loc4 // restore RSE configuration
193 srlz.d // seralize restoration of psr.l
195 END(ia64_pal_call_phys_static)
198 * Make a PAL call using the stacked registers in physical mode.
201 * in0 Index of PAL service
202 * in2 - in3 Remaining PAL arguments
204 GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
205 .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
206 alloc loc1 = ar.pfs,5,7,4,0
207 movl loc2 = pal_entry_point
209 mov r28 = in0 // copy procedure index
210 mov loc0 = rp // save rp
214 ld8 loc2 = [loc2] // loc2 <- entry point
215 mov loc3 = psr // save psr
217 mov loc4=ar.rsc // save RSE configuration
218 dep.z loc2=loc2,0,61 // convert pal entry point to physical
220 mov ar.rsc=0 // put RSE in enforced lazy, LE mode
221 movl r16=PAL_PSR_BITS_TO_CLEAR
222 movl r17=PAL_PSR_BITS_TO_SET
224 or loc3=loc3,r17 // add in psr the bits to set
225 mov b7 = loc2 // install target to branch reg
227 andcm r16=loc3,r16 // removes bits to clear from psr
228 br.call.sptk.many rp=ia64_switch_mode_phys
230 mov out0 = in0 // first argument
231 mov out1 = in1 // copy arg2
232 mov out2 = in2 // copy arg3
233 mov out3 = in3 // copy arg3
237 br.call.sptk.many rp=b7 // now make the call
239 mov ar.rsc=0 // put RSE in enforced lazy, LE mode
240 mov r16=loc3 // r16= original psr
243 br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
245 mov psr.l = loc3 // restore init PSR
249 mov ar.rsc=loc4 // restore RSE configuration
250 srlz.d // seralize restoration of psr.l
252 END(ia64_pal_call_phys_stacked)
255 * Save scratch fp scratch regs which aren't saved in pt_regs already
258 * NOTE: We need to do this since firmware (SAL and PAL) may use any of the
259 * scratch regs fp-low partition.
262 * in0 Address of stack storage for fp regs
264 GLOBAL_ENTRY(ia64_save_scratch_fpregs)
265 alloc r3=ar.pfs,1,0,0,0
268 stf.spill [in0] = f10,32
269 stf.spill [r2] = f11,32
271 stf.spill [in0] = f12,32
272 stf.spill [r2] = f13,32
274 stf.spill [in0] = f14,32
275 stf.spill [r2] = f15,32
277 END(ia64_save_scratch_fpregs)
280 * Load scratch fp scratch regs (fp10-fp15)
283 * in0 Address of stack storage for fp regs
285 GLOBAL_ENTRY(ia64_load_scratch_fpregs)
286 alloc r3=ar.pfs,1,0,0,0
289 ldf.fill f10 = [in0],32
290 ldf.fill f11 = [r2],32
292 ldf.fill f12 = [in0],32
293 ldf.fill f13 = [r2],32
295 ldf.fill f14 = [in0],32
296 ldf.fill f15 = [r2],32
298 END(ia64_load_scratch_fpregs)