r3k_dump_tlb.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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