cacheALib.s
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:8k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* cacheALib.s - i80x86 cache management assembly routines */
  2. /* Copyright 1984-2002 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01j,07mar02,hdn  added bytes checking before the CLFLUSH loop (spr 73360)
  7. 01i,04dec01,hdn  cleaned up cachePen4Flush and cachePen4Clear
  8. 01h,23aug01,hdn  added FUNC/FUNC_LABEL, replaced .align with .balign
  9.  added support for Pentium4.
  10. 01g,27oct94,hdn  changed NW bit not to set.
  11. 01f,27sep94,hdn  changed cacheClear to use wbinvd.
  12. 01e,29may94,hdn  changed a macro I80486 to sysProcessor.
  13. 01d,05nov93,hdn  added cacheFlush.
  14. 01c,27jul93,hdn  changed cacheClear that uses wbinvd now.
  15. 01b,08jun93,hdn  updated to 5.1.
  16. 01a,16mar93,hdn  written based on TRON version.
  17. */
  18. /*
  19. DESCRIPTION
  20. This module contains routines to modify the i80x86 cache control registers.
  21. SEE ALSO: "i80x86 Microprocessor User's Manual"
  22. */
  23. #define _ASMLANGUAGE
  24. #include "vxWorks.h"
  25. #include "asm.h"
  26. #include "regs.h"
  27. #include "cacheLib.h"
  28. .data
  29. .globl  FUNC(copyright_wind_river)
  30. .long   FUNC(copyright_wind_river)
  31. /* internals */
  32. .globl GTEXT(cacheI86Reset)
  33. .globl GTEXT(cacheI86Enable)
  34. .globl GTEXT(cacheI86Disable)
  35. .globl GTEXT(cacheI86Lock)
  36. .globl GTEXT(cacheI86Unlock)
  37. .globl GTEXT(cacheI86Clear)
  38. .globl GTEXT(cacheI86Flush)
  39. .globl GTEXT(cachePen4Clear)
  40. .globl GTEXT(cachePen4Flush)
  41. .text
  42. .balign 16
  43. /*******************************************************************************
  44. *
  45. * cacheI86Reset - reset a cache by clearing it and disabling
  46. *
  47. * This routine resets the all caches.
  48. *
  49. * RETURNS: OK
  50. * STATUS cacheI86Reset ()
  51. */
  52. .balign 16,0x90
  53. FUNC_LABEL(cacheI86Reset)
  54. movl %cr0,%eax
  55. orl $ CR0_CD,%eax
  56. andl $ CR0_NW_NOT,%eax
  57. movl %eax,%cr0
  58. wbinvd /* writeback and invalidate */
  59. ret
  60. /*******************************************************************************
  61. *
  62. * cacheI86Enable - enable a cache
  63. *
  64. * This routine enables the specified cache.
  65. *
  66. * RETURNS: OK, or ERROR if cache, or control not supported.
  67. * STATUS cacheI86Enable (cache)
  68. *     int cache; /* cache to enable *
  69. */
  70. .balign 16,0x90
  71. FUNC_LABEL(cacheI86Enable)
  72. FUNC_LABEL(cacheI86Unlock)
  73. movl %cr0,%eax
  74. andl $ CR0_CD_NOT,%eax
  75. andl $ CR0_NW_NOT,%eax
  76. movl %eax,%cr0
  77. ret
  78. /*******************************************************************************
  79. *
  80. * cacheI86Disable - disable a cache
  81. *
  82. * This routine disables the specified cache.
  83. *
  84. * RETURNS: OK, or ERROR if cache, or control not supported.
  85. * STATUS cacheI86Disable (cache)
  86. *     int cache; /* cache to disable *
  87. */
  88. .balign 16,0x90
  89. FUNC_LABEL(cacheI86Disable)
  90. movl %cr0,%eax
  91. orl $ CR0_CD,%eax
  92. andl $ CR0_NW_NOT,%eax
  93. movl %eax,%cr0
  94. wbinvd /* writeback and invalidate */
  95. ret
  96. /*******************************************************************************
  97. *
  98. * cacheI86Lock - lock all entries in a cache
  99. *
  100. * This routine locks all entries in the specified cache.
  101. *
  102. * RETURNS: OK
  103. * STATUS cacheI86Lock ()
  104. */
  105. .balign 16,0x90
  106. FUNC_LABEL(cacheI86Lock)
  107. movl %cr0,%eax
  108. andl $ CR0_NW_NOT,%eax
  109. orl $ CR0_CD,%eax
  110. movl %eax,%cr0
  111. ret
  112. /*******************************************************************************
  113. *
  114. * cacheI86Clear - clear all entries in a cache
  115. *
  116. * This routine clear all entries in the specified cache.
  117. *
  118. * RETURNS: OK, or ERROR if cache, or control not supported.
  119. * STATUS cacheI86Clear (cache)
  120. *     int cache; /* cache to clear *
  121. */
  122. .balign 16,0x90
  123. FUNC_LABEL(cacheI86Clear)
  124. wbinvd /* writeback and invalidate */
  125. ret
  126. /*******************************************************************************
  127. *
  128. * cacheI86Flush - flush all entries in a cache
  129. *
  130. * This routine flush all entries in the specified cache.
  131. *
  132. * RETURNS: OK, or ERROR if cache, or control not supported.
  133. * STATUS cacheI86Flush (cache)
  134. *     int cache; /* cache to clear *
  135. */
  136. .balign 16,0x90
  137. FUNC_LABEL(cacheI86Flush)
  138. wbinvd /* writeback and invalidate */
  139. ret
  140. /*******************************************************************************
  141. *
  142. * cachePen4Clear - clear specified entries in the cache for Pentium4
  143. *
  144. * This routine clear specified entries in the cache for Pentium4.
  145. *
  146. * RETURNS: OK, or ERROR if cache, or control not supported.
  147. * STATUS cachePen4Clear (CACHE_TYPE cache, void * addr, size_t bytes)
  148. *     CACHE_TYPE cache; /* cache to clear *
  149. *     void * addr; /* address to clear *
  150. *     size_t bytes; /* bytes to clear *
  151. */
  152. /* see below */
  153. /*******************************************************************************
  154. *
  155. * cachePen4Flush - flush specified entries in the cache for Pentium4
  156. *
  157. * This routine flush specified entries in the cache for Pentium4.
  158. * This routine uses following method assuming that cacheFlushBytes
  159. * is power of 2 (2**n).
  160. *
  161. *   bytes += (address % cacheFlushBytes);
  162. *   if ((rem = bytes % cacheFlushBytes) != 0)
  163. *     bytes += (cacheFlushBytes - rem);
  164. *   loopCount = bytes / cacheFlushBytes;
  165. *   address -= (address % cacheFlushBytes);
  166. *   do {
  167. *     CLFLUSH (address);
  168. *     address += cacheFlushBytes;
  169. *   } while (loopCount--);
  170. *
  171. * INTERNAL
  172. * CLFLUSH instruction invalidates the cache line that contains
  173. * the linear address specified with the source operand from all
  174. * levels of the processor cache hierarchy (data and instruction).
  175. * The validation is broadcast throughout the cache coherence 
  176. * domain.  If, at any level of the cache hierarchy, the line is
  177. * inconsistent with memory (dirty) it is written to memory before
  178. * invalidation.  The source operand is a byte memory location.
  179. *
  180. * RETURNS: OK, or ERROR if cache, or control not supported.
  181. * STATUS cachePen4Flush (CACHE_TYPE cache, void * addr, size_t bytes)
  182. *     CACHE_TYPE cache; /* cache to clear *
  183. *     void * addr; /* address to flush *
  184. *     size_t bytes; /* bytes to flush *
  185. */
  186. .balign 16,0x90
  187. FUNC_LABEL(cachePen4Clear)
  188. FUNC_LABEL(cachePen4Flush)
  189. movl SP_ARG2(%esp), %eax /* get address in EAX */
  190. movl SP_ARG3(%esp), %edx /* get bytes in EDX */
  191. cmpl $0, %edx /* return if (bytes == 0) */
  192. jz cachePen4Ret
  193. movl %edx, %ecx
  194. andl $ ~CLFLUSH_MAX_BYTES, %ecx /* WBINVD if (bytes > MAX) */
  195. jnz FUNC(cacheI86Flush)
  196. pushl %ebx /* save EBX */
  197. pushl %esi /* save ESI */
  198. pushl %edi /* save EDI */
  199. movl %eax, %esi /* get address in ESI */
  200. movl %edx, %edi /* get bytes in EDI */
  201. movl FUNC(cacheFlushBytes), %ebx /* get flushBytes in EBX */
  202. /* bytes += (address % cacheFlushBytes); */
  203. movl %ebx, %edx /* get flushBytes in EDX */
  204. subl $1, %edx /* create lowerbit mask */
  205. andl %edx, %eax /* get the lowerbit rem */
  206. addl %eax, %edi /* add the rem to bytes */
  207. /* if ((rem = bytes % cacheFlushBytes) != 0) */
  208. /*   bytes += (cacheFlushBytes - rem); */
  209. movl %edi, %ecx /* get bytes in ECX */
  210. andl %edx, %ecx /* get the lowerbit rem */
  211. jz cachePen4Flush0 /* skip if (rem == 0) */
  212. subl %ecx, %edi /* sub the rem from bytes */
  213. addl %ebx, %edi /* add the flushBytes */ 
  214. /* loopCount = bytes / cacheFlushBytes; */
  215. cachePen4Flush0:
  216. bsfl %ebx, %ecx /* find the LSB, ECX=[0-31] */
  217. shrl %cl, %edi /* shift right ECX bit */
  218. /* address -= (address % cacheFlushBytes); */
  219. movl %esi, %eax /* get address in EAX */
  220. xorl $0xffffffff, %edx /* create the upperbit mask */
  221. andl %edx, %eax /* get the upperbit */
  222. /* do { */
  223. /*   CLFLUSH (address); */
  224. /*   address += cacheFlushBytes; */
  225. /* } while (loopCount--); */
  226. movl %edi, %ecx /* set the loopCount */
  227. cachePen4FlushLoop:
  228. /* clflush (%eax)                        * flush the line */
  229. .byte 0x0f, 0xae, 0x38 /* mod=00b reg=111b r/m=000b */
  230. addl %ebx, %eax /* address += flushBytes */
  231. loop cachePen4FlushLoop /* loop if (ECX-- != 0) */
  232. popl %edi /* restore EDI */
  233. popl %esi /* restore ESI */
  234. popl %ebx /* restore EBX */
  235. cachePen4Ret:
  236. ret