~ubuntu-branches/ubuntu/utopic/xen/utopic

« back to all changes in this revision

Viewing changes to xen/arch/ia64/xen/ivt.S

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2010-05-06 15:47:38 UTC
  • mto: (1.3.1) (15.1.1 sid) (4.1.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20100506154738-agoz0rlafrh1fnq7
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <asm/debugger.h>
 
2
#include <asm/vhpt.h>
 
3
#include <public/arch-ia64.h>
 
4
#include <asm/config.h>
 
5
/*
 
6
 * arch/ia64/kernel/ivt.S
 
7
 *
 
8
 * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
 
9
 *      Stephane Eranian <eranian@hpl.hp.com>
 
10
 *      David Mosberger <davidm@hpl.hp.com>
 
11
 * Copyright (C) 2000, 2002-2003 Intel Co
 
12
 *      Asit Mallick <asit.k.mallick@intel.com>
 
13
 *      Suresh Siddha <suresh.b.siddha@intel.com>
 
14
 *      Kenneth Chen <kenneth.w.chen@intel.com>
 
15
 *      Fenghua Yu <fenghua.yu@intel.com>
 
16
 *
 
17
 * 00/08/23 Asit Mallick <asit.k.mallick@intel.com> TLB handling for SMP
 
18
 * 00/12/20 David Mosberger-Tang <davidm@hpl.hp.com> DTLB/ITLB handler now
 
19
 * uses virtual PT.
 
20
 */
 
21
/*
 
22
 * This file defines the interruption vector table used by the CPU.
 
23
 * It does not include one entry per possible cause of interruption.
 
24
 *
 
25
 * The first 20 entries of the table contain 64 bundles each while the
 
26
 * remaining 48 entries contain only 16 bundles each.
 
27
 *
 
28
 * The 64 bundles are used to allow inlining the whole handler for critical
 
29
 * interruptions like TLB misses.
 
30
 *
 
31
 *  For each entry, the comment is as follows:
 
32
 *
 
33
 *              // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
 
34
 *  entry offset ----/     /         /                  /          /
 
35
 *  entry number ---------/         /                  /          /
 
36
 *  size of the entry -------------/                  /          /
 
37
 *  vector name -------------------------------------/          /
 
38
 *  interruptions triggering this vector ----------------------/
 
39
 *
 
40
 * The table is 32KB in size and must be aligned on 32KB boundary.
 
41
 * (The CPU ignores the 15 lower bits of the address)
 
42
 *
 
43
 * Table is based upon EAS2.6 (Oct 1999)
 
44
 */
 
45
 
 
46
#include <linux/config.h>
 
47
 
 
48
#include <asm/asmmacro.h>
 
49
#include <asm/break.h>
 
50
#include <asm/ia32.h>
 
51
#include <asm/kregs.h>
 
52
#include <asm/offsets.h>
 
53
#include <asm/pgtable.h>
 
54
#include <asm/processor.h>
 
55
#include <asm/ptrace.h>
 
56
#include <asm/system.h>
 
57
#include <asm/thread_info.h>
 
58
#include <asm/unistd.h>
 
59
#include <xen/errno.h>
 
60
#include <linux/efi.h>
 
61
 
 
62
#if 1
 
63
# define PSR_DEFAULT_BITS       psr.ac
 
64
#else
 
65
# define PSR_DEFAULT_BITS       0
 
66
#endif
 
67
 
 
68
#if 0
 
69
  /*
 
70
   * This lets you track the last eight faults that occurred on the CPU.
 
71
   * Make sure ar.k2 isn't needed for something else before enabling this...
 
72
   */
 
73
# define DBG_FAULT(i)           \
 
74
        mov r16=ar.k2;;         \
 
75
        shl r16=r16,8;;         \
 
76
        add r16=(i),r16;;       \
 
77
        mov ar.k2=r16
 
78
#else
 
79
# define DBG_FAULT(i)
 
80
#endif
 
81
 
 
82
#define MINSTATE_VIRT   /* needed by minstate.h */
 
83
#include "minstate.h"
 
84
 
 
85
#define FAULT(n)                                                        \
 
86
        mov r19=n;              /* prepare to save predicates */        \
 
87
        mov r31=pr;                                                     \
 
88
        br.sptk.many dispatch_to_fault_handler
 
89
 
 
90
#define FAULT_OR_REFLECT(n)                                             \
 
91
        mov r20=cr.ipsr;                                                \
 
92
        mov r19=n;              /* prepare to save predicates */        \
 
93
        mov r31=pr;;                                                    \
 
94
        extr.u r20=r20,IA64_PSR_CPL0_BIT,2;;                            \
 
95
        cmp.ne p6,p0=r0,r20;    /* cpl != 0?*/                          \
 
96
(p6)    br.dptk.many dispatch_reflection;                               \
 
97
        br.sptk.few dispatch_to_fault_handler
 
98
 
 
99
        .section .text.ivt,"ax"
 
100
 
 
101
        .align 32768    // align on 32KB boundary
 
102
        .global ia64_ivt
 
103
ia64_ivt:
 
104
//////////////////////////////////////////////////////////////////////////
 
105
// 0x0000 Entry 0 (size 64 bundles) VHPT Translation (8,20,47)
 
106
ENTRY(vhpt_miss)
 
107
        DBG_FAULT(0)
 
108
        FAULT(0)
 
109
END(vhpt_miss)
 
110
 
 
111
        .org ia64_ivt+0x400
 
112
//////////////////////////////////////////////////////////////////////////
 
113
// 0x0400 Entry 1 (size 64 bundles) ITLB (21)
 
114
ENTRY(itlb_miss)
 
115
        DBG_FAULT(1)
 
116
        mov r16 = cr.ifa
 
117
        mov r31 = pr
 
118
        ;;
 
119
        extr.u r17=r16,59,5
 
120
        ;;
 
121
        /* If address belongs to VMM, go to alt tlb handler */
 
122
        cmp.eq p6,p0=0x1e,r17
 
123
(p6)    br.cond.spnt    late_alt_itlb_miss
 
124
        br.cond.sptk fast_tlb_miss_reflect
 
125
        ;;
 
126
END(itlb_miss)
 
127
 
 
128
        .org ia64_ivt+0x0800
 
129
//////////////////////////////////////////////////////////////////////////
 
130
// 0x0800 Entry 2 (size 64 bundles) DTLB (9,48)
 
131
ENTRY(dtlb_miss)
 
132
        DBG_FAULT(2)
 
133
        mov r16=cr.ifa                  // get virtual address
 
134
        mov r31=pr
 
135
        ;;
 
136
        extr.u r17=r16,59,5
 
137
        ;;
 
138
        /* If address belongs to VMM, go to alt tlb handler */
 
139
        cmp.eq p6,p0=0x1e,r17
 
140
(p6)    br.cond.spnt    late_alt_dtlb_miss
 
141
        br.cond.sptk fast_tlb_miss_reflect
 
142
        ;;
 
143
END(dtlb_miss)
 
144
 
 
145
        .org ia64_ivt+0x0c00
 
146
//////////////////////////////////////////////////////////////////////////
 
147
// 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19)
 
148
ENTRY(alt_itlb_miss)
 
149
        DBG_FAULT(3)
 
150
        mov r16=cr.ifa          // get address that caused the TLB miss
 
151
        mov r31=pr
 
152
        ;;
 
153
late_alt_itlb_miss:
 
154
        mov r21=cr.ipsr
 
155
        movl r17=PAGE_KERNEL
 
156
        movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
 
157
        ;;
 
158
        mov r20=cr.itir
 
159
        extr.u r23=r21,IA64_PSR_CPL0_BIT,2      // extract psr.cpl
 
160
        and r19=r19,r16         // clear ed, reserved bits, and PTE ctrl bits
 
161
        extr.u r18=r16,XEN_VIRT_UC_BIT,1        // extract UC bit
 
162
        ;;
 
163
        cmp.ne p8,p0=r0,r23     // psr.cpl != 0?
 
164
        or r19=r17,r19          // insert PTE control bits into r19
 
165
        dep r20=0,r20,IA64_ITIR_KEY,IA64_ITIR_KEY_LEN   // clear the key 
 
166
        ;;
 
167
        dep r19=r18,r19,4,1     // set bit 4 (uncached) if access to UC area.
 
168
        mov cr.itir=r20         // set itir with cleared key
 
169
(p8)    br.cond.spnt page_fault
 
170
        ;;
 
171
        itc.i r19               // insert the TLB entry
 
172
        mov pr=r31,-1
 
173
        rfi
 
174
END(alt_itlb_miss)
 
175
 
 
176
        .org ia64_ivt+0x1000
 
177
//////////////////////////////////////////////////////////////////////////
 
178
// 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46)
 
179
ENTRY(alt_dtlb_miss)
 
180
        DBG_FAULT(4)
 
181
        mov r16=cr.ifa          // get address that caused the TLB miss
 
182
        mov r31=pr
 
183
        ;;
 
184
late_alt_dtlb_miss:
 
185
        mov r20=cr.isr
 
186
        movl r17=PAGE_KERNEL
 
187
        mov r29=cr.ipsr // frametable_miss is shared by paravirtual and HVM sides
 
188
                        // and it assumes ipsr is saved in r29. If change the
 
189
                        // registers usage here, please check both sides!   
 
190
        movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
 
191
        ;;
 
192
        extr.u r23=r29,IA64_PSR_CPL0_BIT,2      // extract psr.cpl
 
193
        and r22=IA64_ISR_CODE_MASK,r20          // get the isr.code field
 
194
        tbit.nz p6,p7=r20,IA64_ISR_SP_BIT       // is speculation bit on?
 
195
        extr.u r18=r16,XEN_VIRT_UC_BIT,1        // extract UC bit
 
196
        and r19=r19,r16                         // clear ed, reserved bits, and
 
197
                                                //   PTE control bits
 
198
        tbit.nz p9,p0=r20,IA64_ISR_NA_BIT       // is non-access bit on?
 
199
        ;;
 
200
        cmp.ne p8,p0=r0,r23
 
201
(p9)    cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22  // check isr.code field
 
202
(p8)    br.cond.spnt page_fault
 
203
        ;;
 
204
        mov r20=cr.itir
 
205
#ifdef CONFIG_VIRTUAL_FRAME_TABLE
 
206
        shr r22=r16,56          // Test for the address of virtual frame_table
 
207
        ;;
 
208
        cmp.eq p8,p0=((VIRT_FRAME_TABLE_ADDR>>56)&0xff)-0x100,r22
 
209
(p8)    br.cond.sptk frametable_miss ;;
 
210
#endif
 
211
        //    !( (r22 == 0x18 && rr6 == XEN_EFI_RR6) ||
 
212
        //       (r22 == 0x1c && rr7 == XEN_EFI_RR7) ||
 
213
        //       r22 == 0x1e)
 
214
 
 
215
        extr.u r22=r16,59,5
 
216
        ;;
 
217
        dep r20=0,r20,IA64_ITIR_KEY,IA64_ITIR_KEY_LEN   // clear the key
 
218
        movl r24=6 << 61
 
219
        movl r23=7 << 61
 
220
        ;;
 
221
        mov r24=rr[r24]
 
222
        mov r23=rr[r23]
 
223
        ;;
 
224
        movl r26=XEN_EFI_RR6
 
225
        movl r25=XEN_EFI_RR7
 
226
 
 
227
        cmp.eq p8,p0=0x18,r22           // 0xc...
 
228
        cmp.eq p9,p0=0x1c,r22           // 0xe...
 
229
        ;;
 
230
        cmp.eq.and p8,p0=r26,r24        // rr6 == XEN_EFI_RR6
 
231
        cmp.eq.and p9,p0=r25,r23        // rr7 == XEN_EFI_RR7
 
232
        ;;
 
233
        cmp.eq.or p9,p0=0x1e,r22        // 0xf...
 
234
(p8)    br.cond.spnt alt_dtlb_miss_identity_map
 
235
(p9)    br.cond.spnt alt_dtlb_miss_identity_map
 
236
        br.cond.spnt page_fault
 
237
        ;;
 
238
alt_dtlb_miss_identity_map:
 
239
        dep r29=-1,r29,IA64_PSR_ED_BIT,1
 
240
        or r19=r19,r17          // insert PTE control bits into r19
 
241
        mov cr.itir=r20         // set itir with cleared key
 
242
        ;;
 
243
        cmp.ne p8,p0=r0,r18             // Xen UC bit set
 
244
        ;;
 
245
        cmp.eq.or p8,p0=0x18,r22        // Region 6 is UC for EFI
 
246
        ;;
 
247
(p8)    dep r19=-1,r19,4,1      // set bit 4 (uncached) if access to UC area
 
248
(p6)    mov cr.ipsr=r29
 
249
        ;;
 
250
(p7)    itc.d r19               // insert the TLB entry
 
251
        mov pr=r31,-1
 
252
        rfi
 
253
END(alt_dtlb_miss)
 
254
 
 
255
#ifdef CONFIG_VIRTUAL_FRAME_TABLE       
 
256
GLOBAL_ENTRY(frametable_miss)
 
257
        rsm psr.dt              // switch to using physical data addressing
 
258
        movl r24=(frametable_pg_dir-PAGE_OFFSET)  // r24=__pa(frametable_pg_dir)
 
259
        ;;
 
260
        srlz.d
 
261
        extr.u r17=r16,PGDIR_SHIFT,(PAGE_SHIFT-3)
 
262
        ;;
 
263
        shladd r24=r17,3,r24    // r24=&pgd[pgd_offset(addr)]
 
264
        ;;
 
265
        ld8 r24=[r24]           // r24=pgd[pgd_offset(addr)]
 
266
        extr.u r18=r16,PMD_SHIFT,(PAGE_SHIFT-3) // r18=pmd_offset
 
267
        ;;
 
268
        cmp.eq p6,p7=0,r24      // pgd present?
 
269
        shladd r24=r18,3,r24    // r24=&pmd[pmd_offset(addr)]
 
270
        ;;
 
271
(p7)    ld8 r24=[r24]           // r24=pmd[pmd_offset(addr)]
 
272
        extr.u r19=r16,PAGE_SHIFT,(PAGE_SHIFT-3)// r19=pte_offset
 
273
(p6)    br.spnt.few frametable_fault
 
274
        ;;
 
275
        cmp.eq p6,p7=0,r24      // pmd present?
 
276
        shladd r24=r19,3,r24    // r24=&pte[pte_offset(addr)]
 
277
        ;;
 
278
(p7)    ld8 r24=[r24]           // r24=pte[pte_offset(addr)]
 
279
        mov r25=(PAGE_SHIFT<<IA64_ITIR_PS)
 
280
(p6)    br.spnt.few frametable_fault
 
281
        ;;
 
282
        mov cr.itir=r25
 
283
        ssm psr.dt              // switch to using virtual data addressing
 
284
        tbit.z p6,p7=r24,_PAGE_P_BIT    // pte present? 
 
285
        ;;
 
286
(p7)    itc.d r24               // install updated PTE
 
287
(p6)    br.spnt.few frametable_fault    // page present bit cleared?
 
288
        ;;
 
289
        mov pr=r31,-1           // restore predicate registers
 
290
        rfi
 
291
END(frametable_miss)
 
292
 
 
293
ENTRY(frametable_fault)         //ipsr saved in r29 before coming here!
 
294
        ssm psr.dt              // switch to using virtual data addressing
 
295
        mov r18=cr.iip
 
296
        movl r19=ia64_frametable_probe
 
297
        ;;
 
298
        cmp.eq p6,p7=r18,r19    // is faulting addrress ia64_frametable_probe?
 
299
        mov r8=0                // assumes that 'probe.r' uses r8
 
300
        dep r29=-1,r29,IA64_PSR_RI_BIT+1,1 // return to next instruction in
 
301
                                           //   bundle 2
 
302
        ;;
 
303
(p6)    mov cr.ipsr=r29
 
304
        mov r19=4               // FAULT(4)
 
305
(p7)    br.spnt.few dispatch_to_fault_handler
 
306
        ;;
 
307
        mov pr=r31,-1
 
308
        rfi
 
309
END(frametable_fault)
 
310
 
 
311
GLOBAL_ENTRY(ia64_frametable_probe)
 
312
        {
 
313
        probe.r r8=r32,0        // destination register must be r8
 
314
        nop.f 0x0
 
315
        br.ret.sptk.many b0     // this instruction must be in bundle 2
 
316
        }
 
317
END(ia64_frametable_probe)
 
318
#endif /* CONFIG_VIRTUAL_FRAME_TABLE */
 
319
 
 
320
        .org ia64_ivt+0x1400
 
321
/////////////////////////////////////////////////////////////////////////////////////////
 
322
// 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45)
 
323
ENTRY(nested_dtlb_miss)
 
324
        DBG_FAULT(5)
 
325
        mov b0=r30
 
326
        br.sptk.many b0                 // return to the continuation point
 
327
        ;;
 
328
END(nested_dtlb_miss)
 
329
 
 
330
GLOBAL_ENTRY(dispatch_reflection)
 
331
        /*
 
332
         * Input:
 
333
         *      psr.ic: off
 
334
         *      r19:    intr type (offset into ivt, see ia64_int.h)
 
335
         *      r31:    contains saved predicates (pr)
 
336
         */
 
337
        SAVE_MIN_WITH_COVER_R19
 
338
        alloc r14=ar.pfs,0,0,5,0
 
339
        mov out4=r15
 
340
        mov out0=cr.ifa
 
341
        adds out1=16,sp
 
342
        mov out2=cr.isr
 
343
        mov out3=cr.iim
 
344
 
 
345
        ssm psr.ic | PSR_DEFAULT_BITS
 
346
        ;;
 
347
        srlz.i                          // guarantee that interruption 
 
348
                                        //   collection is on
 
349
        ;;
 
350
(p15)   ssm psr.i                       // restore psr.i
 
351
        adds r3=8,r2                    // set up second base pointer
 
352
        ;;
 
353
        SAVE_REST
 
354
        movl r14=ia64_leave_kernel
 
355
        ;;
 
356
        mov rp=r14
 
357
//      br.sptk.many ia64_prepare_handle_reflection // TODO: why commented out?
 
358
        br.call.sptk.many b6=ia64_handle_reflection
 
359
END(dispatch_reflection)
 
360
 
 
361
        .org ia64_ivt+0x1800
 
362
//////////////////////////////////////////////////////////////////////////
 
363
// 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24)
 
364
ENTRY(ikey_miss)
 
365
        DBG_FAULT(6)
 
366
        FAULT_OR_REFLECT(6)
 
367
END(ikey_miss)
 
368
 
 
369
        //----------------------------------------------------------------
 
370
        // call do_page_fault (predicates are in r31, psr.dt may be off, 
 
371
        // r16 is faulting address)
 
372
GLOBAL_ENTRY(page_fault)
 
373
        ssm psr.dt
 
374
        ;;
 
375
        srlz.i
 
376
        ;;
 
377
        SAVE_MIN_WITH_COVER
 
378
        alloc r15=ar.pfs,0,0,4,0
 
379
        mov out0=cr.ifa
 
380
        mov out1=cr.isr
 
381
        mov out3=cr.itir
 
382
        adds r3=8,r2                    // set up second base pointer
 
383
        ;;
 
384
        ssm psr.ic | PSR_DEFAULT_BITS
 
385
        ;;
 
386
        srlz.i                          // guarantee that interruption 
 
387
                                        //   collection is on
 
388
        ;;
 
389
(p15)   ssm psr.i                       // restore psr.i
 
390
        movl r14=ia64_leave_kernel
 
391
        ;;
 
392
        SAVE_REST
 
393
        mov rp=r14
 
394
        ;;
 
395
        adds out2=16,r12                // out2 = pointer to pt_regs
 
396
        br.call.sptk.many b6=ia64_do_page_fault // ignore return address
 
397
END(page_fault)
 
398
 
 
399
        .org ia64_ivt+0x1c00
 
400
//////////////////////////////////////////////////////////////////////////
 
401
// 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
 
402
ENTRY(dkey_miss)
 
403
        DBG_FAULT(7)
 
404
        FAULT_OR_REFLECT(7)
 
405
END(dkey_miss)
 
406
 
 
407
        .org ia64_ivt+0x2000
 
408
//////////////////////////////////////////////////////////////////////////
 
409
// 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54)
 
410
ENTRY(dirty_bit)
 
411
        DBG_FAULT(8)
 
412
        mov r20=cr.ipsr
 
413
        mov r31=pr
 
414
        ;;
 
415
        extr.u r20=r20,IA64_PSR_CPL0_BIT,2
 
416
        ;;
 
417
        mov r19=8                       // prepare to save predicates
 
418
        cmp.eq p6,p0=r0,r20             // cpl == 0?
 
419
(p6)    br.sptk.few dispatch_to_fault_handler
 
420
        // If shadow mode is not enabled, reflect the fault.
 
421
        movl r22=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET
 
422
        ;;
 
423
        ld8 r22=[r22]
 
424
        ;;
 
425
        add r22=IA64_VCPU_SHADOW_BITMAP_OFFSET,r22
 
426
        ;;
 
427
        ld8 r22=[r22]
 
428
        ;;
 
429
        cmp.eq p6,p0=r0,r22             // !shadow_bitmap ?
 
430
(p6)    br.dptk.many dispatch_reflection
 
431
 
 
432
        SAVE_MIN_WITH_COVER
 
433
        alloc r14=ar.pfs,0,0,4,0
 
434
        mov out0=cr.ifa
 
435
        mov out1=cr.itir
 
436
        mov out2=cr.isr
 
437
        adds out3=16,sp
 
438
 
 
439
        ssm psr.ic | PSR_DEFAULT_BITS
 
440
        ;;
 
441
        srlz.i                          // guarantee that interruption 
 
442
                                        //   collection is on
 
443
        ;;
 
444
(p15)   ssm psr.i                       // restore psr.i
 
445
        adds r3=8,r2                    // set up second base pointer
 
446
        ;;
 
447
        SAVE_REST
 
448
        movl r14=ia64_leave_kernel
 
449
        ;;
 
450
        mov rp=r14
 
451
        br.call.sptk.many b6=ia64_shadow_fault
 
452
END(dirty_bit)
 
453
 
 
454
        .org ia64_ivt+0x2400
 
455
//////////////////////////////////////////////////////////////////////////
 
456
// 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27)
 
457
ENTRY(iaccess_bit)
 
458
        DBG_FAULT(9)
 
459
        mov r16=cr.isr
 
460
        mov r17=cr.ifa
 
461
        mov r31=pr
 
462
        mov r19=9
 
463
        mov r20=0x2400
 
464
        br.sptk.many fast_access_reflect;;
 
465
END(iaccess_bit)
 
466
 
 
467
        .org ia64_ivt+0x2800
 
468
//////////////////////////////////////////////////////////////////////////
 
469
// 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55)
 
470
ENTRY(daccess_bit)
 
471
        DBG_FAULT(10)
 
472
        mov r16=cr.isr
 
473
        mov r17=cr.ifa
 
474
        mov r18=cr.ipsr
 
475
        mov r31=pr
 
476
        mov r19=10
 
477
        ;;
 
478
        mov r20=0x2800
 
479
        extr.u r18=r18,IA64_PSR_CPL0_BIT,2
 
480
        ;;
 
481
        cmp.ne p6,p0=r0,r18     /* cpl != 0? */
 
482
(p6)    br.sptk.many fast_access_reflect
 
483
        /* __domain_get_bundle() may cause this fault. */
 
484
        br.sptk.few dispatch_to_fault_handler
 
485
        ;;
 
486
END(daccess_bit)
 
487
 
 
488
        .org ia64_ivt+0x2c00
 
489
//////////////////////////////////////////////////////////////////////////
 
490
// 0x2c00 Entry 11 (size 64 bundles) Break instruction (33)
 
491
ENTRY(break_fault)
 
492
        .body
 
493
        /*
 
494
         * The streamlined system call entry/exit paths only save/restore 
 
495
         * the initial part of pt_regs.  This implies that the callers of
 
496
         * system-calls must adhere to the normal procedure calling 
 
497
         * conventions.
 
498
         *
 
499
         *   Registers to be saved & restored:
 
500
         *      CR registers: cr.ipsr, cr.iip, cr.ifs
 
501
         *      AR registers: ar.unat, ar.pfs, ar.rsc, ar.rnat, ar.bspstore,
 
502
         *                    ar.fpsr
 
503
         *      others: pr, b0, b6, loadrs, r1, r11, r12, r13, r15
 
504
         *   Registers to be restored only:
 
505
         *      r8-r11: output value from the system call.
 
506
         *
 
507
         * During system call exit, scratch registers (including r15) are
 
508
         * modified/cleared to prevent leaking bits from kernel to user 
 
509
         * level.
 
510
         */
 
511
        DBG_FAULT(11)
 
512
        mov r16=cr.isr
 
513
        mov r17=cr.iim
 
514
        mov r31=pr
 
515
        ;;
 
516
        cmp.eq p7,p0=r17,r0
 
517
(p7)    br.spnt.few dispatch_break_fault
 
518
        ;;
 
519
#ifdef CRASH_DEBUG
 
520
        // A panic can occur before domain0 is created.  In such cases, 
 
521
        // referencing XSI_PSR_IC causes nested_dtlb_miss.
 
522
        movl r18=CDB_BREAK_NUM
 
523
        ;;
 
524
        cmp.eq p7,p0=r17,r18
 
525
        ;; 
 
526
(p7)    br.spnt.few dispatch_break_fault
 
527
        ;;
 
528
#endif
 
529
        movl r18=THIS_CPU(current_psr_ic_addr)
 
530
        ;;
 
531
        ld8 r18=[r18]    
 
532
        ;;
 
533
#ifdef CONFIG_PRIVIFY
 
534
        // pseudo-cover are replaced by break.b which (unfortunatly) always
 
535
        // clear iim.
 
536
        cmp.eq p7,p0=r0,r17
 
537
(p7)    br.spnt.many dispatch_privop_fault
 
538
        ;;
 
539
#endif
 
540
        // if (ipsr.cpl == CONFIG_CPL0_EMUL &&
 
541
        //    (iim - HYPERPRIVOP_START) < HYPERPRIVOP_MAX)
 
542
        // this is a hyperprivop. A hyperprivop is hand-coded assembly with
 
543
        // psr.ic off which means it can make no calls, cannot use r1-r15,
 
544
        // and it can have no memory accesses unless they are to pinned
 
545
        // addresses!
 
546
        mov r19= cr.ipsr
 
547
        mov r20=HYPERPRIVOP_START
 
548
        mov r21=HYPERPRIVOP_MAX
 
549
        ;;
 
550
        sub r20=r17,r20
 
551
        extr.u r19=r19,IA64_PSR_CPL0_BIT,2  // extract cpl field from cr.ipsr
 
552
        ;;
 
553
        cmp.gtu p7,p0=r21,r20
 
554
        ;;
 
555
        cmp.eq.and p7,p0=CONFIG_CPL0_EMUL,r19   // ipsr.cpl==CONFIG_CPL0_EMUL
 
556
(p7)    br.sptk.many fast_hyperprivop
 
557
        ;;
 
558
        movl r22=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET
 
559
        ;;
 
560
        ld8 r22 = [r22]
 
561
        ;;
 
562
        adds r23=IA64_VCPU_BREAKIMM_OFFSET,r22
 
563
        ;;
 
564
        ld4 r23=[r23];;
 
565
        cmp4.eq p6,p0=r23,r17;;                 // Xen-reserved breakimm?
 
566
        cmp.eq.and p6,p0=CONFIG_CPL0_EMUL,r19        
 
567
(p6)    br.spnt.many fast_hypercall
 
568
        ;;
 
569
        br.sptk.many fast_break_reflect
 
570
        ;;
 
571
 
 
572
 
 
573
fast_hypercall:
 
574
        shr r25=r2,8;;
 
575
        cmp.ne p7,p0=r0,r25
 
576
(p7)    br.spnt.few dispatch_break_fault
 
577
        ;;
 
578
        // fall through
 
579
   
 
580
 
 
581
        /*
 
582
         * The streamlined system call entry/exit paths only save/restore the initial part
 
583
         * of pt_regs.  This implies that the callers of system-calls must adhere to the
 
584
         * normal procedure calling conventions.
 
585
         *
 
586
         *   Registers to be saved & restored:
 
587
         *      CR registers: cr.ipsr, cr.iip, cr.ifs
 
588
         *      AR registers: ar.unat, ar.pfs, ar.rsc, ar.rnat, ar.bspstore, ar.fpsr
 
589
         *      others: pr, b0, b6, loadrs, r1, r11, r12, r13, r15
 
590
         *   Registers to be restored only:
 
591
         *      r8-r11: output value from the system call.
 
592
         *
 
593
         * During system call exit, scratch registers (including r15) are modified/cleared
 
594
         * to prevent leaking bits from kernel to user level.
 
595
         */
 
596
    
 
597
//      DBG_FAULT(11)
 
598
//      mov.m r16=IA64_KR(CURRENT)              // M2 r16 <- current task (12 cyc)
 
599
        mov r16=r22
 
600
        mov r29=cr.ipsr                         // M2 (12 cyc)
 
601
//      mov r31=pr                              // I0 (2 cyc)
 
602
        mov r15=r2
 
603
 
 
604
//      mov r17=cr.iim                          // M2 (2 cyc)
 
605
        mov.m r27=ar.rsc                        // M2 (12 cyc)
 
606
//      mov r18=__IA64_BREAK_SYSCALL            // A
 
607
 
 
608
        mov.m ar.rsc=0                          // M2
 
609
        mov.m r21=ar.fpsr                       // M2 (12 cyc)
 
610
        mov r19=b6                              // I0 (2 cyc)
 
611
        ;;
 
612
        mov.m r23=ar.bspstore                   // M2 (12 cyc)
 
613
        mov.m r24=ar.rnat                       // M2 (5 cyc)
 
614
        mov.i r26=ar.pfs                        // I0 (2 cyc)
 
615
 
 
616
        invala                                  // M0|1
 
617
        nop.m 0                                 // M
 
618
        mov r20=r1                              // A                    save r1
 
619
 
 
620
        nop.m 0
 
621
//      movl r30=sys_call_table                 // X
 
622
        movl r30=ia64_hypercall_table                   // X
 
623
 
 
624
        mov r28=cr.iip                          // M2 (2 cyc)
 
625
//      cmp.eq p0,p7=r18,r17                    // I0 is this a system call?
 
626
//(p7)  br.cond.spnt non_syscall                // B  no ->
 
627
        //
 
628
        // From this point on, we are definitely on the syscall-path
 
629
        // and we can use (non-banked) scratch registers.
 
630
        //
 
631
///////////////////////////////////////////////////////////////////////
 
632
        mov r1=r16                              // A    move task-pointer to "addl"-addressable reg
 
633
        mov r2=r16                              // A    setup r2 for ia64_syscall_setup
 
634
//      add r9=TI_FLAGS+IA64_TASK_SIZE,r16      // A    r9 = &current_thread_info()->flags
 
635
 
 
636
        adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16
 
637
//      adds r15=-1024,r15                      // A    subtract 1024 from syscall number
 
638
//      mov r3=NR_syscalls - 1
 
639
        mov r3=NR_hypercalls - 1
 
640
        ;;
 
641
        ld1.bias r17=[r16]                      // M0|1 r17 = current->thread.on_ustack flag
 
642
//      ld4 r9=[r9]                             // M0|1 r9 = current_thread_info()->flags
 
643
        mov r9=r0               // force flags = 0
 
644
        extr.u r8=r29,41,2                      // I0   extract ei field from cr.ipsr
 
645
 
 
646
        shladd r30=r15,3,r30                    // A    r30 = sys_call_table + 8*(syscall-1024)
 
647
        addl r22=IA64_RBS_OFFSET,r1             // A    compute base of RBS
 
648
        cmp.leu p6,p7=r15,r3                    // A    syscall number in range?
 
649
        ;;
 
650
 
 
651
        lfetch.fault.excl.nt1 [r22]             // M0|1 prefetch RBS
 
652
(p6)    ld8 r30=[r30]                           // M0|1 load address of syscall entry point
 
653
        tnat.nz.or p7,p0=r15                    // I0   is syscall nr a NaT?
 
654
 
 
655
        mov.m ar.bspstore=r22                   // M2   switch to kernel RBS
 
656
        cmp.eq p8,p9=2,r8                       // A    isr.ei==2?
 
657
        ;;
 
658
 
 
659
(p8)    mov r8=0                                // A    clear ei to 0
 
660
//(p7)  movl r30=sys_ni_syscall                 // X
 
661
(p7)    movl r30=do_ni_hypercall                        // X
 
662
 
 
663
(p8)    adds r28=16,r28                         // A    switch cr.iip to next bundle
 
664
(p9)    adds r8=1,r8                            // A    increment ei to next slot
 
665
        nop.i 0
 
666
        ;;
 
667
 
 
668
        mov.m r25=ar.unat                       // M2 (5 cyc)
 
669
        dep r29=r8,r29,41,2                     // I0   insert new ei into cr.ipsr
 
670
//      adds r15=1024,r15                       // A    restore original syscall number
 
671
        //
 
672
        // If any of the above loads miss in L1D, we'll stall here until
 
673
        // the data arrives.
 
674
        //
 
675
///////////////////////////////////////////////////////////////////////
 
676
        st1 [r16]=r0                            // M2|3 clear current->thread.on_ustack flag
 
677
        mov b6=r30                              // I0   setup syscall handler branch reg early
 
678
        cmp.eq pKStk,pUStk=r0,r17               // A    were we on kernel stacks already?
 
679
 
 
680
//      and r9=_TIF_SYSCALL_TRACEAUDIT,r9       // A    mask trace or audit
 
681
        mov r18=ar.bsp                          // M2 (12 cyc)
 
682
        ;;
 
683
(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A    compute base of memory stack
 
684
//      cmp.eq p14,p0=r9,r0                     // A    are syscalls being traced/audited?
 
685
        br.call.sptk.many b7=ia64_syscall_setup // B
 
686
1:
 
687
        mov ar.rsc=0x3                          // M2   set eager mode, pl 0, LE, loadrs=0
 
688
        nop 0
 
689
        bsw.1                                   // B (6 cyc) regs are saved, switch to bank 1
 
690
        ;;
 
691
 
 
692
        PT_REGS_UNWIND_INFO(-48)
 
693
        ssm psr.ic | PSR_DEFAULT_BITS           // M2   now it's safe to re-enable intr.-collection
 
694
//      movl r3=ia64_ret_from_syscall           // X
 
695
        ;;
 
696
 
 
697
        srlz.i                                  // M0   ensure interruption collection is on
 
698
//      mov rp=r3                               // I0   set the real return addr
 
699
//(p10) br.cond.spnt.many ia64_ret_from_syscall // B    return if bad call-frame or r15 is a NaT
 
700
(p15)   ssm psr.i                               // M2   restore psr.i
 
701
//(p14) br.call.sptk.many b6=b6                 // B    invoke syscall-handker (ignore return addr)
 
702
//      br.call.sptk.many b6=b6                 // B    invoke syscall-handker (ignore return addr)
 
703
        br.call.sptk.many b0=b6                 // B    invoke syscall-handker (ignore return addr)
 
704
//      br.cond.spnt.many ia64_trace_syscall    // B    do syscall-tracing thingamagic
 
705
        ;;
 
706
        adds r2=PT(R8)+16,r12
 
707
        ;;
 
708
        st8 [r2]=r8
 
709
        ;;
 
710
        br.call.sptk.many b0=do_softirq
 
711
        ;;
 
712
        //restore hypercall argument if continuation
 
713
        adds r2=IA64_VCPU_HYPERCALL_CONTINUATION_OFS,r13
 
714
        ;;
 
715
        ld1 r20=[r2]
 
716
        ;;
 
717
        st1 [r2]=r0
 
718
        ;;
 
719
        cmp.ne p6,p0=r20,r0
 
720
        ;;
 
721
(p6)    adds r2=PT(R16)+16,r12
 
722
(p6)    adds r3=PT(R17)+16,r12
 
723
        ;;
 
724
(p6)    ld8 r32=[r2],16
 
725
(p6)    ld8 r33=[r3],16
 
726
        ;;
 
727
(p6)    ld8 r34=[r2],16
 
728
(p6)    ld8 r35=[r3],16
 
729
        ;;
 
730
(p6)    ld8 r36=[r2],16
 
731
        ;;
 
732
//save ar.bsp before cover
 
733
        mov r16=ar.bsp
 
734
        add r2=PT(R14)+16,r12
 
735
        ;;
 
736
        st8 [r2]=r16
 
737
        ;;
 
738
        rsm psr.i|psr.ic
 
739
        ;;
 
740
        srlz.i
 
741
        ;;
 
742
        cover
 
743
        ;;
 
744
        mov r20=cr.ifs    
 
745
        adds r2=PT(CR_IFS)+16,r12
 
746
        ;;
 
747
        st8 [r2]=r20
 
748
        ssm psr.ic | PSR_DEFAULT_BITS
 
749
        ;;
 
750
        srlz.i
 
751
        ;;
 
752
        br.call.sptk.many b0=reflect_event
 
753
        ;;
 
754
        rsm psr.i|psr.ic
 
755
        adds r2=PT(R14)+16,r12
 
756
        adds r3=PT(R8)+16,r12
 
757
        ;;
 
758
        //r16 contains ar.bsp before cover
 
759
        ld8 r16=[r2]
 
760
        ld8 r8=[r3]
 
761
        srlz.i
 
762
        ;;
 
763
        br.sptk.many ia64_ret_from_syscall
 
764
        ;;
 
765
END(break_fault)
 
766
 
 
767
        .org ia64_ivt+0x3000
 
768
//////////////////////////////////////////////////////////////////////////
 
769
// 0x3000 Entry 12 (size 64 bundles) External Interrupt (4)
 
770
ENTRY(interrupt)
 
771
        DBG_FAULT(12)
 
772
        mov r31=pr              // prepare to save predicates
 
773
        mov r30=cr.ivr          // pass cr.ivr as first arg
 
774
        // FIXME: this is a hack... use cpuinfo.ksoftirqd because its
 
775
        // not used anywhere else and we need a place to stash ivr and
 
776
        // there's no registers available unused by SAVE_MIN/REST
 
777
        movl r29=THIS_CPU(cpu_info)+IA64_CPUINFO_KSOFTIRQD_OFFSET
 
778
        ;;
 
779
        st8 [r29]=r30
 
780
        movl r28=slow_interrupt
 
781
        ;;
 
782
        mov r29=rp
 
783
        ;;
 
784
        mov rp=r28
 
785
        ;;
 
786
        br.cond.sptk.many fast_tick_reflect
 
787
        ;;
 
788
slow_interrupt:
 
789
        mov rp=r29;;
 
790
        SAVE_MIN_WITH_COVER     // uses r31; defines r2 and r3
 
791
        ssm psr.ic | PSR_DEFAULT_BITS
 
792
        ;;
 
793
        adds r3=8,r2            // set up second base pointer for SAVE_REST
 
794
        srlz.i                  // ensure everybody knows psr.ic is back on
 
795
        ;;
 
796
        SAVE_REST
 
797
        ;;
 
798
        alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
 
799
        movl out0=THIS_CPU(cpu_info)+IA64_CPUINFO_KSOFTIRQD_OFFSET;;
 
800
        ld8 out0=[out0];;
 
801
        add out1=16,sp          // pass pointer to pt_regs as second arg
 
802
        movl r14=ia64_leave_kernel
 
803
        ;;
 
804
        mov rp=r14
 
805
        br.call.sptk.many b6=ia64_handle_irq
 
806
END(interrupt)
 
807
 
 
808
        .org ia64_ivt+0x3400
 
809
//////////////////////////////////////////////////////////////////////////
 
810
// 0x3400 Entry 13 (size 64 bundles) Reserved
 
811
        DBG_FAULT(13)
 
812
        FAULT(13)
 
813
 
 
814
        // There is no particular reason for this code to be here, other
 
815
        // than that there happens to be space here that would go unused 
 
816
        // otherwise.  If this fault ever gets "unreserved", simply move
 
817
        // the following code to a more suitable spot...
 
818
 
 
819
GLOBAL_ENTRY(dispatch_break_fault)
 
820
        SAVE_MIN_WITH_COVER
 
821
        ;;
 
822
dispatch_break_fault_post_save:
 
823
        alloc r14=ar.pfs,0,0,4,0 // now it's safe (must be first in insn group!)
 
824
        mov out0=cr.ifa
 
825
        adds out1=16,sp
 
826
        mov out2=cr.isr         // FIXME: pity to make this slow access twice
 
827
        mov out3=cr.iim         // FIXME: pity to make this slow access twice
 
828
 
 
829
        ssm psr.ic | PSR_DEFAULT_BITS
 
830
        ;;
 
831
        srlz.i                  // guarantee that interruption collection is on
 
832
        ;;
 
833
(p15)   ssm psr.i               // restore psr.i
 
834
        adds r3=8,r2            // set up second base pointer
 
835
        ;;
 
836
        SAVE_REST
 
837
        movl r14=ia64_leave_kernel
 
838
        ;;
 
839
        mov rp=r14
 
840
        br.call.sptk.many b6=ia64_handle_break
 
841
END(dispatch_break_fault)
 
842
 
 
843
        .org ia64_ivt+0x3800
 
844
//////////////////////////////////////////////////////////////////////////
 
845
// 0x3800 Entry 14 (size 64 bundles) Reserved
 
846
        DBG_FAULT(14)
 
847
        FAULT(14)
 
848
 
 
849
    // this code segment is from 2.6.16.13
 
850
    
 
851
        /*
 
852
         * There is no particular reason for this code to be here, other than that
 
853
         * there happens to be space here that would go unused otherwise.  If this
 
854
         * fault ever gets "unreserved", simply moved the following code to a more
 
855
         * suitable spot...
 
856
         *
 
857
         * ia64_syscall_setup() is a separate subroutine so that it can
 
858
         *      allocate stacked registers so it can safely demine any
 
859
         *      potential NaT values from the input registers.
 
860
         *
 
861
         * On entry:
 
862
         *      - executing on bank 0 or bank 1 register set (doesn't matter)
 
863
         *      -  r1: stack pointer
 
864
         *      -  r2: current task pointer
 
865
         *      -  r3: preserved
 
866
         *      - r11: original contents (saved ar.pfs to be saved)
 
867
         *      - r12: original contents (sp to be saved)
 
868
         *      - r13: original contents (tp to be saved)
 
869
         *      - r15: original contents (syscall # to be saved)
 
870
         *      - r18: saved bsp (after switching to kernel stack)
 
871
         *      - r19: saved b6
 
872
         *      - r20: saved r1 (gp)
 
873
         *      - r21: saved ar.fpsr
 
874
         *      - r22: kernel's register backing store base (krbs_base)
 
875
         *      - r23: saved ar.bspstore
 
876
         *      - r24: saved ar.rnat
 
877
         *      - r25: saved ar.unat
 
878
         *      - r26: saved ar.pfs
 
879
         *      - r27: saved ar.rsc
 
880
         *      - r28: saved cr.iip
 
881
         *      - r29: saved cr.ipsr
 
882
         *      - r31: saved pr
 
883
         *      -  b0: original contents (to be saved)
 
884
         * On exit:
 
885
         *      -  p10: TRUE if syscall is invoked with more than 8 out
 
886
         *              registers or r15's Nat is true
 
887
         *      -  r1: kernel's gp
 
888
         *      -  r3: preserved (same as on entry)
 
889
         *      -  r8: -EINVAL if p10 is true
 
890
         *      - r12: points to kernel stack
 
891
         *      - r13: points to current task
 
892
         *      - r14: preserved (same as on entry)
 
893
         *      - p13: preserved
 
894
         *      - p15: TRUE if interrupts need to be re-enabled
 
895
         *      - ar.fpsr: set to kernel settings
 
896
         *      -  b6: preserved (same as on entry)
 
897
         */
 
898
GLOBAL_ENTRY(ia64_syscall_setup)
 
899
#if PT(B6) != 0
 
900
# error This code assumes that b6 is the first field in pt_regs.
 
901
#endif
 
902
        st8 [r1]=r19                            // save b6
 
903
        add r16=PT(CR_IPSR),r1                  // initialize first base pointer
 
904
        add r17=PT(R11),r1                      // initialize second base pointer
 
905
        ;;
 
906
        alloc r19=ar.pfs,8,0,0,0                // ensure in0-in7 are writable
 
907
        st8 [r16]=r29,PT(AR_PFS)-PT(CR_IPSR)    // save cr.ipsr
 
908
        tnat.nz p8,p0=in0
 
909
 
 
910
        st8.spill [r17]=r11,PT(CR_IIP)-PT(R11)  // save r11
 
911
        tnat.nz p9,p0=in1
 
912
(pKStk) mov r18=r0                              // make sure r18 isn't NaT
 
913
        ;;
 
914
 
 
915
        st8 [r16]=r26,PT(CR_IFS)-PT(AR_PFS)     // save ar.pfs
 
916
        st8 [r17]=r28,PT(AR_UNAT)-PT(CR_IIP)    // save cr.iip
 
917
        mov r28=b0                              // save b0 (2 cyc)
 
918
        ;;
 
919
 
 
920
        st8 [r17]=r25,PT(AR_RSC)-PT(AR_UNAT)    // save ar.unat
 
921
        dep r19=0,r19,38,26                     // clear all bits but 0..37 [I0]
 
922
(p8)    mov in0=-1
 
923
        ;;
 
924
 
 
925
        st8 [r16]=r19,PT(AR_RNAT)-PT(CR_IFS)    // store ar.pfs.pfm in cr.ifs
 
926
        extr.u r11=r19,7,7      // I0           // get sol of ar.pfs
 
927
        and r8=0x7f,r19         // A            // get sof of ar.pfs
 
928
 
 
929
        st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc
 
930
        tbit.nz p15,p0=r29,IA64_PSR_I_BIT // I0
 
931
(p9)    mov in1=-1
 
932
        ;;
 
933
 
 
934
(pUStk) sub r18=r18,r22                         // r18=RSE.ndirty*8
 
935
        tnat.nz p10,p0=in2
 
936
        add r11=8,r11
 
937
        ;;
 
938
(pKStk) adds r16=PT(PR)-PT(AR_RNAT),r16         // skip over ar_rnat field
 
939
(pKStk) adds r17=PT(B0)-PT(AR_BSPSTORE),r17     // skip over ar_bspstore field
 
940
        tnat.nz p11,p0=in3
 
941
        ;;
 
942
(p10)   mov in2=-1
 
943
        tnat.nz p12,p0=in4                              // [I0]
 
944
(p11)   mov in3=-1
 
945
        ;;
 
946
(pUStk) st8 [r16]=r24,PT(PR)-PT(AR_RNAT)        // save ar.rnat
 
947
(pUStk) st8 [r17]=r23,PT(B0)-PT(AR_BSPSTORE)    // save ar.bspstore
 
948
        shl r18=r18,16                          // compute ar.rsc to be used for "loadrs"
 
949
        ;;
 
950
        st8 [r16]=r31,PT(LOADRS)-PT(PR)         // save predicates
 
951
        st8 [r17]=r28,PT(R1)-PT(B0)             // save b0
 
952
        tnat.nz p13,p0=in5                              // [I0]
 
953
        ;;
 
954
        st8 [r16]=r18,PT(R12)-PT(LOADRS)        // save ar.rsc value for "loadrs"
 
955
        st8.spill [r17]=r20,PT(R13)-PT(R1)      // save original r1
 
956
(p12)   mov in4=-1
 
957
        ;;
 
958
 
 
959
.mem.offset 0,0; st8.spill [r16]=r12,PT(AR_FPSR)-PT(R12)        // save r12
 
960
.mem.offset 8,0; st8.spill [r17]=r13,PT(R15)-PT(R13)            // save r13
 
961
(p13)   mov in5=-1
 
962
        ;;
 
963
        st8 [r16]=r21,PT(R8)-PT(AR_FPSR)        // save ar.fpsr
 
964
        tnat.nz p13,p0=in6
 
965
        cmp.lt p10,p9=r11,r8    // frame size can't be more than local+8
 
966
        ;;
 
967
        mov r8=1
 
968
(p9)    tnat.nz p10,p0=r15
 
969
        adds r12=-16,r1         // switch to kernel memory stack (with 16 bytes of scratch)
 
970
 
 
971
        st8.spill [r17]=r15                     // save r15
 
972
        tnat.nz p8,p0=in7
 
973
        nop.i 0
 
974
 
 
975
        mov r13=r2                              // establish `current'
 
976
        movl r1=__gp                            // establish kernel global pointer
 
977
        ;;
 
978
        st8 [r16]=r8            // ensure pt_regs.r8 != 0 (see handle_syscall_error)
 
979
(p13)   mov in6=-1
 
980
(p8)    mov in7=-1
 
981
 
 
982
        cmp.eq pSys,pNonSys=r0,r0               // set pSys=1, pNonSys=0
 
983
        movl r17=FPSR_DEFAULT
 
984
        ;;
 
985
        mov.m ar.fpsr=r17                       // set ar.fpsr to kernel default value
 
986
(p10)   mov r8=-EINVAL
 
987
        br.ret.sptk.many b7
 
988
END(ia64_syscall_setup)
 
989
 
 
990
        
 
991
        .org ia64_ivt+0x3c00
 
992
//////////////////////////////////////////////////////////////////////////
 
993
// 0x3c00 Entry 15 (size 64 bundles) Reserved
 
994
        DBG_FAULT(15)
 
995
        FAULT(15)
 
996
 
 
997
 
 
998
        .org ia64_ivt+0x4000
 
999
//////////////////////////////////////////////////////////////////////////
 
1000
// 0x4000 Entry 16 (size 64 bundles) Reserved
 
1001
        DBG_FAULT(16)
 
1002
        FAULT(16)
 
1003
 
 
1004
        // There is no particular reason for this code to be here, other
 
1005
        // than that there happens to be space here that would go unused 
 
1006
        // otherwise.  If this fault ever gets "unreserved", simply move
 
1007
        // the following code to a more suitable spot...
 
1008
 
 
1009
ENTRY(dispatch_privop_fault)
 
1010
        SAVE_MIN_WITH_COVER
 
1011
        ;;
 
1012
        alloc r14=ar.pfs,0,0,4,0        // now it's safe (must be first in
 
1013
                                        //   insn group!)
 
1014
        mov out0=cr.ifa
 
1015
        adds out1=16,sp
 
1016
        mov out2=cr.isr         // FIXME: pity to make this slow access twice
 
1017
        mov out3=cr.itir
 
1018
 
 
1019
        ssm psr.ic | PSR_DEFAULT_BITS
 
1020
        ;;
 
1021
        srlz.i                          // guarantee that interruption 
 
1022
                                        //   collection is on
 
1023
        ;;
 
1024
(p15)   ssm psr.i                       // restore psr.i
 
1025
        adds r3=8,r2                    // set up second base pointer
 
1026
        ;;
 
1027
        SAVE_REST
 
1028
        movl r14=ia64_leave_kernel
 
1029
        ;;
 
1030
        mov rp=r14
 
1031
        br.call.sptk.many b6=ia64_handle_privop
 
1032
END(dispatch_privop_fault)
 
1033
 
 
1034
 
 
1035
        .org ia64_ivt+0x4400
 
1036
//////////////////////////////////////////////////////////////////////////
 
1037
// 0x4400 Entry 17 (size 64 bundles) Reserved
 
1038
        DBG_FAULT(17)
 
1039
        FAULT(17)
 
1040
 
 
1041
 
 
1042
        .org ia64_ivt+0x4800
 
1043
//////////////////////////////////////////////////////////////////////////
 
1044
// 0x4800 Entry 18 (size 64 bundles) Reserved
 
1045
        DBG_FAULT(18)
 
1046
        FAULT(18)
 
1047
 
 
1048
 
 
1049
        .org ia64_ivt+0x4c00
 
1050
//////////////////////////////////////////////////////////////////////////
 
1051
// 0x4c00 Entry 19 (size 64 bundles) Reserved
 
1052
        DBG_FAULT(19)
 
1053
        FAULT(19)
 
1054
 
 
1055
        /*
 
1056
         * There is no particular reason for this code to be here, other 
 
1057
         * than that there happens to be space here that would go unused 
 
1058
         * otherwise.  If this fault ever gets "unreserved", simply move
 
1059
         * the following code to a more suitable spot...
 
1060
         */
 
1061
 
 
1062
GLOBAL_ENTRY(dispatch_to_fault_handler)
 
1063
        /*
 
1064
         * Input:
 
1065
         *      psr.ic: off
 
1066
         *      r19:    fault vector number (e.g., 24 for General Exception)
 
1067
         *      r31:    contains saved predicates (pr)
 
1068
         */
 
1069
        SAVE_MIN_WITH_COVER_R19
 
1070
        alloc r14=ar.pfs,0,0,5,0
 
1071
        mov out0=r15
 
1072
        mov out1=cr.isr
 
1073
        mov out2=cr.ifa
 
1074
        mov out3=cr.iim
 
1075
        mov out4=cr.itir
 
1076
        ;;
 
1077
        ssm psr.ic | PSR_DEFAULT_BITS
 
1078
        ;;
 
1079
        srlz.i                          // guarantee that interruption 
 
1080
                                        //   collection is on
 
1081
        ;;
 
1082
(p15)   ssm psr.i                       // restore psr.i
 
1083
        adds r3=8,r2                    // set up second base pointer for
 
1084
                                        //   SAVE_REST
 
1085
        ;;
 
1086
        SAVE_REST
 
1087
        movl r14=ia64_leave_kernel
 
1088
        ;;
 
1089
        mov rp=r14
 
1090
        br.call.sptk.many b6=ia64_fault
 
1091
END(dispatch_to_fault_handler)
 
1092
 
 
1093
//
 
1094
// --- End of long entries, Beginning of short entries
 
1095
//
 
1096
 
 
1097
        .org ia64_ivt+0x5000
 
1098
//////////////////////////////////////////////////////////////////////////
 
1099
// 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49)
 
1100
ENTRY(page_not_present)
 
1101
        DBG_FAULT(20)
 
1102
        FAULT_OR_REFLECT(20)
 
1103
END(page_not_present)
 
1104
 
 
1105
        .org ia64_ivt+0x5100
 
1106
//////////////////////////////////////////////////////////////////////////
 
1107
// 0x5100 Entry 21 (size 16 bundles) Key Permission (13,25,52)
 
1108
ENTRY(key_permission)
 
1109
        DBG_FAULT(21)
 
1110
        FAULT_OR_REFLECT(21)
 
1111
END(key_permission)
 
1112
 
 
1113
        .org ia64_ivt+0x5200
 
1114
//////////////////////////////////////////////////////////////////////////
 
1115
// 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26)
 
1116
ENTRY(iaccess_rights)
 
1117
        DBG_FAULT(22)
 
1118
        FAULT_OR_REFLECT(22)
 
1119
END(iaccess_rights)
 
1120
 
 
1121
        .org ia64_ivt+0x5300
 
1122
//////////////////////////////////////////////////////////////////////////
 
1123
// 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53)
 
1124
ENTRY(daccess_rights)
 
1125
        DBG_FAULT(23)
 
1126
        mov r31=pr
 
1127
        mov r16=cr.isr
 
1128
        mov r17=cr.ifa
 
1129
        mov r19=23
 
1130
        mov r20=0x5300
 
1131
        br.sptk.many fast_access_reflect
 
1132
        ;;
 
1133
END(daccess_rights)
 
1134
 
 
1135
        .org ia64_ivt+0x5400
 
1136
//////////////////////////////////////////////////////////////////////////
 
1137
// 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39)
 
1138
ENTRY(general_exception)
 
1139
        DBG_FAULT(24)
 
1140
        mov r16=cr.isr
 
1141
        mov r31=pr
 
1142
        ;;
 
1143
        cmp4.ge p6,p0=0x20,r16
 
1144
(p6)    br.sptk.many dispatch_privop_fault
 
1145
        ;;
 
1146
        FAULT_OR_REFLECT(24)
 
1147
END(general_exception)
 
1148
 
 
1149
        .org ia64_ivt+0x5500
 
1150
//////////////////////////////////////////////////////////////////////////
 
1151
// 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35)
 
1152
ENTRY(disabled_fp_reg)
 
1153
        DBG_FAULT(25)
 
1154
        FAULT_OR_REFLECT(25)
 
1155
END(disabled_fp_reg)
 
1156
 
 
1157
        .org ia64_ivt+0x5600
 
1158
//////////////////////////////////////////////////////////////////////////
 
1159
// 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50)
 
1160
ENTRY(nat_consumption)
 
1161
        DBG_FAULT(26)
 
1162
        FAULT_OR_REFLECT(26)
 
1163
END(nat_consumption)
 
1164
 
 
1165
        .org ia64_ivt+0x5700
 
1166
//////////////////////////////////////////////////////////////////////////
 
1167
// 0x5700 Entry 27 (size 16 bundles) Speculation (40)
 
1168
ENTRY(speculation_vector)
 
1169
        DBG_FAULT(27)
 
1170
        // this probably need not reflect...
 
1171
        FAULT_OR_REFLECT(27)
 
1172
END(speculation_vector)
 
1173
 
 
1174
        .org ia64_ivt+0x5800
 
1175
//////////////////////////////////////////////////////////////////////////
 
1176
// 0x5800 Entry 28 (size 16 bundles) Reserved
 
1177
        DBG_FAULT(28)
 
1178
        FAULT(28)
 
1179
 
 
1180
        .org ia64_ivt+0x5900
 
1181
//////////////////////////////////////////////////////////////////////////
 
1182
// 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56)
 
1183
ENTRY(debug_vector)
 
1184
        DBG_FAULT(29)
 
1185
        FAULT_OR_REFLECT(29)
 
1186
END(debug_vector)
 
1187
 
 
1188
        .org ia64_ivt+0x5a00
 
1189
//////////////////////////////////////////////////////////////////////////
 
1190
// 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57)
 
1191
ENTRY(unaligned_access)
 
1192
        DBG_FAULT(30)
 
1193
        FAULT_OR_REFLECT(30)
 
1194
END(unaligned_access)
 
1195
 
 
1196
        .org ia64_ivt+0x5b00
 
1197
//////////////////////////////////////////////////////////////////////////
 
1198
// 0x5b00 Entry 31 (size 16 bundles) Unsupported Data Reference (57)
 
1199
ENTRY(unsupported_data_reference)
 
1200
        DBG_FAULT(31)
 
1201
        FAULT_OR_REFLECT(31)
 
1202
END(unsupported_data_reference)
 
1203
 
 
1204
        .org ia64_ivt+0x5c00
 
1205
//////////////////////////////////////////////////////////////////////////
 
1206
// 0x5c00 Entry 32 (size 16 bundles) Floating-Point Fault (64)
 
1207
ENTRY(floating_point_fault)
 
1208
        DBG_FAULT(32)
 
1209
        FAULT_OR_REFLECT(32)
 
1210
END(floating_point_fault)
 
1211
 
 
1212
        .org ia64_ivt+0x5d00
 
1213
//////////////////////////////////////////////////////////////////////////
 
1214
// 0x5d00 Entry 33 (size 16 bundles) Floating Point Trap (66)
 
1215
ENTRY(floating_point_trap)
 
1216
        DBG_FAULT(33)
 
1217
        FAULT_OR_REFLECT(33)
 
1218
END(floating_point_trap)
 
1219
 
 
1220
        .org ia64_ivt+0x5e00
 
1221
//////////////////////////////////////////////////////////////////////////
 
1222
// 0x5e00 Entry 34 (size 16 bundles) Lower Privilege Transfer Trap (66)
 
1223
ENTRY(lower_privilege_trap)
 
1224
        DBG_FAULT(34)
 
1225
        FAULT_OR_REFLECT(34)
 
1226
END(lower_privilege_trap)
 
1227
 
 
1228
        .org ia64_ivt+0x5f00
 
1229
//////////////////////////////////////////////////////////////////////////
 
1230
// 0x5f00 Entry 35 (size 16 bundles) Taken Branch Trap (68)
 
1231
ENTRY(taken_branch_trap)
 
1232
        DBG_FAULT(35)
 
1233
        FAULT_OR_REFLECT(35)
 
1234
END(taken_branch_trap)
 
1235
 
 
1236
        .org ia64_ivt+0x6000
 
1237
//////////////////////////////////////////////////////////////////////////
 
1238
// 0x6000 Entry 36 (size 16 bundles) Single Step Trap (69)
 
1239
ENTRY(single_step_trap)
 
1240
        DBG_FAULT(36)
 
1241
        FAULT_OR_REFLECT(36)
 
1242
END(single_step_trap)
 
1243
 
 
1244
        .org ia64_ivt+0x6100
 
1245
//////////////////////////////////////////////////////////////////////////
 
1246
// 0x6100 Entry 37 (size 16 bundles) Reserved
 
1247
        DBG_FAULT(37)
 
1248
        FAULT(37)
 
1249
 
 
1250
        .org ia64_ivt+0x6200
 
1251
//////////////////////////////////////////////////////////////////////////
 
1252
// 0x6200 Entry 38 (size 16 bundles) Reserved
 
1253
        DBG_FAULT(38)
 
1254
        FAULT(38)
 
1255
 
 
1256
        .org ia64_ivt+0x6300
 
1257
//////////////////////////////////////////////////////////////////////////
 
1258
// 0x6300 Entry 39 (size 16 bundles) Reserved
 
1259
        DBG_FAULT(39)
 
1260
        FAULT(39)
 
1261
 
 
1262
        .org ia64_ivt+0x6400
 
1263
//////////////////////////////////////////////////////////////////////////
 
1264
// 0x6400 Entry 40 (size 16 bundles) Reserved
 
1265
        DBG_FAULT(40)
 
1266
        FAULT(40)
 
1267
 
 
1268
        .org ia64_ivt+0x6500
 
1269
//////////////////////////////////////////////////////////////////////////
 
1270
// 0x6500 Entry 41 (size 16 bundles) Reserved
 
1271
        DBG_FAULT(41)
 
1272
        FAULT(41)
 
1273
 
 
1274
        .org ia64_ivt+0x6600
 
1275
//////////////////////////////////////////////////////////////////////////
 
1276
// 0x6600 Entry 42 (size 16 bundles) Reserved
 
1277
        DBG_FAULT(42)
 
1278
        FAULT(42)
 
1279
 
 
1280
        .org ia64_ivt+0x6700
 
1281
//////////////////////////////////////////////////////////////////////////
 
1282
// 0x6700 Entry 43 (size 16 bundles) Reserved
 
1283
        DBG_FAULT(43)
 
1284
        FAULT(43)
 
1285
 
 
1286
        .org ia64_ivt+0x6800
 
1287
//////////////////////////////////////////////////////////////////////////
 
1288
// 0x6800 Entry 44 (size 16 bundles) Reserved
 
1289
        DBG_FAULT(44)
 
1290
        FAULT(44)
 
1291
 
 
1292
        .org ia64_ivt+0x6900
 
1293
//////////////////////////////////////////////////////////////////////////
 
1294
// 0x6900 Entry 45 (size 16 bundles) IA-32 Exeception (17,18,29,41,42,43,
 
1295
//                                                     44,58,60,61,62,72,
 
1296
//                                                     73,75,76,77)
 
1297
ENTRY(ia32_exception)
 
1298
        DBG_FAULT(45)
 
1299
        FAULT_OR_REFLECT(45)
 
1300
END(ia32_exception)
 
1301
 
 
1302
        .org ia64_ivt+0x6a00
 
1303
//////////////////////////////////////////////////////////////////////////
 
1304
// 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept  (30,31,59,70,71)
 
1305
ENTRY(ia32_intercept)
 
1306
        DBG_FAULT(46)
 
1307
        FAULT_OR_REFLECT(46)
 
1308
END(ia32_intercept)
 
1309
 
 
1310
        .org ia64_ivt+0x6b00
 
1311
//////////////////////////////////////////////////////////////////////////
 
1312
// 0x6b00 Entry 47 (size 16 bundles) IA-32 Interrupt  (74)
 
1313
ENTRY(ia32_interrupt)
 
1314
        DBG_FAULT(47)
 
1315
        FAULT_OR_REFLECT(47)
 
1316
END(ia32_interrupt)
 
1317
 
 
1318
        .org ia64_ivt+0x6c00
 
1319
//////////////////////////////////////////////////////////////////////////
 
1320
// 0x6c00 Entry 48 (size 16 bundles) Reserved
 
1321
        DBG_FAULT(48)
 
1322
        FAULT(48)
 
1323
 
 
1324
        .org ia64_ivt+0x6d00
 
1325
//////////////////////////////////////////////////////////////////////////
 
1326
// 0x6d00 Entry 49 (size 16 bundles) Reserved
 
1327
        DBG_FAULT(49)
 
1328
        FAULT(49)
 
1329
 
 
1330
        .org ia64_ivt+0x6e00
 
1331
//////////////////////////////////////////////////////////////////////////
 
1332
// 0x6e00 Entry 50 (size 16 bundles) Reserved
 
1333
        DBG_FAULT(50)
 
1334
        FAULT(50)
 
1335
 
 
1336
        .org ia64_ivt+0x6f00
 
1337
//////////////////////////////////////////////////////////////////////////
 
1338
// 0x6f00 Entry 51 (size 16 bundles) Reserved
 
1339
        DBG_FAULT(51)
 
1340
        FAULT(51)
 
1341
 
 
1342
        .org ia64_ivt+0x7000
 
1343
//////////////////////////////////////////////////////////////////////////
 
1344
// 0x7000 Entry 52 (size 16 bundles) Reserved
 
1345
        DBG_FAULT(52)
 
1346
        FAULT(52)
 
1347
 
 
1348
        .org ia64_ivt+0x7100
 
1349
//////////////////////////////////////////////////////////////////////////
 
1350
// 0x7100 Entry 53 (size 16 bundles) Reserved
 
1351
        DBG_FAULT(53)
 
1352
        FAULT(53)
 
1353
 
 
1354
        .org ia64_ivt+0x7200
 
1355
//////////////////////////////////////////////////////////////////////////
 
1356
// 0x7200 Entry 54 (size 16 bundles) Reserved
 
1357
        DBG_FAULT(54)
 
1358
        FAULT(54)
 
1359
 
 
1360
        .org ia64_ivt+0x7300
 
1361
//////////////////////////////////////////////////////////////////////////
 
1362
// 0x7300 Entry 55 (size 16 bundles) Reserved
 
1363
        DBG_FAULT(55)
 
1364
        FAULT(55)
 
1365
 
 
1366
        .org ia64_ivt+0x7400
 
1367
//////////////////////////////////////////////////////////////////////////
 
1368
// 0x7400 Entry 56 (size 16 bundles) Reserved
 
1369
        DBG_FAULT(56)
 
1370
        FAULT(56)
 
1371
 
 
1372
        .org ia64_ivt+0x7500
 
1373
//////////////////////////////////////////////////////////////////////////
 
1374
// 0x7500 Entry 57 (size 16 bundles) Reserved
 
1375
        DBG_FAULT(57)
 
1376
        FAULT(57)
 
1377
 
 
1378
        .org ia64_ivt+0x7600
 
1379
//////////////////////////////////////////////////////////////////////////
 
1380
// 0x7600 Entry 58 (size 16 bundles) Reserved
 
1381
        DBG_FAULT(58)
 
1382
        FAULT(58)
 
1383
 
 
1384
        .org ia64_ivt+0x7700
 
1385
//////////////////////////////////////////////////////////////////////////
 
1386
// 0x7700 Entry 59 (size 16 bundles) Reserved
 
1387
        DBG_FAULT(59)
 
1388
        FAULT(59)
 
1389
 
 
1390
        .org ia64_ivt+0x7800
 
1391
//////////////////////////////////////////////////////////////////////////
 
1392
// 0x7800 Entry 60 (size 16 bundles) Reserved
 
1393
        DBG_FAULT(60)
 
1394
        FAULT(60)
 
1395
 
 
1396
        .org ia64_ivt+0x7900
 
1397
//////////////////////////////////////////////////////////////////////////
 
1398
// 0x7900 Entry 61 (size 16 bundles) Reserved
 
1399
        DBG_FAULT(61)
 
1400
        FAULT(61)
 
1401
 
 
1402
        .org ia64_ivt+0x7a00
 
1403
//////////////////////////////////////////////////////////////////////////
 
1404
// 0x7a00 Entry 62 (size 16 bundles) Reserved
 
1405
        DBG_FAULT(62)
 
1406
        FAULT(62)
 
1407
 
 
1408
        .org ia64_ivt+0x7b00
 
1409
//////////////////////////////////////////////////////////////////////////
 
1410
// 0x7b00 Entry 63 (size 16 bundles) Reserved
 
1411
        DBG_FAULT(63)
 
1412
        FAULT(63)
 
1413
 
 
1414
        .org ia64_ivt+0x7c00
 
1415
//////////////////////////////////////////////////////////////////////////
 
1416
// 0x7c00 Entry 64 (size 16 bundles) Reserved
 
1417
        DBG_FAULT(64)
 
1418
        FAULT(64)
 
1419
 
 
1420
        .org ia64_ivt+0x7d00
 
1421
//////////////////////////////////////////////////////////////////////////
 
1422
// 0x7d00 Entry 65 (size 16 bundles) Reserved
 
1423
        DBG_FAULT(65)
 
1424
        FAULT(65)
 
1425
 
 
1426
        .org ia64_ivt+0x7e00
 
1427
//////////////////////////////////////////////////////////////////////////
 
1428
// 0x7e00 Entry 66 (size 16 bundles) Reserved
 
1429
        DBG_FAULT(66)
 
1430
        FAULT(66)
 
1431
 
 
1432
        .org ia64_ivt+0x7f00
 
1433
//////////////////////////////////////////////////////////////////////////
 
1434
// 0x7f00 Entry 67 (size 16 bundles) Reserved
 
1435
        DBG_FAULT(67)
 
1436
        FAULT(67)
 
1437
 
 
1438
        .org ia64_ivt+0x8000