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.

574 lines
17 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. xor ebx, ebx ; set exchange value
  79. xor edi, edi
  80. mov esi, PCR[PcPrcb] ; get current processor block address
  81. xchg dword ptr [esi].PbRequestSummary, ebx
  82. xchg dword ptr [esi].PbSignalDone, edi
  83. ;
  84. ; Check for freeze request or synchronous request.
  85. ;
  86. test bl, IPI_FREEZE + IPI_SYNCH_REQUEST ; test for freeze or packet
  87. jnz short isr50 ; if nz, freeze or synch request
  88. ;
  89. ; For RequestSummary's other then IPI_FREEZE set return to TRUE
  90. ;
  91. mov bh, 1 ; set return value
  92. ;
  93. ; Check for Packet ready.
  94. ;
  95. ; If a packet is ready, then get the address of the requested function
  96. ; and call the function passing the address of the packet address as a
  97. ; parameter.
  98. ;
  99. isr10: mov edx, edi ; copy request pack address
  100. and edx, NOT 1 ; Clear point to point bit
  101. jz short isr20 ; if z set, no packet ready
  102. push [edx].PbCurrentPacket + 8 ; push parameters on stack
  103. push [edx].PbCurrentPacket + 4 ;
  104. push [edx].PbCurrentPacket + 0 ;
  105. push edi ; push source processor block address
  106. mov eax, [edx].PbWorkerRoutine ; get worker routine address
  107. mov edx, [esp + 16 + 4*4] ; get current trap frame address
  108. mov [esi].PbIpiFrame, edx ; save current trap frame address
  109. call eax ; call worker routine
  110. mov bh, 1 ; set return value
  111. ;
  112. ; Check for APC interrupt request.
  113. ;
  114. isr20: test bl, IPI_APC ; check if APC interrupt requested
  115. jz short isr30 ; if z, APC interrupt not requested
  116. mov ecx, APC_LEVEL ; request APC interrupt
  117. fstCall HalRequestSoftwareInterrupt ;
  118. ;
  119. ; Check for DPC interrupt request.
  120. ;
  121. isr30: test bl, IPI_DPC ; check if DPC interrupt requested
  122. jz short isr40 ; if z, DPC interrupt not requested
  123. mov ecx, DISPATCH_LEVEL ; request DPC interrupt
  124. fstCall HalRequestSoftwareInterrupt ;
  125. isr40: mov al, bh ; return status
  126. pop edi ; restore nonvolatile registers
  127. pop esi ;
  128. pop ebx ;
  129. stdRET _KiIpiServiceRoutine
  130. ;
  131. ; Freeze or synchronous request
  132. ;
  133. isr50: test bl, IPI_FREEZE ; test if freeze request
  134. jz short isr60 ; if z, no freeze request
  135. ;
  136. ; Freeze request is requested
  137. ;
  138. mov ecx, [esp] + 20 ; get exception frame address
  139. mov edx, [esp] + 16 ; get trap frame address
  140. stdCall _KiFreezeTargetExecution, <edx, ecx> ; freeze execution
  141. test bl, not IPI_FREEZE ; Any other IPI RequestSummary?
  142. setnz bh ; Set return code accordingly
  143. test bl, IPI_SYNCH_REQUEST ; test if synch request
  144. jz isr10 ; if z, no sync request
  145. ;
  146. ; Synchronous packet request. Pointer to requesting PRCB in KiSynchPacket.
  147. ;
  148. isr60: mov eax, _KiSynchPacket ; get PRCB of requesting processor
  149. mov edx, eax ; clear low bit in packet address
  150. btr edx, 0 ;
  151. push [edx].PbCurrentPacket+8 ; push parameters on stack
  152. push [edx].PbCurrentPacket+4 ;
  153. push [edx].PbCurrentPacket+0 ;
  154. push eax ; push source processor block address
  155. mov eax, [edx].PbWorkerRoutine ; get worker routine address
  156. mov edx, [esp + 16 + 4*4] ; get current trap frame address
  157. mov [esi].PbIpiFrame, edx ; save current trap frame address
  158. call eax ; call worker routine
  159. mov bh, 1 ; set return value
  160. jmp isr10 ; join common code
  161. else
  162. xor eax, eax ; return FALSE
  163. stdRET _KiIpiServiceRoutine
  164. endif
  165. stdENDP _KiIpiServiceRoutine
  166. ;++
  167. ;
  168. ; VOID
  169. ; FASTCALL
  170. ; KiIpiSend (
  171. ; IN KAFFINITY TargetProcessors,
  172. ; IN KIPI_REQUEST Request
  173. ; )
  174. ;
  175. ; Routine Description:
  176. ;
  177. ; This function requests the specified operation on the targt set of
  178. ; processors.
  179. ;
  180. ; Arguments:
  181. ;
  182. ; TargetProcessors (ecx) - Supplies the set of processors on which the
  183. ; specified operation is to be executed.
  184. ;
  185. ; IpiRequest (edx) - Supplies the request operation code.
  186. ;
  187. ; Return Value:
  188. ;
  189. ; None.
  190. ;
  191. ;--
  192. cPublicFastCall KiIpiSend, 2
  193. ifndef NT_UP
  194. cPublicFpo 0, 2
  195. push esi ; save registers
  196. push edi ;
  197. mov esi, ecx ; save target processor set
  198. shr ecx, 1 ; shift out first bit
  199. lea edi, _KiProcessorBlock ; get processor block array address
  200. jnc short is20 ; if nc, not in target set
  201. is10: mov eax, [edi] ; get processor block address
  202. lock or [eax].PbRequestSummary, edx ; set request summary bit
  203. is20: shr ecx, 1 ; shift out next bit
  204. lea edi, [edi+4] ; advance to next processor
  205. jc short is10 ; if target, go set summary bit
  206. jnz short is20 ; if more, check next
  207. stdCall _HalRequestIpi, <esi> ; request IPI interrupts on targets
  208. pop edi ; restore registers
  209. pop esi ;
  210. endif
  211. fstRet KiIpiSend
  212. fstENDP KiIpiSend
  213. ;++
  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. ;
  226. ; This routine executes the specified worker function on the specified
  227. ; set of processors.
  228. ;
  229. ; Arguments:
  230. ;
  231. ; TargetProcessors [esp + 4] - Supplies the set of processors on which the
  232. ; specfied operation is to be executed.
  233. ;
  234. ; WorkerFunction [esp + 8] - Supplies the address of the worker function.
  235. ;
  236. ; Parameter1 - Parameter3 [esp + 12] - Supplies worker function specific
  237. ; paramters.
  238. ;
  239. ; Return Value:
  240. ;
  241. ; None.
  242. ;
  243. ;--*/
  244. cPublicProc _KiIpiSendPacket, 5
  245. ifndef NT_UP
  246. cPublicFpo 5, 2
  247. push esi ; save registers
  248. push edi ;
  249. ;
  250. ; Store function address and parameters in the packet area of the PRCB on
  251. ; the current processor.
  252. ;
  253. mov edx, PCR[PcPrcb] ; get current processor block address
  254. mov ecx, [esp] + 12 ; get target processor set
  255. mov eax, [esp] + 16 ; get worker function address
  256. mov edi, [esp] + 20 ; get worker function parameter 1
  257. mov esi, [esp] + 24 ; get worker function parameter 2
  258. mov [edx].PbTargetSet, ecx ; set target processor set
  259. mov [edx].PbWorkerRoutine, eax ; set worker function address
  260. mov eax, [esp] + 28 ; get worker function parameter 3
  261. mov [edx].PbCurrentPacket, edi ; set work function parameters
  262. mov [edx].PbCurrentPacket + 4, esi ;
  263. mov [edx].PbCurrentPacket + 8, eax ;
  264. ;
  265. ; Determine whether one and only one bit is set in the target set.
  266. ;
  267. mov edi, ecx ; copy recipient target set
  268. lea esi, dword ptr [ecx-1] ; compute target set - 1
  269. and edi, esi ; and target set with target set - 1
  270. neg edi ; negate result (CF = 0 if zero)
  271. sbb edi, edi ; compute result as one if the
  272. inc edi ; target set has one bit set
  273. jnz short isp5 ; if nz, target set has one bit
  274. mov [edx].PbPacketBarrier, ecx ; set packet barrier
  275. isp5: add edx, edi ; set low order bit if appropriate
  276. ;
  277. ; Loop through the target processors and send the packet to the specified
  278. ; recipients.
  279. ;
  280. shr ecx, 1 ; shift out first bit
  281. lea edi, _KiProcessorBlock ; get processor block array address
  282. jnc short isp30 ; if nc, not in target set
  283. isp10: mov esi, [edi] ; get processor block address
  284. isp20: mov eax, [esi].PbSignalDone ; check if packet being processed
  285. or eax, eax ;
  286. jne isp40 ; if ne, packet being processed
  287. lock cmpxchg [esi].PbSignalDone, edx ; compare and exchange
  288. jnz short isp20 ; if nz, exchange failed
  289. isp30: shr ecx, 1 ; shift out next bit
  290. lea edi, [edi+4] ; advance to next processor
  291. jc short isp10 ; if c, in target set
  292. jnz short isp30 ; if nz, more target processors
  293. mov ecx, [esp] + 12 ; set target processor set
  294. stdCall _HalRequestIpi, <ecx> ; send IPI to targets
  295. pop edi ; restore register
  296. pop esi ;
  297. endif
  298. stdRet _KiIpiSendPacket
  299. ifndef NT_UP
  300. isp40:
  301. YIELD
  302. jmp short isp20 ; retry packet test
  303. endif
  304. stdENDP _KiIpiSendPacket
  305. ;++
  306. ;
  307. ; VOID
  308. ; FASTCALL
  309. ; KiIpiSignalPacketDone (
  310. ; IN PKIPI_CONTEXT Signaldone
  311. ; )
  312. ;
  313. ; Routine Description:
  314. ;
  315. ; This routine signals that a processor has completed a packet by
  316. ; clearing the calling processor's set member of the requesting
  317. ; processor's packet.
  318. ;
  319. ; Arguments:
  320. ;
  321. ; SignalDone (ecx) - Supplies a pointer to the processor block of the
  322. ; sending processor.
  323. ;
  324. ; N.B. The low order bit of signal done is set if the target set
  325. ; has one and only one bit set.
  326. ;
  327. ; Return Value:
  328. ;
  329. ; None.
  330. ;
  331. ;--
  332. cPublicFastCall KiIpiSignalPacketDone, 1
  333. ifndef NT_UP
  334. btr ecx, 0 ; test and clear bit 0
  335. jc short spd20 ; if c set, only one bit set
  336. mov edx, PCR[PcPrcb] ; get current processor block address
  337. mov eax, [edx].PbSetMember ; get processor bit
  338. if DBG
  339. test [ecx].PbTargetSet, eax
  340. jne @f
  341. int 3
  342. @@:
  343. endif
  344. lock xor [ecx].PbTargetSet, eax ; clear processor set member
  345. jnz short spd10 ; if nz, more targets to go
  346. xor eax, eax ; clear packet barrier
  347. if DBG
  348. cmp [ecx].PbPacketBarrier, eax
  349. jne @f
  350. int 3
  351. @@:
  352. endif
  353. mov [ecx].PbPacketBarrier, eax ;
  354. spd10: fstRET KiIpiSignalPacketDone
  355. ;
  356. ; One and only one bit is set in the target set. Since this is the only
  357. ; processor that can clear any bits in the target set, the target set can
  358. ; be cleared with a simple write.
  359. ;
  360. spd20: xor eax, eax ; clear target set
  361. if DBG
  362. cmp [ecx].PbTargetSet, eax
  363. jne @f
  364. int 3
  365. @@:
  366. endif
  367. mov [ecx].PbTargetSet, eax ;
  368. endif
  369. fstRET KiIpiSignalPacketDone
  370. fstENDP KiIpiSignalPacketDone
  371. ;++
  372. ;
  373. ; VOID
  374. ; FASTCALL
  375. ; KiIpiSignalPacketDoneAndStall (
  376. ; IN PKIPI_CONTEXT Signaldone
  377. ; IN PULONG ReverseStall
  378. ; )
  379. ;
  380. ; Routine Description:
  381. ;
  382. ; This routine signals that a processor has completed a packet by
  383. ; clearing the calling processor's set member of the requesting
  384. ; processor's packet, and then stalls on the reverse stall value
  385. ;
  386. ; Arguments:
  387. ;
  388. ; SignalDone (ecx) - Supplies a pointer to the processor block of the
  389. ; sending processor.
  390. ;
  391. ; N.B. The low order bit of signal done is set if the target set
  392. ; has one and only one bit set.
  393. ;
  394. ; ReverseStall (edx) - Supplies a pointer to the reverse stall barrier
  395. ;
  396. ; Return Value:
  397. ;
  398. ; None.
  399. ;
  400. ;--
  401. cPublicFastCall KiIpiSignalPacketDoneAndStall, 2
  402. cPublicFpo 0, 2
  403. ifndef NT_UP
  404. push ebx ; save register
  405. mov ebx, dword ptr [edx] ; get current value of barrier
  406. btr ecx, 0 ; test and clear bit 0
  407. jc short sps10 ; if c set, only one bit set
  408. mov eax, PCR[PcPrcb] ; get processor block address
  409. mov eax, [eax].PbSetMember ; get processor bit
  410. if DBG
  411. test [ecx].PbTargetSet, eax ; Make sure the bit is set in the mask
  412. jne @f
  413. int 3
  414. @@:
  415. endif
  416. lock xor [ecx].PbTargetSet, eax ; clear processor set member
  417. jnz short sps20 ; if nz, more targets to go
  418. xor eax, eax ; clear packet barrier
  419. if DBG
  420. cmp [ecx].PbPacketBarrier, eax ; Make sure the barrier is still set
  421. jne @f
  422. int 3
  423. @@:
  424. endif
  425. mov [ecx].PbPacketBarrier, eax ;
  426. jmp short sps20 ;
  427. ;
  428. ; One and only one bit is set in the target set. Since this is the only
  429. ; processor that can clear any bits in the target set, the target set can
  430. ; be cleared with a simple write.
  431. ;
  432. sps10: xor eax, eax ; clear target set
  433. if DBG
  434. cmp [ecx].PbTargetSet, eax ; Make sure the bit is set in the mask
  435. jne @f
  436. int 3
  437. @@:
  438. endif
  439. mov [ecx].PbTargetSet, eax ;
  440. ;
  441. ; Wait for barrier value to change.
  442. ;
  443. sps20: mov eax, DELAYCOUNT
  444. sps30: cmp ebx, dword ptr [edx] ; barrier set?
  445. jne short sps90 ; yes, all done
  446. YIELD
  447. dec eax ; P54C pre C2 workaround
  448. jnz short sps30 ; if eax = 0, generate bus cycle
  449. ifdef DBGMP
  450. stdCall _KiPollDebugger ; Check for debugger ^C
  451. endif
  452. ;
  453. ; There could be a freeze execution outstanding. Check and clear
  454. ; freeze flag.
  455. ;
  456. .errnz IPI_FREEZE - 4
  457. mov eax, PCR[PcPrcb] ; get processor block address
  458. lock btr [eax].PbRequestSummary, 2 ; Generate bus cycle
  459. jnc short sps20 ; Freeze pending?
  460. cPublicFpo 0,4
  461. push ecx ; save target processor block
  462. push edx ; save barrier address
  463. stdCall _KiFreezeTargetExecution, <[eax].PbIpiFrame, 0> ;
  464. pop edx ; restore barrier address
  465. pop ecx ; restore target procssor block
  466. jmp short sps20 ;
  467. sps90: pop ebx ; restore register
  468. endif
  469. fstRET KiIpiSignalPacketDoneAndStall
  470. fstENDP KiIpiSignalPacketDoneAndStall
  471. _TEXT ends
  472. end