14becef1dSAtsushi Nemoto /* 24becef1dSAtsushi Nemoto * Dump R3000 TLB for debugging purposes. 34becef1dSAtsushi Nemoto * 44becef1dSAtsushi Nemoto * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle. 54becef1dSAtsushi Nemoto * Copyright (C) 1999 by Silicon Graphics, Inc. 64becef1dSAtsushi Nemoto * Copyright (C) 1999 by Harald Koerfgen 74becef1dSAtsushi Nemoto */ 84becef1dSAtsushi Nemoto #include <linux/kernel.h> 94becef1dSAtsushi Nemoto #include <linux/mm.h> 104becef1dSAtsushi Nemoto #include <linux/sched.h> 114becef1dSAtsushi Nemoto #include <linux/string.h> 124becef1dSAtsushi Nemoto 134becef1dSAtsushi Nemoto #include <asm/bootinfo.h> 144becef1dSAtsushi Nemoto #include <asm/cachectl.h> 154becef1dSAtsushi Nemoto #include <asm/cpu.h> 164becef1dSAtsushi Nemoto #include <asm/mipsregs.h> 174becef1dSAtsushi Nemoto #include <asm/page.h> 184becef1dSAtsushi Nemoto #include <asm/pgtable.h> 194becef1dSAtsushi Nemoto 204becef1dSAtsushi Nemoto extern int r3k_have_wired_reg; /* defined in tlb-r3k.c */ 214becef1dSAtsushi Nemoto 224becef1dSAtsushi Nemoto void dump_tlb(int first, int last) 234becef1dSAtsushi Nemoto { 244becef1dSAtsushi Nemoto int i; 254becef1dSAtsushi Nemoto unsigned int asid; 264becef1dSAtsushi Nemoto unsigned long entryhi, entrylo0; 274becef1dSAtsushi Nemoto 284becef1dSAtsushi Nemoto asid = read_c0_entryhi() & 0xfc0; 294becef1dSAtsushi Nemoto 304becef1dSAtsushi Nemoto for (i = first; i <= last; i++) { 314becef1dSAtsushi Nemoto write_c0_index(i<<8); 324becef1dSAtsushi Nemoto __asm__ __volatile__( 334becef1dSAtsushi Nemoto ".set\tnoreorder\n\t" 344becef1dSAtsushi Nemoto "tlbr\n\t" 354becef1dSAtsushi Nemoto "nop\n\t" 364becef1dSAtsushi Nemoto ".set\treorder"); 374becef1dSAtsushi Nemoto entryhi = read_c0_entryhi(); 384becef1dSAtsushi Nemoto entrylo0 = read_c0_entrylo0(); 394becef1dSAtsushi Nemoto 404becef1dSAtsushi Nemoto /* Unused entries have a virtual address of KSEG0. */ 414becef1dSAtsushi Nemoto if ((entryhi & 0xffffe000) != 0x80000000 424becef1dSAtsushi Nemoto && (entryhi & 0xfc0) == asid) { 434becef1dSAtsushi Nemoto /* 444becef1dSAtsushi Nemoto * Only print entries in use 454becef1dSAtsushi Nemoto */ 464becef1dSAtsushi Nemoto printk("Index: %2d ", i); 474becef1dSAtsushi Nemoto 484becef1dSAtsushi Nemoto printk("va=%08lx asid=%08lx" 494becef1dSAtsushi Nemoto " [pa=%06lx n=%d d=%d v=%d g=%d]", 504becef1dSAtsushi Nemoto (entryhi & 0xffffe000), 514becef1dSAtsushi Nemoto entryhi & 0xfc0, 524becef1dSAtsushi Nemoto entrylo0 & PAGE_MASK, 534becef1dSAtsushi Nemoto (entrylo0 & (1 << 11)) ? 1 : 0, 544becef1dSAtsushi Nemoto (entrylo0 & (1 << 10)) ? 1 : 0, 554becef1dSAtsushi Nemoto (entrylo0 & (1 << 9)) ? 1 : 0, 564becef1dSAtsushi Nemoto (entrylo0 & (1 << 8)) ? 1 : 0); 574becef1dSAtsushi Nemoto } 584becef1dSAtsushi Nemoto } 594becef1dSAtsushi Nemoto printk("\n"); 604becef1dSAtsushi Nemoto 614becef1dSAtsushi Nemoto write_c0_entryhi(asid); 624becef1dSAtsushi Nemoto } 634becef1dSAtsushi Nemoto 644becef1dSAtsushi Nemoto void dump_tlb_all(void) 654becef1dSAtsushi Nemoto { 664becef1dSAtsushi Nemoto dump_tlb(0, current_cpu_data.tlbsize - 1); 674becef1dSAtsushi Nemoto } 684becef1dSAtsushi Nemoto 694becef1dSAtsushi Nemoto void dump_tlb_wired(void) 704becef1dSAtsushi Nemoto { 714becef1dSAtsushi Nemoto int wired = r3k_have_wired_reg ? read_c0_wired() : 8; 724becef1dSAtsushi Nemoto 734becef1dSAtsushi Nemoto printk("Wired: %d", wired); 744becef1dSAtsushi Nemoto dump_tlb(0, wired - 1); 754becef1dSAtsushi Nemoto } 764becef1dSAtsushi Nemoto 774becef1dSAtsushi Nemoto void dump_tlb_addr(unsigned long addr) 784becef1dSAtsushi Nemoto { 794becef1dSAtsushi Nemoto unsigned long flags, oldpid; 804becef1dSAtsushi Nemoto int index; 814becef1dSAtsushi Nemoto 824becef1dSAtsushi Nemoto local_irq_save(flags); 834becef1dSAtsushi Nemoto oldpid = read_c0_entryhi() & 0xff; 844becef1dSAtsushi Nemoto write_c0_entryhi((addr & PAGE_MASK) | oldpid); 854becef1dSAtsushi Nemoto tlb_probe(); 864becef1dSAtsushi Nemoto index = read_c0_index(); 874becef1dSAtsushi Nemoto write_c0_entryhi(oldpid); 884becef1dSAtsushi Nemoto local_irq_restore(flags); 894becef1dSAtsushi Nemoto 904becef1dSAtsushi Nemoto if (index < 0) { 914becef1dSAtsushi Nemoto printk("No entry for address 0x%08lx in TLB\n", addr); 924becef1dSAtsushi Nemoto return; 934becef1dSAtsushi Nemoto } 944becef1dSAtsushi Nemoto 954becef1dSAtsushi Nemoto printk("Entry %d maps address 0x%08lx\n", index, addr); 964becef1dSAtsushi Nemoto dump_tlb(index, index); 974becef1dSAtsushi Nemoto } 984becef1dSAtsushi Nemoto 994becef1dSAtsushi Nemoto void dump_tlb_nonwired(void) 1004becef1dSAtsushi Nemoto { 1014becef1dSAtsushi Nemoto int wired = r3k_have_wired_reg ? read_c0_wired() : 8; 1024becef1dSAtsushi Nemoto dump_tlb(wired, current_cpu_data.tlbsize - 1); 1034becef1dSAtsushi Nemoto } 1044becef1dSAtsushi Nemoto 1054becef1dSAtsushi Nemoto void dump_list_process(struct task_struct *t, void *address) 1064becef1dSAtsushi Nemoto { 1074becef1dSAtsushi Nemoto pgd_t *page_dir, *pgd; 1084becef1dSAtsushi Nemoto pud_t *pud; 1094becef1dSAtsushi Nemoto pmd_t *pmd; 1104becef1dSAtsushi Nemoto pte_t *pte, page; 1114becef1dSAtsushi Nemoto unsigned int addr; 1124becef1dSAtsushi Nemoto unsigned long val; 1134becef1dSAtsushi Nemoto 1144becef1dSAtsushi Nemoto addr = (unsigned int) address; 1154becef1dSAtsushi Nemoto 1164becef1dSAtsushi Nemoto printk("Addr == %08x\n", addr); 1174becef1dSAtsushi Nemoto printk("tasks->mm.pgd == %08x\n", (unsigned int) t->mm->pgd); 1184becef1dSAtsushi Nemoto 1194becef1dSAtsushi Nemoto page_dir = pgd_offset(t->mm, 0); 1204becef1dSAtsushi Nemoto printk("page_dir == %08x\n", (unsigned int) page_dir); 1214becef1dSAtsushi Nemoto 1224becef1dSAtsushi Nemoto pgd = pgd_offset(t->mm, addr); 1234becef1dSAtsushi Nemoto printk("pgd == %08x, ", (unsigned int) pgd); 1244becef1dSAtsushi Nemoto 1254becef1dSAtsushi Nemoto pud = pud_offset(pgd, addr); 1264becef1dSAtsushi Nemoto printk("pud == %08x, ", (unsigned int) pud); 1274becef1dSAtsushi Nemoto 1284becef1dSAtsushi Nemoto pmd = pmd_offset(pud, addr); 1294becef1dSAtsushi Nemoto printk("pmd == %08x, ", (unsigned int) pmd); 1304becef1dSAtsushi Nemoto 1314becef1dSAtsushi Nemoto pte = pte_offset(pmd, addr); 1324becef1dSAtsushi Nemoto printk("pte == %08x, ", (unsigned int) pte); 1334becef1dSAtsushi Nemoto 1344becef1dSAtsushi Nemoto page = *pte; 1354becef1dSAtsushi Nemoto printk("page == %08x\n", (unsigned int) pte_val(page)); 1364becef1dSAtsushi Nemoto 1374becef1dSAtsushi Nemoto val = pte_val(page); 1384becef1dSAtsushi Nemoto if (val & _PAGE_PRESENT) printk("present "); 1394becef1dSAtsushi Nemoto if (val & _PAGE_READ) printk("read "); 1404becef1dSAtsushi Nemoto if (val & _PAGE_WRITE) printk("write "); 1414becef1dSAtsushi Nemoto if (val & _PAGE_ACCESSED) printk("accessed "); 1424becef1dSAtsushi Nemoto if (val & _PAGE_MODIFIED) printk("modified "); 1434becef1dSAtsushi Nemoto if (val & _PAGE_GLOBAL) printk("global "); 1444becef1dSAtsushi Nemoto if (val & _PAGE_VALID) printk("valid "); 1454becef1dSAtsushi Nemoto printk("\n"); 1464becef1dSAtsushi Nemoto } 1474becef1dSAtsushi Nemoto 1484becef1dSAtsushi Nemoto void dump_list_current(void *address) 1494becef1dSAtsushi Nemoto { 1504becef1dSAtsushi Nemoto dump_list_process(current, address); 1514becef1dSAtsushi Nemoto } 1524becef1dSAtsushi Nemoto 1534becef1dSAtsushi Nemoto unsigned int vtop(void *address) 1544becef1dSAtsushi Nemoto { 1554becef1dSAtsushi Nemoto pgd_t *pgd; 1564becef1dSAtsushi Nemoto pud_t *pud; 1574becef1dSAtsushi Nemoto pmd_t *pmd; 1584becef1dSAtsushi Nemoto pte_t *pte; 1594becef1dSAtsushi Nemoto unsigned int addr, paddr; 1604becef1dSAtsushi Nemoto 1614becef1dSAtsushi Nemoto addr = (unsigned long) address; 1624becef1dSAtsushi Nemoto pgd = pgd_offset(current->mm, addr); 1634becef1dSAtsushi Nemoto pud = pud_offset(pgd, addr); 1644becef1dSAtsushi Nemoto pmd = pmd_offset(pud, addr); 1654becef1dSAtsushi Nemoto pte = pte_offset(pmd, addr); 1664becef1dSAtsushi Nemoto paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK; 1674becef1dSAtsushi Nemoto paddr |= (addr & ~PAGE_MASK); 1684becef1dSAtsushi Nemoto 1694becef1dSAtsushi Nemoto return paddr; 1704becef1dSAtsushi Nemoto } 1714becef1dSAtsushi Nemoto 1724becef1dSAtsushi Nemoto void dump16(unsigned long *p) 1734becef1dSAtsushi Nemoto { 1744becef1dSAtsushi Nemoto int i; 1754becef1dSAtsushi Nemoto 1764becef1dSAtsushi Nemoto for (i = 0; i < 8; i++) { 1774becef1dSAtsushi Nemoto printk("*%08lx == %08lx, ", (unsigned long)p, *p); 1784becef1dSAtsushi Nemoto p++; 1794becef1dSAtsushi Nemoto printk("*%08lx == %08lx\n", (unsigned long)p, *p); 1804becef1dSAtsushi Nemoto p++; 1814becef1dSAtsushi Nemoto } 1824becef1dSAtsushi Nemoto } 183