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.

416 lines
8.2 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. mpipi.c
  5. Abstract:
  6. This module implements MIPS specific MP routine.
  7. Author:
  8. Bernard Lint 26-Jun-1996
  9. Environment:
  10. Kernel mode only.
  11. Revision History:
  12. Based on version of David N. Cutler 24-Apr-1993
  13. --*/
  14. #include "ki.h"
  15. VOID
  16. KiSaveHigherFPVolatile (
  17. PFLOAT128 SaveArea
  18. );
  19. VOID
  20. KiRestoreProcessorState (
  21. IN PKTRAP_FRAME TrapFrame,
  22. IN PKEXCEPTION_FRAME ExceptionFrame
  23. )
  24. /*++
  25. Routine Description:
  26. This function moves processor register state from the current
  27. processor context structure in the processor block to the
  28. specified trap and exception frames.
  29. Arguments:
  30. TrapFrame - Supplies a pointer to a trap frame.
  31. ExceptionFrame - Supplies a pointer to an exception frame.
  32. Return Value:
  33. None.
  34. --*/
  35. {
  36. #if !defined(NT_UP)
  37. PKPRCB Prcb;
  38. //
  39. // Get the address of the current processor block and move the
  40. // specified register state from the processor context structure
  41. // to the specified trap and exception frames
  42. //
  43. Prcb = KeGetCurrentPrcb();
  44. KeContextToKframes(TrapFrame,
  45. ExceptionFrame,
  46. &Prcb->ProcessorState.ContextFrame,
  47. CONTEXT_FULL,
  48. (KPROCESSOR_MODE)TrapFrame->PreviousMode);
  49. KiRestoreProcessorControlState(&Prcb->ProcessorState);
  50. #endif // !defined(NT_UP)
  51. return;
  52. }
  53. VOID
  54. KiSaveProcessorState (
  55. IN PKTRAP_FRAME TrapFrame,
  56. IN PKEXCEPTION_FRAME ExceptionFrame
  57. )
  58. /*++
  59. Routine Description:
  60. This function moves processor register state from the specified trap
  61. and exception frames to the processor context structure in the current
  62. processor block.
  63. Arguments:
  64. TrapFrame - Supplies a pointer to a trap frame.
  65. ExceptionFrame - Supplies a pointer to an exception frame.
  66. Return Value:
  67. None.
  68. --*/
  69. {
  70. #if !defined(NT_UP)
  71. PKPRCB Prcb;
  72. //
  73. // Get the address of the current processor block and move the
  74. // specified register state from specified trap and exception
  75. // frames to the current processor context structure.
  76. //
  77. Prcb = KeGetCurrentPrcb();
  78. if (KeGetCurrentThread()->Teb) {
  79. KiSaveHigherFPVolatile((PFLOAT128)GET_HIGH_FLOATING_POINT_REGISTER_SAVEAREA(KeGetCurrentThread()->StackBase));
  80. }
  81. Prcb->ProcessorState.ContextFrame.ContextFlags = CONTEXT_FULL;
  82. KeContextFromKframes(TrapFrame,
  83. ExceptionFrame,
  84. &Prcb->ProcessorState.ContextFrame);
  85. //
  86. // Save ISR in special registers
  87. //
  88. Prcb->ProcessorState.SpecialRegisters.StISR = TrapFrame->StISR;
  89. //
  90. // Save the current processor control state.
  91. //
  92. KiSaveProcessorControlState(&Prcb->ProcessorState);
  93. #endif // !defined(NT_UP)
  94. return;
  95. }
  96. BOOLEAN
  97. KiIpiServiceRoutine (
  98. IN PKTRAP_FRAME TrapFrame,
  99. IN PKEXCEPTION_FRAME ExceptionFrame
  100. )
  101. /*++
  102. Routine Description:
  103. This function is called at IPI_LEVEL to process any outstanding
  104. interprocess request for the current processor.
  105. Arguments:
  106. TrapFrame - Supplies a pointer to a trap frame.
  107. ExceptionFrame - Supplies a pointer to an exception frame
  108. Return Value:
  109. A value of TRUE is returned, if one of more requests were service.
  110. Otherwise, FALSE is returned.
  111. --*/
  112. {
  113. #if !defined(NT_UP)
  114. ULONG RequestSummary;
  115. //
  116. // Process any outstanding IPI requests
  117. //
  118. RequestSummary = KiIpiProcessRequests();
  119. //
  120. // If freeze is requested, then freeze target execution.
  121. //
  122. if ((RequestSummary & IPI_FREEZE) != 0) {
  123. KiFreezeTargetExecution(TrapFrame, ExceptionFrame);
  124. }
  125. return ((RequestSummary & ~IPI_FREEZE) != 0);
  126. #else
  127. return TRUE;
  128. #endif // !defined(NT_UP)
  129. }
  130. ULONG
  131. KiIpiProcessRequests (
  132. VOID
  133. )
  134. /*++
  135. Routine Description:
  136. This routine processes interprocessor requests and returns a summary
  137. of the requests that were processed.
  138. Arguments:
  139. None.
  140. Return Value:
  141. The request summary is returned as the function value.
  142. --*/
  143. {
  144. #if !defined(NT_UP)
  145. ULONG RequestSummary;
  146. PKPRCB SignalDone;
  147. PKPRCB Prcb = KeGetCurrentPrcb();
  148. RequestSummary = (ULONG)InterlockedExchange((PLONG)&Prcb->RequestSummary, 0);
  149. //
  150. // If a packet is ready, then get the address of the requested function
  151. // and call the function passing the address of the packet address as a
  152. // parameter.
  153. //
  154. SignalDone = (PKPRCB)( (ULONG_PTR)Prcb->SignalDone & ~(ULONG_PTR)1 );
  155. if (SignalDone != 0) {
  156. Prcb->SignalDone = 0;
  157. (*SignalDone->WorkerRoutine) ((PKIPI_CONTEXT)SignalDone,
  158. SignalDone->CurrentPacket[0],
  159. SignalDone->CurrentPacket[1],
  160. SignalDone->CurrentPacket[2]);
  161. }
  162. if ((RequestSummary & IPI_APC) != 0) {
  163. KiRequestSoftwareInterrupt (APC_LEVEL);
  164. } else if ((RequestSummary & IPI_DPC) != 0) {
  165. KiRequestSoftwareInterrupt (DISPATCH_LEVEL);
  166. }
  167. return RequestSummary;
  168. #else
  169. return 0;
  170. #endif // !defined(NT_UP)
  171. }
  172. VOID
  173. KiIpiSend (
  174. IN KAFFINITY TargetProcessors,
  175. IN KIPI_REQUEST IpiRequest
  176. )
  177. /*++
  178. Routine Description:
  179. This routine requests the specified operation on the target set of
  180. processors.
  181. Arguments:
  182. TargetProcessors (a0) - Supplies the set of processors on which the
  183. specified operation is to be executed.
  184. IpiRequest (a1) - Supplies the request operation mask.
  185. Return Value:
  186. None.
  187. --*/
  188. {
  189. #if !defined(NT_UP)
  190. ULONG RequestSummary;
  191. KAFFINITY NextProcessors;
  192. ULONG Next;
  193. //
  194. // Loop through the target processors and send the packet to the specified
  195. // recipients.
  196. //
  197. NextProcessors = TargetProcessors;
  198. Next = 0;
  199. while (NextProcessors != 0) {
  200. if ((NextProcessors & 1) != 0) {
  201. do {
  202. RequestSummary = KiProcessorBlock[Next]->RequestSummary;
  203. } while(InterlockedCompareExchange(
  204. (PLONG) &KiProcessorBlock[Next]->RequestSummary,
  205. (LONG) (RequestSummary | IpiRequest),
  206. (LONG) RequestSummary) != (LONG) RequestSummary);
  207. }
  208. NextProcessors = NextProcessors >> 1;
  209. Next = Next + 1;
  210. }
  211. HalRequestIpi (TargetProcessors);
  212. #endif
  213. return;
  214. }
  215. VOID
  216. KiIpiSendPacket (
  217. IN KAFFINITY TargetProcessors,
  218. IN PKIPI_WORKER WorkerFunction,
  219. IN PVOID Parameter1,
  220. IN PVOID Parameter2,
  221. IN PVOID Parameter3
  222. )
  223. /*++
  224. Routine Description:
  225. This routine executes the specified worker function on the specified
  226. set of processors.
  227. Arguments:
  228. TargetProcessors (a0) - Supplies the set of processors on which the
  229. specified operation is to be executed.
  230. WorkerFunction (a1) - Supplies the address of the worker function.
  231. Parameter1 - Parameter3 (a2, a3, 4 * 4(sp)) - Supplies worker
  232. function specific parameters.
  233. Return Value:
  234. None.
  235. --*/
  236. {
  237. #if !defined(NT_UP)
  238. PKPRCB Prcb;
  239. KAFFINITY NextProcessors;
  240. ULONG Next;
  241. Prcb = KeGetCurrentPrcb();
  242. Prcb->TargetSet = TargetProcessors;
  243. Prcb->WorkerRoutine = WorkerFunction;
  244. Prcb->CurrentPacket[0] = Parameter1;
  245. Prcb->CurrentPacket[1] = Parameter2;
  246. Prcb->CurrentPacket[2] = Parameter3;
  247. //
  248. // synchronize memory access
  249. //
  250. __mf();
  251. //
  252. // The low order bit of the packet address is set if there is
  253. // exactly one target recipient. Otherwise, the low order bit
  254. // of the packet address is clear.
  255. //
  256. if (((TargetProcessors) & ((TargetProcessors) - 1)) == 0) {
  257. (ULONG_PTR) Prcb |= 0x1;
  258. } else {
  259. Prcb->PacketBarrier = 1;
  260. }
  261. //
  262. // Loop through the target processors and send the packet to the specified
  263. // recipients.
  264. //
  265. NextProcessors = TargetProcessors;
  266. Next = 0;
  267. while (NextProcessors != 0) {
  268. if ((NextProcessors & 1) != 0) {
  269. while(InterlockedCompareExchangePointer(
  270. (PVOID)&KiProcessorBlock[Next]->SignalDone,
  271. (PVOID)Prcb,
  272. (PVOID)0) != (PVOID)0);
  273. }
  274. NextProcessors = NextProcessors >> 1;
  275. Next = Next + 1;
  276. }
  277. HalRequestIpi (TargetProcessors);
  278. #endif
  279. }