1
2
3
4
5
6
7#include <linux/kernel.h>
8#include <linux/mm.h>
9#include <linux/sched.h>
10#include <linux/string.h>
11
12#include <asm/bootinfo.h>
13#include <asm/cachectl.h>
14#include <asm/mipsregs.h>
15#include <asm/page.h>
16#include <asm/pgtable.h>
17
18#define mips_tlb_entries 48
19
20void
21dump_tlb(int first, int last)
22{
23 int i;
24 unsigned int pagemask, c0, c1, asid;
25 unsigned long entryhi, entrylo0, entrylo1;
26
27 asid = get_entryhi() & 0xff;
28
29 for(i=first;i<=last;i++)
30 {
31 write_32bit_cp0_register(CP0_INDEX, i);
32 __asm__ __volatile__(
33 ".set\tmips3\n\t"
34 ".set\tnoreorder\n\t"
35 "nop;nop;nop;nop\n\t"
36 "tlbr\n\t"
37 "nop;nop;nop;nop\n\t"
38 ".set\treorder\n\t"
39 ".set\tmips0\n\t");
40 pagemask = read_32bit_cp0_register(CP0_PAGEMASK);
41 entryhi = read_32bit_cp0_register(CP0_ENTRYHI);
42 entrylo0 = read_32bit_cp0_register(CP0_ENTRYLO0);
43 entrylo1 = read_32bit_cp0_register(CP0_ENTRYLO1);
44
45
46 if ((entryhi & 0xffffe000) != 0x80000000
47 && (entryhi & 0xff) == asid) {
48
49
50
51 printk("Index: %2d pgmask=%08x ", i, pagemask);
52
53 c0 = (entrylo0 >> 3) & 7;
54 c1 = (entrylo1 >> 3) & 7;
55
56 printk("va=%08lx asid=%08lx"
57 " [pa=%06lx c=%d d=%d v=%d g=%ld]"
58 " [pa=%06lx c=%d d=%d v=%d g=%ld]",
59 (entryhi & 0xffffe000),
60 entryhi & 0xff,
61 entrylo0 & PAGE_MASK, c0,
62 (entrylo0 & 4) ? 1 : 0,
63 (entrylo0 & 2) ? 1 : 0,
64 (entrylo0 & 1),
65 entrylo1 & PAGE_MASK, c1,
66 (entrylo1 & 4) ? 1 : 0,
67 (entrylo1 & 2) ? 1 : 0,
68 (entrylo1 & 1));
69
70 }
71 }
72 printk("\n");
73
74 set_entryhi(asid);
75}
76
77void
78dump_tlb_all(void)
79{
80 dump_tlb(0, mips_tlb_entries - 1);
81}
82
83void
84dump_tlb_wired(void)
85{
86 int wired;
87
88 wired = read_32bit_cp0_register(CP0_WIRED);
89 printk("Wired: %d", wired);
90 dump_tlb(0, read_32bit_cp0_register(CP0_WIRED));
91}
92
93#define BARRIER \
94 __asm__ __volatile__( \
95 ".set\tnoreorder\n\t" \
96 "nop;nop;nop;nop;nop;nop;nop\n\t" \
97 ".set\treorder");
98
99void
100dump_tlb_addr(unsigned long addr)
101{
102 unsigned int flags, oldpid;
103 int index;
104
105 local_irq_save(flags);
106 oldpid = get_entryhi() & 0xff;
107 BARRIER;
108 set_entryhi((addr & PAGE_MASK) | oldpid);
109 BARRIER;
110 tlb_probe();
111 BARRIER;
112 index = get_index();
113 set_entryhi(oldpid);
114 local_irq_restore(flags);
115
116 if (index < 0) {
117 printk("No entry for address 0x%08lx in TLB\n", addr);
118 return;
119 }
120
121 printk("Entry %d maps address 0x%08lx\n", index, addr);
122 dump_tlb(index, index);
123}
124
125void
126dump_tlb_nonwired(void)
127{
128 dump_tlb(read_32bit_cp0_register(CP0_WIRED), mips_tlb_entries - 1);
129}
130
131void
132dump_list_process(struct task_struct *t, void *address)
133{
134 pgd_t *page_dir, *pgd;
135 pmd_t *pmd;
136 pte_t *pte, page;
137 unsigned int addr;
138 unsigned long val;
139
140 addr = (unsigned int) address;
141
142 printk("Addr == %08x\n", addr);
143 printk("tasks->mm.pgd == %08x\n", (unsigned int) t->mm->pgd);
144
145 page_dir = pgd_offset(t->mm, 0);
146 printk("page_dir == %08x\n", (unsigned int) page_dir);
147
148 pgd = pgd_offset(t->mm, addr);
149 printk("pgd == %08x, ", (unsigned int) pgd);
150
151 pmd = pmd_offset(pgd, addr);
152 printk("pmd == %08x, ", (unsigned int) pmd);
153
154 pte = pte_offset(pmd, addr);
155 printk("pte == %08x, ", (unsigned int) pte);
156
157 page = *pte;
158 printk("page == %08x\n", (unsigned int) pte_val(page));
159
160 val = pte_val(page);
161 if (val & _PAGE_PRESENT) printk("present ");
162 if (val & _PAGE_READ) printk("read ");
163 if (val & _PAGE_WRITE) printk("write ");
164 if (val & _PAGE_ACCESSED) printk("accessed ");
165 if (val & _PAGE_MODIFIED) printk("modified ");
166 if (val & _PAGE_R4KBUG) printk("r4kbug ");
167 if (val & _PAGE_GLOBAL) printk("global ");
168 if (val & _PAGE_VALID) printk("valid ");
169 printk("\n");
170}
171
172void
173dump_list_current(void *address)
174{
175 dump_list_process(current, address);
176}
177
178unsigned int
179vtop(void *address)
180{
181 pgd_t *pgd;
182 pmd_t *pmd;
183 pte_t *pte;
184 unsigned int addr, paddr;
185
186 addr = (unsigned long) address;
187 pgd = pgd_offset(current->mm, addr);
188 pmd = pmd_offset(pgd, addr);
189 pte = pte_offset(pmd, addr);
190 paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
191 paddr |= (addr & ~PAGE_MASK);
192
193 return paddr;
194}
195
196void
197dump16(unsigned long *p)
198{
199 int i;
200
201 for(i=0;i<8;i++)
202 {
203 printk("*%08lx == %08lx, ",
204 (unsigned long)p, (unsigned long)*p++);
205 printk("*%08lx == %08lx\n",
206 (unsigned long)p, (unsigned long)*p++);
207 }
208}
209