source: trunk/packages/xen-3.1/xen-3.1/xen/arch/ia64/xen/xenasm.S @ 34

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

Add xen and xen-common

File size: 9.8 KB
Line 
1/*
2 * Assembly support routines for Xen/ia64
3 *
4 * Copyright (C) 2004 Hewlett-Packard Co
5 *      Dan Magenheimer <dan.magenheimer@hp.com>
6 */
7
8#include <linux/config.h>
9#include <asm/asmmacro.h>
10#include <asm/processor.h>
11#include <asm/pgtable.h>
12#include <asm/vhpt.h>
13#include <asm/asm-xsi-offsets.h>
14#include <public/xen.h>
15       
16// Change rr7 to the passed value while ensuring
17// Xen is mapped into the new region.
18#define PSR_BITS_TO_CLEAR                                               \
19        (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_RT |         \
20         IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED |        \
21         IA64_PSR_DFL | IA64_PSR_DFH | IA64_PSR_IC)
22// FIXME? Note that this turns off the DB bit (debug)
23#define PSR_BITS_TO_SET IA64_PSR_BN
24
25//extern void ia64_new_rr7(unsigned long rid,            /* in0 */
26//                         void *shared_info,            /* in1 */
27//                         void *shared_arch_info,       /* in2 */
28//                         unsigned long shared_info_va, /* in3 */
29//                         unsigned long va_vhpt)        /* in4 */
30//Local usage:
31//  loc0=rp, loc1=ar.pfs, loc2=percpu_paddr, loc3=psr, loc4=ar.rse
32//  loc5=pal_vaddr, loc6=xen_paddr, loc7=shared_archinfo_paddr,
33//  r16, r19, r20 are used by ia64_switch_mode_{phys, virt}()
34GLOBAL_ENTRY(ia64_new_rr7)
35        // FIXME? not sure this unwind statement is correct...
36        .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(1)
37        alloc loc1 = ar.pfs, 5, 8, 0, 0
38        movl loc2=PERCPU_ADDR
391:      {
40          mov loc3 = psr                // save psr     
41          mov loc0 = rp                 // save rp
42          mov r8   = ip                 // save ip to compute branch
43        };;
44        .body
45        tpa loc2=loc2                   // grab this BEFORE changing rr7
46        tpa in1=in1                     // grab shared_info BEFORE changing rr7
47        adds r8 = 1f-1b,r8              // calculate return address for call
48        ;;
49        tpa loc7=in2                    // grab arch_vcpu_info BEFORE chg rr7
50        movl r17=PSR_BITS_TO_SET
51        mov loc4=ar.rsc                 // save RSE configuration
52        movl r16=PSR_BITS_TO_CLEAR
53        ;;
54        tpa r8=r8                       // convert rp to physical
55        mov ar.rsc=0                    // put RSE in enforced lazy, LE mode
56        or loc3=loc3,r17                // add in psr the bits to set
57        ;;
58        andcm r16=loc3,r16              // removes bits to clear from psr
59        dep loc6=0,r8,0,KERNEL_TR_PAGE_SHIFT // Xen code paddr
60        br.call.sptk.many rp=ia64_switch_mode_phys
611:
62        // now in physical mode with psr.i/ic off so do rr7 switch
63        movl r16=pal_vaddr              // Note: belong to region 7!
64        ;;
65        mov     rr[r16]=in0
66        ;;
67        srlz.d
68        dep     r16=0,r16,60,4          // Get physical address.
69        ;;
70        ld8 loc5=[r16]                  // read pal_vaddr
71        movl    r26=PAGE_KERNEL
72        ;;
73
74        // re-pin mappings for kernel text and data
75        mov r24=KERNEL_TR_PAGE_SHIFT<<2
76        movl r17=KERNEL_START
77        ;;
78        ptr.i   r17,r24
79        ptr.d   r17,r24
80        mov r16=IA64_TR_KERNEL
81        mov cr.itir=r24
82        mov cr.ifa=r17
83        or r18=loc6,r26
84        ;;
85        itr.i itr[r16]=r18
86        ;;
87        itr.d dtr[r16]=r18
88
89        // re-pin mappings for stack (current)
90
91        // unless overlaps with KERNEL_TR
92        dep r18=0,r13,0,KERNEL_TR_PAGE_SHIFT
93        ;;
94        cmp.eq p7,p0=r17,r18
95(p7)    br.cond.sptk    .stack_overlaps
96        mov r25=IA64_GRANULE_SHIFT<<2
97        dep r21=0,r13,60,4              // physical address of "current"
98        ;;
99        ptr.d   r13,r25
100        or r23=r21,r26                  // construct PA | page properties
101        mov cr.itir=r25
102        mov cr.ifa=r13                  // VA of next task...
103        mov r21=IA64_TR_CURRENT_STACK
104        ;;
105        itr.d dtr[r21]=r23              // wire in new mapping...
106
107        //  Per-cpu     
108.stack_overlaps:
109        mov r24=PERCPU_PAGE_SHIFT<<2
110        movl r22=PERCPU_ADDR
111        ;;
112        ptr.d   r22,r24
113        or r23=loc2,r26                 // construct PA | page properties
114        mov cr.itir=r24
115        mov cr.ifa=r22
116        mov r25=IA64_TR_PERCPU_DATA
117        ;;
118        itr.d dtr[r25]=r23              // wire in new mapping...
119
120        // VHPT
121#if VHPT_ENABLED
122#if IA64_GRANULE_SHIFT < VHPT_SIZE_LOG2
123#error "it must be that VHPT_SIZE_LOG2 <= IA64_GRANULE_SHIFT"
124#endif 
125        // unless overlaps with KERNEL_TR and IA64_TR_CURRENT_STACK
126        dep r14=0,in4,0,KERNEL_TR_PAGE_SHIFT
127        dep r15=0,in4,0,IA64_GRANULE_SHIFT
128        dep r21=0,r13,0,IA64_GRANULE_SHIFT
129        ;;
130        cmp.eq p7,p0=r17,r14
131        cmp.eq p8,p0=r15,r21
132(p7)    br.cond.sptk    .vhpt_overlaps
133(p8)    br.cond.sptk    .vhpt_overlaps
134        mov r21=IA64_TR_VHPT
135        dep r22=0,r15,60,4              // physical address of
136                                        // va_vhpt & ~(IA64_GRANULE_SIZE - 1)
137        mov r24=IA64_GRANULE_SHIFT<<2
138        ;;
139        ptr.d   r15,r24
140        or r23=r22,r26                  // construct PA | page properties
141        mov cr.itir=r24
142        mov cr.ifa=r15
143        srlz.d
144        ;;
145        itr.d dtr[r21]=r23              // wire in new mapping...
146.vhpt_overlaps:
147#endif
148
149        //  Shared info
150        mov r24=XSI_SHIFT<<2
151        movl r25=__pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RW)
152        ;;
153        ptr.d   in3,r24
154        or r23=in1,r25                  // construct PA | page properties
155        mov cr.itir=r24
156        mov cr.ifa=in3
157        mov r21=IA64_TR_SHARED_INFO
158        ;;
159        itr.d dtr[r21]=r23              // wire in new mapping...
160       
161        // Map mapped_regs
162        mov r22=XMAPPEDREGS_OFS
163        mov r24=XMAPPEDREGS_SHIFT<<2
164        ;;
165        add r22=r22,in3
166        ;;
167        ptr.d   r22,r24
168        or r23=loc7,r25                 // construct PA | page properties
169        mov cr.itir=r24
170        mov cr.ifa=r22
171        mov r21=IA64_TR_MAPPED_REGS
172        ;;
173        itr.d dtr[r21]=r23              // wire in new mapping...
174
175        // Purge/insert PAL TR
176        mov r24=IA64_TR_PALCODE
177        mov r23=IA64_GRANULE_SHIFT<<2
178        dep r25=0,loc5,60,4             // convert pal vaddr to paddr
179        ;;
180        ptr.i   loc5,r23
181        or r25=r25,r26                  // construct PA | page properties
182        mov cr.itir=r23
183        mov cr.ifa=loc5
184        ;;
185        itr.i itr[r24]=r25
186
187        // done, switch back to virtual and return
188        mov r16=loc3                    // r16= original psr
189        br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
190        mov psr.l = loc3                // restore init PSR
191
192        mov ar.pfs = loc1
193        mov rp = loc0
194        ;;
195        mov ar.rsc=loc4                 // restore RSE configuration
196        srlz.d                          // seralize restoration of psr.l
197        br.ret.sptk.many rp
198END(ia64_new_rr7)
199
200#if 0 /* Not used */
201#include "minstate.h"
202
203GLOBAL_ENTRY(ia64_prepare_handle_privop)
204        .prologue
205        /*
206         * r16 = fake ar.pfs, we simply need to make sure privilege is still 0
207         */
208        mov r16=r0
209        DO_SAVE_SWITCH_STACK
210        br.call.sptk.many rp=ia64_handle_privop // stack frame setup in ivt
211.ret22: .body
212        DO_LOAD_SWITCH_STACK
213        br.cond.sptk.many rp                    // goes to ia64_leave_kernel
214END(ia64_prepare_handle_privop)
215
216GLOBAL_ENTRY(ia64_prepare_handle_break)
217        .prologue
218        /*
219         * r16 = fake ar.pfs, we simply need to make sure privilege is still 0
220         */
221        mov r16=r0
222        DO_SAVE_SWITCH_STACK
223        br.call.sptk.many rp=ia64_handle_break  // stack frame setup in ivt
224.ret23: .body
225        DO_LOAD_SWITCH_STACK
226        br.cond.sptk.many rp                    // goes to ia64_leave_kernel
227END(ia64_prepare_handle_break)
228
229GLOBAL_ENTRY(ia64_prepare_handle_reflection)
230        .prologue
231        /*
232         * r16 = fake ar.pfs, we simply need to make sure privilege is still 0
233         */
234        mov r16=r0
235        DO_SAVE_SWITCH_STACK
236        br.call.sptk.many rp=ia64_handle_reflection // stack frame setup in ivt
237.ret24: .body
238        DO_LOAD_SWITCH_STACK
239        br.cond.sptk.many rp                    // goes to ia64_leave_kernel
240END(ia64_prepare_handle_reflection)
241#endif
242
243GLOBAL_ENTRY(__get_domain_bundle)
244        EX(.failure_in_get_bundle,ld8 r8=[r32],8)
245        ;;
246        EX(.failure_in_get_bundle,ld8 r9=[r32])
247        ;;
248        br.ret.sptk.many rp
249        ;;
250.failure_in_get_bundle:
251        mov r8=0
252        ;;
253        mov r9=0
254        ;;
255        br.ret.sptk.many rp
256        ;;
257END(__get_domain_bundle)
258
259/* derived from linux/arch/ia64/hp/sim/boot/boot_head.S */
260GLOBAL_ENTRY(pal_emulator_static)
261        mov r8=-1
262        mov r9=256
263        ;;
264        cmp.gtu p7,p8=r9,r32            /* r32 <= 255? */
265(p7)    br.cond.sptk.few static
266        ;;
267        mov r9=512
268        ;;
269        cmp.gtu p7,p8=r9,r32
270(p7)    br.cond.sptk.few stacked
271        ;;
272static: cmp.eq p7,p8=6,r32              /* PAL_PTCE_INFO */
273(p8)    br.cond.sptk.few 1f
274        ;;
275        mov r8=0                        /* status = 0 */
276        movl r9=0x100000000             /* tc.base */
277        movl r10=0x0000000200000003     /* count[0], count[1] */
278        movl r11=0x1000000000002000     /* stride[0], stride[1] */
279        br.ret.sptk.few rp
2801:      cmp.eq p7,p8=14,r32             /* PAL_FREQ_RATIOS */
281(p8)    br.cond.sptk.few 1f
282        mov r8=0                        /* status = 0 */
283        movl r9 =0x900000002            /* proc_ratio (1/100) */
284        movl r10=0x100000100            /* bus_ratio<<32 (1/256) */
285        movl r11=0x900000002            /* itc_ratio<<32 (1/100) */
286        ;;
2871:      cmp.eq p7,p8=19,r32             /* PAL_RSE_INFO */
288(p8)    br.cond.sptk.few 1f
289        mov r8=0                        /* status = 0 */
290        mov r9=96                       /* num phys stacked */
291        mov r10=0                       /* hints */
292        mov r11=0
293        br.ret.sptk.few rp
2941:      cmp.eq p7,p8=1,r32              /* PAL_CACHE_FLUSH */
295(p8)    br.cond.sptk.few 1f
296#if 0
297        mov r9=ar.lc
298        movl r8=524288          /* flush 512k million cache lines (16MB) */
299        ;;
300        mov ar.lc=r8
301        movl r8=0xe000000000000000
302        ;;
303.loop:  fc r8
304        add r8=32,r8
305        br.cloop.sptk.few .loop
306        sync.i
307        ;;
308        srlz.i
309        ;;
310        mov ar.lc=r9
311        mov r8=r0
312        ;;
3131:      cmp.eq p7,p8=15,r32             /* PAL_PERF_MON_INFO */
314(p8)    br.cond.sptk.few 1f
315        mov r8=0                        /* status = 0 */
316        movl r9 =0x08122f04             /* generic=4 width=47 retired=8
317                                         * cycles=18
318                                         */
319        mov r10=0                       /* reserved */
320        mov r11=0                       /* reserved */
321        mov r16=0xffff                  /* implemented PMC */
322        mov r17=0x3ffff                 /* implemented PMD */
323        add r18=8,r29                   /* second index */
324        ;;
325        st8 [r29]=r16,16                /* store implemented PMC */
326        st8 [r18]=r0,16                 /* clear remaining bits  */
327        ;;
328        st8 [r29]=r0,16                 /* clear remaining bits  */
329        st8 [r18]=r0,16                 /* clear remaining bits  */
330        ;;
331        st8 [r29]=r17,16                /* store implemented PMD */
332        st8 [r18]=r0,16                 /* clear remaining bits  */
333        mov r16=0xf0                    /* cycles count capable PMC */
334        ;;
335        st8 [r29]=r0,16                 /* clear remaining bits  */
336        st8 [r18]=r0,16                 /* clear remaining bits  */
337        mov r17=0xf0                    /* retired bundles capable PMC */
338        ;;
339        st8 [r29]=r16,16                /* store cycles capable */
340        st8 [r18]=r0,16                 /* clear remaining bits  */
341        ;;
342        st8 [r29]=r0,16                 /* clear remaining bits  */
343        st8 [r18]=r0,16                 /* clear remaining bits  */
344        ;;
345        st8 [r29]=r17,16                /* store retired bundle capable */
346        st8 [r18]=r0,16                 /* clear remaining bits  */
347        ;;
348        st8 [r29]=r0,16                 /* clear remaining bits  */
349        st8 [r18]=r0,16                 /* clear remaining bits  */
350        ;;
3511:      br.cond.sptk.few rp
352#else
3531:
354#endif
355stacked:
356        br.ret.sptk.few rp
357END(pal_emulator_static)
358
359//  These instructions are copied in the domains.
360//  This is the virtual PAL, which simply does a hypercall.
361//  The size is 2 bundles (32 Bytes).  It handles both static and stacked
362//    convention.
363//  If you modify this code, you have to modify dom_fw.h (for the size) and
364//   dom_fw_pal_hypercall_patch.
365GLOBAL_ENTRY(pal_call_stub)
366        {
367         .mii
368        addl r2=0x1000,r0       //  Hypercall number (Value is patched).
369        mov r9=256
370        ;;
371        cmp.gtu p7,p8=r9,r28            /* r32 <= 255? */
372        }
373        {
374         .mbb
375        break 0x1000            //  Hypercall vector (Value is patched).
376(p7)    br.cond.sptk.few rp
377(p8)    br.ret.sptk.few rp
378        }
379END(pal_call_stub)
380
381
Note: See TracBrowser for help on using the repository browser.