PageRenderTime 22ms CodeModel.GetById 1ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/mips/lib-64/dump_tlb.c

https://bitbucket.org/evzijst/gittest
C | 211 lines | 167 code | 34 blank | 10 comment | 16 complexity | eaf597543fb83049875c419b3128164a MD5 | raw file
  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 */
  7#include <linux/config.h>
  8#include <linux/kernel.h>
  9#include <linux/mm.h>
 10#include <linux/sched.h>
 11#include <linux/string.h>
 12
 13#include <asm/bootinfo.h>
 14#include <asm/cachectl.h>
 15#include <asm/cpu.h>
 16#include <asm/mipsregs.h>
 17#include <asm/page.h>
 18#include <asm/pgtable.h>
 19
 20static inline const char *msk2str(unsigned int mask)
 21{
 22	switch (mask) {
 23	case PM_4K:	return "4kb";
 24	case PM_16K:	return "16kb";
 25	case PM_64K:	return "64kb";
 26	case PM_256K:	return "256kb";
 27#ifndef CONFIG_CPU_VR41XX
 28	case PM_1M:	return "1Mb";
 29	case PM_4M:	return "4Mb";
 30	case PM_16M:	return "16Mb";
 31	case PM_64M:	return "64Mb";
 32	case PM_256M:	return "256Mb";
 33#endif
 34	}
 35
 36	return "unknown";
 37}
 38
 39#define BARRIER()					\
 40	__asm__ __volatile__(				\
 41		".set\tnoreorder\n\t"			\
 42		"nop;nop;nop;nop;nop;nop;nop\n\t"	\
 43		".set\treorder");
 44
 45void dump_tlb(int first, int last)
 46{
 47	unsigned long s_entryhi, entryhi, entrylo0, entrylo1, asid;
 48	unsigned int s_index, pagemask, c0, c1, i;
 49
 50	s_entryhi = read_c0_entryhi();
 51	s_index = read_c0_index();
 52	asid = s_entryhi & 0xff;
 53
 54	for (i = first; i <= last; i++) {
 55		write_c0_index(i);
 56		BARRIER();
 57		tlb_read();
 58		BARRIER();
 59		pagemask = read_c0_pagemask();
 60		entryhi  = read_c0_entryhi();
 61		entrylo0 = read_c0_entrylo0();
 62		entrylo1 = read_c0_entrylo1();
 63
 64		/* Unused entries have a virtual address of CKSEG0.  */
 65		if ((entryhi & ~0x1ffffUL) != CKSEG0
 66		    && (entryhi & 0xff) == asid) {
 67			/*
 68			 * Only print entries in use
 69			 */
 70			printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
 71
 72			c0 = (entrylo0 >> 3) & 7;
 73			c1 = (entrylo1 >> 3) & 7;
 74
 75			printk("va=%011lx asid=%02lx\n",
 76			       (entryhi & ~0x1fffUL),
 77			       entryhi & 0xff);
 78			printk("\t[pa=%011lx c=%d d=%d v=%d g=%ld] ",
 79			       (entrylo0 << 6) & PAGE_MASK, c0,
 80			       (entrylo0 & 4) ? 1 : 0,
 81			       (entrylo0 & 2) ? 1 : 0,
 82			       (entrylo0 & 1));
 83			printk("[pa=%011lx c=%d d=%d v=%d g=%ld]\n",
 84			       (entrylo1 << 6) & PAGE_MASK, c1,
 85			       (entrylo1 & 4) ? 1 : 0,
 86			       (entrylo1 & 2) ? 1 : 0,
 87			       (entrylo1 & 1));
 88		}
 89	}
 90	printk("\n");
 91
 92	write_c0_entryhi(s_entryhi);
 93	write_c0_index(s_index);
 94}
 95
 96void dump_tlb_all(void)
 97{
 98	dump_tlb(0, current_cpu_data.tlbsize - 1);
 99}
100
101void dump_tlb_wired(void)
102{
103	int	wired;
104
105	wired = read_c0_wired();
106	printk("Wired: %d", wired);
107	dump_tlb(0, read_c0_wired());
108}
109
110void dump_tlb_addr(unsigned long addr)
111{
112	unsigned int flags, oldpid;
113	int index;
114
115	local_irq_save(flags);
116	oldpid = read_c0_entryhi() & 0xff;
117	BARRIER();
118	write_c0_entryhi((addr & PAGE_MASK) | oldpid);
119	BARRIER();
120	tlb_probe();
121	BARRIER();
122	index = read_c0_index();
123	write_c0_entryhi(oldpid);
124	local_irq_restore(flags);
125
126	if (index < 0) {
127		printk("No entry for address 0x%08lx in TLB\n", addr);
128		return;
129	}
130
131	printk("Entry %d maps address 0x%08lx\n", index, addr);
132	dump_tlb(index, index);
133}
134
135void dump_tlb_nonwired(void)
136{
137	dump_tlb(read_c0_wired(), current_cpu_data.tlbsize - 1);
138}
139
140void dump_list_process(struct task_struct *t, void *address)
141{
142	pgd_t	*page_dir, *pgd;
143	pmd_t	*pmd;
144	pte_t	*pte, page;
145	unsigned long addr, val;
146
147	addr = (unsigned long) address;
148
149	printk("Addr                 == %08lx\n", addr);
150	printk("tasks->mm.pgd        == %08lx\n", (unsigned long) t->mm->pgd);
151
152	page_dir = pgd_offset(t->mm, 0);
153	printk("page_dir == %016lx\n", (unsigned long) page_dir);
154
155	pgd = pgd_offset(t->mm, addr);
156	printk("pgd == %016lx\n", (unsigned long) pgd);
157
158	pmd = pmd_offset(pgd, addr);
159	printk("pmd == %016lx\n", (unsigned long) pmd);
160
161	pte = pte_offset(pmd, addr);
162	printk("pte == %016lx\n", (unsigned long) pte);
163
164	page = *pte;
165	printk("page == %08lx\n", pte_val(page));
166
167	val = pte_val(page);
168	if (val & _PAGE_PRESENT) printk("present ");
169	if (val & _PAGE_READ) printk("read ");
170	if (val & _PAGE_WRITE) printk("write ");
171	if (val & _PAGE_ACCESSED) printk("accessed ");
172	if (val & _PAGE_MODIFIED) printk("modified ");
173	if (val & _PAGE_R4KBUG) printk("r4kbug ");
174	if (val & _PAGE_GLOBAL) printk("global ");
175	if (val & _PAGE_VALID) printk("valid ");
176	printk("\n");
177}
178
179void dump_list_current(void *address)
180{
181	dump_list_process(current, address);
182}
183
184unsigned int vtop(void *address)
185{
186	pgd_t	*pgd;
187	pmd_t	*pmd;
188	pte_t	*pte;
189	unsigned int addr, paddr;
190
191	addr = (unsigned long) address;
192	pgd = pgd_offset(current->mm, addr);
193	pmd = pmd_offset(pgd, addr);
194	pte = pte_offset(pmd, addr);
195	paddr = (CKSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
196	paddr |= (addr & ~PAGE_MASK);
197
198	return paddr;
199}
200
201void dump16(unsigned long *p)
202{
203	int i;
204
205	for (i = 0; i < 8; i++) {
206		printk("*%08lx == %08lx, ", (unsigned long)p, *p);
207		p++;
208		printk("*%08lx == %08lx\n", (unsigned long)p, *p);
209		p++;
210	}
211}