lock.S 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. * File: arch/blackfin/mach-common/lock.S
  3. * Based on:
  4. * Author: LG Soft India
  5. *
  6. * Created: ?
  7. * Description: kernel locks
  8. *
  9. * Modified:
  10. * Copyright 2004-2006 Analog Devices Inc.
  11. *
  12. * Bugs: Enter bugs at http://blackfin.uclinux.org/
  13. *
  14. * This program is free software; you can redistribute it and/or modify
  15. * it under the terms of the GNU General Public License as published by
  16. * the Free Software Foundation; either version 2 of the License, or
  17. * (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, see the file COPYING, or write
  26. * to the Free Software Foundation, Inc.,
  27. * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  28. */
  29. #include <linux/linkage.h>
  30. #include <asm/cplb.h>
  31. #include <asm/blackfin.h>
  32. .text
  33. #ifdef CONFIG_BFIN_ICACHE_LOCK
  34. /* When you come here, it is assumed that
  35. * R0 - Which way to be locked
  36. */
  37. ENTRY(_cache_grab_lock)
  38. [--SP]=( R7:0,P5:0 );
  39. P1.H = HI(IMEM_CONTROL);
  40. P1.L = LO(IMEM_CONTROL);
  41. P5.H = HI(ICPLB_ADDR0);
  42. P5.L = LO(ICPLB_ADDR0);
  43. P4.H = HI(ICPLB_DATA0);
  44. P4.L = LO(ICPLB_DATA0);
  45. R7 = R0;
  46. /* If the code of interest already resides in the cache
  47. * invalidate the entire cache itself.
  48. * invalidate_entire_icache;
  49. */
  50. SP += -12;
  51. [--SP] = RETS;
  52. CALL _invalidate_entire_icache;
  53. RETS = [SP++];
  54. SP += 12;
  55. /* Disable the Interrupts*/
  56. CLI R3;
  57. .LLOCK_WAY:
  58. /* Way0 - 0xFFA133E0
  59. * Way1 - 0xFFA137E0
  60. * Way2 - 0xFFA13BE0 Total Way Size = 4K
  61. * Way3 - 0xFFA13FE0
  62. */
  63. /* Procedure Ex. -Set the locks for other ways by setting ILOC[3:1]
  64. * Only Way0 of the instruction cache can now be
  65. * replaced by a new code
  66. */
  67. R5 = R7;
  68. CC = BITTST(R7,0);
  69. IF CC JUMP .LCLEAR1;
  70. R7 = 0;
  71. BITSET(R7,0);
  72. JUMP .LDONE1;
  73. .LCLEAR1:
  74. R7 = 0;
  75. BITCLR(R7,0);
  76. .LDONE1: R4 = R7 << 3;
  77. R7 = [P1];
  78. R7 = R7 | R4;
  79. SSYNC; /* SSYNC required writing to IMEM_CONTROL. */
  80. .align 8;
  81. [P1] = R7;
  82. SSYNC;
  83. R7 = R5;
  84. CC = BITTST(R7,1);
  85. IF CC JUMP .LCLEAR2;
  86. R7 = 0;
  87. BITSET(R7,1);
  88. JUMP .LDONE2;
  89. .LCLEAR2:
  90. R7 = 0;
  91. BITCLR(R7,1);
  92. .LDONE2: R4 = R7 << 3;
  93. R7 = [P1];
  94. R7 = R7 | R4;
  95. SSYNC; /* SSYNC required writing to IMEM_CONTROL. */
  96. .align 8;
  97. [P1] = R7;
  98. SSYNC;
  99. R7 = R5;
  100. CC = BITTST(R7,2);
  101. IF CC JUMP .LCLEAR3;
  102. R7 = 0;
  103. BITSET(R7,2);
  104. JUMP .LDONE3;
  105. .LCLEAR3:
  106. R7 = 0;
  107. BITCLR(R7,2);
  108. .LDONE3: R4 = R7 << 3;
  109. R7 = [P1];
  110. R7 = R7 | R4;
  111. SSYNC; /* SSYNC required writing to IMEM_CONTROL. */
  112. .align 8;
  113. [P1] = R7;
  114. SSYNC;
  115. R7 = R5;
  116. CC = BITTST(R7,3);
  117. IF CC JUMP .LCLEAR4;
  118. R7 = 0;
  119. BITSET(R7,3);
  120. JUMP .LDONE4;
  121. .LCLEAR4:
  122. R7 = 0;
  123. BITCLR(R7,3);
  124. .LDONE4: R4 = R7 << 3;
  125. R7 = [P1];
  126. R7 = R7 | R4;
  127. SSYNC; /* SSYNC required writing to IMEM_CONTROL. */
  128. .align 8;
  129. [P1] = R7;
  130. SSYNC;
  131. STI R3;
  132. ( R7:0,P5:0 ) = [SP++];
  133. RTS;
  134. ENDPROC(_cache_grab_lock)
  135. /* After the execution of critical code, the code is now locked into
  136. * the cache way. Now we need to set ILOC.
  137. *
  138. * R0 - Which way to be locked
  139. */
  140. ENTRY(_cache_lock)
  141. [--SP]=( R7:0,P5:0 );
  142. P1.H = HI(IMEM_CONTROL);
  143. P1.L = LO(IMEM_CONTROL);
  144. /* Disable the Interrupts*/
  145. CLI R3;
  146. R7 = [P1];
  147. R2 = 0xFFFFFF87 (X);
  148. R7 = R7 & R2;
  149. R0 = R0 << 3;
  150. R7 = R0 | R7;
  151. SSYNC; /* SSYNC required writing to IMEM_CONTROL. */
  152. .align 8;
  153. [P1] = R7;
  154. SSYNC;
  155. /* Renable the Interrupts */
  156. STI R3;
  157. ( R7:0,P5:0 ) = [SP++];
  158. RTS;
  159. ENDPROC(_cache_lock)
  160. #endif /* BFIN_ICACHE_LOCK */
  161. /* Return the ILOC bits of IMEM_CONTROL
  162. */
  163. ENTRY(_read_iloc)
  164. P1.H = HI(IMEM_CONTROL);
  165. P1.L = LO(IMEM_CONTROL);
  166. R1 = 0xF;
  167. R0 = [P1];
  168. R0 = R0 >> 3;
  169. R0 = R0 & R1;
  170. RTS;
  171. ENDPROC(_read_iloc)