dtlb_backend.S 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /* $Id: dtlb_backend.S,v 1.16 2001/10/09 04:02:11 davem Exp $
  2. * dtlb_backend.S: Back end to DTLB miss replacement strategy.
  3. * This is included directly into the trap table.
  4. *
  5. * Copyright (C) 1996,1998 David S. Miller (davem@redhat.com)
  6. * Copyright (C) 1997,1998 Jakub Jelinek (jj@ultra.linux.cz)
  7. */
  8. #include <asm/pgtable.h>
  9. #include <asm/mmu.h>
  10. #if PAGE_SHIFT == 13
  11. #define SZ_BITS _PAGE_SZ8K
  12. #elif PAGE_SHIFT == 16
  13. #define SZ_BITS _PAGE_SZ64K
  14. #elif PAGE_SHIFT == 19
  15. #define SZ_BITS _PAGE_SZ512K
  16. #elif PAGE_SHIFT == 22
  17. #define SZ_BITS _PAGE_SZ4MB
  18. #endif
  19. #define VALID_SZ_BITS (_PAGE_VALID | SZ_BITS)
  20. #define VPTE_BITS (_PAGE_CP | _PAGE_CV | _PAGE_P )
  21. #define VPTE_SHIFT (PAGE_SHIFT - 3)
  22. /* Ways we can get here:
  23. *
  24. * 1) Nucleus loads and stores to/from PA-->VA direct mappings at tl>1.
  25. * 2) Nucleus loads and stores to/from user/kernel window save areas.
  26. * 3) VPTE misses from dtlb_base and itlb_base.
  27. *
  28. * We need to extract out the PMD and PGDIR indexes from the
  29. * linear virtual page table access address. The PTE index
  30. * is at the bottom, but we are not concerned with it. Bits
  31. * 0 to 2 are clear since each PTE is 8 bytes in size. Each
  32. * PMD and PGDIR entry are 4 bytes in size. Thus, this
  33. * address looks something like:
  34. *
  35. * |---------------------------------------------------------------|
  36. * | ... | PGDIR index | PMD index | PTE index | |
  37. * |---------------------------------------------------------------|
  38. * 63 F E D C B A 3 2 0 <- bit nr
  39. *
  40. * The variable bits above are defined as:
  41. * A --> 3 + (PAGE_SHIFT - log2(8))
  42. * --> 3 + (PAGE_SHIFT - 3) - 1
  43. * (ie. this is "bit 3" + PAGE_SIZE - size of PTE entry in bits - 1)
  44. * B --> A + 1
  45. * C --> B + (PAGE_SHIFT - log2(4))
  46. * --> B + (PAGE_SHIFT - 2) - 1
  47. * (ie. this is "bit B" + PAGE_SIZE - size of PMD entry in bits - 1)
  48. * D --> C + 1
  49. * E --> D + (PAGE_SHIFT - log2(4))
  50. * --> D + (PAGE_SHIFT - 2) - 1
  51. * (ie. this is "bit D" + PAGE_SIZE - size of PGDIR entry in bits - 1)
  52. * F --> E + 1
  53. *
  54. * (Note how "B" always evalutes to PAGE_SHIFT, all the other constants
  55. * cancel out.)
  56. *
  57. * For 8K PAGE_SIZE (thus, PAGE_SHIFT of 13) the bit numbers are:
  58. * A --> 12
  59. * B --> 13
  60. * C --> 23
  61. * D --> 24
  62. * E --> 34
  63. * F --> 35
  64. *
  65. * For 64K PAGE_SIZE (thus, PAGE_SHIFT of 16) the bit numbers are:
  66. * A --> 15
  67. * B --> 16
  68. * C --> 29
  69. * D --> 30
  70. * E --> 43
  71. * F --> 44
  72. *
  73. * Because bits both above and below each PGDIR and PMD index need to
  74. * be masked out, and the index can be as long as 14 bits (when using a
  75. * 64K PAGE_SIZE, and thus a PAGE_SHIFT of 16), we need 3 instructions
  76. * to extract each index out.
  77. *
  78. * Shifts do not pair very well on UltraSPARC-I, II, IIi, and IIe, so
  79. * we try to avoid using them for the entire operation. We could setup
  80. * a mask anywhere from bit 31 down to bit 10 using the sethi instruction.
  81. *
  82. * We need a mask covering bits B --> C and one covering D --> E.
  83. * For 8K PAGE_SIZE these masks are 0x00ffe000 and 0x7ff000000.
  84. * For 64K PAGE_SIZE these masks are 0x3fff0000 and 0xfffc0000000.
  85. * The second in each set cannot be loaded with a single sethi
  86. * instruction, because the upper bits are past bit 32. We would
  87. * need to use a sethi + a shift.
  88. *
  89. * For the time being, we use 2 shifts and a simple "and" mask.
  90. * We shift left to clear the bits above the index, we shift down
  91. * to clear the bits below the index (sans the log2(4 or 8) bits)
  92. * and a mask to clear the log2(4 or 8) bits. We need therefore
  93. * define 4 shift counts, all of which are relative to PAGE_SHIFT.
  94. *
  95. * Although unsupportable for other reasons, this does mean that
  96. * 512K and 4MB page sizes would be generaally supported by the
  97. * kernel. (ELF binaries would break with > 64K PAGE_SIZE since
  98. * the sections are only aligned that strongly).
  99. *
  100. * The operations performed for extraction are thus:
  101. *
  102. * ((X << FOO_SHIFT_LEFT) >> FOO_SHIFT_RIGHT) & ~0x3
  103. *
  104. */
  105. #define A (3 + (PAGE_SHIFT - 3) - 1)
  106. #define B (A + 1)
  107. #define C (B + (PAGE_SHIFT - 2) - 1)
  108. #define D (C + 1)
  109. #define E (D + (PAGE_SHIFT - 2) - 1)
  110. #define F (E + 1)
  111. #define PMD_SHIFT_LEFT (64 - D)
  112. #define PMD_SHIFT_RIGHT (64 - (D - B) - 2)
  113. #define PGDIR_SHIFT_LEFT (64 - F)
  114. #define PGDIR_SHIFT_RIGHT (64 - (F - D) - 2)
  115. #define LOW_MASK_BITS 0x3
  116. /* TLB1 ** ICACHE line 1: tl1 DTLB and quick VPTE miss */
  117. ldxa [%g1 + %g1] ASI_DMMU, %g4 ! Get TAG_ACCESS
  118. add %g3, %g3, %g5 ! Compute VPTE base
  119. cmp %g4, %g5 ! VPTE miss?
  120. bgeu,pt %xcc, 1f ! Continue here
  121. andcc %g4, TAG_CONTEXT_BITS, %g5 ! tl0 miss Nucleus test
  122. ba,a,pt %xcc, from_tl1_trap ! Fall to tl0 miss
  123. 1: sllx %g6, VPTE_SHIFT, %g4 ! Position TAG_ACCESS
  124. or %g4, %g5, %g4 ! Prepare TAG_ACCESS
  125. /* TLB1 ** ICACHE line 2: Quick VPTE miss */
  126. mov TSB_REG, %g1 ! Grab TSB reg
  127. ldxa [%g1] ASI_DMMU, %g5 ! Doing PGD caching?
  128. sllx %g6, PMD_SHIFT_LEFT, %g1 ! Position PMD offset
  129. be,pn %xcc, sparc64_vpte_nucleus ! Is it from Nucleus?
  130. srlx %g1, PMD_SHIFT_RIGHT, %g1 ! Mask PMD offset bits
  131. brnz,pt %g5, sparc64_vpte_continue ! Yep, go like smoke
  132. andn %g1, LOW_MASK_BITS, %g1 ! Final PMD mask
  133. sllx %g6, PGDIR_SHIFT_LEFT, %g5 ! Position PGD offset
  134. /* TLB1 ** ICACHE line 3: Quick VPTE miss */
  135. srlx %g5, PGDIR_SHIFT_RIGHT, %g5 ! Mask PGD offset bits
  136. andn %g5, LOW_MASK_BITS, %g5 ! Final PGD mask
  137. lduwa [%g7 + %g5] ASI_PHYS_USE_EC, %g5! Load PGD
  138. brz,pn %g5, vpte_noent ! Valid?
  139. sparc64_kpte_continue:
  140. sllx %g5, 11, %g5 ! Shift into place
  141. sparc64_vpte_continue:
  142. lduwa [%g5 + %g1] ASI_PHYS_USE_EC, %g5! Load PMD
  143. sllx %g5, 11, %g5 ! Shift into place
  144. brz,pn %g5, vpte_noent ! Valid?
  145. /* TLB1 ** ICACHE line 4: Quick VPTE miss */
  146. mov (VALID_SZ_BITS >> 61), %g1 ! upper vpte into %g1
  147. sllx %g1, 61, %g1 ! finish calc
  148. or %g5, VPTE_BITS, %g5 ! Prepare VPTE data
  149. or %g5, %g1, %g5 ! ...
  150. mov TLB_SFSR, %g1 ! Restore %g1 value
  151. stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Load VPTE into TLB
  152. stxa %g4, [%g1 + %g1] ASI_DMMU ! Restore previous TAG_ACCESS
  153. retry ! Load PTE once again
  154. #undef SZ_BITS
  155. #undef VALID_SZ_BITS
  156. #undef VPTE_SHIFT
  157. #undef VPTE_BITS
  158. #undef A
  159. #undef B
  160. #undef C
  161. #undef D
  162. #undef E
  163. #undef F
  164. #undef PMD_SHIFT_LEFT
  165. #undef PMD_SHIFT_RIGHT
  166. #undef PGDIR_SHIFT_LEFT
  167. #undef PGDIR_SHIFT_RIGHT
  168. #undef LOW_MASK_BITS