在ARM架构下,TLB miss后的作业绝大多数状况是由hardwarepage table walk完结,特别状况下hardware page table walk能够被封闭,此刻产生TLB miss后CPU就会产生一个translationfault,剩下的作业由OS接收,完结关于translation fault的反常处理。
默许状况下,产生TLB miss后,hardware page table walk主动发动开端扫描内存中的pagetable,若找到相应PTE(page table entry),则主动完结TLB entry的重填作业;假如找不到,则宣布一个page fault反常,然后OS接收处理page fault。内核中有do_page_fault函数,该函数从硬盘中互换页面进内存,更新页表,然后从头履行产生TLB miss的那条指令,hardware page table walk从头履行,完结TLB重填的作业。
这儿关怀的是封闭hardware pagetable walk后,再产生TLB miss后的处理例程。假如产生这种状况,ARM CPU会宣布一个translation fault(If translation table walksare disabled, for example, PD0 or EPD0 is set to 1 for TTBR0, or PD1 or EPD1 isset to 1 for TTBR1, the processor returns a Translation fault.见cortex-A15TRM p 5-5)。OS处理该反常的流程如下。
首要产生translation fault后,CPU会宣布一个abort反常,然后跳转到该反常地址处(以产生指令预取间断反常为例,跳转到0x00000010)去履行,该地址处寄存的是一个跳转指令 (W(b) vector_pabt +stubs_offset),然后,经过判别,若产生该反常的指令处于usr形式,则跳转到__pabt_usr函数去履行,该函数中有条跳转指令bl CPU_PABORT_HANDLER,CPU_PABORT_HANDLER是个宏界说,关于ARMv7,该界说是:# define CPU_PABORT_HANDLER v7_pabort,
v7_pabort函数中就读取了IFSR和IFAR两个寄存器的值:
//pabort-v7.S
/*
*Function: v6_pabort
*
*Params : r0 = address of aborted instruction
*
*Returns : r0 = address of abort
* : r1 = IFSR
*
*Purpose : obtain information about current prefetch abort.
*/
.align 5
ENTRY(v7_pabort)
mrc p15,0, r0, c6, c0, 2 @ get IFAR
mrc p15,0, r1, c5, c0, 1 @ get IFSR
mov pc,lr
ENDPROC(v7_pabort)
IFAR中存储了产生反常的指令地址,IFSR中存储的是一个32位数,其间某些位标明反常类型等(参阅Cortex-A15TRM p4-76)
剩下的作业便是依据以上两个寄存器提取出来的信息,调用相应函数(do_PrefetchAbort——>do_translation_fault)进行处理。OS接收后的操作是(do_translation_fault函数),首要判别产生TLBmiss的那条指令是用户指令仍是体系指令,假如是体系指令则剩下作业是对页大局目录(pgd),页上级目录(pud),页中心目录(pmd)进行操作;假如是用户指令,则调用do_page_fault函数,剩下的作业便是page fault的处理进程,依据不同状况判别,包含权限查看,分配页面,发送SIGSEGV信号给进程,直接杀死进程等。不论哪种操作,OS都没有对TLB进行重填。
关于page fault的处理进程如下:在取数或许取指令时,产生指令或许数据的地址不存在的状况,则产生间断反常。
以取指产生反常为例。产生指令预取间断反常后,CPU主动跳转到0x0000000C(可装备成0xfffffffc,这儿不考虑)去履行,该地址处是一个跳转指令(W(b) vector_pabt + stubs_offset),然后,经过判别,若产生该反常的指令处于usr形式,则跳转到__pabt_usr函数去履行,该函数中有条跳转指令bl CPU_PABORT_HANDLER,CPU_PABORT_HANDLER是个宏界说,关于ARMv7,该界说是:# defineCPU_PABORT_HANDLER v7_pabort,v7_pabort函数中就读取了IFSR和IFAR两个寄存器的值:
//pabort-v7.S
/*
* Function: v6_pabort
*
* Params : r0 = address ofaborted instruction
*
* Returns : r0 = address of abort
* : r1 = IFSR
*
* Purpose : obtain information aboutcurrent prefetch abort.
*/
.align 5
ENTRY(v7_pabort)
mrc p15, 0, r0, c6, c0, 2 @ get IFAR
mrc p15, 0, r1, c5, c0, 1 @ get IFSR
mov pc, lr
ENDPROC(v7_pabort)
IFAR中存储了产生反常的指令地址,IFSR中存储的是一个32位数,其间某些位标明反常类型等(参阅Cortex-A15 TRM p4-76)
剩下的作业便是依据以上两个寄存器提取出来的信息,调用相应函数(do_PrefetchAbort——>do_page_fault)进行处理。