1
#include <asm/debugger.h>
3
#include <public/arch-ia64.h>
4
#include <asm/config.h>
6
* arch/ia64/kernel/ivt.S
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>
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
22
* This file defines the interruption vector table used by the CPU.
23
* It does not include one entry per possible cause of interruption.
25
* The first 20 entries of the table contain 64 bundles each while the
26
* remaining 48 entries contain only 16 bundles each.
28
* The 64 bundles are used to allow inlining the whole handler for critical
29
* interruptions like TLB misses.
31
* For each entry, the comment is as follows:
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 ----------------------/
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)
43
* Table is based upon EAS2.6 (Oct 1999)
46
#include <linux/config.h>
48
#include <asm/asmmacro.h>
49
#include <asm/break.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>
63
# define PSR_DEFAULT_BITS psr.ac
65
# define PSR_DEFAULT_BITS 0
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...
73
# define DBG_FAULT(i) \
82
#define MINSTATE_VIRT /* needed by minstate.h */
86
mov r19=n; /* prepare to save predicates */ \
88
br.sptk.many dispatch_to_fault_handler
90
#define FAULT_OR_REFLECT(n) \
92
mov r19=n; /* prepare to save predicates */ \
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
99
.section .text.ivt,"ax"
101
.align 32768 // align on 32KB boundary
104
//////////////////////////////////////////////////////////////////////////
105
// 0x0000 Entry 0 (size 64 bundles) VHPT Translation (8,20,47)
112
//////////////////////////////////////////////////////////////////////////
113
// 0x0400 Entry 1 (size 64 bundles) ITLB (21)
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
129
//////////////////////////////////////////////////////////////////////////
130
// 0x0800 Entry 2 (size 64 bundles) DTLB (9,48)
133
mov r16=cr.ifa // get virtual address
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
146
//////////////////////////////////////////////////////////////////////////
147
// 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19)
150
mov r16=cr.ifa // get address that caused the TLB miss
156
movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
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
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
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
171
itc.i r19 // insert the TLB entry
177
//////////////////////////////////////////////////////////////////////////
178
// 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46)
181
mov r16=cr.ifa // get address that caused the TLB miss
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)
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
198
tbit.nz p9,p0=r20,IA64_ISR_NA_BIT // is non-access bit on?
201
(p9) cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22 // check isr.code field
202
(p8) br.cond.spnt page_fault
205
#ifdef CONFIG_VIRTUAL_FRAME_TABLE
206
shr r22=r16,56 // Test for the address of virtual frame_table
208
cmp.eq p8,p0=((VIRT_FRAME_TABLE_ADDR>>56)&0xff)-0x100,r22
209
(p8) br.cond.sptk frametable_miss ;;
211
// !( (r22 == 0x18 && rr6 == XEN_EFI_RR6) ||
212
// (r22 == 0x1c && rr7 == XEN_EFI_RR7) ||
217
dep r20=0,r20,IA64_ITIR_KEY,IA64_ITIR_KEY_LEN // clear the key
227
cmp.eq p8,p0=0x18,r22 // 0xc...
228
cmp.eq p9,p0=0x1c,r22 // 0xe...
230
cmp.eq.and p8,p0=r26,r24 // rr6 == XEN_EFI_RR6
231
cmp.eq.and p9,p0=r25,r23 // rr7 == XEN_EFI_RR7
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
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
243
cmp.ne p8,p0=r0,r18 // Xen UC bit set
245
cmp.eq.or p8,p0=0x18,r22 // Region 6 is UC for EFI
247
(p8) dep r19=-1,r19,4,1 // set bit 4 (uncached) if access to UC area
250
(p7) itc.d r19 // insert the TLB entry
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)
261
extr.u r17=r16,PGDIR_SHIFT,(PAGE_SHIFT-3)
263
shladd r24=r17,3,r24 // r24=&pgd[pgd_offset(addr)]
265
ld8 r24=[r24] // r24=pgd[pgd_offset(addr)]
266
extr.u r18=r16,PMD_SHIFT,(PAGE_SHIFT-3) // r18=pmd_offset
268
cmp.eq p6,p7=0,r24 // pgd present?
269
shladd r24=r18,3,r24 // r24=&pmd[pmd_offset(addr)]
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
275
cmp.eq p6,p7=0,r24 // pmd present?
276
shladd r24=r19,3,r24 // r24=&pte[pte_offset(addr)]
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
283
ssm psr.dt // switch to using virtual data addressing
284
tbit.z p6,p7=r24,_PAGE_P_BIT // pte present?
286
(p7) itc.d r24 // install updated PTE
287
(p6) br.spnt.few frametable_fault // page present bit cleared?
289
mov pr=r31,-1 // restore predicate registers
293
ENTRY(frametable_fault) //ipsr saved in r29 before coming here!
294
ssm psr.dt // switch to using virtual data addressing
296
movl r19=ia64_frametable_probe
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
304
mov r19=4 // FAULT(4)
305
(p7) br.spnt.few dispatch_to_fault_handler
309
END(frametable_fault)
311
GLOBAL_ENTRY(ia64_frametable_probe)
313
probe.r r8=r32,0 // destination register must be r8
315
br.ret.sptk.many b0 // this instruction must be in bundle 2
317
END(ia64_frametable_probe)
318
#endif /* CONFIG_VIRTUAL_FRAME_TABLE */
321
/////////////////////////////////////////////////////////////////////////////////////////
322
// 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45)
323
ENTRY(nested_dtlb_miss)
326
br.sptk.many b0 // return to the continuation point
328
END(nested_dtlb_miss)
330
GLOBAL_ENTRY(dispatch_reflection)
334
* r19: intr type (offset into ivt, see ia64_int.h)
335
* r31: contains saved predicates (pr)
337
SAVE_MIN_WITH_COVER_R19
338
alloc r14=ar.pfs,0,0,5,0
345
ssm psr.ic | PSR_DEFAULT_BITS
347
srlz.i // guarantee that interruption
350
(p15) ssm psr.i // restore psr.i
351
adds r3=8,r2 // set up second base pointer
354
movl r14=ia64_leave_kernel
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)
362
//////////////////////////////////////////////////////////////////////////
363
// 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24)
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)
378
alloc r15=ar.pfs,0,0,4,0
382
adds r3=8,r2 // set up second base pointer
384
ssm psr.ic | PSR_DEFAULT_BITS
386
srlz.i // guarantee that interruption
389
(p15) ssm psr.i // restore psr.i
390
movl r14=ia64_leave_kernel
395
adds out2=16,r12 // out2 = pointer to pt_regs
396
br.call.sptk.many b6=ia64_do_page_fault // ignore return address
400
//////////////////////////////////////////////////////////////////////////
401
// 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
408
//////////////////////////////////////////////////////////////////////////
409
// 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54)
415
extr.u r20=r20,IA64_PSR_CPL0_BIT,2
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
425
add r22=IA64_VCPU_SHADOW_BITMAP_OFFSET,r22
429
cmp.eq p6,p0=r0,r22 // !shadow_bitmap ?
430
(p6) br.dptk.many dispatch_reflection
433
alloc r14=ar.pfs,0,0,4,0
439
ssm psr.ic | PSR_DEFAULT_BITS
441
srlz.i // guarantee that interruption
444
(p15) ssm psr.i // restore psr.i
445
adds r3=8,r2 // set up second base pointer
448
movl r14=ia64_leave_kernel
451
br.call.sptk.many b6=ia64_shadow_fault
455
//////////////////////////////////////////////////////////////////////////
456
// 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27)
464
br.sptk.many fast_access_reflect;;
468
//////////////////////////////////////////////////////////////////////////
469
// 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55)
479
extr.u r18=r18,IA64_PSR_CPL0_BIT,2
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
489
//////////////////////////////////////////////////////////////////////////
490
// 0x2c00 Entry 11 (size 64 bundles) Break instruction (33)
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
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,
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.
507
* During system call exit, scratch registers (including r15) are
508
* modified/cleared to prevent leaking bits from kernel to user
517
(p7) br.spnt.few dispatch_break_fault
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
526
(p7) br.spnt.few dispatch_break_fault
529
movl r18=THIS_CPU(current_psr_ic_addr)
533
#ifdef CONFIG_PRIVIFY
534
// pseudo-cover are replaced by break.b which (unfortunatly) always
537
(p7) br.spnt.many dispatch_privop_fault
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
547
mov r20=HYPERPRIVOP_START
548
mov r21=HYPERPRIVOP_MAX
551
extr.u r19=r19,IA64_PSR_CPL0_BIT,2 // extract cpl field from cr.ipsr
553
cmp.gtu p7,p0=r21,r20
555
cmp.eq.and p7,p0=CONFIG_CPL0_EMUL,r19 // ipsr.cpl==CONFIG_CPL0_EMUL
556
(p7) br.sptk.many fast_hyperprivop
558
movl r22=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET
562
adds r23=IA64_VCPU_BREAKIMM_OFFSET,r22
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
569
br.sptk.many fast_break_reflect
576
(p7) br.spnt.few dispatch_break_fault
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.
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.
593
* During system call exit, scratch registers (including r15) are modified/cleared
594
* to prevent leaking bits from kernel to user level.
598
// mov.m r16=IA64_KR(CURRENT) // M2 r16 <- current task (12 cyc)
600
mov r29=cr.ipsr // M2 (12 cyc)
601
// mov r31=pr // I0 (2 cyc)
604
// mov r17=cr.iim // M2 (2 cyc)
605
mov.m r27=ar.rsc // M2 (12 cyc)
606
// mov r18=__IA64_BREAK_SYSCALL // A
609
mov.m r21=ar.fpsr // M2 (12 cyc)
610
mov r19=b6 // I0 (2 cyc)
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)
618
mov r20=r1 // A save r1
621
// movl r30=sys_call_table // X
622
movl r30=ia64_hypercall_table // X
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 ->
628
// From this point on, we are definitely on the syscall-path
629
// and we can use (non-banked) scratch registers.
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 = ¤t_thread_info()->flags
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
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
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?
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?
655
mov.m ar.bspstore=r22 // M2 switch to kernel RBS
656
cmp.eq p8,p9=2,r8 // A isr.ei==2?
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
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
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
672
// If any of the above loads miss in L1D, we'll stall here until
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?
680
// and r9=_TIF_SYSCALL_TRACEAUDIT,r9 // A mask trace or audit
681
mov r18=ar.bsp // M2 (12 cyc)
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
687
mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0
689
bsw.1 // B (6 cyc) regs are saved, switch to bank 1
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
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
706
adds r2=PT(R8)+16,r12
710
br.call.sptk.many b0=do_softirq
712
//restore hypercall argument if continuation
713
adds r2=IA64_VCPU_HYPERCALL_CONTINUATION_OFS,r13
721
(p6) adds r2=PT(R16)+16,r12
722
(p6) adds r3=PT(R17)+16,r12
732
//save ar.bsp before cover
734
add r2=PT(R14)+16,r12
745
adds r2=PT(CR_IFS)+16,r12
748
ssm psr.ic | PSR_DEFAULT_BITS
752
br.call.sptk.many b0=reflect_event
755
adds r2=PT(R14)+16,r12
756
adds r3=PT(R8)+16,r12
758
//r16 contains ar.bsp before cover
763
br.sptk.many ia64_ret_from_syscall
768
//////////////////////////////////////////////////////////////////////////
769
// 0x3000 Entry 12 (size 64 bundles) External Interrupt (4)
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
780
movl r28=slow_interrupt
786
br.cond.sptk.many fast_tick_reflect
790
SAVE_MIN_WITH_COVER // uses r31; defines r2 and r3
791
ssm psr.ic | PSR_DEFAULT_BITS
793
adds r3=8,r2 // set up second base pointer for SAVE_REST
794
srlz.i // ensure everybody knows psr.ic is back on
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;;
801
add out1=16,sp // pass pointer to pt_regs as second arg
802
movl r14=ia64_leave_kernel
805
br.call.sptk.many b6=ia64_handle_irq
809
//////////////////////////////////////////////////////////////////////////
810
// 0x3400 Entry 13 (size 64 bundles) Reserved
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...
819
GLOBAL_ENTRY(dispatch_break_fault)
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!)
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
829
ssm psr.ic | PSR_DEFAULT_BITS
831
srlz.i // guarantee that interruption collection is on
833
(p15) ssm psr.i // restore psr.i
834
adds r3=8,r2 // set up second base pointer
837
movl r14=ia64_leave_kernel
840
br.call.sptk.many b6=ia64_handle_break
841
END(dispatch_break_fault)
844
//////////////////////////////////////////////////////////////////////////
845
// 0x3800 Entry 14 (size 64 bundles) Reserved
849
// this code segment is from 2.6.16.13
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
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.
862
* - executing on bank 0 or bank 1 register set (doesn't matter)
863
* - r1: stack pointer
864
* - r2: current task pointer
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)
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
883
* - b0: original contents (to be saved)
885
* - p10: TRUE if syscall is invoked with more than 8 out
886
* registers or r15's Nat is true
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)
894
* - p15: TRUE if interrupts need to be re-enabled
895
* - ar.fpsr: set to kernel settings
896
* - b6: preserved (same as on entry)
898
GLOBAL_ENTRY(ia64_syscall_setup)
900
# error This code assumes that b6 is the first field in pt_regs.
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
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
910
st8.spill [r17]=r11,PT(CR_IIP)-PT(R11) // save r11
912
(pKStk) mov r18=r0 // make sure r18 isn't NaT
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)
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]
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
929
st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc
930
tbit.nz p15,p0=r29,IA64_PSR_I_BIT // I0
934
(pUStk) sub r18=r18,r22 // r18=RSE.ndirty*8
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
943
tnat.nz p12,p0=in4 // [I0]
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"
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]
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
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
963
st8 [r16]=r21,PT(R8)-PT(AR_FPSR) // save ar.fpsr
965
cmp.lt p10,p9=r11,r8 // frame size can't be more than local+8
968
(p9) tnat.nz p10,p0=r15
969
adds r12=-16,r1 // switch to kernel memory stack (with 16 bytes of scratch)
971
st8.spill [r17]=r15 // save r15
975
mov r13=r2 // establish `current'
976
movl r1=__gp // establish kernel global pointer
978
st8 [r16]=r8 // ensure pt_regs.r8 != 0 (see handle_syscall_error)
982
cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0
983
movl r17=FPSR_DEFAULT
985
mov.m ar.fpsr=r17 // set ar.fpsr to kernel default value
988
END(ia64_syscall_setup)
992
//////////////////////////////////////////////////////////////////////////
993
// 0x3c00 Entry 15 (size 64 bundles) Reserved
999
//////////////////////////////////////////////////////////////////////////
1000
// 0x4000 Entry 16 (size 64 bundles) Reserved
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...
1009
ENTRY(dispatch_privop_fault)
1012
alloc r14=ar.pfs,0,0,4,0 // now it's safe (must be first in
1016
mov out2=cr.isr // FIXME: pity to make this slow access twice
1019
ssm psr.ic | PSR_DEFAULT_BITS
1021
srlz.i // guarantee that interruption
1024
(p15) ssm psr.i // restore psr.i
1025
adds r3=8,r2 // set up second base pointer
1028
movl r14=ia64_leave_kernel
1031
br.call.sptk.many b6=ia64_handle_privop
1032
END(dispatch_privop_fault)
1035
.org ia64_ivt+0x4400
1036
//////////////////////////////////////////////////////////////////////////
1037
// 0x4400 Entry 17 (size 64 bundles) Reserved
1042
.org ia64_ivt+0x4800
1043
//////////////////////////////////////////////////////////////////////////
1044
// 0x4800 Entry 18 (size 64 bundles) Reserved
1049
.org ia64_ivt+0x4c00
1050
//////////////////////////////////////////////////////////////////////////
1051
// 0x4c00 Entry 19 (size 64 bundles) Reserved
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...
1062
GLOBAL_ENTRY(dispatch_to_fault_handler)
1066
* r19: fault vector number (e.g., 24 for General Exception)
1067
* r31: contains saved predicates (pr)
1069
SAVE_MIN_WITH_COVER_R19
1070
alloc r14=ar.pfs,0,0,5,0
1077
ssm psr.ic | PSR_DEFAULT_BITS
1079
srlz.i // guarantee that interruption
1082
(p15) ssm psr.i // restore psr.i
1083
adds r3=8,r2 // set up second base pointer for
1087
movl r14=ia64_leave_kernel
1090
br.call.sptk.many b6=ia64_fault
1091
END(dispatch_to_fault_handler)
1094
// --- End of long entries, Beginning of short entries
1097
.org ia64_ivt+0x5000
1098
//////////////////////////////////////////////////////////////////////////
1099
// 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49)
1100
ENTRY(page_not_present)
1102
FAULT_OR_REFLECT(20)
1103
END(page_not_present)
1105
.org ia64_ivt+0x5100
1106
//////////////////////////////////////////////////////////////////////////
1107
// 0x5100 Entry 21 (size 16 bundles) Key Permission (13,25,52)
1108
ENTRY(key_permission)
1110
FAULT_OR_REFLECT(21)
1113
.org ia64_ivt+0x5200
1114
//////////////////////////////////////////////////////////////////////////
1115
// 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26)
1116
ENTRY(iaccess_rights)
1118
FAULT_OR_REFLECT(22)
1121
.org ia64_ivt+0x5300
1122
//////////////////////////////////////////////////////////////////////////
1123
// 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53)
1124
ENTRY(daccess_rights)
1131
br.sptk.many fast_access_reflect
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)
1143
cmp4.ge p6,p0=0x20,r16
1144
(p6) br.sptk.many dispatch_privop_fault
1146
FAULT_OR_REFLECT(24)
1147
END(general_exception)
1149
.org ia64_ivt+0x5500
1150
//////////////////////////////////////////////////////////////////////////
1151
// 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35)
1152
ENTRY(disabled_fp_reg)
1154
FAULT_OR_REFLECT(25)
1155
END(disabled_fp_reg)
1157
.org ia64_ivt+0x5600
1158
//////////////////////////////////////////////////////////////////////////
1159
// 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50)
1160
ENTRY(nat_consumption)
1162
FAULT_OR_REFLECT(26)
1163
END(nat_consumption)
1165
.org ia64_ivt+0x5700
1166
//////////////////////////////////////////////////////////////////////////
1167
// 0x5700 Entry 27 (size 16 bundles) Speculation (40)
1168
ENTRY(speculation_vector)
1170
// this probably need not reflect...
1171
FAULT_OR_REFLECT(27)
1172
END(speculation_vector)
1174
.org ia64_ivt+0x5800
1175
//////////////////////////////////////////////////////////////////////////
1176
// 0x5800 Entry 28 (size 16 bundles) Reserved
1180
.org ia64_ivt+0x5900
1181
//////////////////////////////////////////////////////////////////////////
1182
// 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56)
1185
FAULT_OR_REFLECT(29)
1188
.org ia64_ivt+0x5a00
1189
//////////////////////////////////////////////////////////////////////////
1190
// 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57)
1191
ENTRY(unaligned_access)
1193
FAULT_OR_REFLECT(30)
1194
END(unaligned_access)
1196
.org ia64_ivt+0x5b00
1197
//////////////////////////////////////////////////////////////////////////
1198
// 0x5b00 Entry 31 (size 16 bundles) Unsupported Data Reference (57)
1199
ENTRY(unsupported_data_reference)
1201
FAULT_OR_REFLECT(31)
1202
END(unsupported_data_reference)
1204
.org ia64_ivt+0x5c00
1205
//////////////////////////////////////////////////////////////////////////
1206
// 0x5c00 Entry 32 (size 16 bundles) Floating-Point Fault (64)
1207
ENTRY(floating_point_fault)
1209
FAULT_OR_REFLECT(32)
1210
END(floating_point_fault)
1212
.org ia64_ivt+0x5d00
1213
//////////////////////////////////////////////////////////////////////////
1214
// 0x5d00 Entry 33 (size 16 bundles) Floating Point Trap (66)
1215
ENTRY(floating_point_trap)
1217
FAULT_OR_REFLECT(33)
1218
END(floating_point_trap)
1220
.org ia64_ivt+0x5e00
1221
//////////////////////////////////////////////////////////////////////////
1222
// 0x5e00 Entry 34 (size 16 bundles) Lower Privilege Transfer Trap (66)
1223
ENTRY(lower_privilege_trap)
1225
FAULT_OR_REFLECT(34)
1226
END(lower_privilege_trap)
1228
.org ia64_ivt+0x5f00
1229
//////////////////////////////////////////////////////////////////////////
1230
// 0x5f00 Entry 35 (size 16 bundles) Taken Branch Trap (68)
1231
ENTRY(taken_branch_trap)
1233
FAULT_OR_REFLECT(35)
1234
END(taken_branch_trap)
1236
.org ia64_ivt+0x6000
1237
//////////////////////////////////////////////////////////////////////////
1238
// 0x6000 Entry 36 (size 16 bundles) Single Step Trap (69)
1239
ENTRY(single_step_trap)
1241
FAULT_OR_REFLECT(36)
1242
END(single_step_trap)
1244
.org ia64_ivt+0x6100
1245
//////////////////////////////////////////////////////////////////////////
1246
// 0x6100 Entry 37 (size 16 bundles) Reserved
1250
.org ia64_ivt+0x6200
1251
//////////////////////////////////////////////////////////////////////////
1252
// 0x6200 Entry 38 (size 16 bundles) Reserved
1256
.org ia64_ivt+0x6300
1257
//////////////////////////////////////////////////////////////////////////
1258
// 0x6300 Entry 39 (size 16 bundles) Reserved
1262
.org ia64_ivt+0x6400
1263
//////////////////////////////////////////////////////////////////////////
1264
// 0x6400 Entry 40 (size 16 bundles) Reserved
1268
.org ia64_ivt+0x6500
1269
//////////////////////////////////////////////////////////////////////////
1270
// 0x6500 Entry 41 (size 16 bundles) Reserved
1274
.org ia64_ivt+0x6600
1275
//////////////////////////////////////////////////////////////////////////
1276
// 0x6600 Entry 42 (size 16 bundles) Reserved
1280
.org ia64_ivt+0x6700
1281
//////////////////////////////////////////////////////////////////////////
1282
// 0x6700 Entry 43 (size 16 bundles) Reserved
1286
.org ia64_ivt+0x6800
1287
//////////////////////////////////////////////////////////////////////////
1288
// 0x6800 Entry 44 (size 16 bundles) Reserved
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,
1297
ENTRY(ia32_exception)
1299
FAULT_OR_REFLECT(45)
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)
1307
FAULT_OR_REFLECT(46)
1310
.org ia64_ivt+0x6b00
1311
//////////////////////////////////////////////////////////////////////////
1312
// 0x6b00 Entry 47 (size 16 bundles) IA-32 Interrupt (74)
1313
ENTRY(ia32_interrupt)
1315
FAULT_OR_REFLECT(47)
1318
.org ia64_ivt+0x6c00
1319
//////////////////////////////////////////////////////////////////////////
1320
// 0x6c00 Entry 48 (size 16 bundles) Reserved
1324
.org ia64_ivt+0x6d00
1325
//////////////////////////////////////////////////////////////////////////
1326
// 0x6d00 Entry 49 (size 16 bundles) Reserved
1330
.org ia64_ivt+0x6e00
1331
//////////////////////////////////////////////////////////////////////////
1332
// 0x6e00 Entry 50 (size 16 bundles) Reserved
1336
.org ia64_ivt+0x6f00
1337
//////////////////////////////////////////////////////////////////////////
1338
// 0x6f00 Entry 51 (size 16 bundles) Reserved
1342
.org ia64_ivt+0x7000
1343
//////////////////////////////////////////////////////////////////////////
1344
// 0x7000 Entry 52 (size 16 bundles) Reserved
1348
.org ia64_ivt+0x7100
1349
//////////////////////////////////////////////////////////////////////////
1350
// 0x7100 Entry 53 (size 16 bundles) Reserved
1354
.org ia64_ivt+0x7200
1355
//////////////////////////////////////////////////////////////////////////
1356
// 0x7200 Entry 54 (size 16 bundles) Reserved
1360
.org ia64_ivt+0x7300
1361
//////////////////////////////////////////////////////////////////////////
1362
// 0x7300 Entry 55 (size 16 bundles) Reserved
1366
.org ia64_ivt+0x7400
1367
//////////////////////////////////////////////////////////////////////////
1368
// 0x7400 Entry 56 (size 16 bundles) Reserved
1372
.org ia64_ivt+0x7500
1373
//////////////////////////////////////////////////////////////////////////
1374
// 0x7500 Entry 57 (size 16 bundles) Reserved
1378
.org ia64_ivt+0x7600
1379
//////////////////////////////////////////////////////////////////////////
1380
// 0x7600 Entry 58 (size 16 bundles) Reserved
1384
.org ia64_ivt+0x7700
1385
//////////////////////////////////////////////////////////////////////////
1386
// 0x7700 Entry 59 (size 16 bundles) Reserved
1390
.org ia64_ivt+0x7800
1391
//////////////////////////////////////////////////////////////////////////
1392
// 0x7800 Entry 60 (size 16 bundles) Reserved
1396
.org ia64_ivt+0x7900
1397
//////////////////////////////////////////////////////////////////////////
1398
// 0x7900 Entry 61 (size 16 bundles) Reserved
1402
.org ia64_ivt+0x7a00
1403
//////////////////////////////////////////////////////////////////////////
1404
// 0x7a00 Entry 62 (size 16 bundles) Reserved
1408
.org ia64_ivt+0x7b00
1409
//////////////////////////////////////////////////////////////////////////
1410
// 0x7b00 Entry 63 (size 16 bundles) Reserved
1414
.org ia64_ivt+0x7c00
1415
//////////////////////////////////////////////////////////////////////////
1416
// 0x7c00 Entry 64 (size 16 bundles) Reserved
1420
.org ia64_ivt+0x7d00
1421
//////////////////////////////////////////////////////////////////////////
1422
// 0x7d00 Entry 65 (size 16 bundles) Reserved
1426
.org ia64_ivt+0x7e00
1427
//////////////////////////////////////////////////////////////////////////
1428
// 0x7e00 Entry 66 (size 16 bundles) Reserved
1432
.org ia64_ivt+0x7f00
1433
//////////////////////////////////////////////////////////////////////////
1434
// 0x7f00 Entry 67 (size 16 bundles) Reserved
1438
.org ia64_ivt+0x8000