tlb-flush.S 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /* tlb-flush.S: TLB flushing routines
  2. *
  3. * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
  4. * Written by David Howells (dhowells@redhat.com)
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the License, or (at your option) any later version.
  10. */
  11. #include <linux/sys.h>
  12. #include <linux/linkage.h>
  13. #include <asm/page.h>
  14. #include <asm/ptrace.h>
  15. #include <asm/spr-regs.h>
  16. .macro DEBUG ch
  17. # sethi.p %hi(0xfeff9c00),gr4
  18. # setlo %lo(0xfeff9c00),gr4
  19. # setlos #\ch,gr5
  20. # stbi gr5,@(gr4,#0)
  21. # membar
  22. .endm
  23. .section .rodata
  24. # sizes corresponding to TPXR.LMAX
  25. .balign 1
  26. __tlb_lmax_sizes:
  27. .byte 0, 64, 0, 0
  28. .byte 0, 0, 0, 0
  29. .byte 0, 0, 0, 0
  30. .byte 0, 0, 0, 0
  31. .section .text
  32. .balign 4
  33. ###############################################################################
  34. #
  35. # flush everything
  36. # - void __flush_tlb_all(void)
  37. #
  38. ###############################################################################
  39. .globl __flush_tlb_all
  40. .type __flush_tlb_all,@function
  41. __flush_tlb_all:
  42. DEBUG 'A'
  43. # kill cached PGE value
  44. setlos #0xffffffff,gr4
  45. movgs gr4,scr0
  46. movgs gr4,scr1
  47. # kill AMPR-cached TLB values
  48. movgs gr0,iamlr1
  49. movgs gr0,iampr1
  50. movgs gr0,damlr1
  51. movgs gr0,dampr1
  52. # find out how many lines there are
  53. movsg tpxr,gr5
  54. sethi.p %hi(__tlb_lmax_sizes),gr4
  55. srli gr5,#TPXR_LMAX_SHIFT,gr5
  56. setlo.p %lo(__tlb_lmax_sizes),gr4
  57. andi gr5,#TPXR_LMAX_SMASK,gr5
  58. ldub @(gr4,gr5),gr4
  59. # now, we assume that the TLB line step is page size in size
  60. setlos.p #PAGE_SIZE,gr5
  61. setlos #0,gr6
  62. 1:
  63. tlbpr gr6,gr0,#6,#0
  64. subicc.p gr4,#1,gr4,icc0
  65. add gr6,gr5,gr6
  66. bne icc0,#2,1b
  67. DEBUG 'B'
  68. bralr
  69. .size __flush_tlb_all, .-__flush_tlb_all
  70. ###############################################################################
  71. #
  72. # flush everything to do with one context
  73. # - void __flush_tlb_mm(unsigned long contextid [GR8])
  74. #
  75. ###############################################################################
  76. .globl __flush_tlb_mm
  77. .type __flush_tlb_mm,@function
  78. __flush_tlb_mm:
  79. DEBUG 'M'
  80. # kill cached PGE value
  81. setlos #0xffffffff,gr4
  82. movgs gr4,scr0
  83. movgs gr4,scr1
  84. # specify the context we want to flush
  85. movgs gr8,tplr
  86. # find out how many lines there are
  87. movsg tpxr,gr5
  88. sethi.p %hi(__tlb_lmax_sizes),gr4
  89. srli gr5,#TPXR_LMAX_SHIFT,gr5
  90. setlo.p %lo(__tlb_lmax_sizes),gr4
  91. andi gr5,#TPXR_LMAX_SMASK,gr5
  92. ldub @(gr4,gr5),gr4
  93. # now, we assume that the TLB line step is page size in size
  94. setlos.p #PAGE_SIZE,gr5
  95. setlos #0,gr6
  96. 0:
  97. tlbpr gr6,gr0,#5,#0
  98. subicc.p gr4,#1,gr4,icc0
  99. add gr6,gr5,gr6
  100. bne icc0,#2,0b
  101. DEBUG 'N'
  102. bralr
  103. .size __flush_tlb_mm, .-__flush_tlb_mm
  104. ###############################################################################
  105. #
  106. # flush a range of addresses from the TLB
  107. # - void __flush_tlb_page(unsigned long contextid [GR8],
  108. # unsigned long start [GR9])
  109. #
  110. ###############################################################################
  111. .globl __flush_tlb_page
  112. .type __flush_tlb_page,@function
  113. __flush_tlb_page:
  114. # kill cached PGE value
  115. setlos #0xffffffff,gr4
  116. movgs gr4,scr0
  117. movgs gr4,scr1
  118. # specify the context we want to flush
  119. movgs gr8,tplr
  120. # zap the matching TLB line and AMR values
  121. setlos #~(PAGE_SIZE-1),gr5
  122. and gr9,gr5,gr9
  123. tlbpr gr9,gr0,#5,#0
  124. bralr
  125. .size __flush_tlb_page, .-__flush_tlb_page
  126. ###############################################################################
  127. #
  128. # flush a range of addresses from the TLB
  129. # - void __flush_tlb_range(unsigned long contextid [GR8],
  130. # unsigned long start [GR9],
  131. # unsigned long end [GR10])
  132. #
  133. ###############################################################################
  134. .globl __flush_tlb_range
  135. .type __flush_tlb_range,@function
  136. __flush_tlb_range:
  137. # kill cached PGE value
  138. setlos #0xffffffff,gr4
  139. movgs gr4,scr0
  140. movgs gr4,scr1
  141. # specify the context we want to flush
  142. movgs gr8,tplr
  143. # round the start down to beginning of TLB line and end up to beginning of next TLB line
  144. setlos.p #~(PAGE_SIZE-1),gr5
  145. setlos #PAGE_SIZE,gr6
  146. subi.p gr10,#1,gr10
  147. and gr9,gr5,gr9
  148. and gr10,gr5,gr10
  149. 2:
  150. tlbpr gr9,gr0,#5,#0
  151. subcc.p gr9,gr10,gr0,icc0
  152. add gr9,gr6,gr9
  153. bne icc0,#0,2b ; most likely a 1-page flush
  154. bralr
  155. .size __flush_tlb_range, .-__flush_tlb_range