📄 ivt.s
字号:
shr.u r18=r16,r18(p7) dep r17=r17,r19,(PAGE_SHIFT-3),3 // put region number bits in place srlz.d LOAD_PHYSICAL(p6, r19, swapper_pg_dir) // region 5 is rooted at swapper_pg_dir .pred.rel "mutex", p6, p7(p6) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT(p7) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3 ;;(p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=PTA + IFA(33,42)*8(p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8) cmp.eq p7,p6=0,r21 // unused address bits all zeroes? shr.u r18=r22,PMD_SHIFT // shift L2 index into position ;; ld8 r17=[r17] // fetch the L1 entry (may be 0) ;;(p7) cmp.eq p6,p7=r17,r0 // was L1 entry NULL? dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry ;;(p7) ld8 r17=[r17] // fetch the L2 entry (may be 0) shr.u r19=r22,PAGE_SHIFT // shift L3 index into position ;;(p7) cmp.eq.or.andcm p6,p7=r17,r0 // was L2 entry NULL? dep r17=r19,r17,3,(PAGE_SHIFT-3) // compute address of L3 page table entry(p6) br.cond.spnt page_fault mov b0=r30 br.sptk.many b0 // return to continuation pointEND(nested_dtlb_miss) .org ia64_ivt+0x1800/////////////////////////////////////////////////////////////////////////////////////////// 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24)ENTRY(ikey_miss) DBG_FAULT(6) FAULT(6)END(ikey_miss) //----------------------------------------------------------------------------------- // call do_page_fault (predicates are in r31, psr.dt may be off, r16 is faulting address)ENTRY(page_fault) ssm psr.dt ;; srlz.i ;; SAVE_MIN_WITH_COVER alloc r15=ar.pfs,0,0,3,0 mov out0=cr.ifa mov out1=cr.isr adds r3=8,r2 // set up second base pointer ;; ssm psr.ic | PSR_DEFAULT_BITS ;; srlz.i // guarantee that interruption collectin is on ;;(p15) ssm psr.i // restore psr.i movl r14=ia64_leave_kernel ;; SAVE_REST mov rp=r14 ;; adds out2=16,r12 // out2 = pointer to pt_regs br.call.sptk.many b6=ia64_do_page_fault // ignore return addressEND(page_fault) .org ia64_ivt+0x1c00/////////////////////////////////////////////////////////////////////////////////////////// 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)ENTRY(dkey_miss) DBG_FAULT(7) FAULT(7)END(dkey_miss) .org ia64_ivt+0x2000/////////////////////////////////////////////////////////////////////////////////////////// 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54)ENTRY(dirty_bit) DBG_FAULT(8) /* * What we do here is to simply turn on the dirty bit in the PTE. We need to * update both the page-table and the TLB entry. To efficiently access the PTE, * we address it through the virtual page table. Most likely, the TLB entry for * the relevant virtual page table page is still present in the TLB so we can * normally do this without additional TLB misses. In case the necessary virtual * page table TLB entry isn't present, we take a nested TLB miss hit where we look * up the physical address of the L3 PTE and then continue at label 1 below. */ mov r16=cr.ifa // get the address that caused the fault movl r30=1f // load continuation point in case of nested fault ;; thash r17=r16 // compute virtual address of L3 PTE mov r29=b0 // save b0 in case of nested fault mov r31=pr // save pr#ifdef CONFIG_SMP mov r28=ar.ccv // save ar.ccv ;;1: ld8 r18=[r17] ;; // avoid RAW on r18 mov ar.ccv=r18 // set compare value for cmpxchg or r25=_PAGE_D|_PAGE_A,r18 // set the dirty and accessed bits ;; cmpxchg8.acq r26=[r17],r25,ar.ccv mov r24=PAGE_SHIFT<<2 ;; cmp.eq p6,p7=r26,r18 ;;(p6) itc.d r25 // install updated PTE ;; /* * Tell the assemblers dependency-violation checker that the above "itc" instructions * cannot possibly affect the following loads: */ dv_serialize_data ld8 r18=[r17] // read PTE again ;; cmp.eq p6,p7=r18,r25 // is it same as the newly installed ;;(p7) ptc.l r16,r24 mov b0=r29 // restore b0 mov ar.ccv=r28#else ;;1: ld8 r18=[r17] ;; // avoid RAW on r18 or r18=_PAGE_D|_PAGE_A,r18 // set the dirty and accessed bits mov b0=r29 // restore b0 ;; st8 [r17]=r18 // store back updated PTE itc.d r18 // install updated PTE#endif mov pr=r31,-1 // restore pr rfiEND(dirty_bit) .org ia64_ivt+0x2400/////////////////////////////////////////////////////////////////////////////////////////// 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27)ENTRY(iaccess_bit) DBG_FAULT(9) // Like Entry 8, except for instruction access mov r16=cr.ifa // get the address that caused the fault movl r30=1f // load continuation point in case of nested fault mov r31=pr // save predicates#ifdef CONFIG_ITANIUM /* * Erratum 10 (IFA may contain incorrect address) has "NoFix" status. */ mov r17=cr.ipsr ;; mov r18=cr.iip tbit.z p6,p0=r17,IA64_PSR_IS_BIT // IA64 instruction set? ;;(p6) mov r16=r18 // if so, use cr.iip instead of cr.ifa#endif /* CONFIG_ITANIUM */ ;; thash r17=r16 // compute virtual address of L3 PTE mov r29=b0 // save b0 in case of nested fault)#ifdef CONFIG_SMP mov r28=ar.ccv // save ar.ccv ;;1: ld8 r18=[r17] ;; mov ar.ccv=r18 // set compare value for cmpxchg or r25=_PAGE_A,r18 // set the accessed bit ;; cmpxchg8.acq r26=[r17],r25,ar.ccv mov r24=PAGE_SHIFT<<2 ;; cmp.eq p6,p7=r26,r18 ;;(p6) itc.i r25 // install updated PTE ;; /* * Tell the assemblers dependency-violation checker that the above "itc" instructions * cannot possibly affect the following loads: */ dv_serialize_data ld8 r18=[r17] // read PTE again ;; cmp.eq p6,p7=r18,r25 // is it same as the newly installed ;;(p7) ptc.l r16,r24 mov b0=r29 // restore b0 mov ar.ccv=r28#else /* !CONFIG_SMP */ ;;1: ld8 r18=[r17] ;; or r18=_PAGE_A,r18 // set the accessed bit mov b0=r29 // restore b0 ;; st8 [r17]=r18 // store back updated PTE itc.i r18 // install updated PTE#endif /* !CONFIG_SMP */ mov pr=r31,-1 rfiEND(iaccess_bit) .org ia64_ivt+0x2800/////////////////////////////////////////////////////////////////////////////////////////// 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55)ENTRY(daccess_bit) DBG_FAULT(10) // Like Entry 8, except for data access mov r16=cr.ifa // get the address that caused the fault movl r30=1f // load continuation point in case of nested fault ;; thash r17=r16 // compute virtual address of L3 PTE mov r31=pr mov r29=b0 // save b0 in case of nested fault)#ifdef CONFIG_SMP mov r28=ar.ccv // save ar.ccv ;;1: ld8 r18=[r17] ;; // avoid RAW on r18 mov ar.ccv=r18 // set compare value for cmpxchg or r25=_PAGE_A,r18 // set the dirty bit ;; cmpxchg8.acq r26=[r17],r25,ar.ccv mov r24=PAGE_SHIFT<<2 ;; cmp.eq p6,p7=r26,r18 ;;(p6) itc.d r25 // install updated PTE /* * Tell the assemblers dependency-violation checker that the above "itc" instructions * cannot possibly affect the following loads: */ dv_serialize_data ;; ld8 r18=[r17] // read PTE again ;; cmp.eq p6,p7=r18,r25 // is it same as the newly installed ;;(p7) ptc.l r16,r24 mov ar.ccv=r28#else ;;1: ld8 r18=[r17] ;; // avoid RAW on r18 or r18=_PAGE_A,r18 // set the accessed bit ;; st8 [r17]=r18 // store back updated PTE itc.d r18 // install updated PTE#endif mov b0=r29 // restore b0 mov pr=r31,-1 rfiEND(daccess_bit) .org ia64_ivt+0x2c00/////////////////////////////////////////////////////////////////////////////////////////// 0x2c00 Entry 11 (size 64 bundles) Break instruction (33)ENTRY(break_fault) /* * The streamlined system call entry/exit paths only save/restore the initial part * of pt_regs. This implies that the callers of system-calls must adhere to the * normal procedure calling conventions. * * Registers to be saved & restored: * CR registers: cr.ipsr, cr.iip, cr.ifs * AR registers: ar.unat, ar.pfs, ar.rsc, ar.rnat, ar.bspstore, ar.fpsr * others: pr, b0, b6, loadrs, r1, r11, r12, r13, r15 * Registers to be restored only: * r8-r11: output value from the system call. * * During system call exit, scratch registers (including r15) are modified/cleared * to prevent leaking bits from kernel to user level. */ DBG_FAULT(11) mov.m r16=IA64_KR(CURRENT) // M2 r16 <- current task (12 cyc) mov r29=cr.ipsr // M2 (12 cyc) mov r31=pr // I0 (2 cyc) mov r17=cr.iim // M2 (2 cyc) mov.m r27=ar.rsc // M2 (12 cyc) mov r18=__IA64_BREAK_SYSCALL // A mov.m ar.rsc=0 // M2 mov.m r21=ar.fpsr // M2 (12 cyc) mov r19=b6 // I0 (2 cyc) ;; mov.m r23=ar.bspstore // M2 (12 cyc) mov.m r24=ar.rnat // M2 (5 cyc) mov.i r26=ar.pfs // I0 (2 cyc) invala // M0|1 nop.m 0 // M mov r20=r1 // A save r1 nop.m 0 movl r30=sys_call_table // X mov r28=cr.iip // M2 (2 cyc) cmp.eq p0,p7=r18,r17 // I0 is this a system call?(p7) br.cond.spnt non_syscall // B no -> // // From this point on, we are definitely on the syscall-path // and we can use (non-banked) scratch registers. ///////////////////////////////////////////////////////////////////////// mov r1=r16 // A move task-pointer to "addl"-addressable reg mov r2=r16 // A setup r2 for ia64_syscall_setup add r9=TI_FLAGS+IA64_TASK_SIZE,r16 // A r9 = ¤t_thread_info()->flags adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 adds r15=-1024,r15 // A subtract 1024 from syscall number mov r3=NR_syscalls - 1 ;; ld1.bias r17=[r16] // M0|1 r17 = current->thread.on_ustack flag ld4 r9=[r9] // M0|1 r9 = current_thread_info()->flags extr.u r8=r29,41,2 // I0 extract ei field from cr.ipsr shladd r30=r15,3,r30 // A r30 = sys_call_table + 8*(syscall-1024) addl r22=IA64_RBS_OFFSET,r1 // A compute base of RBS cmp.leu p6,p7=r15,r3 // A syscall number in range? ;; lfetch.fault.excl.nt1 [r22] // M0|1 prefetch RBS(p6) ld8 r30=[r30] // M0|1 load address of syscall entry point tnat.nz.or p7,p0=r15 // I0 is syscall nr a NaT? mov.m ar.bspstore=r22 // M2 switch to kernel RBS cmp.eq p8,p9=2,r8 // A isr.ei==2? ;;(p8) mov r8=0 // A clear ei to 0(p7) movl r30=sys_ni_syscall // X(p8) adds r28=16,r28 // A switch cr.iip to next bundle(p9) adds r8=1,r8 // A increment ei to next slot nop.i 0 ;; mov.m r25=ar.unat // M2 (5 cyc) dep r29=r8,r29,41,2 // I0 insert new ei into cr.ipsr adds r15=1024,r15 // A restore original syscall number // // If any of the above loads miss in L1D, we'll stall here until // the data arrives. ///////////////////////////////////////////////////////////////////////// st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag mov b6=r30 // I0 setup syscall handler branch reg early cmp.eq pKStk,pUStk=r0,r17 // A were we on kernel stacks already? and r9=_TIF_SYSCALL_TRACEAUDIT,r9 // A mask trace or audit mov r18=ar.bsp // M2 (12 cyc)(pKStk) br.cond.spnt .break_fixup // B we're already in kernel-mode -- fix up RBS ;;.back_from_break_fixup:(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A compute base of memory stack cmp.eq p14,p0=r9,r0 // A are syscalls being traced/audited? br.call.sptk.many b7=ia64_syscall_setup // B1: mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0 nop 0 bsw.1 // B (6 cyc) regs are saved, switch to bank 1 ;; ssm psr.ic | PSR_DEFAULT_BITS // M2 now it's safe to re-enable intr.-collection movl r3=ia64_ret_from_syscall // X ;; srlz.i // M0 ensure interruption collection is on mov rp=r3 // I0 set the real return addr(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT(p15) ssm psr.i // M2 restore psr.i(p14) br.call.sptk.many b6=b6 // B invoke syscall-handker (ignore return addr) br.cond.spnt.many ia64_trace_syscall // B do syscall-tracing thingamagic // NOT REACHED/////////////////////////////////////////////////////////////////////// // On entry, we optimistically assumed that we're coming from user-space. // For the rare cases where a system-call is done from within the kernel, // we fix things up at this point:.break_fixup: add r1=-IA64_PT_REGS_SIZE,sp // A allocate space for pt_regs structure mov ar.rnat=r24 // M2 restore kernel's AR.RNAT ;; mov ar.bspstore=r23 // M2 restore kernel's AR.BSPSTORE br.cond.sptk .back_from_break_fixupEND(break_fault) .org ia64_ivt+0x3000/////////////////////////////////////////////////////////////////////////////////////////// 0x3000 Entry 12 (size 64 bundles) External Interrupt (4)ENTRY(interrupt) DBG_FAULT(12) mov r31=pr // prepare to save predicates ;; SAVE_MIN_WITH_COVER // uses r31; defines r2 and r3 ssm psr.ic | PSR_DEFAULT_BITS ;; adds r3=8,r2 // set up second base pointer for SAVE_REST srlz.i // ensure everybody knows psr.ic is back on ;; SAVE_REST ;; alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group mov out0=cr.ivr // pass cr.ivr as first arg add out1=16,sp // pass pointer to pt_regs as second arg ;; srlz.d // make sure we see the effect of cr.ivr movl r14=ia64_leave_kernel ;; mov rp=r14 br.call.sptk.many b6=ia64_handle_irqEND(interrupt) .org ia64_ivt+0x3400/////////////////////////////////////////////////////////////////////////////////////////// 0x3400 Entry 13 (size 64 bundles) Reserved DBG_FAULT(13) FAULT(13) .org ia64_ivt+0x3800/////////////////////////////////////////////////////////////////////////////////////////// 0x3800 Entry 14 (size 64 bundles) Reserved
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -