Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

332 lines
6.4 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. flush.c
  5. Abstract:
  6. This module implements i386 machine dependent kernel functions to flush
  7. the data and instruction caches and to stall processor execution.
  8. Author:
  9. David N. Cutler (davec) 26-Apr-1990
  10. Environment:
  11. Kernel mode only.
  12. Revision History:
  13. --*/
  14. #include "ki.h"
  15. //
  16. // Prototypes
  17. //
  18. VOID
  19. KeInvalidateAllCachesTarget (
  20. IN PKIPI_CONTEXT SignalDone,
  21. IN PVOID Parameter1,
  22. IN PVOID Parameter2,
  23. IN PVOID Parameter3
  24. );
  25. extern ULONG KeI386CpuType;
  26. // i386 and i486 have transparent caches, so these routines are nooped
  27. // out in macros in i386.h.
  28. #if 0
  29. VOID
  30. KeSweepDcache (
  31. IN BOOLEAN AllProcessors
  32. )
  33. /*++
  34. Routine Description:
  35. This function flushes the data cache on all processors that are currently
  36. running threads which are children of the current process or flushes the
  37. data cache on all processors in the host configuration.
  38. Arguments:
  39. AllProcessors - Supplies a boolean value that determines which data
  40. caches are flushed.
  41. Return Value:
  42. None.
  43. --*/
  44. {
  45. HalSweepDcache();
  46. return;
  47. }
  48. VOID
  49. KeSweepIcache (
  50. IN BOOLEAN AllProcessors
  51. )
  52. /*++
  53. Routine Description:
  54. This function flushes the instruction cache on all processors that are
  55. currently running threads which are children of the current process or
  56. flushes the instruction cache on all processors in the host configuration.
  57. Arguments:
  58. AllProcessors - Supplies a boolean value that determines which instruction
  59. caches are flushed.
  60. Return Value:
  61. None.
  62. --*/
  63. {
  64. HalSweepIcache();
  65. #if defined(R4000)
  66. HalSweepDcache();
  67. #endif
  68. return;
  69. }
  70. VOID
  71. KeSweepIcacheRange (
  72. IN BOOLEAN AllProcessors,
  73. IN PVOID BaseAddress,
  74. IN ULONG Length
  75. )
  76. /*++
  77. Routine Description:
  78. This function flushes the an range of virtual addresses from the primary
  79. instruction cache on all processors that are currently running threads
  80. which are children of the current process or flushes the range of virtual
  81. addresses from the primary instruction cache on all processors in the host
  82. configuration.
  83. Arguments:
  84. AllProcessors - Supplies a boolean value that determines which instruction
  85. caches are flushed.
  86. BaseAddress - Supplies a pointer to the base of the range that is flushed.
  87. Length - Supplies the length of the range that is flushed if the base
  88. address is specified.
  89. Return Value:
  90. None.
  91. --*/
  92. {
  93. ULONG Offset;
  94. //
  95. // If the length of the range is greater than the size of the primary
  96. // instruction cache, then set the length of the flush to the size of
  97. // the primary instruction cache and set the ase address of zero.
  98. //
  99. // N.B. It is assumed that the size of the primary instruction and
  100. // data caches are the same.
  101. //
  102. if (Length > PCR->FirstLevelIcacheSize) {
  103. BaseAddress = (PVOID)0;
  104. Length = PCR->FirstLevelIcacheSize;
  105. }
  106. //
  107. // Flush the specified range of virtual addresses from the primary
  108. // instruction cache.
  109. //
  110. Offset = (ULONG)BaseAddress & PCR->DcacheAlignment;
  111. Length = (Offset + Length + PCR->DcacheAlignment) & ~PCR->DcacheAlignment;
  112. BaseAddress = (PVOID)((ULONG)BaseAddress & ~PCR->DcacheAlignment);
  113. HalSweepIcacheRange(BaseAddress, Length);
  114. #if defined(R4000)
  115. HalSweepDcacheRange(BaseAddress, Length);
  116. #endif
  117. return;
  118. }
  119. #endif
  120. BOOLEAN
  121. KeInvalidateAllCaches (
  122. IN BOOLEAN AllProcessors
  123. )
  124. /*++
  125. Routine Description:
  126. This function writes back and invalidates the cache on all processors
  127. that are currently running threads which are children of the current
  128. process or on all processors in the host configuration.
  129. Arguments:
  130. AllProcessors - Supplies a boolean value that determines which data
  131. caches are flushed.
  132. Return Value:
  133. TRUE if the invalidation was done, FALSE otherwise.
  134. --*/
  135. {
  136. PKPRCB Prcb;
  137. PKPROCESS Process;
  138. KIRQL OldIrql;
  139. KAFFINITY TargetProcessors;
  140. //
  141. // Support for wbinvd on Pentium based platforms is vendor dependent.
  142. // Check for family first and support on Pentium Pro based platforms
  143. // onward.
  144. //
  145. if (KeI386CpuType < 6 ) {
  146. return FALSE;
  147. }
  148. #ifndef NT_UP
  149. //
  150. // Compute target set of processors.
  151. //
  152. KiLockContextSwap(&OldIrql);
  153. Prcb = KeGetCurrentPrcb();
  154. if (AllProcessors) {
  155. TargetProcessors = KeActiveProcessors;
  156. } else {
  157. Process = Prcb->CurrentThread->ApcState.Process;
  158. TargetProcessors = Process->ActiveProcessors;
  159. }
  160. TargetProcessors &= ~Prcb->SetMember;
  161. //
  162. // If any target processors are specified, then send writeback
  163. // invalidate packet to the target set of processors.
  164. //
  165. if (TargetProcessors != 0) {
  166. KiIpiSendSynchronousPacket(Prcb,
  167. TargetProcessors,
  168. KeInvalidateAllCachesTarget,
  169. (PVOID)&Prcb->ReverseStall,
  170. NULL,
  171. NULL);
  172. KiIpiStallOnPacketTargets(TargetProcessors);
  173. }
  174. //
  175. // All target processors have written back and invalidated caches and
  176. // are waiting to proceed. Write back invalidate current cache and
  177. // then continue the execution of target processors.
  178. //
  179. #endif
  180. _asm {
  181. ;
  182. ; wbinvd
  183. ;
  184. _emit 0Fh
  185. _emit 09h
  186. }
  187. #ifndef NT_UP
  188. //
  189. // Wait until all target processors have finished and completed packet.
  190. //
  191. if (TargetProcessors != 0) {
  192. Prcb->ReverseStall += 1;
  193. }
  194. //
  195. // Release the context swap lock.
  196. //
  197. KiUnlockContextSwap(OldIrql);
  198. #endif
  199. return TRUE;
  200. }
  201. VOID
  202. KeInvalidateAllCachesTarget (
  203. IN PKIPI_CONTEXT SignalDone,
  204. IN PVOID Proceed,
  205. IN PVOID Parameter2,
  206. IN PVOID Parameter3
  207. )
  208. /*++
  209. Routine Description:
  210. This is the target function for writing back and invalidating the cache.
  211. Arguments:
  212. SignalDone - Supplies a pointer to a variable that is cleared when the
  213. requested operation has been performed.
  214. Proceed - pointer to flag to syncronize with
  215. Return Value:
  216. None.
  217. --*/
  218. {
  219. //
  220. // Write back invalidate current cache
  221. //
  222. _asm {
  223. ;
  224. ; wbinvd
  225. ;
  226. _emit 0Fh
  227. _emit 09h
  228. }
  229. KiIpiSignalPacketDoneAndStall (SignalDone, Proceed);
  230. }