__REF
_GLOBAL(create_hpte) /* Convert linux-style PTE (r5) to low word of PPC-style PTE (r8) */
lis r0, TASK_SIZE@h
rlwinm r5,r5,0,~3/* Clear PP bits */
cmplw r4,r0
rlwinm r8,r5,32-9,30,30/* _PAGE_WRITE -> PP msb */
rlwinm r0,r5,32-6,30,30/* _PAGE_DIRTY -> PP msb */
and r8,r8,r0 /* writable if _RW & _DIRTY */
bge- 1f /* Kernelspace ? Skip */
ori r5,r5,3/* Userspace ? PP = 3 */ 1: ori r8,r8,0xe04 /* clear out reserved bits */
andc r8,r5,r8 /* PP = user? (rw&dirty? 1: 3): 0 */
BEGIN_FTR_SECTION
rlwinm r8,r8,0,~_PAGE_COHERENT /* clear M (coherence not required) */
END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
#ifdef CONFIG_PTE_64BIT /* Put the XPN bits into the PTE */
rlwimi r8,r10,8,20,22
rlwimi r8,r10,2,29,29
#endif
/* Construct the high word of the PPC-style PTE (r5) */
rlwinm r5,r3,7,1,24/* put VSID in 0x7fffff80 bits */
rlwimi r5,r4,10,26,31/* put in API (abbrev page index) */
SET_V(r5) /* set V (valid) bit */
patch_site 0f, patch__hash_page_A0
patch_site 1f, patch__hash_page_A1
patch_site 2f, patch__hash_page_A2 /* Get the address of the primary PTE group in the hash table (r3) */ 0: lis r0, (Hash_base - PAGE_OFFSET)@h /* base address of hash table */ 1: rlwimi r0,r3,LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* VSID -> hash */ 2: rlwinm r3,r4,20+LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* PI -> hash */
xor r3,r3,r0 /* make primary hash */
li r0,8/* PTEs/group */
/* *Testthe_PAGE_HASHPTEbitintheoldlinuxPTE,andskipthesearch *ifitisclear,meaningthattheHPTEisn'ttherealready...
*/
andi. r6,r6,_PAGE_HASHPTE
beq+ 10f /* no PTE: go look for an empty slot */
tlbie r4
/* Search the primary PTEG for a PTE whose 1st (d)word matches r5 */
mtctr r0
addi r4,r3,-HPTE_SIZE 1: LDPTEu r6,HPTE_SIZE(r4) /* get next PTE */
CMPPTE 0,r6,r5
bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */
beq+ .Lfound_slot
patch_site 0f, patch__hash_page_B /* Search the secondary PTEG for a matching PTE */
ori r5,r5,PTE_H /* set H (secondary hash) bit */ 0: xoris r4,r3,Hash_msk>>16/* compute secondary hash */
xori r4,r4,(-PTEG_SIZE & 0xffff)
addi r4,r4,-HPTE_SIZE
mtctr r0 2: LDPTEu r6,HPTE_SIZE(r4)
CMPPTE 0,r6,r5
bdnzf 2,2b
beq+ .Lfound_slot
xori r5,r5,PTE_H /* clear H bit again */
/* Search the primary PTEG for an empty slot */ 10: mtctr r0
addi r4,r3,-HPTE_SIZE /* search primary PTEG */ 1: LDPTEu r6,HPTE_SIZE(r4) /* get next PTE */
TST_V(r6) /* test valid bit */
bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */
beq+ .Lfound_empty
patch_site 0f, patch__hash_page_C /* Search the secondary PTEG for an empty slot */
ori r5,r5,PTE_H /* set H (secondary hash) bit */ 0: xoris r4,r3,Hash_msk>>16/* compute secondary hash */
xori r4,r4,(-PTEG_SIZE & 0xffff)
addi r4,r4,-HPTE_SIZE
mtctr r0 2: LDPTEu r6,HPTE_SIZE(r4)
TST_V(r6)
bdnzf 2,2b
beq+ .Lfound_empty
xori r5,r5,PTE_H /* clear H bit again */
/* First find a PTE in the range that has _PAGE_HASHPTE set */
#ifndef CONFIG_PTE_64BIT
rlwimi r5,r4,22,20,29
#else
rlwimi r5,r4,23,20,28
addi r5,r5,PTE_FLAGS_OFFSET
#endif 1: lwz r0,0(r5)
cmpwi cr1,r6,1
andi. r0,r0,_PAGE_HASHPTE
bne 2f
ble cr1,19f
addi r4,r4,0x1000
addi r5,r5,PTE_T_SIZE
addi r6,r6,-1
b 1b
/* Convert context and va to VSID */ 2: mulli r3,r3,897*16/* multiply context by context skew */
rlwinm r0,r4,4,28,31/* get ESID (top 4 bits of va) */
mulli r0,r0,0x111 /* multiply by ESID skew */
add r3,r3,r0 /* note code below trims to 24 bits */
/* Construct the high word of the PPC-style PTE (r11) */
rlwinm r11,r3,7,1,24/* put VSID in 0x7fffff80 bits */
rlwimi r11,r4,10,26,31/* put in API (abbrev page index) */
SET_V(r11) /* set V (valid) bit */
/* *Checkthe_PAGE_HASHPTEbitinthelinuxPTE.Ifitis *alreadyclear,we'redone(forthispte).Ifnot, *clearit(atomically)andproceed.--paulus.
*/ 33: lwarx r8,0,r5 /* fetch the pte flags word */
andi. r0,r8,_PAGE_HASHPTE
beq 8f /* done if HASHPTE is already clear */
rlwinm r8,r8,0,31,29/* clear HASHPTE bit */
stwcx. r8,0,r5 /* update the pte */
bne- 33b
patch_site 0f, patch__flush_hash_A0
patch_site 1f, patch__flush_hash_A1
patch_site 2f, patch__flush_hash_A2 /* Get the address of the primary PTE group in the hash table (r3) */ 0: lis r8, (Hash_base - PAGE_OFFSET)@h /* base address of hash table */ 1: rlwimi r8,r3,LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* VSID -> hash */ 2: rlwinm r0,r4,20+LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* PI -> hash */
xor r8,r0,r8 /* make primary hash */
/* Search the primary PTEG for a PTE whose 1st (d)word matches r5 */
li r0,8/* PTEs/group */
mtctr r0
addi r12,r8,-HPTE_SIZE 1: LDPTEu r0,HPTE_SIZE(r12) /* get next PTE */
CMPPTE 0,r0,r11
bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */
beq+ 3f
patch_site 0f, patch__flush_hash_B /* Search the secondary PTEG for a matching PTE */
ori r11,r11,PTE_H /* set H (secondary hash) bit */
li r0,8/* PTEs/group */ 0: xoris r12,r8,Hash_msk>>16/* compute secondary hash */
xori r12,r12,(-PTEG_SIZE & 0xffff)
addi r12,r12,-HPTE_SIZE
mtctr r0 2: LDPTEu r0,HPTE_SIZE(r12)
CMPPTE 0,r0,r11
bdnzf 2,2b
xori r11,r11,PTE_H /* clear H again */
bne- 4f /* should rarely fail to find it */
3: li r0,0
STPTE r0,0(r12) /* invalidate entry */ 4: sync
tlbie r4 /* in hw tlb too */
sync
8: ble cr1,9f /* if all ptes checked */ 81: addi r6,r6,-1
addi r5,r5,PTE_T_SIZE
addi r4,r4,0x1000
lwz r0,0(r5) /* check next pte */
cmpwi cr1,r6,1
andi. r0,r0,_PAGE_HASHPTE
bne 33b
bgt cr1,81b
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.