linux/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
  10#include <asm/mipsregs.h>
  11#include <asm/page.h>
  12#include <asm/pgtable.h>
  13#include <asm/tlbdebug.h>
  14
  15static inline const char *msk2str(unsigned int mask)
  16{
  17        switch (mask) {
  18        case PM_4K:     return "4kb";
  19        case PM_16K:    return "16kb";
  20        case PM_64K:    return "64kb";
  21        case PM_256K:   return "256kb";
  22#ifdef CONFIG_CPU_CAVIUM_OCTEON
  23        case PM_8K:     return "8kb";
  24        case PM_32K:    return "32kb";
  25        case PM_128K:   return "128kb";
  26        case PM_512K:   return "512kb";
  27        case PM_2M:     return "2Mb";
  28        case PM_8M:     return "8Mb";
  29        case PM_32M:    return "32Mb";
  30#endif
  31#ifndef CONFIG_CPU_VR41XX
  32        case PM_1M:     return "1Mb";
  33        case PM_4M:     return "4Mb";
  34        case PM_16M:    return "16Mb";
  35        case PM_64M:    return "64Mb";
  36        case PM_256M:   return "256Mb";
  37        case PM_1G:     return "1Gb";
  38#endif
  39        }
  40        return "";
  41}
  42
  43#define BARRIER()                                       \
  44        __asm__ __volatile__(                           \
  45                ".set\tnoreorder\n\t"                   \
  46                "nop;nop;nop;nop;nop;nop;nop\n\t"       \
  47                ".set\treorder");
  48
  49static void dump_tlb(int first, int last)
  50{
  51        unsigned long s_entryhi, entryhi, asid;
  52        unsigned long long entrylo0, entrylo1;
  53        unsigned int s_index, pagemask, c0, c1, i;
  54
  55        s_entryhi = read_c0_entryhi();
  56        s_index = read_c0_index();
  57        asid = s_entryhi & 0xff;
  58
  59        for (i = first; i <= last; i++) {
  60                write_c0_index(i);
  61                BARRIER();
  62                tlb_read();
  63                BARRIER();
  64                pagemask = read_c0_pagemask();
  65                entryhi  = read_c0_entryhi();
  66                entrylo0 = read_c0_entrylo0();
  67                entrylo1 = read_c0_entrylo1();
  68
  69                /* Unused entries have a virtual address of CKSEG0.  */
  70                if ((entryhi & ~0x1ffffUL) != CKSEG0
  71                    && (entryhi & 0xff) == asid) {
  72#ifdef CONFIG_32BIT
  73                        int width = 8;
  74#else
  75                        int width = 11;
  76#endif
  77                        /*
  78                         * Only print entries in use
  79                         */
  80                        printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
  81
  82                        c0 = (entrylo0 >> 3) & 7;
  83                        c1 = (entrylo1 >> 3) & 7;
  84
  85                        printk("va=%0*lx asid=%02lx\n",
  86                               width, (entryhi & ~0x1fffUL),
  87                               entryhi & 0xff);
  88                        printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ",
  89                               width,
  90                               (entrylo0 << 6) & PAGE_MASK, c0,
  91                               (entrylo0 & 4) ? 1 : 0,
  92                               (entrylo0 & 2) ? 1 : 0,
  93                               (entrylo0 & 1) ? 1 : 0);
  94                        printk("[pa=%0*llx c=%d d=%d v=%d g=%d]\n",
  95                               width,
  96                               (entrylo1 << 6) & PAGE_MASK, c1,
  97                               (entrylo1 & 4) ? 1 : 0,
  98                               (entrylo1 & 2) ? 1 : 0,
  99                               (entrylo1 & 1) ? 1 : 0);
 100                }
 101        }
 102        printk("\n");
 103
 104        write_c0_entryhi(s_entryhi);
 105        write_c0_index(s_index);
 106}
 107
 108void dump_tlb_all(void)
 109{
 110        dump_tlb(0, current_cpu_data.tlbsize - 1);
 111}
 112