📄 hashtable.s
字号:
xori r3,r3,0xffc0 addi r3,r3,-8 mtctr r22: lwzu r0,8(r3) rlwinm. r0,r0,0,0,0 /* only want to check valid bit */ bdnzf 2,2b beq+ found_empty /* * Choose an arbitrary slot in the primary PTEG to overwrite. * Since both the primary and secondary PTEGs are full, and we * have no information that the PTEs in the primary PTEG are * more important or useful than those in the secondary PTEG, * and we know there is a definite (although small) speed * advantage to putting the PTE in the primary PTEG, we always * put the PTE in the primary PTEG. */ xori r5,r5,0x40 /* clear H bit again */ lis r3,next_slot@ha tophys(r3,r3) lwz r2,next_slot@l(r3) addi r2,r2,8 andi. r2,r2,0x38 stw r2,next_slot@l(r3) add r3,r4,r211: /* update counter of evicted pages */ lis r2,htab_evicts@ha tophys(r2,r2) lwz r4,htab_evicts@l(r2) addi r4,r4,1 stw r4,htab_evicts@l(r2)#ifndef CONFIG_SMP /* Store PTE in PTEG */found_empty: stw r5,0(r3)found_slot: stw r6,4(r3) sync#else /* CONFIG_SMP *//* * Between the tlbie above and updating the hash table entry below, * another CPU could read the hash table entry and put it in its TLB. * There are 3 cases: * 1. using an empty slot * 2. updating an earlier entry to change permissions (i.e. enable write) * 3. taking over the PTE for an unrelated address * * In each case it doesn't really matter if the other CPUs have the old * PTE in their TLB. So we don't need to bother with another tlbie here, * which is convenient as we've overwritten the register that had the * address. :-) The tlbie above is mainly to make sure that this CPU comes * and gets the new PTE from the hash table. * * We do however have to make sure that the PTE is never in an invalid * state with the V bit set. */found_empty:found_slot: rlwinm r5,r5,0,1,31 /* clear V (valid) bit in PTE */ stw r5,0(r3) sync tlbsync sync stw r6,4(r3) /* put in correct RPN, WIMG, PP bits */ sync oris r5,r5,0x8000 stw r5,0(r3) /* finally set V bit in PTE */#endif /* CONFIG_SMP */#endif /* CONFIG_PPC64BRIDGE *//* * Update the hash table miss count. We only want misses here * that _are_ valid addresses and have a pte otherwise we don't * count it as a reload. do_page_fault() takes care of bad addrs * and entries that need linux-style pte's created. * * safe to use r2 here since we're not using it as current yet * update the htab misses count * -- Cort */ lis r2,htab_reloads@ha tophys(r2,r2) lwz r3,htab_reloads@l(r2) addi r3,r3,1 stw r3,htab_reloads@l(r2)#ifdef CONFIG_SMP lis r2,hash_table_lock@ha tophys(r2,r2) li r0,0 stw r0,hash_table_lock@l(r2) eieio#endif /* Return from the exception */ lwz r3,_CCR(r21) lwz r4,_LINK(r21) lwz r5,_CTR(r21) mtcrf 0xff,r3 mtlr r4 mtctr r5 lwz r0,GPR0(r21) lwz r1,GPR1(r21) lwz r2,GPR2(r21) lwz r3,GPR3(r21) lwz r4,GPR4(r21) lwz r5,GPR5(r21) lwz r6,GPR6(r21) /* we haven't used xer */ mtspr SRR1,r23 mtspr SRR0,r22 lwz r20,GPR20(r21) lwz r22,GPR22(r21) lwz r23,GPR23(r21) lwz r21,GPR21(r21) RFI #ifdef CONFIG_SMPhash_page_out: lis r2,hash_table_lock@ha tophys(r2,r2) li r0,0 stw r0,hash_table_lock@l(r2) eieio blr .data .globl hash_table_lockhash_table_lock: .long 0#endif /* CONFIG_SMP */ .datanext_slot: .long 0 .text/* * Flush entries from the hash table with VSIDs in the range * given. */_GLOBAL(flush_hash_segments) lis r5,Hash@ha lwz r5,Hash@l(r5) /* base of hash table */ cmpwi 0,r5,0 bne+ 99f tlbia sync#ifdef CONFIG_SMP tlbsync sync#endif blr99:#if defined(CONFIG_SMP) || defined(CONFIG_PPC64BRIDGE) /* Note - we had better not do anything which could generate a hash table miss while we have the hash table locked, or we'll get a deadlock. -paulus */ mfmsr r10 sync rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ mtmsr r0 SYNC#endif#ifdef CONFIG_SMP lis r9,hash_table_lock@h ori r9,r9,hash_table_lock@l lwz r8,PROCESSOR(r2) oris r8,r8,810: lwarx r6,0,r9 cmpi 0,r6,0 bne- 10b stwcx. r8,0,r9 bne- 10b eieio#endif#ifndef CONFIG_PPC64BRIDGE rlwinm r3,r3,7,1,24 /* put VSID lower limit in position */ oris r3,r3,0x8000 /* set V bit */ rlwinm r4,r4,7,1,24 /* put VSID upper limit in position */ oris r4,r4,0x8000 ori r4,r4,0x7f lis r6,Hash_size@ha lwz r6,Hash_size@l(r6) /* size in bytes */ srwi r6,r6,3 /* # PTEs */ mtctr r6 addi r5,r5,-8 li r0,01: lwzu r6,8(r5) /* get next tag word */ cmplw 0,r6,r3 cmplw 1,r6,r4 cror 0,0,5 /* set cr0.lt if out of range */ blt 2f /* branch if out of range */ stw r0,0(r5) /* invalidate entry */2: bdnz 1b /* continue with loop */#else /* CONFIG_PPC64BRIDGE */ rldic r3,r3,12,20 /* put VSID lower limit in position */ ori r3,r3,1 /* set V bit */ rldic r4,r4,12,20 /* put VSID upper limit in position */ ori r4,r4,0xfff /* set V bit, API etc. */ lis r6,Hash_size@ha lwz r6,Hash_size@l(r6) /* size in bytes */ srwi r6,r6,4 /* # PTEs */ mtctr r6 addi r5,r5,-16 li r0,01: ldu r6,16(r5) /* get next tag word */ cmpld 0,r6,r3 cmpld 1,r6,r4 cror 0,0,5 /* set cr0.lt if out of range */ blt 2f /* branch if out of range */ std r0,0(r5) /* invalidate entry */2: bdnz 1b /* continue with loop */#endif /* CONFIG_PPC64BRIDGE */ sync tlbia sync#ifdef CONFIG_SMP tlbsync sync lis r3,hash_table_lock@ha stw r0,hash_table_lock@l(r3)#endif#if defined(CONFIG_SMP) || defined(CONFIG_PPC64BRIDGE) mtmsr r10 SYNC#endif blr/* * Flush the entry for a particular page from the hash table. * * flush_hash_page(unsigned context, unsigned long va) */_GLOBAL(flush_hash_page)#ifdef CONFIG_MOL mflr r10 MOL_HOOK_MMU(10, r6) mtlr r10#endif lis r6,Hash@ha lwz r6,Hash@l(r6) /* hash table base */ cmpwi 0,r6,0 /* hash table in use? */ bne+ 99f tlbie r4 /* in hw tlb too */ sync#ifdef CONFIG_SMP tlbsync sync#endif blr99:#if defined(CONFIG_SMP) || defined(CONFIG_PPC64BRIDGE) /* Note - we had better not do anything which could generate a hash table miss while we have the hash table locked, or we'll get a deadlock. -paulus */ mfmsr r10 sync rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ mtmsr r0 SYNC#endif#ifdef CONFIG_SMP lis r9,hash_table_lock@h ori r9,r9,hash_table_lock@l lwz r8,PROCESSOR(r2) oris r8,r8,910: lwarx r7,0,r9 cmpi 0,r7,0 bne- 10b stwcx. r8,0,r9 bne- 10b eieio#endif#ifndef CONFIG_PPC64BRIDGE rlwinm r3,r3,11,1,20 /* put context into vsid */ rlwimi r3,r4,11,21,24 /* put top 4 bits of va into vsid */ oris r3,r3,0x8000 /* set V (valid) bit */ rlwimi r3,r4,10,26,31 /* put in API (abbrev page index) */ rlwinm r7,r4,32-6,10,25 /* get page index << 6 */ rlwinm r5,r3,32-1,7,25 /* vsid << 6 */ xor r7,r7,r5 /* primary hash << 6 */ lis r5,Hash_mask@ha lwz r5,Hash_mask@l(r5) /* hash mask */ slwi r5,r5,6 /* << 6 */ and r7,r7,r5 add r6,r6,r7 /* address of primary PTEG */ li r8,8 mtctr r8 addi r7,r6,-81: lwzu r0,8(r7) /* get next PTE */ cmpw 0,r0,r3 /* see if tag matches */ bdnzf 2,1b /* while --ctr != 0 && !cr0.eq */ beq 3f /* if we found it */ ori r3,r3,0x40 /* set H (alt. hash) bit */ xor r6,r6,r5 /* address of secondary PTEG */ mtctr r8 addi r7,r6,-82: lwzu r0,8(r7) /* get next PTE */ cmpw 0,r0,r3 /* see if tag matches */ bdnzf 2,2b /* while --ctr != 0 && !cr0.eq */ bne 4f /* if we didn't find it */3: li r0,0 stw r0,0(r7) /* invalidate entry */#else /* CONFIG_PPC64BRIDGE */ rldic r3,r3,16,16 /* put context into vsid (<< 12) */ rlwimi r3,r4,16,16,24 /* top 4 bits of va and API */ ori r3,r3,1 /* set V (valid) bit */ rlwinm r7,r4,32-5,9,24 /* get page index << 7 */ srdi r5,r3,5 /* vsid << 7 */ rlwinm r5,r5,0,1,24 /* vsid << 7 (limited to 24 bits) */ xor r7,r7,r5 /* primary hash << 7 */ lis r5,Hash_mask@ha lwz r5,Hash_mask@l(r5) /* hash mask */ slwi r5,r5,7 /* << 7 */ and r7,r7,r5 add r6,r6,r7 /* address of primary PTEG */ li r8,8 mtctr r8 addi r7,r6,-161: ldu r0,16(r7) /* get next PTE */ cmpd 0,r0,r3 /* see if tag matches */ bdnzf 2,1b /* while --ctr != 0 && !cr0.eq */ beq 3f /* if we found it */ ori r3,r3,2 /* set H (alt. hash) bit */ xor r6,r6,r5 /* address of secondary PTEG */ mtctr r8 addi r7,r6,-162: ldu r0,16(r7) /* get next PTE */ cmpd 0,r0,r3 /* see if tag matches */ bdnzf 2,2b /* while --ctr != 0 && !cr0.eq */ bne 4f /* if we didn't find it */3: li r0,0 std r0,0(r7) /* invalidate entry */#endif /* CONFIG_PPC64BRIDGE */4: sync tlbie r4 /* in hw tlb too */ sync#ifdef CONFIG_SMP tlbsync sync li r0,0 stw r0,0(r9) /* clear hash_table_lock */#endif#if defined(CONFIG_SMP) || defined(CONFIG_PPC64BRIDGE) mtmsr r10 SYNC#endif blr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -