source: trunk/packages/xen-3.1/xen-3.1/extras/mini-os/arch/ia64/ivt.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: 20.6 KB
Line 
1/*
2 * Copyright (c) 2007 Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
3 * Description: ia64 specific trap handling.
4 *
5 ****************************************************************************
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 */
25
26
27#include "asm.h"
28#include "page.h"
29#include "ia64_cpu.h"
30#include "privop.h"
31#include "offsets.h"
32
33
34/* General register usage in interrupt handling:
35 *      r16, r17, ... are used for input parameters of sub-routines
36 *      r29:    used to access memory which may raise nested TLB fault
37 *      r30:    b0 save register
38 *      r31:    predicates save register
39 *      p30,p31:        used for TLB stuff: (0,1)=data, (1,0)=instruction
40 */
41
42
43#define FILL_FP_PAIR(f1, f2, b1, b2)    \
44        ldf.fill        f1=[b1],32      ;\
45        ldf.fill        f2=[b2],32      ;\
46        ;;
47
48#define SPILL_FP_PAIR(f1, f2, b1, b2)   \
49        stf.spill       [b1]=f1,32      ;\
50        stf.spill       [b2]=f2,32      ;\
51        ;;
52
53#define FILL_REG_PAIR(r1, r2, b1, b2)   \
54        ld8.fill        r1=[b1],16      ;\
55        ld8.fill        r2=[b2],16      ;\
56        ;;
57
58#define SPILL_REG_PAIR(r1, r2, b1, b2)  \
59        .mem.offset 0,0                 ;\
60        st8.spill       [b1]=r1,16      ;\
61        .mem.offset 8,0                 ;\
62        st8.spill       [b2]=r2,16      ;\
63        ;;
64
65
66/**
67 *      The function does a store of the current processor context
68 *      to the given exception frame address.
69 *      These are some special and the scratch registers for calling
70 *      C-functions later.
71 *      The bspstore will be the same. A clean RSE is made with the
72 *      cover instruction.
73 *     
74 *      The return is done through a jump to the next bundle after ip (r16).
75 *
76 *      Used register: r16, r18, r19, r20, r21, r22 of bank 0
77 *
78 *      @param: r16 ip of the bundle with the jump.
79 *      @param: r18 pointer to the trap frame.
80 *      @param: r23 trap number/err val
81 *
82 */
83
84ENTRY(save_tf_rse_switch)
85        movl    r21=XSI_IPSR            // XEN !!
86        movl    r22=XSI_IIP             // XEN !!
87        ;;
88        ld8     r21=[r21]               // XEN.ipsr
89        ld8     r22=[r22];;             // XEN.iip
90#if defined(BIG_ENDIAN)
91        mux1    r21=r21,@rev            // swap because mini-os is in BE
92        mux1    r22=r22,@rev            // swap because mini-os is in BE
93        ;;
94#endif
95        add     r19=TF_IPSR,r18
96        add     r20=TF_IIP,r18
97        ;;
98        st8     [r19]=r21               // store cr.ipsr
99        st8     [r20]=r22               // store cr.iip
100        ;;
101        //// r16 return jump pointer, r18 - trap frame base,
102        add     r19=TF_UNAT,r18
103        mov     r20=ar.unat
104        ;;
105        st8     [r19]=r20               // store scratch unat
106        ;;
107
108        add     r19=TF_GP,r18
109        add     r20=TF_SP,r18
110        ;;
111        st8     [r19]=gp,TF_TP-TF_GP    // store gp
112        st8     [r20]=sp,TF_PR-TF_SP    // store sp
113        mov     r21=pr
114        ;;
115        st8     [r19]=r13               // store tp
116        st8     [r20]=r21               // store pr
117        ;;
118        add     r19=TF_GREG2,r18        // Now first general regs.
119        add     r20=TF_GREG3,r18
120        ;;
121        SPILL_REG_PAIR( r2, r3,r19,r20)
122        SPILL_REG_PAIR( r8, r9,r19,r20)
123        SPILL_REG_PAIR(r10,r11,r19,r20)
124        SPILL_REG_PAIR(r14,r15,r19,r20)
125        ;;
126        mov     r14=r18         // move trap frame base for bsw
127        mov     r15=r16         // save return address
128        ;;
129        //bsw.1         // switch to bank 1 for saving these registers.
130        movl r30=XSI_BANKNUM            // Switch to bank 1.
131        mov r31=1;;
132#if defined(BIG_ENDIAN)
133        mux1    r31=r31,@rev            // swap because mini-os is in BE
134        ;;
135#endif
136        st4 [r30]=r31
137        ;;
138        /*
139         * On XEN the hypervisor has stored the bank 1 registers
140         * r16-r31. I must reload these registers here to get
141         * access.
142         */
143        movl r30=XSI_BANK1_R16;
144        movl r31=XSI_BANK1_R16+8;;
145        ld8 r16=[r30],16; ld8 r17=[r31],16;;
146#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
147        mux1    r16=r16,@rev; mux1 r17=r17,@rev;;
148#endif
149        ld8 r18=[r30],16; ld8 r19=[r31],16;;
150#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
151        mux1    r18=r18,@rev; mux1 r19=r19,@rev;;
152#endif
153        ld8 r20=[r30],16; ld8 r21=[r31],16;;
154#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
155        mux1    r20=r20,@rev; mux1 r21=r21,@rev;;
156#endif
157        ld8 r22=[r30],16; ld8 r23=[r31],16;;
158#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
159        mux1    r22=r22,@rev; mux1 r23=r23,@rev;;
160#endif
161        ld8 r24=[r30],16; ld8 r25=[r31],16;;
162#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
163        mux1    r24=r24,@rev; mux1 r25=r25,@rev;;
164#endif
165        ld8 r26=[r30],16; ld8 r27=[r31],16;;
166#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
167        mux1    r26=r26,@rev; mux1 r27=r27,@rev;;
168#endif
169        ld8 r28=[r30],16; ld8 r29=[r31],16;;
170#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
171        mux1    r28=r28,@rev; mux1 r29=r29,@rev;;
172#endif
173        ld8 r30=[r30]; ld8 r31=[r31];;
174#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
175        mux1    r30=r30,@rev; mux1 r31=r31,@rev;;
176#endif
177
178        add     r2=TF_GREG16,r14
179        add     r3=TF_GREG17,r14
180        ;;
181        SPILL_REG_PAIR(r16,r17,r2,r3)
182        SPILL_REG_PAIR(r18,r19,r2,r3)
183        SPILL_REG_PAIR(r20,r21,r2,r3)
184        SPILL_REG_PAIR(r22,r23,r2,r3)
185        SPILL_REG_PAIR(r24,r25,r2,r3)
186        SPILL_REG_PAIR(r26,r27,r2,r3)
187        SPILL_REG_PAIR(r28,r29,r2,r3)
188        SPILL_REG_PAIR(r30,r31,r2,r3)
189        ;;
190        //bsw.0                         // back to interrupt bank 0
191        movl r2=XSI_BANKNUM;;
192        st4 [r2]=r0
193        ;;
194        mov     r18=r14                 // restore context pointer
195        mov     r16=r15                 // restore return address
196        ;;
197        //// r16 return jump pointer, r18 - trap frame base,
198        add     r19=TF_CCV,r18
199        add     r20=TF_CSD,r18
200        mov     r21=ar.ccv
201        mov     r22=ar.csd
202        ;;
203        st8     [r19]=r21               // ar.ccv
204        st8     [r20]=r22               // ar.csd
205        ;;
206        add     r19=TF_SSD,r18
207        mov     r21=ar.ssd
208        ;;
209        st8     [r19]=r21               // ar.ssd
210        ;;
211        add     r19=TF_FREG6,r18
212        add     r20=TF_FREG7,r18
213        ;;
214        SPILL_FP_PAIR(f6, f7, r19, r20)
215        SPILL_FP_PAIR(f8, f9, r19, r20)
216        SPILL_FP_PAIR(f10, f11, r19, r20)
217
218        add     r19=TF_BREG0,r18        // b0, b6, b7
219        add     r20=TF_BREG6,r18
220        mov     r21=b0
221        mov     r22=b6
222        ;;
223        st8     [r19]=r21,TF_BREG7-TF_BREG0     // store b0
224        st8     [r20]=r22,16            // store b6
225        ;;
226        mov     r21=b7
227        ;;
228        st8     [r19]=r21               // store b7
229
230        //// r16 return jump pointer, r18 - trap frame base,
231
232                // Read and save RSC, PFS
233        add     r19=TF_PFS,r18
234        add     r20=TF_RSC,r18
235        mov     r21=ar.pfs
236        mov     r22=ar.rsc
237        ;;
238{       .mmb
239        st8     [r19]=r21               // store ar.pfs
240        st8     [r20]=r22               // store ar.rsc
241                // Issue cover instruction
242        cover           // must be the last instruction in bundle
243        //XEN_HYPER_COVER
244        ;;
245}
246                // Read and save IFS
247        add     r19=TF_IFS,r18
248        add     r20=TF_CFM,r18
249                /* xen special handling for possibly lazy cover */
250        movl    r8=XSI_PRECOVER_IFS;
251        ;;
252        ld8     r21=[r8];
253        ;;
254#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
255        mux1    r21=r21,@rev
256        ;;
257#endif
258        st8     [r19]=r21               // store cr.ifs
259        dep.z   r22=r21,0,38            // copy ifm part from ifs.ifm
260        ;;
261        st8     [r20]=r22               // store cfm
262                // RSE in enforced lazy mode
263        mov     ar.rsc=IA64_RSE_LAZY
264        ;;
265                // Read and save BSPSTORE and RNAT
266        add     r19=TF_BSP,r18
267        add     r20=TF_RNAT,r18
268        mov     r21=ar.bspstore
269        mov     r22=ar.rnat
270        ;;
271        st8     [r19]=r21                       // store ar.bspstore
272        st8     [r20]=r22                       // store ar.rnat
273        ;;
274                // Write new BSPSTORE
275        //mov   r21=ar.bsp
276        //;;
277        mov     r22=r21                 // new bspstore equal to old
278        ;;
279        mov     ar.bspstore=r22         // the new bspstore
280        ;;
281                // Read and save the new BSP for calculating number of dirty regs.
282        mov     r21=ar.bsp
283        ;;
284        sub     r21=r21,r22             // r21 -> ndirty
285        add     r19=TF_NDIRTY-TF_BSP,r19        // TF_NDIRTY pos in r19
286        ;;
287        st8     [r19]=r21               // store ndirty
288        ;;
289        mov     ar.rsc=IA64_RSE_EAGER   // RSE on again
290        ;;
291        add     r19=TF_FPSR,r18
292        ;;
293        mov     r21=ar.fpsr
294        ;;
295        st8     [r19]=r21               // ar.fpsr
296        ;;
297        //// r16 return jump pointer, r18 - trap frame base,
298                // Load the gp with our module __gp
299        movl    gp=__gp
300        ;;
301        add     r16=16,r16      // for jump to next bundle
302        ;;
303        mov     b7=r16
304        ;;
305
306{       .mfb
307        srlz.d
308        nop     0
309        br.sptk b7
310        ;;
311}
312
313END(save_tf_rse_switch)
314
315
316/**
317 *      The function reloads the processor context stored in
318 *      save_tf_rse_switch().
319 *     
320 *      On calling the function the bank 0 must be activ.
321 *      The return is done through a rfi.
322 *      Used register: b7, r16, r18, r19, r20, r21, r22 of bank 0
323 *
324 *      @param: r18 pointer to the exception frame
325 *
326 */
327ENTRY(restore_tf_rse_switch)
328        add     r19=TF_IPSR,r18
329        add     r20=TF_IIP,r18
330        ;;
331        ld8     r21=[r19]               // load cr.ipsr
332        ld8     r22=[r20]               // load cr.iip
333#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
334        ;;
335        mux1    r21=r21,@rev
336        mux1    r22=r22,@rev
337        ;;
338#endif
339        movl    r16=XSI_IPSR            // XEN !!
340        ;;
341        st8     [r16]=r21,XSI_IIP_OFS-XSI_IPSR_OFS      // XEN.ipsr
342        mov     r2=r21                  // save for fp stuff below
343        ;;
344        st8     [r16]=r22               // XEN.iip
345        ;;
346        //// r18 - trap frame base
347                // Allocate a zero sized frame
348        alloc   r30=ar.pfs,0,0,0,0      // discard current frame
349        ;;
350                // calc number of dirty regs and put this into rsc.loardrs
351        add     r19=TF_NDIRTY,r18
352        ;;
353        ld8     r22=[r19]               // ndirty
354        ;;
355        shl     r21=r22,16              // value for ar.rsc
356        //mov   r19=(MOS_IA64_RSC_BE << IA64_RSC_BE)
357        ;;
358        or      r21=(MOS_IA64_RSC_BE << IA64_RSC_BE),r21
359        ;;
360        mov     ar.rsc=r21              // setup for loadrs
361        ;;
362                // Issue a loadrs instruction
363{       .mmi
364        loadrs          // must be the first instruction
365        ;;
366        nop 0x0
367        nop 0x0
368}
369                // Restore BSPSTORE from interrupted context
370        add     r19=TF_BSP,r18
371        add     r20=TF_RNAT,r18
372        ;;     
373        ld8     r21=[r19]               // load ar.bspstore
374        ld8     r22=[r20]               // load ar.rnat
375        ;;
376        mov     ar.bspstore=r21         // set ar.bspstore
377        ;;
378                // Restore RNAT
379        mov     ar.rnat=r22             // set ar.rnat
380        ;;
381                // Restore PFS and IFS
382        add     r19=TF_PFS,r18
383        add     r20=TF_IFS,r18
384        movl    r16=XSI_IFS             // XEN !!
385        ;;
386        ld8     r21=[r19]               // load ar.pfs
387        ld8     r22=[r20]               // load cr.ifs
388        ;;
389#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
390        mux1    r22=r22,@rev
391        ;;
392#endif
393        add     r19=TF_RSC,r18
394        mov     ar.pfs=r21
395        st8     [r16]=r22               // XEN.ifs
396        ;;
397                // Restore RSC
398        ld8     r21=[r19]               // load ar.rsc
399        ;;
400        mov     ar.rsc=r21              // set ar.rsc
401        //// r18 - trap frame base
402        add     r19=TF_GP,r18
403        add     r20=TF_SP,r18
404        ;;
405        ld8     gp=[r19],TF_TP-TF_GP    // load gp
406        ld8     sp=[r20],TF_PR-TF_SP    // load sp
407        ;;
408        ld8     r13=[r19]               // load tp
409        ld8     r21=[r20]               // load pr
410        ;;
411        mov     pr=r21,-1               // set pr
412        ;;
413        add     r19=TF_BREG0,r18
414        add     r20=TF_BREG6,r18
415        ;;
416        ld8     r21=[r19],TF_BREG7-TF_BREG0     // load b0
417        ld8     r22=[r20],16            // load b6
418        ;;
419        mov     b0=r21
420        mov     b6=r22
421        ;;
422        ld8     r21=[r19]               // load b7
423        ld8     r22=[r20],16            // load b3
424        ;;
425        mov     b7=r21
426        //// r18 - trap frame base
427        mov     r14=r18                 // Save the context pointer
428        ;;
429        // bsw.1
430        movl r30=XSI_BANKNUM            // Switch to bank 1.
431        mov r31=1;;
432#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
433        mux1    r31=r31,@rev
434        ;;
435#endif
436        st4 [r30]=r31
437        ;;
438        add     r2=TF_GREG16,r14
439        add     r3=TF_GREG17,r14
440        ;;
441        FILL_REG_PAIR(r16,r17,r2,r3)
442        FILL_REG_PAIR(r18,r19,r2,r3)
443        FILL_REG_PAIR(r20,r21,r2,r3)
444        FILL_REG_PAIR(r22,r23,r2,r3)
445        FILL_REG_PAIR(r24,r25,r2,r3)
446        FILL_REG_PAIR(r26,r27,r2,r3)
447        FILL_REG_PAIR(r28,r29,r2,r3)
448        FILL_REG_PAIR(r30,r31,r2,r3)
449
450        /*
451         * On XEN I have to store the bank 1 register into the
452         * global XSI_... area.
453         */
454                // r16-r31 all now hold bank1 values
455        movl r2=XSI_BANK1_R16
456        movl r3=XSI_BANK1_R16+8
457        ;;
458#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
459        mux1    r16=r16,@rev; mux1 r17=r17,@rev;;
460#endif
461        .mem.offset 0,0; st8.spill [r2]=r16,16
462        .mem.offset 8,0; st8.spill [r3]=r17,16
463        ;;
464#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
465        mux1    r18=r18,@rev; mux1 r19=r19,@rev;;
466#endif
467        .mem.offset 0,0; st8.spill [r2]=r18,16
468        .mem.offset 8,0; st8.spill [r3]=r19,16
469        ;;
470#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
471        mux1    r20=r20,@rev; mux1 r21=r21,@rev;;
472#endif
473        .mem.offset 0,0; st8.spill [r2]=r20,16
474        .mem.offset 8,0; st8.spill [r3]=r21,16
475        ;;
476#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
477        mux1    r22=r22,@rev; mux1 r23=r23,@rev;;
478#endif
479        .mem.offset 0,0; st8.spill [r2]=r22,16
480        .mem.offset 8,0; st8.spill [r3]=r23,16
481        ;;
482#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
483        mux1    r24=r24,@rev; mux1 r25=r25,@rev;;
484#endif
485        .mem.offset 0,0; st8.spill [r2]=r24,16
486        .mem.offset 8,0; st8.spill [r3]=r25,16
487        ;;
488#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
489        mux1    r26=r26,@rev; mux1 r27=r27,@rev;;
490#endif
491        .mem.offset 0,0; st8.spill [r2]=r26,16
492        .mem.offset 8,0; st8.spill [r3]=r27,16
493        ;;
494#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
495        mux1    r28=r28,@rev; mux1 r29=r29,@rev;;
496#endif
497        .mem.offset 0,0; st8.spill [r2]=r28,16
498        .mem.offset 8,0; st8.spill [r3]=r29,16
499        ;;
500#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
501        mux1    r30=r30,@rev; mux1 r31=r31,@rev;;
502#endif
503        .mem.offset 0,0; st8.spill [r2]=r30,16
504        .mem.offset 8,0; st8.spill [r3]=r31,16
505        ;;
506        // bsw.0
507        movl r2=XSI_BANKNUM;;
508        st4 [r2]=r0;
509
510        mov     r18=r14                 // Move back the context pointer
511        ;;
512        add     r19=TF_GREG2,r18
513        add     r20=TF_GREG3,r18
514        ;;
515        FILL_REG_PAIR( r2, r3,r19,r20)
516        FILL_REG_PAIR( r8, r9,r19,r20)
517        FILL_REG_PAIR(r10,r11,r19,r20)
518        FILL_REG_PAIR(r14,r15,r19,r20)
519
520        //// r18 - trap frame base,
521
522        add     r19=TF_CCV,r18
523        add     r20=TF_CSD,r18
524        ;;
525        ld8     r21=[r19]               // ar.ccv
526        ld8     r22=[r20]               // ar.csd
527        ;;
528        mov     ar.ccv=r21
529        mov     ar.csd=r22
530        add     r19=TF_SSD,r18
531        ;;
532        ld8     r21=[r19]               // ar.ssd
533        ;;
534        mov     ar.ssd=r21
535        add     r19=TF_FREG6,r18
536        add     r20=TF_FREG7,r18
537        ;;
538        FILL_FP_PAIR(f6, f7, r19, r20)
539        FILL_FP_PAIR(f8, f9, r19, r20)
540        FILL_FP_PAIR(f10, f11, r19, r20)
541        add     r19=TF_FPSR,r18
542        ;;
543        ld8     r21=[r19]               // ar.fpsr
544        ;;
545        mov     ar.fpsr=r21
546        add     r19=TF_UNAT,r18
547        ;;
548        ld8     r21=[r19]
549        ;;
550        mov     ar.unat=r21
551        ;;
552        srlz.i
553        ;;
554        //rfi
555        XEN_HYPER_RFI;
556        ;;
557END(restore_tf_rse_switch)
558
559
560ENTRY(save_special_regs)
561        alloc   loc0=ar.pfs,1,7,0,0
562        movl    loc1=XSI_IFA            // XEN !!
563        movl    loc2=XSI_ISR            // XEN !!
564        ;;
565        ld8     loc3=[loc1],XSI_IIM_OFS-XSI_IFA_OFS     // load XEN.ifa
566        ld8     loc4=[loc2],XSI_IIPA_OFS-XSI_ISR_OFS    // load XEN.isr
567        add     loc5=TF_IFA,in0
568        add     loc6=TF_ISR,in0
569        ;;
570#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
571        mux1    loc3=loc3,@rev; mux1 loc4=loc4,@rev;;
572#endif
573        st8     [loc5]=loc3,TF_IIM-TF_IFA       // store cr.ifa
574        st8     [loc6]=loc4                     // store cr.isr
575        ;;
576        ld8     loc3=[loc1]                     // load XEN.iim
577        ;;
578#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
579        mux1    loc3=loc3,@rev;;
580#endif
581        st8     [loc5]=loc3                     // store cr.iim
582        ;;
583        mov     ar.pfs=loc0
584        ;;
585        br.ret.sptk.few rp
586END(save_special_regs)
587
588
589ENTRY(hypervisor_callback)
590                // Calculate the stack address for storing.
591                // Use the kernel stack here because it's mapped wired!
592                // -> no nested tlb faults!
593        movl    r18=kstack+KSTACK_PAGES * PAGE_SIZE - 16 - TF_SIZE
594
595        //add   r18=-TF_SIZE,sp
596        add     r30=0xabab,r0
597        ;;
598{       .mib
599        nop     0x02
600        mov     r16=ip          // for jump back from save_tf_rse_switch
601        br.sptk save_tf_rse_switch
602        ;;
603}
604        add     sp=-16,r18              // the new stack
605        alloc   r15=ar.pfs,0,0,1,0      // 1 out for do_trap_error
606        ;;
607        mov     out0=r18                // the trap frame
608        movl    r22=XSI_PSR_IC
609        mov     r23=1;;
610#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
611        mux1    r23=r23,@rev;;
612#endif
613        st8     [r22]=r23               // ssm psr.ic
614        ;;
615        br.call.sptk.few rp = do_hypervisor_callback
616
617        movl    r22=XSI_PSR_IC
618        ;;
619        st4     [r22]=r0                // rsm psr.ic
620
621        add     r16=16,sp               // load EF-pointer again
622        ;;
623        //mov   r18=sp
624        movl    r18=kstack+KSTACK_PAGES * PAGE_SIZE - 16 - TF_SIZE
625        ;;
626
627                        // must have r18-efp, calls rfi at the end.
628        br.sptk restore_tf_rse_switch
629        ;;
630END(hypervisor_callback)
631
632        /*
633         * In: r30 - trap number
634         */
635ENTRY(trap_error)
636                // Calculate the stack address for storing.
637        add     r18=-TF_SIZE,sp
638        ;;
639        add     r20=TF_TRAP_NUM,r18
640        ;;
641        st2     [r20]=r30       // save trap number
642        ;;
643
644{       .mib
645        nop     0x02
646        mov     r16=ip          // for jumping back from save_tf_rse_switch
647                // Used register: r16, r18, r19, r20, r21, r22 of bank 0
648        br.sptk save_tf_rse_switch
649        ;;
650}
651
652        alloc   r15=ar.pfs,0,0,1,0      // 1 out for do_trap_error
653        ;;
654        mov     out0=r18                // the trap frame
655        add     sp=-16,r18              // C-call abi
656        ;;
657
658        //bsw.1
659        movl r30=XSI_BANKNUM
660        mov r31=1;;
661#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
662        mux1    r31=r31,@rev;;
663#endif
664        st4 [r30]=r31;;
665
666                /* Save extra interrupt registers to the trap frame. */
667        br.call.sptk.few rp = save_special_regs
668        ;;
669
670        movl    r22=XSI_PSR_IC
671        movl    r23=XSI_PSR_I_ADDR
672        ;;
673        ld8     r23=[r23]
674        mov     r25=1
675        ;;
676#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
677        mux1    r25=r25,@rev; mux1 r23=r23,@rev;;
678#endif
679        st4     [r22]=r25               // ssm psr.ic
680        st1     [r23]=r0                // ssm psr.i
681        ;;
682
683        br.call.sptk.few rp = do_trap_error
684        ;;
685                // --> currently not reached!!!
686        movl r23=XSI_PSR_I_ADDR
687        movl r22=XSI_PSR_IC
688        ;;
689        ld8 r23=[r23]
690        mov r25=1
691        ;;
692#if defined(BIG_ENDIAN)                 // swap because mini-os is in BE
693        mux1    r25=r25,@rev;;
694        mux1    r25=r25,@rev; mux1 r23=r23,@rev;;
695#endif
696        st1 [r23]=r25
697        st4 [r22]=r0            // note: clears both vpsr.i and vpsr.ic!
698        ;;
699        bsw.0
700        ;;
701        add     r18=16,sp               // load EF-pointer again
702        ;;
703        mov     sp=r18
704                        // must have r18-efp, calls rfi at the end.
705        br.sptk restore_tf_rse_switch
706        ;;
707END(trap_error)
708
709
710/*
711 * The trap handler stuff.
712 */
713
714#define TRAP_ERR(num)                   \
715        mov     r30 = num;              \
716        ;;              ;               \
717        br.sptk trap_error              \
718        ;;
719
720#define IVT_ENTRY(name, offset)                 \
721        .org    ia64_trap_table + offset;       \
722        .global hivt_##name;                    \
723        .proc   hivt_##name;                    \
724        .prologue;                              \
725        .body;                                  \
726hivt_##name:
727
728#define IVT_END(name)                           \
729        .endp   hivt_##name;                    \
730        .align  0x100
731
732#define IVT_ERR(name, num, offset)              \
733        IVT_ENTRY(name, offset);                \
734        TRAP_ERR(num);                          \
735        IVT_END(name)
736/*
737 * The IA64 Interrupt Vector Table (IVT) contains 20 slots with 64
738 * bundles per vector and 48 slots with 16 bundles per vector.
739 */
740
741        .section .text.hivt,"ax"
742        .align  32768
743        .global ia64_trap_table
744        .size   ia64_trap_table, 32768
745ia64_trap_table:
746
747IVT_ERR(VHPT_Translation, 0, 0x0)
748IVT_ERR(Instruction_TLB, 1, 0x0400)
749IVT_ERR(Data_TLB, 2, 0x0800)
750IVT_ERR(Alternate_Instruction_TLB, 3, 0x0c00)
751
752
753IVT_ENTRY(Alternate_Data_TLB, 0x1000)
754        mov     r30=4                   // trap number
755        mov     r16=cr.ifa              // where did it happen
756        mov     r31=pr                  // save predicates
757        ;;
758        extr.u  r17=r16,IA64_RR_IDX_POS,3       // get region number
759        ;;
760        cmp.eq  p14,p15=7,r17
761        ;;
762//(p14) br.sptk adt_regf_addr           // Check for region 7 - phys addresses
763//      ;;
764//      br.sptk trap_error
765//              // No return
766//
767//adt_regf_addr:
768//      extr.u  r17=r16,60,4    // get region number
769//      ;;
770//      cmp.eq  p14,p15=0xf,r17
771//      ;;
772(p14)   br.sptk adt_reg7_addr           // Check for region 7 - phys addresses
773        ;;
774        br.sptk trap_error
775
776adt_reg7_addr:
777        /*
778         * region 7 addresses are only directly mapped physically
779         * addresses. Currently I don't do a check.
780         */
781        movl    r20=~((7 << IA64_RR_IDX_POS) | 0xfff)
782        movl    r18=((PTE_PS_16K<<IA64_ITIR_PS)|(0<<IA64_ITIR_KEY))
783        ;;
784        movl    r19=    ((1<<PTE_OFF_P) | (PTE_MA_WB<<PTE_OFF_MA) | \
785                         (1<<PTE_OFF_A) | (1<<PTE_OFF_D) | \
786                         (PTE_PL_KERN<<PTE_OFF_PL) | (PTE_AR_RW<<PTE_OFF_AR))
787                        // clear the region bits and 0-11
788                        // extract the pfn from the ifa
789        mov     cr.itir=r18
790        and     r20=r20, r16
791        ;;
792        or      r20=r20,r19             // put pfn into pte
793        ;;
794        mov     pr=r31,-1               // restore predicates
795        itc.d   r20
796        ;;
797        XEN_HYPER_RFI;
798        ;;
799
800IVT_END(Alternate_Data_TLB)
801
802
803IVT_ERR(Data_Nested_TLB, 5, 0x1400)
804IVT_ERR(Instruction_Key_Miss, 6, 0x1800)
805IVT_ERR(Data_Key_Miss, 7, 0x1c00)
806IVT_ERR(Dirty_Bit, 8, 0x2000)
807IVT_ERR(Instruction_Access_Bit, 9, 0x2400)
808IVT_ERR(Data_Access_Bit, 10, 0x2800)
809IVT_ERR(Break_Instruction, 11, 0x2c00)
810IVT_ERR(External_Interrupt, 12, 0x3000)
811IVT_ERR(Reserved_3400, 13, 0x3400)
812IVT_ERR(Reserved_3800, 14, 0x3800)
813IVT_ERR(Reserved_3c00, 15, 0x3c00)
814IVT_ERR(Reserved_4000, 16, 0x4000)
815IVT_ERR(Reserved_4400, 17, 0x4400)
816IVT_ERR(Reserved_4800, 18, 0x4800)
817IVT_ERR(Reserved_4c00, 19, 0x4c00)
818IVT_ERR(Page_Not_Present, 20, 0x5000)
819IVT_ERR(Key_Permission, 21, 0x5100)
820IVT_ERR(Instruction_Access_Rights, 22, 0x5200)
821IVT_ERR(Data_Access_Rights, 23, 0x5300)
822IVT_ERR(General_Exception, 24, 0x5400)
823IVT_ERR(Disabled_FP_Register, 25, 0x5500)
824IVT_ERR(NaT_Consumption, 26, 0x5600)
825IVT_ERR(Speculation, 27, 0x5700)
826IVT_ERR(Reserved_5800, 28, 0x5800)
827IVT_ERR(Debug, 29, 0x5900)
828IVT_ERR(Unaligned_Reference, 30, 0x5a00)
829IVT_ERR(Unsupported_Data_Reference, 31, 0x5b00)
830IVT_ERR(Floating_Point_Fault, 32, 0x5c00)
831IVT_ERR(Floating_Point_Trap, 33, 0x5d00)
832IVT_ERR(Lower_Privilege_Transfer_Trap, 34, 0x5e00)
833IVT_ERR(Taken_Branch_Trap, 35, 0x5f00)
834IVT_ERR(Single_Step_Trap, 36, 0x6000)
835IVT_ERR(Reserved_6100, 37, 0x6100)
836IVT_ERR(Reserved_6200, 38, 0x6200)
837IVT_ERR(Reserved_6300, 39, 0x6300)
838IVT_ERR(Reserved_6400, 40, 0x6400)
839IVT_ERR(Reserved_6500, 41, 0x6500)
840IVT_ERR(Reserved_6600, 42, 0x6600)
841IVT_ERR(Reserved_6700, 43, 0x6700)
842IVT_ERR(Reserved_6800, 44, 0x6800)
843IVT_ERR(IA_32_Exception, 45, 0x6900)
844IVT_ERR(IA_32_Intercept, 46, 0x6a00)
845IVT_ERR(IA_32_Interrupt, 47, 0x6b00)
846IVT_ERR(Reserved_6c00, 48, 0x6c00)
847IVT_ERR(Reserved_6d00, 49, 0x6d00)
848IVT_ERR(Reserved_6e00, 50, 0x6e00)
849IVT_ERR(Reserved_6f00, 51, 0x6f00)
850IVT_ERR(Reserved_7000, 52, 0x7000)
851IVT_ERR(Reserved_7100, 53, 0x7100)
852IVT_ERR(Reserved_7200, 54, 0x7200)
853IVT_ERR(Reserved_7300, 55, 0x7300)
854IVT_ERR(Reserved_7400, 56, 0x7400)
855IVT_ERR(Reserved_7500, 57, 0x7500)
856IVT_ERR(Reserved_7600, 58, 0x7600)
857IVT_ERR(Reserved_7700, 59, 0x7700)
858IVT_ERR(Reserved_7800, 60, 0x7800)
859IVT_ERR(Reserved_7900, 61, 0x7900)
860IVT_ERR(Reserved_7a00, 62, 0x7a00)
861IVT_ERR(Reserved_7b00, 63, 0x7b00)
862IVT_ERR(Reserved_7c00, 64, 0x7c00)
863IVT_ERR(Reserved_7d00, 65, 0x7d00)
864IVT_ERR(Reserved_7e00, 66, 0x7e00)
865IVT_ERR(Reserved_7f00, 67, 0x7f00)
Note: See TracBrowser for help on using the repository browser.