patch-2.3.48 linux/arch/mips/lib/dump_tlb.c

Next file: linux/arch/mips/lib/floppy-no.c
Previous file: linux/arch/mips/lib/csum_partial_copy.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.47/linux/arch/mips/lib/dump_tlb.c linux/arch/mips/lib/dump_tlb.c
@@ -1,8 +1,8 @@
 /*
  * Dump R4x00 TLB for debugging purposes.
  *
- * Copyright (C) 1994, 1995 by Waldorf Electronics,
- * written by Ralf Baechle.
+ * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
+ * Copyright (C) 1999 by Silicon Graphics, Inc.
  */
 #include <linux/kernel.h>
 #include <linux/mm.h>
@@ -11,27 +11,22 @@
 
 #include <asm/bootinfo.h>
 #include <asm/cachectl.h>
-#include <asm/mipsconfig.h>
 #include <asm/mipsregs.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
-static char *region_map [] = {
-	"u", "s", "k", "!"
-};
+#define mips_tlb_entries 48
 
 void
 dump_tlb(int first, int last)
 {
 	int	i;
-	int	wired;
-	unsigned int pagemask, c0, c1, r;
-	unsigned long long entryhi, entrylo0, entrylo1;
+	unsigned int pagemask, c0, c1, asid;
+	unsigned long entryhi, entrylo0, entrylo1;
 
-	wired = read_32bit_cp0_register(CP0_WIRED);
-	printk("Wired: %d", wired);
-	
-	for(i=first;i<last;i++)
+	asid = get_entryhi() & 0xff;
+
+	for(i=first;i<=last;i++)
 	{
 		write_32bit_cp0_register(CP0_INDEX, i);
 		__asm__ __volatile__(
@@ -43,30 +38,31 @@
 			".set\treorder\n\t"
 			".set\tmips0\n\t");
 		pagemask = read_32bit_cp0_register(CP0_PAGEMASK);
-		entryhi  = read_64bit_cp0_register(CP0_ENTRYHI);
-		entrylo0 = read_64bit_cp0_register(CP0_ENTRYLO0);
-		entrylo1 = read_64bit_cp0_register(CP0_ENTRYLO1);
-
-		if((entrylo0|entrylo1) & 2)
-		{
+		entryhi  = read_32bit_cp0_register(CP0_ENTRYHI);
+		entrylo0 = read_32bit_cp0_register(CP0_ENTRYLO0);
+		entrylo1 = read_32bit_cp0_register(CP0_ENTRYLO1);
+
+		/* Unused entries have a virtual address of KSEG0.  */
+		if ((entryhi & 0xffffe000) != 0x80000000
+		    && (entryhi & 0xff) == asid) {
 			/*
 			 * Only print entries in use
 			 */
-			printk("\nIndex: %2d pgmask=%08x ", i, pagemask);
+			printk("Index: %2d pgmask=%08x ", i, pagemask);
 
-			r  = entryhi >> 62;
 			c0 = (entrylo0 >> 3) & 7;
 			c1 = (entrylo1 >> 3) & 7;
 
-			printk("%s vpn2=%08Lx "
-			       "[pfn=%06Lx c=%d d=%d v=%d g=%Ld]"
-			       "[pfn=%06Lx c=%d d=%d v=%d g=%Ld]",
-			       region_map [r], (entryhi >> 13) & 0xffffffff,
-			       (entrylo0 >> 6) & 0xffffff, c0,
+			printk("va=%08lx asid=%08lx"
+			       "  [pa=%06lx c=%d d=%d v=%d g=%ld]"
+			       "  [pa=%06lx c=%d d=%d v=%d g=%ld]",
+			       (entryhi & 0xffffe000),
+			       entryhi & 0xff,
+			       entrylo0 & PAGE_MASK, c0,
 			       (entrylo0 & 4) ? 1 : 0,
 			       (entrylo0 & 2) ? 1 : 0,
 			       (entrylo0 & 1),
-			       (entrylo1 >> 6) & 0xffffff, c1,
+			       entrylo1 & PAGE_MASK, c1,
 			       (entrylo1 & 4) ? 1 : 0,
 			       (entrylo1 & 2) ? 1 : 0,
 			       (entrylo1 & 1));
@@ -74,6 +70,8 @@
 		}
 	}
 	printk("\n");
+
+	set_entryhi(asid);
 }
 
 void
@@ -85,9 +83,45 @@
 void
 dump_tlb_wired(void)
 {
+	int	wired;
+
+	wired = read_32bit_cp0_register(CP0_WIRED);
+	printk("Wired: %d", wired);
 	dump_tlb(0, read_32bit_cp0_register(CP0_WIRED));
 }
 
+#define BARRIER						\
+	__asm__ __volatile__(				\
+		".set\tnoreorder\n\t"			\
+		"nop;nop;nop;nop;nop;nop;nop\n\t"	\
+		".set\treorder");
+
+void
+dump_tlb_addr(unsigned long addr)
+{
+	unsigned int flags, oldpid;
+	int index;
+
+	__save_and_cli(flags);
+	oldpid = get_entryhi() & 0xff;
+	BARRIER;
+	set_entryhi((addr & PAGE_MASK) | oldpid);
+	BARRIER;
+	tlb_probe();
+	BARRIER;
+	index = get_index();
+	set_entryhi(oldpid);
+	__restore_flags(flags);
+
+	if (index < 0) {
+		printk("No entry for address 0x%08lx in TLB\n", addr);
+		return;
+	}
+
+	printk("Entry %d maps address 0x%08lx\n", index, addr);
+	dump_tlb(index, index);
+}
+
 void
 dump_tlb_nonwired(void)
 {
@@ -101,12 +135,12 @@
 	pmd_t	*pmd;
 	pte_t	*pte, page;
 	unsigned int addr;
+	unsigned long val;
 
 	addr = (unsigned int) address;
 
-	printk("Addr              == %08x\n", addr);
-	printk("tasks->tss.pg_dir == %08x\n", (unsigned int) t->tss.pg_dir);
-	printk("tasks->mm.pgd     == %08x\n", (unsigned int) t->mm->pgd);
+	printk("Addr                 == %08x\n", addr);
+	printk("tasks->mm.pgd        == %08x\n", (unsigned int) t->mm->pgd);
 
 	page_dir = pgd_offset(t->mm, 0);
 	printk("page_dir == %08x\n", (unsigned int) page_dir);
@@ -122,6 +156,17 @@
 
 	page = *pte;
 	printk("page == %08x\n", (unsigned int) pte_val(page));
+
+	val = pte_val(page);
+	if (val & _PAGE_PRESENT) printk("present ");
+	if (val & _PAGE_READ) printk("read ");
+	if (val & _PAGE_WRITE) printk("write ");
+	if (val & _PAGE_ACCESSED) printk("accessed ");
+	if (val & _PAGE_MODIFIED) printk("modified ");
+	if (val & _PAGE_R4KBUG) printk("r4kbug ");
+	if (val & _PAGE_GLOBAL) printk("global ");
+	if (val & _PAGE_VALID) printk("valid ");
+	printk("\n");
 }
 
 void

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)