Import changeset
[linux-flexiantxendom0-3.2.10.git] / arch / ia64 / kernel / mca_asm.S
1 // 
2 // assembly portion of the IA64 MCA handling
3 //
4 // Mods by cfleck to integrate into kernel build
5 // 00/03/15 davidm Added various stop bits to get a clean compile
6 //
7 // 00/03/29 cfleck Added code to save INIT handoff state in pt_regs format, switch to temp
8 //                 kstack, switch modes, jump to C INIT handler
9 //
10 #include <linux/config.h>
11 #include <asm/pgtable.h>
12 #include <asm/processor.h>
13 #include <asm/mca_asm.h>
14 #include <asm/mca.h>
15
16 /*
17  * When we get an machine check, the kernel stack pointer is no longer
18  * valid, so we need to set a new stack pointer.
19  */
20 #define MINSTATE_PHYS   /* Make sure stack access is physical for MINSTATE */ 
21
22 #include "minstate.h"
23         
24         .psr abi64
25         .psr lsb
26         .lsb
27
28 /*
29  *      SAL_TO_OS_MCA_HANDOFF_STATE
30  *              1. GR1 = OS GP
31  *              2. GR8 = PAL_PROC physical address
32  *              3. GR9 = SAL_PROC physical address
33  *              4. GR10 = SAL GP (physical)
34  *              5. GR11 = Rendez state
35  *              6. GR12 = Return address to location within SAL_CHECK
36  */
37 #define SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(_tmp)          \
38         movl    _tmp=ia64_sal_to_os_handoff_state;;     \
39         st8     [_tmp]=r1,0x08;;                        \
40         st8     [_tmp]=r8,0x08;;                        \
41         st8     [_tmp]=r9,0x08;;                        \
42         st8     [_tmp]=r10,0x08;;                       \
43         st8     [_tmp]=r11,0x08;;                       \
44         st8     [_tmp]=r12,0x08;;
45
46 /*
47  *      OS_MCA_TO_SAL_HANDOFF_STATE
48  *              1. GR8 = OS_MCA status
49  *              2. GR9 = SAL GP (physical)
50  *              3. GR22 = New min state save area pointer
51  */     
52 #define OS_MCA_TO_SAL_HANDOFF_STATE_RESTORE(_tmp)       \
53         movl    _tmp=ia64_os_to_sal_handoff_state;;     \
54         DATA_VA_TO_PA(_tmp);;                           \
55         ld8     r8=[_tmp],0x08;;                        \
56         ld8     r9=[_tmp],0x08;;                        \
57         ld8     r22=[_tmp],0x08;;
58
59 /*
60  *      BRANCH
61  *              Jump to the instruction referenced by
62  *      "to_label".
63  *              Branch is taken only if the predicate
64  *      register "p" is true.
65  *              "ip" is the address of the instruction
66  *      located at "from_label".
67  *              "temp" is a scratch register like r2
68  *              "adjust" needed for HP compiler. 
69  *      A screwup somewhere with constant arithmetic.
70  */     
71 #define BRANCH(to_label, temp, p, adjust)               \
72 100:    (p)     mov             temp=ip;                \
73                 ;;                                      \
74         (p)     adds            temp=to_label-100b,temp;\
75                 ;;                                      \
76         (p)     adds            temp=adjust,temp;       \
77                 ;;                                      \
78         (p)     mov             b1=temp ;               \
79         (p)     br              b1      
80
81         .global ia64_os_mca_dispatch
82         .global ia64_os_mca_dispatch_end
83         .global ia64_sal_to_os_handoff_state
84         .global ia64_os_to_sal_handoff_state
85         .global ia64_os_mca_ucmc_handler
86         .global ia64_mca_proc_state_dump
87         .global ia64_mca_proc_state_restore
88         .global ia64_mca_stack
89         .global ia64_mca_stackframe
90         .global ia64_mca_bspstore
91         .global ia64_init_stack 
92                         
93         .text
94         .align 16
95         
96 ia64_os_mca_dispatch:
97
98 #if defined(MCA_TEST)
99         // Pretend that we are in interrupt context
100         mov             r2=psr
101         dep             r2=0, r2, PSR_IC, 2;
102         mov             psr.l = r2
103 #endif  /* #if defined(MCA_TEST) */
104
105         // Save the SAL to OS MCA handoff state as defined
106         // by SAL SPEC 2.5
107         // NOTE : The order in which the state gets saved
108         //        is dependent on the way the C-structure
109         //        for ia64_mca_sal_to_os_state_t has been
110         //        defined in include/asm/mca.h
111         SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(r2)
112
113         // LOG PROCESSOR STATE INFO FROM HERE ON..
114         ;;
115 begin_os_mca_dump:
116         BRANCH(ia64_os_mca_proc_state_dump, r2, p0, 0x0)
117         ;;
118 ia64_os_mca_done_dump:
119
120         // Setup new stack frame for OS_MCA handling 
121         movl        r2=ia64_mca_bspstore                // local bspstore area location in r2
122         movl        r3=ia64_mca_stackframe              // save stack frame to memory in r3
123         rse_switch_context(r6,r3,r2);;                  // RSC management in this new context
124         movl        r12=ia64_mca_stack;;
125
126         // Enter virtual mode from physical mode
127         VIRTUAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_begin, r4)
128 ia64_os_mca_virtual_begin:
129
130         // call our handler
131         movl            r2=ia64_mca_ucmc_handler;;
132         mov             b6=r2;;
133         br.call.sptk.few        b0=b6
134 .ret0:
135         // Revert back to physical mode before going back to SAL
136         PHYSICAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_end, r4)
137 ia64_os_mca_virtual_end:
138
139 #if defined(MCA_TEST)
140         // Pretend that we are in interrupt context
141         mov             r2=psr
142         dep             r2=0, r2, PSR_IC, 2;
143         mov             psr.l = r2
144 #endif  /* #if defined(MCA_TEST) */
145
146         // restore the original stack frame here
147         movl    r2=ia64_mca_stackframe               // restore stack frame from memory at r2
148         ;;
149         DATA_VA_TO_PA(r2)
150         movl    r4=IA64_PSR_MC
151         ;;
152         rse_return_context(r4,r3,r2)                 // switch from interrupt context for RSE
153         
154         // let us restore all the registers from our PSI structure
155         mov             r8=gp
156         ;;
157 begin_os_mca_restore:
158         BRANCH(ia64_os_mca_proc_state_restore, r2, p0, 0x0)
159         ;;
160
161 ia64_os_mca_done_restore:
162         ;;
163 #ifdef SOFTSDV
164         VIRTUAL_MODE_ENTER(r2,r3, vmode_enter, r4)
165 vmode_enter:    
166         br.ret.sptk.few         b0      
167 #else
168         // branch back to SALE_CHECK
169         OS_MCA_TO_SAL_HANDOFF_STATE_RESTORE(r2)
170         ld8             r3=[r2];;              
171         mov             b0=r3                       // SAL_CHECK return address
172         br              b0
173         ;;
174 #endif /* #ifdef SOFTSDV */
175 ia64_os_mca_dispatch_end:       
176 //EndMain//////////////////////////////////////////////////////////////////////
177
178
179 //++
180 // Name:
181 //      ia64_os_mca_proc_state_dump()
182 // 
183 // Stub Description:
184 //
185 //       This stub dumps the processor state during MCHK to a data area
186 //
187 //--
188
189 ia64_os_mca_proc_state_dump:
190 // Get and save GR0-31 from Proc. Min. State Save Area to SAL PSI
191         movl            r2=ia64_mca_proc_state_dump;;           // Os state dump area
192
193 // save ar.NaT 
194         mov             r5=ar.unat                  // ar.unat
195
196 // save banked GRs 16-31 along with NaT bits
197         bsw.1;;
198         st8.spill       [r2]=r16,8;;
199         st8.spill       [r2]=r17,8;;
200         st8.spill       [r2]=r18,8;;
201         st8.spill       [r2]=r19,8;;
202         st8.spill       [r2]=r20,8;;
203         st8.spill       [r2]=r21,8;;
204         st8.spill       [r2]=r22,8;;
205         st8.spill       [r2]=r23,8;;
206         st8.spill       [r2]=r24,8;;
207         st8.spill       [r2]=r25,8;;
208         st8.spill       [r2]=r26,8;;
209         st8.spill       [r2]=r27,8;;
210         st8.spill       [r2]=r28,8;;
211         st8.spill       [r2]=r29,8;;
212         st8.spill       [r2]=r30,8;;
213         st8.spill       [r2]=r31,8;;
214
215         mov             r4=ar.unat;;
216         st8             [r2]=r4,8                // save User NaT bits for r16-r31
217         mov             ar.unat=r5                  // restore original unat
218         bsw.0;;
219
220 //save BRs
221         add             r4=8,r2                  // duplicate r2 in r4
222         add             r6=2*8,r2                // duplicate r2 in r4
223
224         mov             r3=b0
225         mov             r5=b1
226         mov             r7=b2;;
227         st8             [r2]=r3,3*8
228         st8             [r4]=r5,3*8
229         st8             [r6]=r7,3*8;;  
230
231         mov             r3=b3
232         mov             r5=b4
233         mov             r7=b5;;
234         st8             [r2]=r3,3*8
235         st8             [r4]=r5,3*8
236         st8             [r6]=r7,3*8;;  
237
238         mov             r3=b6
239         mov             r5=b7;;
240         st8             [r2]=r3,2*8
241         st8             [r4]=r5,2*8;;
242
243 cSaveCRs:
244 // save CRs
245         add             r4=8,r2                  // duplicate r2 in r4
246         add             r6=2*8,r2                // duplicate r2 in r4
247
248         mov             r3=cr0                      // cr.dcr
249         mov             r5=cr1                      // cr.itm
250         mov             r7=cr2;;                    // cr.iva
251
252         st8             [r2]=r3,8*8
253         st8             [r4]=r5,3*8
254         st8             [r6]=r7,3*8;;            // 48 byte rements
255
256         mov             r3=cr8;;                    // cr.pta
257         st8             [r2]=r3,8*8;;            // 64 byte rements
258
259 // if PSR.ic=0, reading interruption registers causes an illegal operation fault
260         mov             r3=psr;;
261         tbit.nz.unc     p2,p0=r3,PSR_IC;;           // PSI Valid Log bit pos. test
262 (p2)    st8             [r2]=r0,9*8+160             // increment by 168 byte inc.
263 begin_skip_intr_regs:   
264         BRANCH(SkipIntrRegs,  r9, p2, 0x0)
265         ;; 
266         add             r4=8,r2                  // duplicate r2 in r4
267         add             r6=2*8,r2                // duplicate r2 in r6
268         
269         mov             r3=cr16                     // cr.ipsr
270         mov             r5=cr17                     // cr.isr
271         mov             r7=r0;;                     // cr.ida => cr18
272         st8             [r2]=r3,3*8
273         st8             [r4]=r5,3*8
274         st8             [r6]=r7,3*8;;                                      
275
276         mov             r3=cr19                     // cr.iip
277         mov             r5=cr20                     // cr.idtr
278         mov             r7=cr21;;                   // cr.iitr
279         st8             [r2]=r3,3*8
280         st8             [r4]=r5,3*8
281         st8             [r6]=r7,3*8;;                                      
282
283         mov             r3=cr22                     // cr.iipa
284         mov             r5=cr23                     // cr.ifs
285         mov             r7=cr24;;                   // cr.iim
286         st8             [r2]=r3,3*8
287         st8             [r4]=r5,3*8
288         st8             [r6]=r7,3*8;;    
289                                           
290         mov             r3=cr25;;                   // cr.iha
291         st8             [r2]=r3,160;;               // 160 byte rement
292
293 SkipIntrRegs:
294         st8             [r2]=r0,168                 // another 168 byte .
295
296         mov             r3=cr66;;                   // cr.lid
297         st8             [r2]=r3,40                  // 40 byte rement
298
299         mov             r3=cr71;;                   // cr.ivr
300         st8             [r2]=r3,8
301
302         mov             r3=cr72;;                   // cr.tpr
303         st8             [r2]=r3,24                  // 24 byte increment
304     
305         mov             r3=r0;;                     // cr.eoi => cr75
306         st8             [r2]=r3,168                 // 168 byte inc.
307     
308         mov             r3=r0;;                     // cr.irr0 => cr96
309         st8             [r2]=r3,16               // 16 byte inc.
310
311         mov             r3=r0;;                     // cr.irr1 => cr98
312         st8             [r2]=r3,16               // 16 byte inc.
313
314         mov             r3=r0;;                     // cr.irr2 => cr100
315         st8             [r2]=r3,16               // 16 byte inc
316
317         mov             r3=r0;;                     // cr.irr3 => cr100
318         st8             [r2]=r3,16               // 16b inc.
319
320         mov             r3=r0;;                     // cr.itv => cr114
321         st8             [r2]=r3,16               // 16 byte inc.
322
323         mov             r3=r0;;                     // cr.pmv => cr116
324         st8             [r2]=r3,8
325
326         mov             r3=r0;;                     // cr.lrr0 => cr117
327         st8             [r2]=r3,8
328
329         mov             r3=r0;;                     // cr.lrr1 => cr118
330         st8             [r2]=r3,8
331
332         mov             r3=r0;;                     // cr.cmcv => cr119
333         st8             [r2]=r3,8*10;;
334
335 cSaveARs:
336 // save ARs
337         add             r4=8,r2                  // duplicate r2 in r4
338         add             r6=2*8,r2                // duplicate r2 in r6
339
340         mov             r3=ar0                      // ar.kro
341         mov             r5=ar1                      // ar.kr1
342         mov             r7=ar2;;                    // ar.kr2
343         st8             [r2]=r3,3*8
344         st8             [r4]=r5,3*8
345         st8             [r6]=r7,3*8;;
346
347         mov             r3=ar3                      // ar.kr3                               
348         mov             r5=ar4                      // ar.kr4
349         mov             r7=ar5;;                    // ar.kr5
350         st8             [r2]=r3,3*8
351         st8             [r4]=r5,3*8
352         st8             [r6]=r7,3*8;;
353
354         mov             r3=ar6                      // ar.kr6
355         mov             r5=ar7                      // ar.kr7
356         mov             r7=r0;;                     // ar.kr8
357         st8             [r2]=r3,10*8
358         st8             [r4]=r5,10*8
359         st8             [r6]=r7,10*8;;           // rement by 72 bytes
360
361         mov             r3=ar16                     // ar.rsc
362         mov             ar16=r0                     // put RSE in enforced lazy mode
363         mov             r5=ar17                     // ar.bsp
364         ;;
365         mov             r7=ar18;;                   // ar.bspstore
366         st8             [r2]=r3,3*8
367         st8             [r4]=r5,3*8
368         st8             [r6]=r7,3*8;;
369
370         mov             r3=ar19;;                   // ar.rnat
371         st8             [r2]=r3,8*13             // increment by 13x8 bytes
372
373         mov             r3=ar32;;                   // ar.ccv
374         st8             [r2]=r3,8*4
375
376         mov             r3=ar36;;                   // ar.unat
377         st8             [r2]=r3,8*4
378
379         mov             r3=ar40;;                   // ar.fpsr
380         st8             [r2]=r3,8*4
381
382         mov             r3=ar44;;                   // ar.itc
383         st8             [r2]=r3,160                 // 160
384
385         mov             r3=ar64;;                   // ar.pfs
386         st8             [r2]=r3,8
387
388         mov             r3=ar65;;                   // ar.lc
389         st8             [r2]=r3,8
390
391         mov             r3=ar66;;                   // ar.ec
392         st8             [r2]=r3
393         add             r2=8*62,r2               //padding
394     
395 // save RRs
396         mov             ar.lc=0x08-1
397         movl            r4=0x00;;
398
399 cStRR:
400         mov             r3=rr[r4];;
401         st8             [r2]=r3,8
402         add             r4=1,r4
403         br.cloop.sptk.few       cStRR
404         ;;
405 end_os_mca_dump:
406         BRANCH(ia64_os_mca_done_dump, r2, p0, -0x10)
407         ;;
408
409 //EndStub//////////////////////////////////////////////////////////////////////
410
411
412 //++
413 // Name:
414 //       ia64_os_mca_proc_state_restore()
415 // 
416 // Stub Description:
417 //
418 //       This is a stub to restore the saved processor state during MCHK
419 //
420 //--
421
422 ia64_os_mca_proc_state_restore:
423
424 // Restore bank1 GR16-31 
425         movl            r2=ia64_mca_proc_state_dump     // Convert virtual address
426         ;;                                              // of OS state dump area
427         DATA_VA_TO_PA(r2)                               // to physical address
428         ;;
429 restore_GRs:                                    // restore bank-1 GRs 16-31
430         bsw.1;;
431         add             r3=16*8,r2;;                // to get to NaT of GR 16-31
432         ld8             r3=[r3];;
433         mov             ar.unat=r3;;                // first restore NaT
434
435         ld8.fill        r16=[r2],8;;
436         ld8.fill        r17=[r2],8;;
437         ld8.fill        r18=[r2],8;;
438         ld8.fill        r19=[r2],8;;
439         ld8.fill        r20=[r2],8;;
440         ld8.fill        r21=[r2],8;;
441         ld8.fill        r22=[r2],8;;
442         ld8.fill        r23=[r2],8;;
443         ld8.fill        r24=[r2],8;;
444         ld8.fill        r25=[r2],8;;
445         ld8.fill        r26=[r2],8;;
446         ld8.fill        r27=[r2],8;;
447         ld8.fill        r28=[r2],8;;
448         ld8.fill        r29=[r2],8;;
449         ld8.fill        r30=[r2],8;;
450         ld8.fill        r31=[r2],8;;
451
452         ld8             r3=[r2],8;;              // increment to skip NaT
453         bsw.0;;
454
455 restore_BRs:
456         add             r4=8,r2                  // duplicate r2 in r4
457         add             r6=2*8,r2;;              // duplicate r2 in r4
458
459         ld8             r3=[r2],3*8
460         ld8             r5=[r4],3*8
461         ld8             r7=[r6],3*8;;  
462         mov             b0=r3
463         mov             b1=r5
464         mov             b2=r7;;
465
466         ld8             r3=[r2],3*8
467         ld8             r5=[r4],3*8
468         ld8             r7=[r6],3*8;;  
469         mov             b3=r3
470         mov             b4=r5
471         mov             b5=r7;;
472
473         ld8             r3=[r2],2*8
474         ld8             r5=[r4],2*8;;  
475         mov             b6=r3
476         mov             b7=r5;;
477
478 restore_CRs:
479         add             r4=8,r2                  // duplicate r2 in r4
480         add             r6=2*8,r2;;              // duplicate r2 in r4
481
482         ld8             r3=[r2],8*8
483         ld8             r5=[r4],3*8
484         ld8             r7=[r6],3*8;;            // 48 byte increments
485         mov             cr0=r3                      // cr.dcr
486         mov             cr1=r5                      // cr.itm
487         mov             cr2=r7;;                    // cr.iva
488
489         ld8             r3=[r2],8*8;;            // 64 byte increments
490 //      mov             cr8=r3                      // cr.pta
491
492
493 // if PSR.ic=1, reading interruption registers causes an illegal operation fault
494         mov             r3=psr;;
495         tbit.nz.unc     p2,p0=r3,PSR_IC;;           // PSI Valid Log bit pos. test
496 (p2)    st8             [r2]=r0,9*8+160             // increment by 160 byte inc.
497
498 begin_rskip_intr_regs:  
499         BRANCH(rSkipIntrRegs, r9, p2, 0x0)
500         ;; 
501
502         add             r4=8,r2                  // duplicate r2 in r4
503         add             r6=2*8,r2;;              // duplicate r2 in r4
504
505         ld8             r3=[r2],3*8
506         ld8             r5=[r4],3*8
507         ld8             r7=[r6],3*8;;
508         mov             cr16=r3                     // cr.ipsr
509         mov             cr17=r5                     // cr.isr is read only
510 //      mov             cr18=r7;;                   // cr.ida
511
512         ld8             r3=[r2],3*8
513         ld8             r5=[r4],3*8
514         ld8             r7=[r6],3*8;;
515         mov             cr19=r3                     // cr.iip
516         mov             cr20=r5                     // cr.idtr
517         mov             cr21=r7;;                   // cr.iitr
518
519         ld8             r3=[r2],3*8
520         ld8             r5=[r4],3*8
521         ld8             r7=[r6],3*8;;
522         mov             cr22=r3                     // cr.iipa
523         mov             cr23=r5                     // cr.ifs
524         mov             cr24=r7                     // cr.iim
525
526         ld8             r3=[r2],160;;               // 160 byte increment
527         mov             cr25=r3                     // cr.iha 
528
529 rSkipIntrRegs:
530         ld8             r3=[r2],168;;               // another 168 byte inc.
531
532         ld8             r3=[r2],40;;                // 40 byte increment
533         mov             cr66=r3                     // cr.lid
534
535         ld8             r3=[r2],8;;
536 //      mov             cr71=r3                     // cr.ivr is read only
537         ld8             r3=[r2],24;;                // 24 byte increment
538         mov             cr72=r3                     // cr.tpr
539    
540         ld8             r3=[r2],168;;               // 168 byte inc.
541 //      mov             cr75=r3                     // cr.eoi
542    
543         ld8             r3=[r2],16;;             // 16 byte inc.
544 //      mov             cr96=r3                     // cr.irr0 is read only
545
546         ld8             r3=[r2],16;;             // 16 byte inc.
547 //      mov             cr98=r3                     // cr.irr1 is read only
548
549         ld8             r3=[r2],16;;             // 16 byte inc
550 //      mov             cr100=r3                    // cr.irr2 is read only
551
552         ld8             r3=[r2],16;;             // 16b inc.
553 //      mov             cr102=r3                    // cr.irr3 is read only
554
555         ld8             r3=[r2],16;;             // 16 byte inc.
556 //      mov             cr114=r3                    // cr.itv
557
558         ld8             r3=[r2],8;;
559 //      mov             cr116=r3                    // cr.pmv
560         ld8             r3=[r2],8;;
561 //      mov             cr117=r3                    // cr.lrr0
562         ld8             r3=[r2],8;;
563 //      mov             cr118=r3                    // cr.lrr1
564         ld8             r3=[r2],8*10;;
565 //      mov             cr119=r3                    // cr.cmcv
566
567 restore_ARs:
568         add             r4=8,r2                  // duplicate r2 in r4
569         add             r6=2*8,r2;;              // duplicate r2 in r4
570
571         ld8             r3=[r2],3*8
572         ld8             r5=[r4],3*8
573         ld8             r7=[r6],3*8;;
574         mov             ar0=r3                      // ar.kro
575         mov             ar1=r5                      // ar.kr1
576         mov             ar2=r7;;                    // ar.kr2
577
578         ld8             r3=[r2],3*8
579         ld8             r5=[r4],3*8
580         ld8             r7=[r6],3*8;;
581         mov             ar3=r3                      // ar.kr3                               
582         mov             ar4=r5                      // ar.kr4
583         mov             ar5=r7;;                    // ar.kr5
584
585         ld8             r3=[r2],10*8
586         ld8             r5=[r4],10*8
587         ld8             r7=[r6],10*8;;
588         mov             ar6=r3                      // ar.kr6
589         mov             ar7=r5                      // ar.kr7
590 //      mov             ar8=r6                      // ar.kr8
591         ;;
592
593         ld8             r3=[r2],3*8
594         ld8             r5=[r4],3*8
595         ld8             r7=[r6],3*8;;
596 //      mov             ar16=r3                     // ar.rsc
597 //      mov             ar17=r5                     // ar.bsp is read only
598         mov             ar16=r0                     // make sure that RSE is in enforced lazy mode
599         ;;
600         mov             ar18=r7;;                   // ar.bspstore
601
602         ld8             r9=[r2],8*13;;
603         mov             ar19=r9                     // ar.rnat
604
605         mov             ar16=r3                     // ar.rsc
606         ld8             r3=[r2],8*4;;
607         mov             ar32=r3                     // ar.ccv
608
609         ld8             r3=[r2],8*4;;
610         mov             ar36=r3                     // ar.unat
611
612         ld8             r3=[r2],8*4;;
613         mov             ar40=r3                     // ar.fpsr
614
615         ld8             r3=[r2],160;;               // 160
616 //      mov             ar44=r3                     // ar.itc
617
618         ld8             r3=[r2],8;;
619         mov             ar64=r3                     // ar.pfs
620
621         ld8             r3=[r2],8;;
622         mov             ar65=r3                     // ar.lc
623
624         ld8             r3=[r2];;
625         mov             ar66=r3                     // ar.ec
626         add             r2=8*62,r2;;             // padding 
627     
628 restore_RRs:
629         mov             r5=ar.lc
630         mov             ar.lc=0x08-1
631         movl            r4=0x00
632 cStRRr:
633         ld8             r3=[r2],8;;
634 //      mov             rr[r4]=r3                   // what are its access previledges?
635         add             r4=1,r4
636         br.cloop.sptk.few       cStRRr
637         ;;
638         mov             ar.lc=r5
639         ;;
640 end_os_mca_restore:
641         BRANCH(ia64_os_mca_done_restore, r2, p0, -0x20)
642         ;; 
643 //EndStub//////////////////////////////////////////////////////////////////////
644
645 // ok, the issue here is that we need to save state information so
646 // it can be useable by the kernel debugger and show regs routines.
647 // In order to do this, our best bet is save the current state (plus
648 // the state information obtain from the MIN_STATE_AREA) into a pt_regs
649 // format.  This way we can pass it on in a useable format.
650 //                              
651
652 //
653 // SAL to OS entry point for INIT on the monarch processor
654 // This has been defined for registration purposes with SAL 
655 // as a part of ia64_mca_init.
656 //
657 // When we get here, the follow registers have been
658 // set by the SAL for our use
659 //              
660 //              1. GR1 = OS INIT GP
661 //              2. GR8 = PAL_PROC physical address
662 //              3. GR9 = SAL_PROC physical address
663 //              4. GR10 = SAL GP (physical)
664 //              5. GR11 = Init Reason
665 //                      0 = Received INIT for event other than crash dump switch
666 //                      1 = Received wakeup at the end of an OS_MCA corrected machine check
667 //                      2 = Received INIT dude to CrashDump switch assertion
668 //      
669 //              6. GR12 = Return address to location within SAL_INIT procedure
670
671                                 
672         .text
673         .align 16
674 .global ia64_monarch_init_handler       
675 .proc ia64_monarch_init_handler       
676 ia64_monarch_init_handler:
677
678 #if defined(CONFIG_SMP) && defined(SAL_MPINIT_WORKAROUND)
679         //
680         // work around SAL bug that sends all processors to monarch entry
681         //
682         mov     r17=cr.lid
683         movl    r18=__cpu_physical_id
684         ;;
685         dep     r18=0,r18,61,3          // convert to physical address
686         ;;
687         shr.u   r17=r17,16
688         ld4     r18=[r18]               // get the BSP ID
689         ;;
690         dep     r17=0,r17,16,48
691         ;;
692         cmp4.ne p6,p0=r17,r18           // Am I the BSP ?
693 (p6)    br.cond.spnt slave_init_spin_me
694         ;;
695 #endif
696
697         
698 //
699 // ok, the first thing we do is stash the information
700 // the SAL passed to os
701 //
702 _tmp = r2
703         movl    _tmp=ia64_sal_to_os_handoff_state
704         ;;
705         dep     _tmp=0,_tmp, 61, 3      // get physical address
706         ;;
707         st8     [_tmp]=r1,0x08;;
708         st8     [_tmp]=r8,0x08;;
709         st8     [_tmp]=r9,0x08;;                        
710         st8     [_tmp]=r10,0x08;;                       
711         st8     [_tmp]=r11,0x08;;
712         st8     [_tmp]=r12,0x08;;
713
714 // now we want to save information so we can dump registers
715         SAVE_MIN_WITH_COVER
716         ;;
717         mov r8=cr.ifa
718         mov r9=cr.isr
719         adds r3=8,r2                            // set up second base pointer
720         ;;
721         SAVE_REST
722         
723 // ok, enough should be saved at this point to be dangerous, and  supply
724 // information for a dump
725 // We need to switch to Virtual mode before hitting the C functions.
726 //
727 // 
728 //
729         movl    r2=IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN
730         mov     r3=psr  // get the current psr, minimum enabled at this point
731         ;;
732         or      r2=r2,r3
733         ;;
734         movl    r3=IVirtual_Switch
735         ;;
736         mov     cr.iip=r3               // short return to set the appropriate bits
737         mov     cr.ipsr=r2              // need to do an rfi to set appropriate bits
738         ;;
739         rfi
740         ;;
741 IVirtual_Switch:
742         //      
743         // We should now be running virtual
744         //
745         // Lets call the C handler to get the rest of the state info
746         //
747         alloc r14=ar.pfs,0,0,1,0                // now it's safe (must be first in insn group!)
748         ;;                                      //
749         adds out0=16,sp                         // out0 = pointer to pt_regs
750         ;;
751
752         br.call.sptk.few rp=ia64_init_handler
753 .ret1:
754
755 return_from_init:
756         br.sptk return_from_init
757
758         .endp
759
760 //
761 // SAL to OS entry point for INIT on the slave processor
762 // This has been defined for registration purposes with SAL 
763 // as a part of ia64_mca_init.
764 //
765
766         .text
767         .align 16
768 .global ia64_slave_init_handler
769 .proc ia64_slave_init_handler
770 ia64_slave_init_handler:                
771
772
773 slave_init_spin_me:     
774         br.sptk slave_init_spin_me
775         ;;
776         .endp