Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Dump R4x00 TLB for debugging purposes. | |
3 | * | |
4 | * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle. | |
5 | * Copyright (C) 1999 by Silicon Graphics, Inc. | |
6 | */ | |
1da177e4 LT |
7 | #include <linux/kernel.h> |
8 | #include <linux/mm.h> | |
1da177e4 | 9 | |
137877e4 | 10 | #include <asm/hazards.h> |
1da177e4 LT |
11 | #include <asm/mipsregs.h> |
12 | #include <asm/page.h> | |
13 | #include <asm/pgtable.h> | |
40df3831 | 14 | #include <asm/tlbdebug.h> |
1da177e4 LT |
15 | |
16 | static inline const char *msk2str(unsigned int mask) | |
17 | { | |
18 | switch (mask) { | |
19 | case PM_4K: return "4kb"; | |
20 | case PM_16K: return "16kb"; | |
21 | case PM_64K: return "64kb"; | |
22 | case PM_256K: return "256kb"; | |
c52399be RB |
23 | #ifdef CONFIG_CPU_CAVIUM_OCTEON |
24 | case PM_8K: return "8kb"; | |
25 | case PM_32K: return "32kb"; | |
26 | case PM_128K: return "128kb"; | |
27 | case PM_512K: return "512kb"; | |
28 | case PM_2M: return "2Mb"; | |
29 | case PM_8M: return "8Mb"; | |
30 | case PM_32M: return "32Mb"; | |
31 | #endif | |
1da177e4 LT |
32 | #ifndef CONFIG_CPU_VR41XX |
33 | case PM_1M: return "1Mb"; | |
34 | case PM_4M: return "4Mb"; | |
35 | case PM_16M: return "16Mb"; | |
36 | case PM_64M: return "64Mb"; | |
37 | case PM_256M: return "256Mb"; | |
542c1020 | 38 | case PM_1G: return "1Gb"; |
1da177e4 LT |
39 | #endif |
40 | } | |
4becef1d | 41 | return ""; |
1da177e4 LT |
42 | } |
43 | ||
69ed25b8 | 44 | static void dump_tlb(int first, int last) |
1da177e4 | 45 | { |
4becef1d AN |
46 | unsigned long s_entryhi, entryhi, asid; |
47 | unsigned long long entrylo0, entrylo1; | |
01422ff4 | 48 | unsigned int s_index, s_pagemask, pagemask, c0, c1, i; |
d1ce483e JH |
49 | #ifdef CONFIG_32BIT |
50 | int width = 8; | |
51 | #else | |
52 | int width = 11; | |
53 | #endif | |
1da177e4 | 54 | |
01422ff4 | 55 | s_pagemask = read_c0_pagemask(); |
1da177e4 LT |
56 | s_entryhi = read_c0_entryhi(); |
57 | s_index = read_c0_index(); | |
48c4ac97 | 58 | asid = s_entryhi & 0xff; |
1da177e4 LT |
59 | |
60 | for (i = first; i <= last; i++) { | |
61 | write_c0_index(i); | |
137877e4 | 62 | mtc0_tlbr_hazard(); |
1da177e4 | 63 | tlb_read(); |
137877e4 | 64 | tlb_read_hazard(); |
1da177e4 | 65 | pagemask = read_c0_pagemask(); |
70342287 | 66 | entryhi = read_c0_entryhi(); |
1da177e4 LT |
67 | entrylo0 = read_c0_entrylo0(); |
68 | entrylo1 = read_c0_entrylo1(); | |
69 | ||
decebccd JH |
70 | /* EHINV bit marks entire entry as invalid */ |
71 | if (cpu_has_tlbinv && entryhi & MIPS_ENTRYHI_EHINV) | |
72 | continue; | |
d1ce483e JH |
73 | /* |
74 | * Prior to tlbinv, unused entries have a virtual address of | |
75 | * CKSEG0. | |
76 | */ | |
77 | if ((entryhi & ~0x1ffffUL) == CKSEG0) | |
78 | continue; | |
48269c78 JH |
79 | /* |
80 | * ASID takes effect in absence of G (global) bit. | |
81 | * We check both G bits, even though architecturally they should | |
82 | * match one another, because some revisions of the SB1 core may | |
83 | * leave only a single G bit set after a machine check exception | |
84 | * due to duplicate TLB entry. | |
85 | */ | |
86 | if (!((entrylo0 | entrylo1) & MIPS_ENTRYLO_G) && | |
87 | (entryhi & 0xff) != asid) | |
d1ce483e JH |
88 | continue; |
89 | ||
90 | /* | |
91 | * Only print entries in use | |
92 | */ | |
93 | printk("Index: %2d pgmask=%s ", i, msk2str(pagemask)); | |
1da177e4 | 94 | |
d7f5499d JH |
95 | c0 = (entrylo0 & MIPS_ENTRYLO_C) >> MIPS_ENTRYLO_C_SHIFT; |
96 | c1 = (entrylo1 & MIPS_ENTRYLO_C) >> MIPS_ENTRYLO_C_SHIFT; | |
1da177e4 | 97 | |
d1ce483e JH |
98 | printk("va=%0*lx asid=%02lx\n", |
99 | width, (entryhi & ~0x1fffUL), | |
100 | entryhi & 0xff); | |
101 | printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ", | |
102 | width, | |
103 | (entrylo0 << 6) & PAGE_MASK, c0, | |
d7f5499d JH |
104 | (entrylo0 & MIPS_ENTRYLO_D) ? 1 : 0, |
105 | (entrylo0 & MIPS_ENTRYLO_V) ? 1 : 0, | |
106 | (entrylo0 & MIPS_ENTRYLO_G) ? 1 : 0); | |
d1ce483e JH |
107 | printk("[pa=%0*llx c=%d d=%d v=%d g=%d]\n", |
108 | width, | |
109 | (entrylo1 << 6) & PAGE_MASK, c1, | |
d7f5499d JH |
110 | (entrylo1 & MIPS_ENTRYLO_D) ? 1 : 0, |
111 | (entrylo1 & MIPS_ENTRYLO_V) ? 1 : 0, | |
112 | (entrylo1 & MIPS_ENTRYLO_G) ? 1 : 0); | |
1da177e4 LT |
113 | } |
114 | printk("\n"); | |
115 | ||
116 | write_c0_entryhi(s_entryhi); | |
117 | write_c0_index(s_index); | |
01422ff4 | 118 | write_c0_pagemask(s_pagemask); |
1da177e4 LT |
119 | } |
120 | ||
121 | void dump_tlb_all(void) | |
122 | { | |
123 | dump_tlb(0, current_cpu_data.tlbsize - 1); | |
124 | } |