linux-bk/arch/mips/lib/dump_tlb.c
<<
>>
Prefs
   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/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                /* Unused entries have a virtual address of KSEG0.  */
  46                if ((entryhi & 0xffffe000) != 0x80000000
  47                    && (entryhi & 0xff) == asid) {
  48                        /*
  49                         * Only print entries in use
  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
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.