64-bit multi-core MIPS exception and interrupt kernel code analysis (3)

Source: Internet
Author: User

64-bit multi-core MIPS exception and interrupt kernel code analysis (3)

 

Analysis of RMI xlr732tlb related processing functions

0. Background

 

The virtual address space in mips64 is divided:

 

The kernel space is xkphys and xkseg, and xkphys are fixed mappings without TLB (unmapped)

The user space is xuseg.


1. Rmi xlr732 TLB refill handler Analysis


@ 0 xFFFF FFFF 8000 0000
C: 07610005 bgez K1, 24 <0x24>/* If vaddr [61]! = 1 (0xc000 0000 0000 0000 ~ 0 xdfff FFFF), Branch */
10: 3c1bc000 lui K1, 0xc000 -----> at delay slot, commit new value to K1 after reading K1 (bgez)

# Vaddr is at 0xe000000000000000 ~ 0 xFFFF FFFF. kseg2 is used by 64-bit Linux kernel and must pass through TLB. This address is used by kernel modules by default.
14: 035bd02f dsubu K0, K0, K1/* K0 = vaddr-0 xFFFF FFFF c0000000 */
18: 3c1b8396 lui K1, 0x8396
1c: 10000023 B AC <0xac> ----> @@@
20: 277ba000 addiu K1, K1,-24576/* 0 xFFFF FFFF 8395a000 = module_pg_dir, using the module_pg_dir as the PGD entry */

 

# Vaddr is at 0xc00000000000 ~ 0 xdfff FFFF
24: 001bd83c dsll32 K1, K1, 0x0/* (0 xFFFF FFFF c0000000 <32 )*/
28: 035bd02f dsubu K0, K0, K1/* K0 = vaddr-0xc00000000000 */
2c: 1000001f B AC <0xac> ----> @@@
30: 3c1b8396 lui K1, 0x8396/* 0 xFFFF FFFF 83960000 = swapper_pg_current, using the swapper_pg_current as the PGD entry */

34: 00000000

38: 00000000 <repeat>

......

@ 0 xFFFF FFFF 8000 0080 (xtlb refill entry)

8c: 403a4000 dmfc0 K0, c0_badvaddr

90: 0740001a BLTZ K0, FC <0xfc>/* If badvaddr> = 0x80000000 00000000 Branch */

 

# Vaddr is <0x8000 0000 0000 000, So it's at kuseg
94: 403b2000 dmfc0 K1, c0_context
98: 001 bddfa dsrl K1, K1, 0x17/* Get (smp_processor_id () <3) (26-23), see ASM/mmu_context.h */
9C: 3c1a8396 lui K0, 0x8396/* swapper_pg_current = 0 xFFFF FFFF 83960000 */
A0: 037ad82d daddu K1, K1, K0/* k1 = swapper_pg_current [smp_processor_id ()] */
A4: 403a4000 dmfc0 K0, c0_badvaddr
A8: df7b2000 LD K1, 8192 (K1 )/*
* PGD = * (void *) (K1 + 8192), 8 bytes per PGD entry, pgd_current = 0 xFFFF FFFF 8396 2000,
X 0x2000 = 8192
* Actually it's PGD = pgd_current [smp_processor_id ()]
*/

@@@
AC: 001ad6fa dsrl K0, K0, 0x1b #> 27
B0: 335a1ff8 Andi K0, K0, 0x1ff8/* Get (vaddr [39: 30] <3), for indexing PGD */
B4: 037ad82d daddu K1, K1, K0/* index PGD */

B8: 403a4000 dmfc0 K0, c0_badvaddr
BC: df7b0000 LD K1, 0 (K1)/* Get p_pmd */
C0: 001ad4ba dsrl K0, K0, 0x12
C4: 335a0ff8 Andi K0, K0, 0xff8/* Get (vaddr [29:21] <3), for indexing PMD */
C8: 037ad82d daddu K1, K1, K0/* index PMD */

Cc: 403aa000 dmfc0 K0, c0_xcontext
D0: df7b0000 LD K1, 0 (K1)/* Get p_pt */
D4: 335a0ff0 Andi K0, K0, 0xff0/* Get (va [20: 13] <4), actually use va [20: 12] index the PT, VA [12] = 0, for indexing Pt */
D8: 037ad82d daddu K1, K1, K0/* index Pt */

DC: df7a0000 LD K0, 0 (K1)/* Get Even page ADDR */<-------------
E0: df7b0008 LD K1, 8 (K1)/* get odd page ADDR */

E4: 001ad1ba dsrl K0, K0, 0x6/* ignore the low 6 bits, it's for OS */
E8: 409a1000 mtc0 K0, c0_entrylo0/* TLB even page entry */
EC: 001bd9ba dsrl K1, K1, 0x6/* same as abve */
F0: 409b1800 mtc0 K1, c0_entrylo1/* TLB odd page entry */
F4: 42000006 tlbwr/* random write TLB */
F8: 42000018 eret

 

