]> err.no Git - linux-2.6/blob - arch/ia64/kernel/pal.S
[IA64] remove unused PAL_CALL_IC_OFF
[linux-2.6] / arch / ia64 / kernel / pal.S
1 /*
2  * PAL Firmware support
3  * IA-64 Processor Programmers Reference Vol 2
4  *
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>
10  *
11  * 05/22/2000 eranian Added support for stacked register calls
12  * 05/24/2000 eranian Added support for physical mode static calls
13  */
14
15 #include <asm/asmmacro.h>
16 #include <asm/processor.h>
17
18         .data
19 pal_entry_point:
20         data8 ia64_pal_default_handler
21         .text
22
23 /*
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
26  * not a big deal).
27  *
28  * in0          Address of the PAL entry point (text address, NOT a function descriptor).
29  */
30 GLOBAL_ENTRY(ia64_pal_handler_init)
31         alloc r3=ar.pfs,1,0,0,0
32         movl r2=pal_entry_point
33         ;;
34         st8 [r2]=in0
35         br.ret.sptk.many rp
36 END(ia64_pal_handler_init)
37
38 /*
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").
42  */
43 GLOBAL_ENTRY(ia64_pal_default_handler)
44         mov r8=-1
45         br.cond.sptk.many rp
46 END(ia64_pal_default_handler)
47
48 /*
49  * Make a PAL call using the static calling convention.
50  *
51  * in0         Index of PAL service
52  * in1 - in3   Remaining PAL arguments
53  */
54 GLOBAL_ENTRY(ia64_pal_call_static)
55         .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
56         alloc loc1 = ar.pfs,4,5,0,0
57         movl loc2 = pal_entry_point
58 1:      {
59           mov r28 = in0
60           mov r29 = in1
61           mov r8 = ip
62         }
63         ;;
64         ld8 loc2 = [loc2]               // loc2 <- entry point
65         adds r8 = 1f-1b,r8
66         mov loc4=ar.rsc                 // save RSE configuration
67         ;;
68         mov ar.rsc=0                    // put RSE in enforced lazy, LE mode
69         mov loc3 = psr
70         mov loc0 = rp
71         .body
72         mov r30 = in2
73
74         mov r31 = in3
75         mov b7 = loc2
76
77         rsm psr.i
78         ;;
79         mov rp = r8
80         br.cond.sptk.many b7
81 1:      mov psr.l = loc3
82         mov ar.rsc = loc4               // restore RSE configuration
83         mov ar.pfs = loc1
84         mov rp = loc0
85         ;;
86         srlz.d                          // seralize restoration of psr.l
87         br.ret.sptk.many b0
88 END(ia64_pal_call_static)
89
90 /*
91  * Make a PAL call using the stacked registers calling convention.
92  *
93  * Inputs:
94  *      in0         Index of PAL service
95  *      in2 - in3   Remaning PAL arguments
96  */
97 GLOBAL_ENTRY(ia64_pal_call_stacked)
98         .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
99         alloc loc1 = ar.pfs,4,4,4,0
100         movl loc2 = pal_entry_point
101
102         mov r28  = in0                  // Index MUST be copied to r28
103         mov out0 = in0                  // AND in0 of PAL function
104         mov loc0 = rp
105         .body
106         ;;
107         ld8 loc2 = [loc2]               // loc2 <- entry point
108         mov out1 = in1
109         mov out2 = in2
110         mov out3 = in3
111         mov loc3 = psr
112         ;;
113         rsm psr.i
114         mov b7 = loc2
115         ;;
116         br.call.sptk.many rp=b7         // now make the call
117 .ret0:  mov psr.l  = loc3
118         mov ar.pfs = loc1
119         mov rp = loc0
120         ;;
121         srlz.d                          // serialize restoration of psr.l
122         br.ret.sptk.many b0
123 END(ia64_pal_call_stacked)
124
125 /*
126  * Make a physical mode PAL call using the static registers calling convention.
127  *
128  * Inputs:
129  *      in0         Index of PAL service
130  *      in2 - in3   Remaning PAL arguments
131  *
132  * PSR_LP, PSR_TB, PSR_ID, PSR_DA are never set by the kernel.
133  * So we don't need to clear them.
134  */
135 #define PAL_PSR_BITS_TO_CLEAR                                                   \
136         (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT  | IA64_PSR_DB | IA64_PSR_RT |  \
137          IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED |                \
138          IA64_PSR_DFL | IA64_PSR_DFH)
139
140 #define PAL_PSR_BITS_TO_SET                                                     \
141         (IA64_PSR_BN)
142
143
144 GLOBAL_ENTRY(ia64_pal_call_phys_static)
145         .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
146         alloc loc1 = ar.pfs,4,7,0,0
147         movl loc2 = pal_entry_point
148 1:      {
149           mov r28  = in0                // copy procedure index
150           mov r8   = ip                 // save ip to compute branch
151           mov loc0 = rp                 // save rp
152         }
153         .body
154         ;;
155         ld8 loc2 = [loc2]               // loc2 <- entry point
156         mov r29  = in1                  // first argument
157         mov r30  = in2                  // copy arg2
158         mov r31  = in3                  // copy arg3
159         ;;
160         mov loc3 = psr                  // save psr
161         adds r8  = 1f-1b,r8             // calculate return address for call
162         ;;
163         mov loc4=ar.rsc                 // save RSE configuration
164         dep.z loc2=loc2,0,61            // convert pal entry point to physical
165         tpa r8=r8                       // convert rp to physical
166         ;;
167         mov b7 = loc2                   // install target to branch reg
168         mov ar.rsc=0                    // put RSE in enforced lazy, LE mode
169         movl r16=PAL_PSR_BITS_TO_CLEAR
170         movl r17=PAL_PSR_BITS_TO_SET
171         ;;
172         or loc3=loc3,r17                // add in psr the bits to set
173         ;;
174         andcm r16=loc3,r16              // removes bits to clear from psr
175         br.call.sptk.many rp=ia64_switch_mode_phys
176 .ret1:  mov rp = r8                     // install return address (physical)
177         mov loc5 = r19
178         mov loc6 = r20
179         br.cond.sptk.many b7
180 1:
181         mov ar.rsc=0                    // put RSE in enforced lazy, LE mode
182         mov r16=loc3                    // r16= original psr
183         mov r19=loc5
184         mov r20=loc6
185         br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
186 .ret2:
187         mov psr.l = loc3                // restore init PSR
188
189         mov ar.pfs = loc1
190         mov rp = loc0
191         ;;
192         mov ar.rsc=loc4                 // restore RSE configuration
193         srlz.d                          // seralize restoration of psr.l
194         br.ret.sptk.many b0
195 END(ia64_pal_call_phys_static)
196
197 /*
198  * Make a PAL call using the stacked registers in physical mode.
199  *
200  * Inputs:
201  *      in0         Index of PAL service
202  *      in2 - in3   Remaning PAL arguments
203  */
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
208 1:      {
209           mov r28  = in0                // copy procedure index
210           mov loc0 = rp         // save rp
211         }
212         .body
213         ;;
214         ld8 loc2 = [loc2]               // loc2 <- entry point
215         mov loc3 = psr                  // save psr
216         ;;
217         mov loc4=ar.rsc                 // save RSE configuration
218         dep.z loc2=loc2,0,61            // convert pal entry point to physical
219         ;;
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
223         ;;
224         or loc3=loc3,r17                // add in psr the bits to set
225         mov b7 = loc2                   // install target to branch reg
226         ;;
227         andcm r16=loc3,r16              // removes bits to clear from psr
228         br.call.sptk.many rp=ia64_switch_mode_phys
229
230         mov out0 = in0                  // first argument
231         mov out1 = in1                  // copy arg2
232         mov out2 = in2                  // copy arg3
233         mov out3 = in3                  // copy arg3
234         mov loc5 = r19
235         mov loc6 = r20
236
237         br.call.sptk.many rp=b7         // now make the call
238
239         mov ar.rsc=0                    // put RSE in enforced lazy, LE mode
240         mov r16=loc3                    // r16= original psr
241         mov r19=loc5
242         mov r20=loc6
243         br.call.sptk.many rp=ia64_switch_mode_virt      // return to virtual mode
244
245         mov psr.l  = loc3               // restore init PSR
246         mov ar.pfs = loc1
247         mov rp = loc0
248         ;;
249         mov ar.rsc=loc4                 // restore RSE configuration
250         srlz.d                          // seralize restoration of psr.l
251         br.ret.sptk.many b0
252 END(ia64_pal_call_phys_stacked)
253
254 /*
255  * Save scratch fp scratch regs which aren't saved in pt_regs already (fp10-fp15).
256  *
257  * NOTE: We need to do this since firmware (SAL and PAL) may use any of the scratch
258  * regs fp-low partition.
259  *
260  * Inputs:
261  *      in0     Address of stack storage for fp regs
262  */
263 GLOBAL_ENTRY(ia64_save_scratch_fpregs)
264         alloc r3=ar.pfs,1,0,0,0
265         add r2=16,in0
266         ;;
267         stf.spill [in0] = f10,32
268         stf.spill [r2]  = f11,32
269         ;;
270         stf.spill [in0] = f12,32
271         stf.spill [r2]  = f13,32
272         ;;
273         stf.spill [in0] = f14,32
274         stf.spill [r2]  = f15,32
275         br.ret.sptk.many rp
276 END(ia64_save_scratch_fpregs)
277
278 /*
279  * Load scratch fp scratch regs (fp10-fp15)
280  *
281  * Inputs:
282  *      in0     Address of stack storage for fp regs
283  */
284 GLOBAL_ENTRY(ia64_load_scratch_fpregs)
285         alloc r3=ar.pfs,1,0,0,0
286         add r2=16,in0
287         ;;
288         ldf.fill  f10 = [in0],32
289         ldf.fill  f11 = [r2],32
290         ;;
291         ldf.fill  f12 = [in0],32
292         ldf.fill  f13 = [r2],32
293         ;;
294         ldf.fill  f14 = [in0],32
295         ldf.fill  f15 = [r2],32
296         br.ret.sptk.many rp
297 END(ia64_load_scratch_fpregs)