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.

537 lines
16 KiB

  1. title "mpipia"
  2. ;++
  3. ;
  4. ; Copyright (c) 1989-1995 Microsoft Corporation
  5. ;
  6. ; Module Name:
  7. ;
  8. ; mpipia.asm
  9. ;
  10. ; Abstract:
  11. ;
  12. ; This module implements the x86 specific fucntions required to
  13. ; support multiprocessor systems.
  14. ;
  15. ; Author:
  16. ;
  17. ; David N. Cutler (davec) 5-Feb-1995
  18. ;
  19. ; Environment:
  20. ;
  21. ; Krnel mode only.
  22. ;
  23. ; Revision History:
  24. ;
  25. ;--
  26. .586p
  27. .xlist
  28. include ks386.inc
  29. include mac386.inc
  30. include callconv.inc
  31. .list
  32. EXTRNP HalRequestSoftwareInterrupt,1,IMPORT,FASTCALL
  33. EXTRNP HalRequestSoftwareInterrupt,1,IMPORT,FASTCALL
  34. EXTRNP _HalRequestIpi,1,IMPORT
  35. EXTRNP _KiFreezeTargetExecution, 2
  36. ifdef DBGMP
  37. EXTRNP _KiPollDebugger
  38. endif
  39. extrn _KiProcessorBlock:DWORD
  40. DELAYCOUNT equ 2000h
  41. _DATA SEGMENT DWORD PUBLIC 'DATA'
  42. public _KiSynchPacket
  43. _KiSynchPacket dd 0
  44. _DATA ENDS
  45. _TEXT SEGMENT DWORD PUBLIC 'CODE'
  46. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  47. ;++
  48. ;
  49. ; BOOLEAN
  50. ; KiIpiServiceRoutine (
  51. ; IN PKTRAP_FRAME TrapFrame,
  52. ; IN PKEXCEPTION_FRAME ExceptionFrame
  53. ; )
  54. ;
  55. ; Routine Description:
  56. ;
  57. ; This routine is called at IPI level to process any outstanding
  58. ; interporcessor requests for the current processor.
  59. ;
  60. ; Arguments:
  61. ;
  62. ; TrapFrame - Supplies a pointer to a trap frame.
  63. ;
  64. ; ExceptionFrame - Not used.
  65. ;
  66. ; Return Value:
  67. ;
  68. ; A value of TRUE is returned, if one of more requests were service.
  69. ; Otherwise, FALSE is returned.
  70. ;
  71. ;--
  72. cPublicProc _KiIpiServiceRoutine, 2
  73. ifndef NT_UP
  74. cPublicFpo 2, 3
  75. push ebx ; save nonvolatile registers
  76. push esi ;
  77. push edi ;
  78. mov esi, PCR[PcPrcb] ; get current processor block address
  79. xor ebx, ebx ; set exchange value
  80. xor ecx, ecx ;
  81. mov eax, [esi].PbRequestSummary ; get current request summary
  82. mov edx, [esi].PbSignalDone ; get current request packet
  83. isr05: ;
  84. lock cmpxchg8b qword ptr PbRequestSummary[esi] ; capture and clear request data
  85. jnz short isr05 ; if nz, compare exchange failed
  86. mov ebx, eax ; save request summary
  87. mov edi, edx ; save request packet
  88. ;
  89. ; Check for freeze request or synchronous request.
  90. ;
  91. test bl, IPI_FREEZE + IPI_SYNCH_REQUEST ; test for freeze or packet
  92. jnz short isr50 ; if nz, freeze or synch request
  93. ;
  94. ; For RequestSummary's other then IPI_FREEZE set return to TRUE
  95. ;
  96. mov bh, 1 ; set return value
  97. ;
  98. ; Check for Packet ready.
  99. ;
  100. ; If a packet is ready, then get the address of the requested function
  101. ; and call the function passing the address of the packet address as a
  102. ; parameter.
  103. ;
  104. isr10: test edi, edi ; test for request packet
  105. jz short isr20 ; if z set, no packet ready
  106. mov edx, edi ; clear low bit in packet address
  107. btr edx, 0 ;
  108. push [edx].PbCurrentPacket + 8 ; push parameters on stack
  109. push [edx].PbCurrentPacket + 4 ;
  110. push [edx].PbCurrentPacket + 0 ;
  111. push edi ; push source processor block address
  112. mov eax, [edx].PbWorkerRoutine ; get worker routine address
  113. mov edx, [esp + 16 + 4*4] ; get current trap frame address
  114. mov [esi].PbIpiFrame, edx ; save current trap frame address
  115. call eax ; call worker routine
  116. mov bh, 1 ; set return value
  117. ;
  118. ; Check for APC interrupt request.
  119. ;
  120. isr20: test bl, IPI_APC ; check if APC interrupt requested
  121. jz short isr30 ; if z, APC interrupt not requested
  122. mov ecx, APC_LEVEL ; request APC interrupt
  123. fstCall HalRequestSoftwareInterrupt ;
  124. ;
  125. ; Check for DPC interrupt request.
  126. ;
  127. isr30: test bl, IPI_DPC ; check if DPC interrupt requested
  128. jz short isr40 ; if z, DPC interrupt not requested
  129. mov ecx, DISPATCH_LEVEL ; request DPC interrupt
  130. fstCall HalRequestSoftwareInterrupt ;
  131. isr40: mov al, bh ; return status
  132. pop edi ; restore nonvolatile registers
  133. pop esi ;
  134. pop ebx ;
  135. stdRET _KiIpiServiceRoutine
  136. ;
  137. ; Freeze or synchronous request
  138. ;
  139. isr50: test bl, IPI_FREEZE ; test if freeze request
  140. jz short isr60 ; if z, no freeze request
  141. ;
  142. ; Freeze request is requested
  143. ;
  144. mov ecx, [esp] + 20 ; get exception frame address
  145. mov edx, [esp] + 16 ; get trap frame address
  146. stdCall _KiFreezeTargetExecution, <edx, ecx> ; freeze execution
  147. test bl, not IPI_FREEZE ; Any other IPI RequestSummary?
  148. setnz bh ; Set return code accordingly
  149. test bl, IPI_SYNCH_REQUEST ; test if synch request
  150. jz isr10 ; if z, no sync request
  151. ;
  152. ; Synchronous packet request. Pointer to requesting PRCB in KiSynchPacket.
  153. ;
  154. isr60: mov eax, _KiSynchPacket ; get PRCB of requesting processor
  155. mov edx, eax ; clear low bit in packet address
  156. btr edx, 0 ;
  157. push [edx].PbCurrentPacket+8 ; push parameters on stack
  158. push [edx].PbCurrentPacket+4 ;
  159. push [edx].PbCurrentPacket+0 ;
  160. push eax ; push source processor block address
  161. mov eax, [edx].PbWorkerRoutine ; get worker routine address
  162. mov edx, [esp + 16 + 4*4] ; get current trap frame address
  163. mov [esi].PbIpiFrame, edx ; save current trap frame address
  164. call eax ; call worker routine
  165. mov bh, 1 ; set return value
  166. jmp isr10 ; join common code
  167. else
  168. xor eax, eax ; return FALSE
  169. stdRET _KiIpiServiceRoutine
  170. endif
  171. stdENDP _KiIpiServiceRoutine
  172. ;++
  173. ;
  174. ; VOID
  175. ; FASTCALL
  176. ; KiIpiSend (
  177. ; IN KAFFINITY TargetProcessors,
  178. ; IN KIPI_REQUEST Request
  179. ; )
  180. ;
  181. ; Routine Description:
  182. ;
  183. ; This function requests the specified operation on the targt set of
  184. ; processors.
  185. ;
  186. ; Arguments:
  187. ;
  188. ; TargetProcessors (ecx) - Supplies the set of processors on which the
  189. ; specified operation is to be executed.
  190. ;
  191. ; IpiRequest (edx) - Supplies the request operation code.
  192. ;
  193. ; Return Value:
  194. ;
  195. ; None.
  196. ;
  197. ;--
  198. cPublicFastCall KiIpiSend, 2
  199. ifndef NT_UP
  200. cPublicFpo 0, 2
  201. push esi ; save registers
  202. push edi ;
  203. mov esi, ecx ; save target processor set
  204. shr ecx, 1 ; shift out first bit
  205. lea edi, _KiProcessorBlock ; get processor block array address
  206. jnc short is20 ; if nc, not in target set
  207. is10: mov eax, [edi] ; get processor block address
  208. lock or [eax].PbRequestSummary, edx ; set request summary bit
  209. is20: shr ecx, 1 ; shift out next bit
  210. lea edi, [edi+4] ; advance to next processor
  211. jc short is10 ; if target, go set summary bit
  212. jnz short is20 ; if more, check next
  213. stdCall _HalRequestIpi, <esi> ; request IPI interrupts on targets
  214. pop edi ; restore registers
  215. pop esi ;
  216. endif
  217. fstRet KiIpiSend
  218. fstENDP KiIpiSend
  219. ;++
  220. ;
  221. ; VOID
  222. ; KiIpiSendPacket (
  223. ; IN KAFFINITY TargetProcessors,
  224. ; IN PKIPI_WORKER WorkerFunction,
  225. ; IN PVOID Parameter1,
  226. ; IN PVOID Parameter2,
  227. ; IN PVOID Parameter3
  228. ; )
  229. ;
  230. ; Routine Description:
  231. ;
  232. ; This routine executes the specified worker function on the specified
  233. ; set of processors.
  234. ;
  235. ; Arguments:
  236. ;
  237. ; TargetProcessors [esp + 4] - Supplies the set of processors on which the
  238. ; specfied operation is to be executed.
  239. ;
  240. ; WorkerFunction [esp + 8] - Supplies the address of the worker function.
  241. ;
  242. ; Parameter1 - Parameter3 [esp + 12] - Supplies worker function specific
  243. ; paramters.
  244. ;
  245. ; Return Value:
  246. ;
  247. ; None.
  248. ;
  249. ;--*/
  250. cPublicProc _KiIpiSendPacket, 5
  251. ifndef NT_UP
  252. cPublicFpo 5, 2
  253. push esi ; save registers
  254. push edi ;
  255. ;
  256. ; Store function address and parameters in the packet area of the PRCB on
  257. ; the current processor.
  258. ;
  259. mov edx, PCR[PcPrcb] ; get current processor block address
  260. mov ecx, [esp] + 12 ; get target processor set
  261. mov eax, [esp] + 16 ; get worker function address
  262. mov edi, [esp] + 20 ; get worker function parameter 1
  263. mov esi, [esp] + 24 ; get worker function parameter 2
  264. mov [edx].PbTargetSet, ecx ; set target processor set
  265. mov [edx].PbWorkerRoutine, eax ; set worker function address
  266. mov eax, [esp] + 28 ; get worker function parameter 3
  267. mov [edx].PbCurrentPacket, edi ; set work function parameters
  268. mov [edx].PbCurrentPacket + 4, esi ;
  269. mov [edx].PbCurrentPacket + 8, eax ;
  270. ;
  271. ; Determine whether one and only one bit is set in the target set.
  272. ;
  273. mov edi, ecx ; copy recipient target set
  274. lea esi, dword ptr [ecx-1] ; compute target set - 1
  275. and edi, esi ; and target set with target set - 1
  276. neg edi ; negate result (CF = 0 if zero)
  277. sbb edi, edi ; compute result as one if the
  278. inc edi ; target set has one bit set
  279. jnz short isp5 ; if nz, target set has one bit
  280. mov [edx].PbPacketBarrier, ecx ; set packet barrier
  281. isp5: add edx, edi ; set low order bit if appropriate
  282. ;
  283. ; Loop through the target processors and send the packet to the specified
  284. ; recipients.
  285. ;
  286. shr ecx, 1 ; shift out first bit
  287. lea edi, _KiProcessorBlock ; get processor block array address
  288. jnc short isp30 ; if nc, not in target set
  289. isp10: mov esi, [edi] ; get processor block address
  290. isp20: mov eax, [esi].PbSignalDone ; check if packet being processed
  291. or eax, eax ;
  292. jne short isp20 ; if ne, packet being processed
  293. lock cmpxchg [esi].PbSignalDone, edx ; compare and exchange
  294. jnz short isp20 ; if nz, exchange failed
  295. isp30: shr ecx, 1 ; shift out next bit
  296. lea edi, [edi+4] ; advance to next processor
  297. jc short isp10 ; if c, in target set
  298. jnz short isp30 ; if nz, more target processors
  299. mov ecx, [esp] + 12 ; set target processor set
  300. stdCall _HalRequestIpi, <ecx> ; send IPI to targets
  301. pop edi ; restore register
  302. pop esi ;
  303. endif
  304. stdRet _KiIpiSendPacket
  305. stdENDP _KiIpiSendPacket
  306. ;++
  307. ;
  308. ; VOID
  309. ; FASTCALL
  310. ; KiIpiSignalPacketDone (
  311. ; IN PKIPI_CONTEXT Signaldone
  312. ; )
  313. ;
  314. ; Routine Description:
  315. ;
  316. ; This routine signals that a processor has completed a packet by
  317. ; clearing the calling processor's set member of the requesting
  318. ; processor's packet.
  319. ;
  320. ; Arguments:
  321. ;
  322. ; SignalDone (ecx) - Supplies a pointer to the processor block of the
  323. ; sending processor.
  324. ;
  325. ; N.B. The low order bit of signal done is set if the target set
  326. ; has one and only one bit set.
  327. ;
  328. ; Return Value:
  329. ;
  330. ; None.
  331. ;
  332. ;--
  333. cPublicFastCall KiIpiSignalPacketDone, 1
  334. ifndef NT_UP
  335. btr ecx, 0 ; test and clear bit 0
  336. jc short spd20 ; if c set, only one bit set
  337. mov edx, PCR[PcPrcb] ; get current processor block address
  338. mov eax, [edx].PbSetMember ; get processor bit
  339. lock xor [ecx].PbTargetSet, eax ; clear processor set member
  340. jnz short spd10 ; if nz, more targets to go
  341. xor eax, eax ; clear packet barrier
  342. mov [ecx].PbPacketBarrier, eax ;
  343. spd10: fstRET KiIpiSignalPacketDone
  344. ;
  345. ; One and only one bit is set in the target set. Since this is the only
  346. ; processor that can clear any bits in the target set, the target set can
  347. ; be cleared with a simple write.
  348. ;
  349. spd20: xor eax, eax ; clear target set
  350. mov [ecx].PbTargetSet, eax ;
  351. endif
  352. fstRET KiIpiSignalPacketDone
  353. fstENDP KiIpiSignalPacketDone
  354. ;++
  355. ;
  356. ; VOID
  357. ; FASTCALL
  358. ; KiIpiSignalPacketDoneAndStall (
  359. ; IN PKIPI_CONTEXT Signaldone
  360. ; IN PULONG ReverseStall
  361. ; )
  362. ;
  363. ; Routine Description:
  364. ;
  365. ; This routine signals that a processor has completed a packet by
  366. ; clearing the calling processor's set member of the requesting
  367. ; processor's packet, and then stalls of the reverse stall value
  368. ;
  369. ; Arguments:
  370. ;
  371. ; SignalDone (ecx) - Supplies a pointer to the processor block of the
  372. ; sending processor.
  373. ;
  374. ; N.B. The low order bit of signal done is set if the target set
  375. ; has one and only one bit set.
  376. ;
  377. ; ReverseStall (edx) - Supplies a pointer to the reverse stall barrier
  378. ;
  379. ; Return Value:
  380. ;
  381. ; None.
  382. ;
  383. ;--
  384. cPublicFastCall KiIpiSignalPacketDoneAndStall, 2
  385. cPublicFpo 0, 2
  386. ifndef NT_UP
  387. push ebx ; save register
  388. mov ebx, dword ptr [edx] ; get current value of barrier
  389. btr ecx, 0 ; test and clear bit 0
  390. jc short sps10 ; if c set, only one bit set
  391. mov eax, PCR[PcPrcb] ; get processor block address
  392. mov eax, [eax].PbSetMember ; get processor bit
  393. lock xor [ecx].PbTargetSet, eax ; clear processor set member
  394. jnz short sps20 ; if nz, more targets to go
  395. xor eax, eax ; clear packet barrier
  396. mov [ecx].PbPacketBarrier, eax ;
  397. jmp short sps20 ;
  398. ;
  399. ; One and only one bit is set in the target set. Since this is the only
  400. ; processor that can clear any bits in the target set, the target set can
  401. ; be cleared with a simple write.
  402. ;
  403. sps10: xor eax, eax ; clear target set
  404. mov [ecx].PbTargetSet, eax ;
  405. ;
  406. ; Wait for barrier value to change.
  407. ;
  408. sps20: mov eax, DELAYCOUNT
  409. sps30: cmp ebx, dword ptr [edx] ; barrier set?
  410. jne short sps90 ; yes, all done
  411. YIELD
  412. dec eax ; P54C pre C2 workaround
  413. jnz short sps30 ; if eax = 0, generate bus cycle
  414. ifdef DBGMP
  415. stdCall _KiPollDebugger ; Check for debugger ^C
  416. endif
  417. ;
  418. ; There could be a freeze execution outstanding. Check and clear
  419. ; freeze flag.
  420. ;
  421. .errnz IPI_FREEZE - 4
  422. mov eax, PCR[PcPrcb] ; get processor block address
  423. lock btr [eax].PbRequestSummary, 2 ; Generate bus cycle
  424. jnc short sps20 ; Freeze pending?
  425. cPublicFpo 0,4
  426. push ecx ; save target processor block
  427. push edx ; save barrier address
  428. stdCall _KiFreezeTargetExecution, <[eax].PbIpiFrame, 0> ;
  429. pop edx ; restore barrier address
  430. pop ecx ; restore target procssor block
  431. jmp short sps20 ;
  432. sps90: pop ebx ; restore register
  433. endif
  434. fstRET KiIpiSignalPacketDoneAndStall
  435. fstENDP KiIpiSignalPacketDoneAndStall
  436. _TEXT ends
  437. end