📄 tlb-miss.s
字号:
ori gr31,#xAMPRx_V,gr31 /* entry was invalidated by tlbpr #4 */ movgs gr31,tppr movsg damlr1,gr31 /* set TPLR.CXN */ movgs gr31,tplr tlbpr gr31,gr0,#2,#0 /* save to the TLB */ movsg tpxr,gr31 /* check the TLB write error flag */ andicc.p gr31,#TPXR_E,gr0,icc0 setlos #0xfffff000,gr31 bne icc0,#0,__tlb_kernel_fault__dtlb_k_nopunt: # assemble the new TLB entry and gr29,gr31,gr29 movsg cxnr,gr31 or gr29,gr31,gr29 movgs gr29,iamlr1 /* xAMLR = address | context number */ movgs gr30,iampr1 movgs gr29,damlr1 movgs gr30,dampr1 # return, restoring registers movsg scr2,gr30 movgs gr30,ccr sethi.p %hi(__kernel_current_task),gr29 setlo %lo(__kernel_current_task),gr29 ldi @(gr29,#0),gr29 rett #0 beq icc0,#3,0 /* prevent icache prefetch */ # the PTE we want wasn't in the PTD we have mapped, so we need to go looking for a more # appropriate page table and map that instead # - access the PGD with EAR0[31:26] # - DAMLR3 points to the virtual address of the page directory # - the PGD holds 64 PGEs and each PGE/PME points to a set of page tables__dtlb_k_PTD_miss: srli gr29,#26,gr31 /* calculate PGE offset */ slli gr31,#8,gr31 /* and clear bottom bits */ movsg damlr3,gr30 ld @(gr31,gr30),gr30 /* access the PGE */ andicc.p gr30,#_PAGE_PRESENT,gr0,icc0 andicc gr30,#xAMPRx_SS,gr0,icc1 # map this PTD instead and record coverage address ori.p gr30,#xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr30 beq icc0,#0,__tlb_kernel_fault /* jump if PGE not present */ slli.p gr31,#18,gr31 bne icc1,#0,__dtlb_k_bigpage movgs gr30,dampr5 movgs gr31,scr1 # we can now resume normal service setlos 0x3ffc,gr30 srli.p gr29,#12,gr31 /* use EAR0[25:14] as PTE index */ bra __dtlb_k_PTD_mapped__dtlb_k_bigpage: break nop .size __entry_kernel_data_tlb_miss, .-__entry_kernel_data_tlb_miss################################################################################# Userspace instruction TLB miss handler (with PGE prediction)# On entry:# GR28 - faulting address# GR31 - EAR0 ^ SCR0# SCR0 - base of virtual range covered by cached PGE from last ITLB miss (or 0xffffffff)# DAMR3 - mapped page directory# DAMR4 - mapped page table as matched by SCR0################################################################################ .globl __entry_user_insn_tlb_miss .type __entry_user_insn_tlb_miss,@function__entry_user_insn_tlb_miss:#if 0 sethi.p %hi(0xe1200004),gr30 setlo %lo(0xe1200004),gr30 st gr0,@(gr30,gr0) sethi.p %hi(0xffc00100),gr30 setlo %lo(0xffc00100),gr30 sth gr30,@(gr30,gr0) membar#endif movsg ccr,gr30 /* save CCR */ movgs gr30,scr2 # see if the cached page table mapping is appropriate srlicc.p gr31,#26,gr0,icc0 setlos 0x3ffc,gr30 srli.p gr28,#12,gr31 /* use EAR0[25:14] as PTE index */ bne icc0,#0,__itlb_u_PTD_miss__itlb_u_PTD_mapped: # access the PTD with EAR0[25:14] # - DAMLR4 points to the virtual address of the appropriate page table # - the PTD holds 4096 PTEs # - the PTD must be accessed uncached # - the PTE must be marked accessed if it was valid # and gr31,gr30,gr31 movsg damlr4,gr30 add gr30,gr31,gr31 ldi @(gr31,#0),gr30 /* fetch the PTE */ andicc gr30,#_PAGE_PRESENT,gr0,icc0 ori.p gr30,#_PAGE_ACCESSED,gr30 beq icc0,#0,__tlb_user_fault /* jump if PTE invalid */ sti.p gr30,@(gr31,#0) /* update the PTE */ andi gr30,#~_PAGE_ACCESSED,gr30 # we're using IAMR1/DAMR1 as an extra TLB entry # - punt the entry here (if valid) to the real TLB and then replace with the new PTE movsg dampr1,gr31 andicc gr31,#xAMPRx_V,gr0,icc0 setlos.p 0xfffff000,gr31 beq icc0,#0,__itlb_u_nopunt /* punt not required */ movsg dampr1,gr31 movgs gr31,tppr movsg damlr1,gr31 /* set TPLR.CXN */ movgs gr31,tplr tlbpr gr31,gr0,#2,#0 /* save to the TLB */ movsg tpxr,gr31 /* check the TLB write error flag */ andicc.p gr31,#TPXR_E,gr0,icc0 setlos #0xfffff000,gr31 bne icc0,#0,__tlb_user_fault__itlb_u_nopunt: # assemble the new TLB entry and gr28,gr31,gr28 movsg cxnr,gr31 or gr28,gr31,gr28 movgs gr28,iamlr1 /* xAMLR = address | context number */ movgs gr30,iampr1 movgs gr28,damlr1 movgs gr30,dampr1 # return, restoring registers movsg scr2,gr30 movgs gr30,ccr rett #0 beq icc0,#3,0 /* prevent icache prefetch */ # the PTE we want wasn't in the PTD we have mapped, so we need to go looking for a more # appropriate page table and map that instead # - access the PGD with EAR0[31:26] # - DAMLR3 points to the virtual address of the page directory # - the PGD holds 64 PGEs and each PGE/PME points to a set of page tables__itlb_u_PTD_miss: srli gr28,#26,gr31 /* calculate PGE offset */ slli gr31,#8,gr31 /* and clear bottom bits */ movsg damlr3,gr30 ld @(gr31,gr30),gr30 /* access the PGE */ andicc.p gr30,#_PAGE_PRESENT,gr0,icc0 andicc gr30,#xAMPRx_SS,gr0,icc1 # map this PTD instead and record coverage address ori.p gr30,#xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr30 beq icc0,#0,__tlb_user_fault /* jump if PGE not present */ slli.p gr31,#18,gr31 bne icc1,#0,__itlb_u_bigpage movgs gr30,dampr4 movgs gr31,scr0 # we can now resume normal service setlos 0x3ffc,gr30 srli.p gr28,#12,gr31 /* use EAR0[25:14] as PTE index */ bra __itlb_u_PTD_mapped__itlb_u_bigpage: break nop .size __entry_user_insn_tlb_miss, .-__entry_user_insn_tlb_miss################################################################################# Userspace data TLB miss handler# On entry:# GR28 - faulting address# GR31 - EAR0 ^ SCR1# SCR1 - base of virtual range covered by cached PGE from last DTLB miss (or 0xffffffff)# DAMR3 - mapped page directory# DAMR5 - mapped page table as matched by SCR1################################################################################ .globl __entry_user_data_tlb_miss .type __entry_user_data_tlb_miss,@function__entry_user_data_tlb_miss:#if 0 sethi.p %hi(0xe1200004),gr30 setlo %lo(0xe1200004),gr30 st gr0,@(gr30,gr0) sethi.p %hi(0xffc00100),gr30 setlo %lo(0xffc00100),gr30 sth gr30,@(gr30,gr0) membar#endif movsg ccr,gr30 /* save CCR */ movgs gr30,scr2 # see if the cached page table mapping is appropriate srlicc.p gr31,#26,gr0,icc0 setlos 0x3ffc,gr30 srli.p gr28,#12,gr31 /* use EAR0[25:14] as PTE index */ bne icc0,#0,__dtlb_u_PTD_miss__dtlb_u_PTD_mapped: # access the PTD with EAR0[25:14] # - DAMLR5 points to the virtual address of the appropriate page table # - the PTD holds 4096 PTEs # - the PTD must be accessed uncached # - the PTE must be marked accessed if it was valid # and gr31,gr30,gr31 movsg damlr5,gr30__dtlb_u_using_iPTD: add gr30,gr31,gr31 ldi @(gr31,#0),gr30 /* fetch the PTE */ andicc gr30,#_PAGE_PRESENT,gr0,icc0 ori.p gr30,#_PAGE_ACCESSED,gr30 beq icc0,#0,__tlb_user_fault /* jump if PTE invalid */ sti.p gr30,@(gr31,#0) /* update the PTE */ andi gr30,#~_PAGE_ACCESSED,gr30 # we're using DAMR1 as an extra TLB entry # - punt the entry here (if valid) to the real TLB and then replace with the new PTE movsg dampr1,gr31 andicc gr31,#xAMPRx_V,gr0,icc0 setlos.p 0xfffff000,gr31 beq icc0,#0,__dtlb_u_nopunt /* punt not required */ movsg dampr1,gr31 movgs gr31,tppr movsg damlr1,gr31 /* set TPLR.CXN */ movgs gr31,tplr tlbpr gr31,gr0,#2,#0 /* save to the TLB */ movsg tpxr,gr31 /* check the TLB write error flag */ andicc.p gr31,#TPXR_E,gr0,icc0 setlos #0xfffff000,gr31 bne icc0,#0,__tlb_user_fault__dtlb_u_nopunt: # assemble the new TLB entry and gr28,gr31,gr28 movsg cxnr,gr31 or gr28,gr31,gr28 movgs gr28,iamlr1 /* xAMLR = address | context number */ movgs gr30,iampr1 movgs gr28,damlr1 movgs gr30,dampr1 # return, restoring registers movsg scr2,gr30 movgs gr30,ccr rett #0 beq icc0,#3,0 /* prevent icache prefetch */ # the PTE we want wasn't in the PTD we have mapped, so we need to go looking for a more # appropriate page table and map that instead # - first of all, check the insn PGE cache - we may well get a hit there # - access the PGD with EAR0[31:26] # - DAMLR3 points to the virtual address of the page directory # - the PGD holds 64 PGEs and each PGE/PME points to a set of page tables__dtlb_u_PTD_miss: movsg scr0,gr31 /* consult the insn-PGE-cache key */ xor gr28,gr31,gr31 srlicc gr31,#26,gr0,icc0 srli gr28,#12,gr31 /* use EAR0[25:14] as PTE index */ bne icc0,#0,__dtlb_u_iPGE_miss # what we're looking for is covered by the insn-PGE-cache setlos 0x3ffc,gr30 and gr31,gr30,gr31 movsg damlr4,gr30 bra __dtlb_u_using_iPTD__dtlb_u_iPGE_miss: srli gr28,#26,gr31 /* calculate PGE offset */ slli gr31,#8,gr31 /* and clear bottom bits */ movsg damlr3,gr30 ld @(gr31,gr30),gr30 /* access the PGE */ andicc.p gr30,#_PAGE_PRESENT,gr0,icc0 andicc gr30,#xAMPRx_SS,gr0,icc1 # map this PTD instead and record coverage address ori.p gr30,#xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr30 beq icc0,#0,__tlb_user_fault /* jump if PGE not present */ slli.p gr31,#18,gr31 bne icc1,#0,__dtlb_u_bigpage movgs gr30,dampr5 movgs gr31,scr1 # we can now resume normal service setlos 0x3ffc,gr30 srli.p gr28,#12,gr31 /* use EAR0[25:14] as PTE index */ bra __dtlb_u_PTD_mapped__dtlb_u_bigpage: break nop .size __entry_user_data_tlb_miss, .-__entry_user_data_tlb_miss
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -