debuggers.hg

view extras/mini-os/arch/ia64/ivt.S @ 0:7d21f7218375

Exact replica of unstable on 051908 + README-this
author Mukesh Rathor
date Mon May 19 15:34:57 2008 -0700 (2008-05-19)
parents
children 46f8fc57b1a4
line source
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 */
27 #include "asm.h"
28 #include "page.h"
29 #include "ia64_cpu.h"
30 #include "privop.h"
31 #include "offsets.h"
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 */
43 #define FILL_FP_PAIR(f1, f2, b1, b2) \
44 ldf.fill f1=[b1],32 ;\
45 ldf.fill f2=[b2],32 ;\
46 ;;
48 #define SPILL_FP_PAIR(f1, f2, b1, b2) \
49 stf.spill [b1]=f1,32 ;\
50 stf.spill [b2]=f2,32 ;\
51 ;;
53 #define FILL_REG_PAIR(r1, r2, b1, b2) \
54 ld8.fill r1=[b1],16 ;\
55 ld8.fill r2=[b2],16 ;\
56 ;;
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 ;;
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 */
84 ENTRY(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 ;;
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
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)
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
230 //// r16 return jump pointer, r18 - trap frame base,
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 ;;
306 { .mfb
307 srlz.d
308 nop 0
309 br.sptk b7
310 ;;
311 }
313 END(save_tf_rse_switch)
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 */
327 ENTRY(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)
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;
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)
520 //// r18 - trap frame base,
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 ;;
557 END(restore_tf_rse_switch)
560 ENTRY(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
586 END(save_special_regs)
589 ENTRY(hypervisor_callback)
590 /*
591 * Use the thread stack here for storing the trap frame.
592 * It's not wired mapped, so nested data tlb faults may occur!
593 */
594 add r18=-TF_SIZE,sp
595 ;;
596 { .mib
597 nop 0x02
598 mov r16=ip // for jump back from save_tf_rse_switch
599 br.sptk save_tf_rse_switch
600 ;;
601 }
602 add sp=-16,r18 // the new stack
603 alloc r15=ar.pfs,0,0,1,0 // 1 out for do_hypervisor_callback
604 ;;
605 mov out0=r18 // the trap frame
606 movl r22=XSI_PSR_IC
607 mov r23=1;;
608 #if defined(BIG_ENDIAN) // swap because mini-os is in BE
609 mux1 r23=r23,@rev;;
610 #endif
611 st8 [r22]=r23 // ssm psr.ic
612 ;;
613 br.call.sptk.few rp = do_hypervisor_callback
615 movl r22=XSI_PSR_IC
616 ;;
617 st4 [r22]=r0 // rsm psr.ic
618 add r18=16,sp // load EF-pointer again
619 ;;
620 // must have r18-efp, calls rfi at the end.
621 br.sptk restore_tf_rse_switch
622 ;;
623 END(hypervisor_callback)
625 /*
626 * In: r30 - trap number
627 */
628 ENTRY(trap_error)
629 // Calculate the stack address for storing.
630 add r18=-TF_SIZE,sp
631 ;;
632 add r20=TF_TRAP_NUM,r18
633 ;;
634 st2 [r20]=r30 // save trap number
635 ;;
637 { .mib
638 nop 0x02
639 mov r16=ip // for jumping back from save_tf_rse_switch
640 // Used register: r16, r18, r19, r20, r21, r22 of bank 0
641 br.sptk save_tf_rse_switch
642 ;;
643 }
645 alloc r15=ar.pfs,0,0,1,0 // 1 out for do_trap_error
646 ;;
647 mov out0=r18 // the trap frame
648 add sp=-16,r18 // C-call abi
649 ;;
650 movl r30=XSI_BANKNUM // bsw.1
651 mov r31=1;;
652 #if defined(BIG_ENDIAN) // swap because mini-os is in BE
653 mux1 r31=r31,@rev;;
654 #endif
655 st4 [r30]=r31;;
657 /* Save extra interrupt registers to the trap frame. */
658 br.call.sptk.few rp = save_special_regs
659 ;;
661 movl r22=XSI_PSR_IC
662 movl r23=XSI_PSR_I_ADDR
663 ;;
664 ld8 r23=[r23]
665 mov r25=1
666 ;;
667 #if defined(BIG_ENDIAN) // swap because mini-os is in BE
668 mux1 r25=r25,@rev; mux1 r23=r23,@rev;;
669 #endif
670 st4 [r22]=r25 // ssm psr.ic
671 st1 [r23]=r0 // ssm psr.i
672 ;;
674 br.call.sptk.few rp = do_trap_error
675 ;;
676 // --> currently not reached!!!
677 movl r23=XSI_PSR_I_ADDR
678 movl r22=XSI_PSR_IC
679 ;;
680 ld8 r23=[r23]
681 mov r25=1
682 ;;
683 #if defined(BIG_ENDIAN) // swap because mini-os is in BE
684 mux1 r25=r25,@rev;;
685 mux1 r25=r25,@rev; mux1 r23=r23,@rev;;
686 #endif
687 st1 [r23]=r25
688 st4 [r22]=r0 // note: clears both vpsr.i and vpsr.ic!
689 ;;
690 bsw.0
691 ;;
692 add r18=16,sp // load EF-pointer again
693 ;;
694 mov sp=r18
695 // must have r18-efp, calls rfi at the end.
696 br.sptk restore_tf_rse_switch
697 ;;
698 END(trap_error)
701 /*
702 * The trap handler stuff.
703 */
705 #define TRAP_ERR(num) \
706 mov r30 = num; \
707 ;; ; \
708 br.sptk trap_error \
709 ;;
711 #define IVT_ENTRY(name, offset) \
712 .org ia64_trap_table + offset; \
713 .global hivt_##name; \
714 .proc hivt_##name; \
715 .prologue; \
716 .body; \
717 hivt_##name:
719 #define IVT_END(name) \
720 .endp hivt_##name; \
721 .align 0x100
723 #define IVT_ERR(name, num, offset) \
724 IVT_ENTRY(name, offset); \
725 TRAP_ERR(num); \
726 IVT_END(name)
727 /*
728 * The IA64 Interrupt Vector Table (IVT) contains 20 slots with 64
729 * bundles per vector and 48 slots with 16 bundles per vector.
730 */
732 .section .text.hivt,"ax"
733 .align 32768
734 .global ia64_trap_table
735 .size ia64_trap_table, 32768
736 ia64_trap_table:
738 IVT_ERR(VHPT_Translation, 0, 0x0)
739 IVT_ERR(Instruction_TLB, 1, 0x0400)
740 IVT_ERR(Data_TLB, 2, 0x0800)
741 IVT_ERR(Alternate_Instruction_TLB, 3, 0x0c00)
744 IVT_ENTRY(Alternate_Data_TLB, 0x1000)
745 mov r30=4 // trap number
746 adt_common:
747 mov r16=cr.ifa // where did it happen
748 mov r31=pr // save predicates
749 ;;
750 extr.u r17=r16,IA64_RR_IDX_POS,3 // get region number
751 ;;
752 cmp.eq p14,p15=7,r17
753 ;;
754 //(p14) br.sptk adt_regf_addr // Check for region 7 - phys addresses
755 // ;;
756 // br.sptk trap_error
757 // // No return
758 //
759 //adt_regf_addr:
760 // extr.u r17=r16,60,4 // get region number
761 // ;;
762 // cmp.eq p14,p15=0xf,r17
763 // ;;
764 (p14) br.sptk adt_reg7_addr // Check for region 7 - phys addresses
765 ;;
766 br.sptk trap_error
768 adt_reg7_addr:
769 /*
770 * region 7 addresses are only directly mapped physically
771 * addresses. Currently I don't do a check.
772 */
773 movl r20=~((7 << IA64_RR_IDX_POS) | 0xfff)
774 movl r18=((PTE_PS_16K<<IA64_ITIR_PS)|(IA64_KEY_REG7<<IA64_ITIR_KEY))
775 ;;
776 movl r19= ((1<<PTE_OFF_P) | (PTE_MA_WB<<PTE_OFF_MA) | \
777 (1<<PTE_OFF_A) | (1<<PTE_OFF_D) | \
778 (PTE_PL_KERN<<PTE_OFF_PL) | (PTE_AR_RW<<PTE_OFF_AR))
779 // clear the region bits and 0-11
780 // extract the pfn from the ifa
781 mov cr.itir=r18
782 and r20=r20, r16
783 ;;
784 or r20=r20,r19 // put pfn into pte
785 ;;
786 mov pr=r31,-1 // restore predicates
787 itc.d r20
788 ;;
789 XEN_HYPER_RFI;
790 ;;
792 IVT_END(Alternate_Data_TLB)
794 /*
795 * Handling of nested data tlb is needed, because in hypervisor_callback()
796 * the stack is used to store the register trap frame. This stack is allocated
797 * dynamically (as identity mapped address) and therewidth no tr mapped page!
798 */
799 IVT_ENTRY(Data_Nested_TLB, 0x1400)
801 mov r30=5 // trap number
802 add r28=-TF_SIZE,sp // r28 is never used in trap handling
803 ;;
804 mov cr.ifa=r28
805 ;;
806 br.sptk adt_common
807 IVT_END(Data_Nested_TLB)
811 IVT_ERR(Instruction_Key_Miss, 6, 0x1800)
812 IVT_ERR(Data_Key_Miss, 7, 0x1c00)
813 IVT_ERR(Dirty_Bit, 8, 0x2000)
814 IVT_ERR(Instruction_Access_Bit, 9, 0x2400)
815 IVT_ERR(Data_Access_Bit, 10, 0x2800)
816 IVT_ERR(Break_Instruction, 11, 0x2c00)
817 IVT_ERR(External_Interrupt, 12, 0x3000)
818 IVT_ERR(Reserved_3400, 13, 0x3400)
819 IVT_ERR(Reserved_3800, 14, 0x3800)
820 IVT_ERR(Reserved_3c00, 15, 0x3c00)
821 IVT_ERR(Reserved_4000, 16, 0x4000)
822 IVT_ERR(Reserved_4400, 17, 0x4400)
823 IVT_ERR(Reserved_4800, 18, 0x4800)
824 IVT_ERR(Reserved_4c00, 19, 0x4c00)
825 IVT_ERR(Page_Not_Present, 20, 0x5000)
826 IVT_ERR(Key_Permission, 21, 0x5100)
827 IVT_ERR(Instruction_Access_Rights, 22, 0x5200)
828 IVT_ERR(Data_Access_Rights, 23, 0x5300)
829 IVT_ERR(General_Exception, 24, 0x5400)
830 IVT_ERR(Disabled_FP_Register, 25, 0x5500)
831 IVT_ERR(NaT_Consumption, 26, 0x5600)
832 IVT_ERR(Speculation, 27, 0x5700)
833 IVT_ERR(Reserved_5800, 28, 0x5800)
834 IVT_ERR(Debug, 29, 0x5900)
835 IVT_ERR(Unaligned_Reference, 30, 0x5a00)
836 IVT_ERR(Unsupported_Data_Reference, 31, 0x5b00)
837 IVT_ERR(Floating_Point_Fault, 32, 0x5c00)
838 IVT_ERR(Floating_Point_Trap, 33, 0x5d00)
839 IVT_ERR(Lower_Privilege_Transfer_Trap, 34, 0x5e00)
840 IVT_ERR(Taken_Branch_Trap, 35, 0x5f00)
841 IVT_ERR(Single_Step_Trap, 36, 0x6000)
842 IVT_ERR(Reserved_6100, 37, 0x6100)
843 IVT_ERR(Reserved_6200, 38, 0x6200)
844 IVT_ERR(Reserved_6300, 39, 0x6300)
845 IVT_ERR(Reserved_6400, 40, 0x6400)
846 IVT_ERR(Reserved_6500, 41, 0x6500)
847 IVT_ERR(Reserved_6600, 42, 0x6600)
848 IVT_ERR(Reserved_6700, 43, 0x6700)
849 IVT_ERR(Reserved_6800, 44, 0x6800)
850 IVT_ERR(IA_32_Exception, 45, 0x6900)
851 IVT_ERR(IA_32_Intercept, 46, 0x6a00)
852 IVT_ERR(IA_32_Interrupt, 47, 0x6b00)
853 IVT_ERR(Reserved_6c00, 48, 0x6c00)
854 IVT_ERR(Reserved_6d00, 49, 0x6d00)
855 IVT_ERR(Reserved_6e00, 50, 0x6e00)
856 IVT_ERR(Reserved_6f00, 51, 0x6f00)
857 IVT_ERR(Reserved_7000, 52, 0x7000)
858 IVT_ERR(Reserved_7100, 53, 0x7100)
859 IVT_ERR(Reserved_7200, 54, 0x7200)
860 IVT_ERR(Reserved_7300, 55, 0x7300)
861 IVT_ERR(Reserved_7400, 56, 0x7400)
862 IVT_ERR(Reserved_7500, 57, 0x7500)
863 IVT_ERR(Reserved_7600, 58, 0x7600)
864 IVT_ERR(Reserved_7700, 59, 0x7700)
865 IVT_ERR(Reserved_7800, 60, 0x7800)
866 IVT_ERR(Reserved_7900, 61, 0x7900)
867 IVT_ERR(Reserved_7a00, 62, 0x7a00)
868 IVT_ERR(Reserved_7b00, 63, 0x7b00)
869 IVT_ERR(Reserved_7c00, 64, 0x7c00)
870 IVT_ERR(Reserved_7d00, 65, 0x7d00)
871 IVT_ERR(Reserved_7e00, 66, 0x7e00)
872 IVT_ERR(Reserved_7f00, 67, 0x7f00)