source: trunk/packages/xen-common/xen-common/linux-2.6-xen-sparse/arch/ia64/kernel/pal.S @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

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