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