Leaked source code of windows server 2003
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.

437 lines
9.3 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. #else
  51. UNREFERENCED_PARAMETER (TrapFrame);
  52. UNREFERENCED_PARAMETER (ExceptionFrame);
  53. #endif // !defined(NT_UP)
  54. return;
  55. }
  56. VOID
  57. KiSaveProcessorState (
  58. IN PKTRAP_FRAME TrapFrame,
  59. IN PKEXCEPTION_FRAME ExceptionFrame
  60. )
  61. /*++
  62. Routine Description:
  63. This function moves processor register state from the specified trap
  64. and exception frames to the processor context structure in the current
  65. processor block.
  66. Arguments:
  67. TrapFrame - Supplies a pointer to a trap frame.
  68. ExceptionFrame - Supplies a pointer to an exception frame.
  69. Return Value:
  70. None.
  71. --*/
  72. {
  73. #if !defined(NT_UP)
  74. PKPRCB Prcb;
  75. //
  76. // Get the address of the current processor block and move the
  77. // specified register state from specified trap and exception
  78. // frames to the current processor context structure.
  79. //
  80. Prcb = KeGetCurrentPrcb();
  81. if (KeGetCurrentThread()->Teb) {
  82. KiSaveHigherFPVolatile((PFLOAT128)GET_HIGH_FLOATING_POINT_REGISTER_SAVEAREA(KeGetCurrentThread()->StackBase));
  83. }
  84. Prcb->ProcessorState.ContextFrame.ContextFlags = CONTEXT_FULL;
  85. KeContextFromKframes(TrapFrame,
  86. ExceptionFrame,
  87. &Prcb->ProcessorState.ContextFrame);
  88. //
  89. // Save ISR in special registers
  90. //
  91. Prcb->ProcessorState.SpecialRegisters.StISR = TrapFrame->StISR;
  92. //
  93. // Save the current processor control state.
  94. //
  95. KiSaveProcessorControlState(&Prcb->ProcessorState);
  96. #else
  97. UNREFERENCED_PARAMETER (TrapFrame);
  98. UNREFERENCED_PARAMETER (ExceptionFrame);
  99. #endif // !defined(NT_UP)
  100. return;
  101. }
  102. BOOLEAN
  103. KiIpiServiceRoutine (
  104. IN PKTRAP_FRAME TrapFrame,
  105. IN PKEXCEPTION_FRAME ExceptionFrame
  106. )
  107. /*++
  108. Routine Description:
  109. This function is called at IPI_LEVEL to process any outstanding
  110. interprocess request for the current processor.
  111. Arguments:
  112. TrapFrame - Supplies a pointer to a trap frame.
  113. ExceptionFrame - Supplies a pointer to an exception frame
  114. Return Value:
  115. A value of TRUE is returned, if one of more requests were service.
  116. Otherwise, FALSE is returned.
  117. --*/
  118. {
  119. #if !defined(NT_UP)
  120. ULONG RequestSummary;
  121. //
  122. // Process any outstanding IPI requests
  123. //
  124. RequestSummary = KiIpiProcessRequests();
  125. //
  126. // If freeze is requested, then freeze target execution.
  127. //
  128. if ((RequestSummary & IPI_FREEZE) != 0) {
  129. KiFreezeTargetExecution(TrapFrame, ExceptionFrame);
  130. }
  131. return ((RequestSummary & ~IPI_FREEZE) != 0 ? TRUE : FALSE);
  132. #else
  133. UNREFERENCED_PARAMETER (TrapFrame);
  134. UNREFERENCED_PARAMETER (ExceptionFrame);
  135. return TRUE;
  136. #endif // !defined(NT_UP)
  137. }
  138. ULONG
  139. KiIpiProcessRequests (
  140. VOID
  141. )
  142. /*++
  143. Routine Description:
  144. This routine processes interprocessor requests and returns a summary
  145. of the requests that were processed.
  146. Arguments:
  147. None.
  148. Return Value:
  149. The request summary is returned as the function value.
  150. --*/
  151. {
  152. #if !defined(NT_UP)
  153. ULONG RequestSummary;
  154. PKPRCB SignalDone;
  155. PKPRCB Prcb = KeGetCurrentPrcb();
  156. RequestSummary = (ULONG)InterlockedExchange((PLONG)&Prcb->RequestSummary, 0);
  157. //
  158. // If a packet is ready, then get the address of the requested function
  159. // and call the function passing the address of the packet address as a
  160. // parameter.
  161. //
  162. SignalDone = (PKPRCB)( (ULONG_PTR)Prcb->SignalDone & ~(ULONG_PTR)1 );
  163. if (SignalDone != 0) {
  164. Prcb->SignalDone = 0;
  165. (*SignalDone->WorkerRoutine) ((PKIPI_CONTEXT)SignalDone,
  166. SignalDone->CurrentPacket[0],
  167. SignalDone->CurrentPacket[1],
  168. SignalDone->CurrentPacket[2]);
  169. }
  170. if ((RequestSummary & IPI_APC) != 0) {
  171. KiRequestSoftwareInterrupt (APC_LEVEL);
  172. }
  173. if ((RequestSummary & IPI_DPC) != 0) {
  174. KiRequestSoftwareInterrupt (DISPATCH_LEVEL);
  175. }
  176. return RequestSummary;
  177. #else
  178. return 0;
  179. #endif // !defined(NT_UP)
  180. }
  181. VOID
  182. KiIpiSend (
  183. IN KAFFINITY TargetProcessors,
  184. IN KIPI_REQUEST IpiRequest
  185. )
  186. /*++
  187. Routine Description:
  188. This routine requests the specified operation on the target set of
  189. processors.
  190. Arguments:
  191. TargetProcessors (a0) - Supplies the set of processors on which the
  192. specified operation is to be executed.
  193. IpiRequest (a1) - Supplies the request operation mask.
  194. Return Value:
  195. None.
  196. --*/
  197. {
  198. #if !defined(NT_UP)
  199. ULONG RequestSummary;
  200. KAFFINITY NextProcessors;
  201. ULONG Next;
  202. //
  203. // Loop through the target processors and send the packet to the specified
  204. // recipients.
  205. //
  206. NextProcessors = TargetProcessors;
  207. Next = 0;
  208. while (NextProcessors != 0) {
  209. if ((NextProcessors & 1) != 0) {
  210. do {
  211. RequestSummary = KiProcessorBlock[Next]->RequestSummary;
  212. } while(InterlockedCompareExchange(
  213. (PLONG) &KiProcessorBlock[Next]->RequestSummary,
  214. (LONG) (RequestSummary | IpiRequest),
  215. (LONG) RequestSummary) != (LONG) RequestSummary);
  216. }
  217. NextProcessors = NextProcessors >> 1;
  218. Next = Next + 1;
  219. }
  220. HalRequestIpi (TargetProcessors);
  221. #else
  222. UNREFERENCED_PARAMETER (TargetProcessors);
  223. UNREFERENCED_PARAMETER (IpiRequest);
  224. #endif // !defined(NT_UP)
  225. return;
  226. }
  227. VOID
  228. KiIpiSendPacket (
  229. IN KAFFINITY TargetProcessors,
  230. IN PKIPI_WORKER WorkerFunction,
  231. IN PVOID Parameter1,
  232. IN PVOID Parameter2,
  233. IN PVOID Parameter3
  234. )
  235. /*++
  236. Routine Description:
  237. This routine executes the specified worker function on the specified
  238. set of processors.
  239. Arguments:
  240. TargetProcessors (a0) - Supplies the set of processors on which the
  241. specified operation is to be executed.
  242. WorkerFunction (a1) - Supplies the address of the worker function.
  243. Parameter1 - Parameter3 (a2, a3, 4 * 4(sp)) - Supplies worker
  244. function specific parameters.
  245. Return Value:
  246. None.
  247. --*/
  248. {
  249. #if !defined(NT_UP)
  250. PKPRCB Prcb;
  251. KAFFINITY NextProcessors;
  252. ULONG Next;
  253. Prcb = KeGetCurrentPrcb();
  254. Prcb->TargetSet = TargetProcessors;
  255. Prcb->WorkerRoutine = WorkerFunction;
  256. Prcb->CurrentPacket[0] = Parameter1;
  257. Prcb->CurrentPacket[1] = Parameter2;
  258. Prcb->CurrentPacket[2] = Parameter3;
  259. //
  260. // synchronize memory access
  261. //
  262. __mf();
  263. //
  264. // The low order bit of the packet address is set if there is
  265. // exactly one target recipient. Otherwise, the low order bit
  266. // of the packet address is clear.
  267. //
  268. if (((TargetProcessors) & ((TargetProcessors) - 1)) == 0) {
  269. Prcb = (PKPRCB)((ULONG_PTR) Prcb | 0x1);
  270. } else {
  271. Prcb->PacketBarrier = 1;
  272. }
  273. //
  274. // Loop through the target processors and send the packet to the specified
  275. // recipients.
  276. //
  277. NextProcessors = TargetProcessors;
  278. Next = 0;
  279. while (NextProcessors != 0) {
  280. if ((NextProcessors & 1) != 0) {
  281. while(InterlockedCompareExchangePointer(
  282. (PVOID)&KiProcessorBlock[Next]->SignalDone,
  283. (PVOID)Prcb,
  284. (PVOID)0) != (PVOID)0);
  285. }
  286. NextProcessors = NextProcessors >> 1;
  287. Next = Next + 1;
  288. }
  289. HalRequestIpi (TargetProcessors);
  290. #else
  291. UNREFERENCED_PARAMETER (TargetProcessors);
  292. UNREFERENCED_PARAMETER (WorkerFunction);
  293. UNREFERENCED_PARAMETER (Parameter1);
  294. UNREFERENCED_PARAMETER (Parameter2);
  295. UNREFERENCED_PARAMETER (Parameter3);
  296. #endif
  297. }