# Go here, vaddr is> = 0x8000 0000 0000, so it's in xkphys or xkseg; and 0x0000 8000 0000 0000 ~ 0 xbfff FFFF is xkphys, unmapped, do not index TLB, so vaddr is at 0xc000 0000 0000 0000
FC: 001ad8b8 dsll K1, K0, 0x2 # vaddr <2, will be test the vaddr [61]
100: 1000ffc2 B C <0xc>

104: 00000000 NOP
108: 00000000 NOP


2. Rmi xlr732 handle_tlbl Analysis

 

Handle_tlbl:

C: 403a4000 dmfc0 K0, c0_badvaddr <---- handle_tlbl start
10: 07400027 BLTZ K0, B0 <0xb0> # If badvaddr> = 0x80000000 00000000 Branch

14: 403b2000 dmfc0 K1, c0_context
18: 001 bddfa dsrl K1, K1, 0x17/* Get (smp_processor_id () <3) (26-23 )*/
1c: 3c1a8396 lui K0, 0x8396/* 0xffffffff83960000 + 0x2000 = pgd_current */
20: 037ad82d daddu K1, K1, K0
24: 403a4000 dmfc0 K0, c0_badvaddr
28: df7b2000 LD K1, 8192 (K1)/* PGD = pgd_current [smp_processor_id ()] */

@@
2c: 001ad6fa dsrl K0, K0, 0x1b #> 27
30: 335a1ff8 Andi K0, K0, 0x1ff8/* Get (vaddr [39: 30] <3), for indexing PGD */
34: 037ad82d daddu K1, K1, K0/* index PGD */
38: 403a4000 dmfc0 K0, c0_badvaddr
3c: df7b0000 LD K1, 0 (K1)/* Get PMD */
40: 001ad4ba dsrl K0, K0, 0x12 #> 18
44: 335a0ff8 Andi K0, K0, 0xff8 # Get (vaddr [29:21] <3)
48: 037ad82d daddu K1, K1, K0 # index PMD
4c: 403a4000 dmfc0 K0, c0_badvaddr
50: df7b0000 LD K1, 0 (K1) # Get p_pt
54: 001ad27a dsrl K0, K0, 0x9
58: 335a0ff8 Andi K0, K0, 0xff8 # Get (vaddr [20:12])
5C: 037ad82d daddu K1, K1, K0 # index PT

60: d37a0000 LLD K0, 0 (K1) # Get PT entry
64: 42000008 tlbp # To distinguish TLB invalid or TLB refill exception

68: 335a0003 Andi K0, K0, 0x3
6c: 3b5a0003 xori K0, K0, 0x3 # _ present and _ read
70: 1740001a bnez K0, DC <0xdc> # Low two bits is not 011, Branch --> out
74: d37a0000 LLD K0, 0 (K1) # Get PT entry again

78: 375a0088 Ori K0, K0, 0x88
7c: f37a0000 SCD K0, 0 (K1) # Set PT entry's PTE [7] = 1, PTE [3] = 1
80: 1340fff7 beqz K0, 60 <0x60>
84: 00000000 NOP

88: 377b0008 Ori K1, K1, 0x8
8c: 3b7b0008 xori K1, K1, 0x8 # For getting even page
90: df7a0000 LD K0, 0 (K1) # Get Even page ADDR
94: df7b0008 LD K1, 8 (K1) # Get odd page ADDR
98: 001ad1ba dsrl K0, K0, 0x6
9C: 409a1000 mtc0 K0, c0_entrylo0
A0: 001bd9ba dsrl K1, K1, 0x6
A4: 409b1800 mtc0 K1, c0_entrylo1
A8: 42000002 tlbwi
AC: 42000018 eret

@@
B0: 001ad8b8 dsll K1, K0, 0x2 # Go here, vaddr is in xkphys or xkseg (> 0x8000.. 0000)
#0x8000... 0000 ~ 0xc000 .. 0000 is xkphys, unmapped,
# So vaddr> 0xc000 .. 0000; vaddr <2
B4: 07610005 bgez K1, CC <0xcc>
# Vaddr [61]! = 1 (0xc000... 0000 ~ 0xdfff .. FFFF), Branch
B8: 3c1bc000 lui K1, 0xc000

# Vaddr, 0xe000... 0000 ~ 0xffff .. FFFF
BC: 035bd02f dsubu K0, K0, K1 # K0 = vaddr-0xffffffffc0000000
C0: 3c1b8396 lui K1, 0x8396
C4: 1000ffd9 B 2C <0x2c>
C8: 277ba000 addiu K1, K1,-24576 # k1 = 0xffffffff8395a000, module_pg_dir
# Module_pg_dir & swapper_pg_dir don't need the SMP

@@
# Vaddr, 0xc000... 0000 ~ 0xdfff .. FFFF
Cc: 001bd83c dsll32 K1, K1, 0x0 #0xc0000000 00000000
D0: 035bd02f dsubu K0, K0, K1 # K0 = vaddr-0xc0000000 00000000
D4: 1000ffd5 B 2C <0x2c>
D8: 3c1b8396 lui K1, 0x8396 # Only swapper_pg_current

@ --> Do_page_fault
DC: 08d01150 J 3404540 <0 x3404540>
E0: 00000000 NOP
...

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.