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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * This file is subject to the terms and conditions of the GNU General Public
  3.  * License.  See the file "COPYING" in the main directory of this archive
  4.  * for more details.
  5.  *
  6.  * Copyright (C) 2000 Silicon Graphics, Inc.
  7.  * Written by Ulf Carlsson (ulfc@engr.sgi.com)
  8.  * Copyright (C) 2002  Maciej W. Rozycki
  9.  */
  10. #include <linux/config.h>
  11. #include <linux/init.h>
  12. #include <linux/threads.h>
  13. #include <asm/asm.h>
  14. #include <asm/regdef.h>
  15. #include <asm/mipsregs.h>
  16. #include <asm/pgtable.h>
  17. #include <asm/stackframe.h>
  18. .data
  19. .comm pgd_current, NR_CPUS * 8, 8
  20. /*
  21.  * After this macro runs we have a pointer to the pte of the address
  22.  * that caused the fault in PTR.
  23.  */
  24. .macro LOAD_PTE2, ptr, tmp, kaddr
  25. #ifdef CONFIG_SMP
  26. dmfc0 ptr, CP0_CONTEXT
  27. dmfc0 tmp, CP0_BADVADDR
  28. dsra ptr, 23 # get pgd_current[cpu]
  29. #else
  30. dmfc0 tmp, CP0_BADVADDR
  31. dla ptr, pgd_current
  32. #endif
  33. bltz tmp, kaddr
  34.  ld ptr, (ptr)
  35. dsrl tmp, (PGDIR_SHIFT-3) # get pgd offset in bytes
  36. andi tmp, ((PTRS_PER_PGD - 1)<<3)
  37. daddu ptr, tmp # add in pgd offset
  38. dmfc0 tmp, CP0_BADVADDR
  39. ld ptr, (ptr) # get pmd pointer
  40. dsrl tmp, (PMD_SHIFT-3) # get pmd offset in bytes
  41. andi tmp, ((PTRS_PER_PMD - 1)<<3)
  42. daddu ptr, tmp # add in pmd offset
  43. dmfc0 tmp, CP0_XCONTEXT
  44. ld ptr, (ptr) # get pte pointer
  45. andi tmp, 0xff0 # get pte offset
  46. daddu ptr, tmp
  47. .endm
  48. /*
  49.  * Ditto for the kernel table.
  50.  */
  51. .macro LOAD_KPTE2, ptr, tmp, not_vmalloc
  52. /*
  53.  * First, determine that the address is in/above vmalloc range.
  54.  */
  55. dmfc0 tmp, CP0_BADVADDR
  56. dli ptr, VMALLOC_START
  57. /*
  58.  * Now find offset into kptbl.
  59.  */
  60. dsubu tmp, tmp, ptr
  61. dla ptr, kptbl
  62. dsrl tmp, (PAGE_SHIFT+1) # get vpn2
  63. dsll tmp, 4 # byte offset of pte
  64. daddu ptr, ptr, tmp
  65. /*
  66.  * Determine that fault address is within vmalloc range.
  67.  */
  68. dla tmp, ekptbl
  69. sltu tmp, ptr, tmp
  70. beqz tmp, not_vmalloc # not vmalloc
  71. .endm
  72. /*
  73.  * This places the even/odd pte pair in the page table at the pte
  74.  * entry pointed to by PTE into ENTRYLO0 and ENTRYLO1.
  75.  */
  76. .macro PTE_RELOAD, pte0, pte1
  77. dsrl pte0, 6 # convert to entrylo0
  78. dmtc0 pte0, CP0_ENTRYLO0 # load it
  79. dsrl pte1, 6 # convert to entrylo1
  80. dmtc0 pte1, CP0_ENTRYLO1 # load it
  81. .endm
  82. .text
  83. .set noreorder
  84. .set mips3
  85. __INIT
  86. .align 5
  87. LEAF(except_vec0)
  88. .set noat
  89. PANIC("Unused vector called")
  90. 1: b 1b
  91.  nop
  92. END(except_vec0)
  93. /*
  94.  * TLB refill handler for the R4000.
  95.  * Attention:  We may only use 32 instructions / 128 bytes.
  96.  */
  97. .align  5
  98. LEAF(except_vec1_r4k)
  99. .set    noat
  100. dla     k0, handle_vec1_r4k
  101. jr      k0
  102.  nop
  103. END(except_vec1_r4k)
  104. __FINIT
  105. .align  5
  106. LEAF(handle_vec1_r4k)
  107. .set    noat
  108. LOAD_PTE2 k1 k0 9f
  109. ld k0, 0(k1) # get even pte
  110. ld k1, 8(k1) # get odd pte
  111. PTE_RELOAD k0 k1
  112. b 1f
  113.  tlbwr
  114. 1: nop
  115. eret
  116. 9: # handle the vmalloc range
  117. LOAD_KPTE2 k1 k0 invalid_vmalloc_address
  118. ld k0, 0(k1) # get even pte
  119. ld k1, 8(k1) # get odd pte
  120. PTE_RELOAD k0 k1
  121. b 1f
  122.  tlbwr
  123. 1: nop
  124. eret
  125. END(handle_vec1_r4k)
  126. __INIT
  127. /*
  128.  * TLB refill handler for the R10000.
  129.  * Attention:  We may only use 32 instructions / 128 bytes.
  130.  */
  131. .align 5
  132. LEAF(except_vec1_r10k)
  133. .set    noat
  134. dla     k0, handle_vec1_r10k
  135. jr      k0
  136.  nop
  137. END(except_vec1_r10k)
  138. __FINIT
  139. .align 5
  140. LEAF(handle_vec1_r10k)
  141. .set noat
  142. LOAD_PTE2 k1 k0 9f
  143. ld k0, 0(k1) # get even pte
  144. ld k1, 8(k1) # get odd pte
  145. PTE_RELOAD k0 k1
  146. nop
  147. tlbwr
  148. eret
  149. 9: # handle the vmalloc range
  150. LOAD_KPTE2 k1 k0 invalid_vmalloc_address
  151. ld k0, 0(k1) # get even pte
  152. ld k1, 8(k1) # get odd pte
  153. PTE_RELOAD k0 k1
  154. nop
  155. tlbwr
  156. eret
  157. END(handle_vec1_r10k)
  158. .align 5
  159. LEAF(invalid_vmalloc_address)
  160. .set noat
  161. PANIC("Invalid kernel address")
  162. 1: b 1b
  163.  nop
  164. END(invalid_vmalloc_address)