dump_tlb.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  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. #include <asm/bootinfo.h>
  12. #include <asm/cachectl.h>
  13. #include <asm/mipsregs.h>
  14. #include <asm/page.h>
  15. #include <asm/pgtable.h>
  16. #define mips_tlb_entries 64
  17. void
  18. dump_tlb(int first, int last)
  19. {
  20. unsigned long s_entryhi, entryhi, entrylo0, entrylo1, asid;
  21. unsigned int s_index, pagemask, c0, c1, i;
  22. s_entryhi = get_entryhi();
  23. s_index = get_index();
  24. asid = s_entryhi & 0xff;
  25. for (i = first; i <= last; i++) {
  26. write_32bit_cp0_register(CP0_INDEX, i);
  27. __asm__ __volatile__(
  28. ".settnoreordernt"
  29. "nop;nop;nop;nopnt"
  30. "tlbrnt"
  31. "nop;nop;nop;nopnt"
  32. ".settreorder");
  33. pagemask = read_32bit_cp0_register(CP0_PAGEMASK);
  34. entryhi  = get_entryhi();
  35. entrylo0 = get_entrylo0();
  36. entrylo1 = get_entrylo1();
  37. /* Unused entries have a virtual address of CKSEG0.  */
  38. if ((entryhi & ~0x1ffffUL) != CKSEG0
  39.     && (entryhi & 0xff) == asid) {
  40. /*
  41.  * Only print entries in use
  42.  */
  43. printk("Index: %2d pgmask=%08x ", i, pagemask);
  44. c0 = (entrylo0 >> 3) & 7;
  45. c1 = (entrylo1 >> 3) & 7;
  46. printk("va=%08lx asid=%02lx"
  47.        "  [pa=%06lx c=%d d=%d v=%d g=%ld]"
  48.        "  [pa=%06lx c=%d d=%d v=%d g=%ld]n",
  49.        (entryhi & ~0x1fffUL),
  50.        entryhi & 0xff,
  51.        entrylo0 & PAGE_MASK, c0,
  52.        (entrylo0 & 4) ? 1 : 0,
  53.        (entrylo0 & 2) ? 1 : 0,
  54.        (entrylo0 & 1),
  55.        entrylo1 & PAGE_MASK, c1,
  56.        (entrylo1 & 4) ? 1 : 0,
  57.        (entrylo1 & 2) ? 1 : 0,
  58.        (entrylo1 & 1));
  59.        
  60. }
  61. }
  62. printk("n");
  63. set_entryhi(s_entryhi);
  64. set_index(s_index);
  65. }
  66. void
  67. dump_tlb_all(void)
  68. {
  69. dump_tlb(0, mips_tlb_entries - 1);
  70. }
  71. void
  72. dump_tlb_wired(void)
  73. {
  74. int wired;
  75. wired = read_32bit_cp0_register(CP0_WIRED);
  76. printk("Wired: %d", wired);
  77. dump_tlb(0, read_32bit_cp0_register(CP0_WIRED));
  78. }
  79. #define BARRIER
  80. __asm__ __volatile__(
  81. ".settnoreordernt"
  82. "nop;nop;nop;nop;nop;nop;nopnt"
  83. ".settreorder");
  84. void
  85. dump_tlb_addr(unsigned long addr)
  86. {
  87. unsigned int flags, oldpid;
  88. int index;
  89. __save_and_cli(flags);
  90. oldpid = get_entryhi() & 0xff;
  91. BARRIER;
  92. set_entryhi((addr & PAGE_MASK) | oldpid);
  93. BARRIER;
  94. tlb_probe();
  95. BARRIER;
  96. index = get_index();
  97. set_entryhi(oldpid);
  98. __restore_flags(flags);
  99. if (index < 0) {
  100. printk("No entry for address 0x%08lx in TLBn", addr);
  101. return;
  102. }
  103. printk("Entry %d maps address 0x%08lxn", index, addr);
  104. dump_tlb(index, index);
  105. }
  106. void
  107. dump_tlb_nonwired(void)
  108. {
  109. dump_tlb(read_32bit_cp0_register(CP0_WIRED), mips_tlb_entries - 1);
  110. }
  111. void
  112. dump_list_process(struct task_struct *t, void *address)
  113. {
  114. pgd_t *page_dir, *pgd;
  115. pmd_t *pmd;
  116. pte_t *pte, page;
  117. unsigned long addr;
  118. unsigned long val;
  119. addr = (unsigned long) address;
  120. printk("Addr                 == %08lxn", addr);
  121. printk("tasks->mm.pgd        == %08lxn", (unsigned long) t->mm->pgd);
  122. page_dir = pgd_offset(t->mm, 0);
  123. printk("page_dir == %08lxn", (unsigned long) page_dir);
  124. pgd = pgd_offset(t->mm, addr);
  125. printk("pgd == %08lx, ", (unsigned long) pgd);
  126. pmd = pmd_offset(pgd, addr);
  127. printk("pmd == %08lx, ", (unsigned long) pmd);
  128. pte = pte_offset(pmd, addr);
  129. printk("pte == %08lx, ", (unsigned long) pte);
  130. page = *pte;
  131. printk("page == %08lxn", (unsigned long) pte_val(page));
  132. val = pte_val(page);
  133. if (val & _PAGE_PRESENT) printk("present ");
  134. if (val & _PAGE_READ) printk("read ");
  135. if (val & _PAGE_WRITE) printk("write ");
  136. if (val & _PAGE_ACCESSED) printk("accessed ");
  137. if (val & _PAGE_MODIFIED) printk("modified ");
  138. if (val & _PAGE_R4KBUG) printk("r4kbug ");
  139. if (val & _PAGE_GLOBAL) printk("global ");
  140. if (val & _PAGE_VALID) printk("valid ");
  141. printk("n");
  142. }
  143. void dump_list_current(void *address)
  144. {
  145. dump_list_process(current, address);
  146. }
  147. unsigned int vtop(void *address)
  148. {
  149. pgd_t *pgd;
  150. pmd_t *pmd;
  151. pte_t *pte;
  152. unsigned int addr, paddr;
  153. addr = (unsigned long) address;
  154. pgd = pgd_offset(current->mm, addr);
  155. pmd = pmd_offset(pgd, addr);
  156. pte = pte_offset(pmd, addr);
  157. paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
  158. paddr |= (addr & ~PAGE_MASK);
  159. return paddr;
  160. }
  161. void dump16(unsigned long *p)
  162. {
  163. int i;
  164. for(i=0;i<8;i++)
  165. {
  166. printk("*%08lx == %08lx, ",
  167.        (unsigned long)p, (unsigned long)*p);
  168. p++;
  169. printk("*%08lx == %08lxn",
  170.        (unsigned long)p, (unsigned long)*p);
  171. p++;
  172. }
  173. }