Windows NT 4.0 source code leak
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.

571 lines
12 KiB

4 years ago
  1. title "Interprocessor Interrupt"
  2. ;++
  3. ;
  4. ;Copyright (c) 1991 Microsoft Corporation
  5. ;
  6. ;Module Name:
  7. ;
  8. ; oliipi.asm
  9. ;
  10. ;Abstract:
  11. ;
  12. ; SystemPro IPI code.
  13. ; Provides the HAL support for Interprocessor Interrupts for hte
  14. ; MP SystemPro implementation.
  15. ;
  16. ;Author:
  17. ;
  18. ; Ken Reneris (kenr) 13-Jan-1992
  19. ;
  20. ;Revision History:
  21. ;
  22. ; Bruno Sartirana (o-obruno) 3-Mar-92
  23. ; Added support for the Olivetti LSX5030.
  24. ;--
  25. .386p
  26. .xlist
  27. ;
  28. ; Include LSX5030 detection code
  29. ;
  30. include i386\olidtect.asm
  31. ;
  32. ; Normal includes
  33. ;
  34. include hal386.inc
  35. include callconv.inc
  36. include i386\kimacro.inc
  37. include i386\ix8259.inc
  38. ;LSX5030 start
  39. include i386\olimp.inc
  40. EXTRNP _HalpInitializeProcessor,1
  41. extrn _IdtIpiVector:DWORD
  42. extrn KiI8259MaskTable:DWORD
  43. ;LSX5030 end
  44. EXTRNP _KiCoprocessorError,0,IMPORT
  45. EXTRNP Kei386EoiHelper,0,IMPORT
  46. EXTRNP _HalBeginSystemInterrupt,3
  47. EXTRNP _HalEndSystemInterrupt,2
  48. EXTRNP _KiIpiServiceRoutine,2,IMPORT
  49. EXTRNP _HalEnableSystemInterrupt,3
  50. EXTRNP _HalpInitializePICs,0
  51. EXTRNP _HalDisplayString,1
  52. EXTRNP _HalEnableSystemInterrupt,3
  53. EXTRNP _HalDisableSystemInterrupt,2
  54. extrn _HalpActiveProcessors:DWORD
  55. _DATA SEGMENT DWORD PUBLIC 'DATA'
  56. ;LSX5030 start
  57. ;ifdef HALOLI_DBG
  58. ; for debug only
  59. public DbgDelay
  60. DbgDelay dd 20000000
  61. ;endif
  62. ; IPI IRQL decoding array
  63. public PcrIpiIrql
  64. PcrIpiIrql db 15
  65. db 11
  66. db 10
  67. db 13
  68. ;LSX5030 end
  69. ;
  70. ; Processor Control Ports
  71. ;
  72. public ProcessorControlPort, _HalpProcessorPCR, _HalpInitializedProcessors
  73. ProcessorControlPort dw PCR_P0 ; P0 Processor Control Port
  74. dw PCR_P1 ; P1 Processor Control Port
  75. dw PCR_P2 ; P2 Processor Control Port
  76. dw PCR_P3 ; P3 Processor Control Port
  77. _HalpProcessorPCR dd MAXIMUM_PROCESSORS dup (?) ; PCR pointer for each processor
  78. _HalpInitializedProcessors dd 0
  79. ;
  80. ;InterruptVectorControl dw 0 ; P0 none for p0
  81. ;dw ICP_P1 ; P1 Processor Control Port
  82. ;dw ICP_P2 ; P2 Processor Control Port
  83. ;dw ICP_P3 ; P3 Processor Control Port
  84. public _HalpFindFirstSetRight
  85. _HalpFindFirstSetRight db 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
  86. public _SystemType
  87. _SystemType dd 0
  88. ;LSX5030 start
  89. BadHalString db 'HAL: LSX5030 HAL.DLL cannot be run on non LSX5030', cr, lf
  90. db ' Replace the hal.dll with the correct hal', cr, lf
  91. db ' System is HALTING *********', 0
  92. ;LSX5030 end
  93. _DATA ends
  94. page ,132
  95. subttl "Post InterProcessor Interrupt"
  96. _TEXT SEGMENT DWORD PUBLIC 'CODE'
  97. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  98. ;++
  99. ;
  100. ; VOID
  101. ; HalInitializeProcessor(
  102. ; ULONG Number
  103. ; );
  104. ;
  105. ;Routine Description:
  106. ;
  107. ; Initialize hal pcr values for current processor (if any)
  108. ; (called shortly after processor reaches kernel, before
  109. ; HalInitSystem if P0)
  110. ;
  111. ; IPI's and KeReadir/LowerIrq's must be available once this function
  112. ; returns. (IPI's are only used once two or more processors are
  113. ; available)
  114. ;
  115. ; . Enable IPI interrupt (makes sense for P1, P2, ...).
  116. ; . Save Processor Number in PCR.
  117. ; . if (P0)
  118. ; . determine what kind of system is it,
  119. ; . if (NotSysProCompatible) Halt;
  120. ; . InitializePICs.
  121. ; . if (P1)
  122. ; . program VECTOR_PORT to accept IPI at IRQ13.
  123. ; . Save ProcesserControlPort (PCR) to PCRegion, per processor.
  124. ; . Enable PINTs on CPU.
  125. ;
  126. ;Arguments:
  127. ;
  128. ; eax: processor number - Logical processor number of calling processor
  129. ;
  130. ;Return Value:
  131. ;
  132. ; None.
  133. ;
  134. ;--
  135. cPublicProc _HalInitializeProcessor,1
  136. ;LSX5030 start
  137. ;DBG_DISPLAY 0a0h
  138. ; Initialize PcIDR in PCR to enable slave IRQ
  139. mov fs:PcIDR, 0fffffffbh
  140. movzx eax, byte ptr [esp+4] ; get processor number
  141. mov fs:PcHal.PcrNumber, al ; Save processor # in PCR
  142. lock bts _HalpActiveProcessors, eax
  143. lock inc _HalpInitializedProcessors
  144. mov ecx, fs:PcSelfPcr ; Flat address of this PCR
  145. mov _HalpProcessorPCR[eax*4], ecx ; Save it away
  146. or eax, eax
  147. jnz hip20_Any ; jump if not P0
  148. ; For P0 only, determine if this is an LSX5030 or not.
  149. lea eax, _SystemType ; this just to honor the
  150. ; DetectOlivettiMp call interface
  151. stdCall _DetectOlivettiMp,<eax>
  152. ;DBG_DISPLAY 0a1h
  153. mov _SystemType, eax ; Remember system type
  154. or eax, eax
  155. jz _NotAnLSX5030 ; (SystemType == 0): Alien machine
  156. ; P0
  157. ; Initialized the stall scale factor to something other that 0,
  158. ; just in case KeStallExecutionProcessor was called before
  159. ; HalpInitializeStallExecution (when a DbgBreakPoint() is used
  160. ; before HalpInitializeStallExecution() is called.
  161. ;
  162. mov dword ptr fs:PcStallScaleFactor, INITIAL_STALL_COUNT
  163. ; load eax with the processor #
  164. movzx eax, byte ptr fs:PcHal.PcrNumber ; get processor # from PCR
  165. hip20_Any:
  166. ; Note: at this point eax must contain the processor number
  167. mov dx, word ptr ProcessorControlPort[eax*2]
  168. in al, dx ; get PCR status
  169. and al, not PINT ; clear IPI pending bit
  170. or al, IPI_EN ; enable IPI's
  171. out dx, al ; store the new PCR status
  172. mov fs:PcHal.PcrControlPort, dx ; Save port value
  173. movzx eax, byte ptr [esp+4] ; get processor number
  174. or eax, eax
  175. jz hip30_Any ; jump if P0
  176. ; init PICs, interval timer, stall scale factor...
  177. ;DBG_DISPLAY 0a2h
  178. stdCall _HalpInitializeProcessor,<eax>
  179. ;DBG_DISPLAY 0a3h
  180. hip30_Any:
  181. ;LSX5030 end
  182. stdRET _HalInitializeProcessor
  183. ;LSX5030 start
  184. _NotAnLSX5030:
  185. stdCall _HalDisplayString,<offset BadHalString>
  186. hlt
  187. ;LSX5030 end
  188. stdENDP _HalInitializeProcessor
  189. ;++
  190. ;
  191. ; VOID
  192. ; HalRequestIpi(
  193. ; IN ULONG Mask
  194. ; );
  195. ;
  196. ;Routine Description:
  197. ;
  198. ; Requests an interprocessor interrupt
  199. ;
  200. ;Arguments:
  201. ;
  202. ; Mask - Supplies a mask of the processors to be interrupted
  203. ;
  204. ;Return Value:
  205. ;
  206. ; None.
  207. ;
  208. ;--
  209. cPublicProc _HalRequestIpi,1
  210. movzx ecx, byte ptr [esp+4] ; (eax) = Processor bitmask
  211. ifdef DBG
  212. or ecx, ecx ; must ipi somebody
  213. jz short ipibad
  214. movzx eax, byte ptr fs:PcHal.PcrNumber
  215. bt ecx, eax ; cannot ipi yourself
  216. jc short ipibad
  217. endif
  218. @@:
  219. movzx eax, _HalpFindFirstSetRight[ecx] ; lookup first processor to ipi
  220. btr ecx, eax
  221. mov dx, ProcessorControlPort[eax*2]
  222. in al, dx ; (al) = original content of PCP
  223. or al, PINT ; generate Ipi on target
  224. out dx, al
  225. or ecx, ecx ; ipi any other processors?
  226. jnz @b ; yes, loop
  227. stdRET _HalRequestIpi
  228. ifdef DBG
  229. ipibad: int 3
  230. stdRET _HalRequestIpi
  231. endif
  232. stdENDP _HalRequestIpi
  233. page ,132
  234. subttl "LSX5030 Inter-Processor Interrupt Handler"
  235. ;LSX5030 start
  236. ;++
  237. ;
  238. ; VOID
  239. ; HalpIpiHandler (
  240. ; );
  241. ;
  242. ; Routine Description:
  243. ;
  244. ; This routine is entered as the result of an interrupt generated by inter
  245. ; processor communication.
  246. ; The interrupt is dismissed.
  247. ;
  248. ; Arguments:
  249. ;
  250. ; None.
  251. ;
  252. ; Return Value:
  253. ;
  254. ; None.
  255. ;
  256. ;--
  257. ENTER_DR_ASSIST Hixx_a, Hixx_t
  258. cPublicProc _HalpIpiHandler,0
  259. ;
  260. ; Save machine state in trap frame
  261. ;
  262. ENTER_INTERRUPT Hixx_a, Hixx_t ; (ebp) -> Trap frame
  263. ;
  264. ; Save previous IRQL
  265. ;
  266. mov eax, _IdtIpiVector
  267. push eax ; Vector
  268. sub esp, 4 ; space for OldIrql
  269. ;DBG_DISPLAY 90h
  270. ; Dismiss interrupt.
  271. ;
  272. mov dx, fs:PcHal.PcrControlPort
  273. in al, dx
  274. ;
  275. ; Dismiss the interprocessor interrupt and call its handler
  276. ;
  277. and al, not PINT
  278. out dx, al ; clear PINT
  279. ;DBG_DISPLAY 91h
  280. mov eax, _IdtIpiVector
  281. ; esp - stack location of OldIrql
  282. ; eax - vector
  283. ; IPI_LEVEL - Irql
  284. stdCall _HalBeginSystemInterrupt,<IPI_LEVEL,eax,esp>
  285. ;DBG_DISPLAY 92h
  286. ; Pass Null ExceptionFrame
  287. ; Pass TrapFrame to Ipi service rtn
  288. stdCall _KiIpiServiceRoutine ,<ebp,0>
  289. ;
  290. ; Do interrupt exit processing
  291. ;
  292. ;DBG_DISPLAY 9fh
  293. INTERRUPT_EXIT ; will return to caller
  294. stdENDP _HalpIpiHandler
  295. ifdef HALOLI_DBG
  296. ;++
  297. ;
  298. ; DbgDisplay (
  299. ; IN UCHAR DisplayCode
  300. ; )
  301. ;
  302. ; Description:
  303. ;
  304. ; This function writes 'DisplayCode' to the parallel port, where a LED
  305. ; display can be plugged in to show such a code.
  306. ; In order to allow the user to read the code on the LED display,
  307. ; after writing, a delay is introduced.
  308. ;
  309. ; Arguments:
  310. ; DisplayCode - Byte to write to the parallel port
  311. ;
  312. ; Return Value:
  313. ; None.
  314. ;
  315. ;--
  316. public _DbgDisplay
  317. _DbgDisplay proc
  318. push eax
  319. push edx
  320. ; signal something on the parallel port
  321. mov dx, 378h
  322. mov eax, [esp+12]
  323. out dx, al
  324. mov eax, DbgDelay
  325. @@:
  326. dec eax
  327. cmp eax, 0
  328. jne @b
  329. pop edx
  330. pop eax
  331. ret
  332. _DbgDisplay endp
  333. endif ; HALOLI_DBG
  334. ; ULONG
  335. ; HalpGetIpiIrqNumber (
  336. ; );
  337. ;
  338. ; Routine Description:
  339. ;
  340. ; This routine is entered during the phase 0 initialization of the
  341. ; first processor. It determines the IRQ # for IPI's.
  342. ; The IPI IRQ is stored in the PCR's by the LSX5030 configuration
  343. ; utility.
  344. ;
  345. ; Arguments:
  346. ;
  347. ; None.
  348. ;
  349. ; Return Value:
  350. ;
  351. ; The IPI IRQ# in eax.
  352. ;
  353. ;--
  354. cPublicProc _HalpGetIpiIrqNumber,0
  355. mov dx, word ptr ProcessorControlPort ; get 1st CPU slot #
  356. in al, dx ; get PCR content
  357. ; determine which IRQ for IPI has been set by the user
  358. shr eax, 2 ; bits 0,1 encode the IPI IRQ
  359. and eax, 3 ; zero all the bits but 0,1
  360. movzx ecx, byte ptr PcrIpiIrql[eax] ; decode the IRQ
  361. push ecx
  362. ; edit the 8259 mask table to unmask IPI's from IPI_LEVEL-1 down
  363. mov edx, 1
  364. shl edx, cl
  365. not edx ; mask with IPI IRQ# bit set to
  366. ; 0
  367. ; mov eax, IPI_LEVEL
  368. ; sub eax, ecx
  369. lea eax, KiI8259MaskTable ; start from the beginning
  370. ; lea eax, KiI8259MaskTable[eax*4] ; start from
  371. ; IPI_LEVEL - IPI_IRQ#
  372. mov ecx, IPI_LEVEL
  373. NextEntry:
  374. and [eax], edx
  375. add eax, 4
  376. dec ecx ; loop for IPI IRQ# times
  377. jnz NextEntry
  378. pop eax ; return IPI IRQ#
  379. stdRET _HalpGetIpiIrqNumber
  380. stdENDP _HalpGetIpiIrqNumber
  381. page ,132
  382. subttl "Irq13 Interrupt Handler"
  383. ;++
  384. ;
  385. ; VOID
  386. ; HalpIrq13Handler (
  387. ; );
  388. ;
  389. ; Routine Description:
  390. ;
  391. ; This routine is entered as the result of an interrupt generated by
  392. ; coprocessor error,
  393. ; This routine will lower irql to its original level, and finally invoke
  394. ; coprocessor error handler. By doing this, the coprocessor
  395. ; error will be handled at Irql 0 as it should be.
  396. ;
  397. ; Arguments:
  398. ;
  399. ; None.
  400. ; Interrupt is dismissed
  401. ;
  402. ; Return Value:
  403. ;
  404. ; None.
  405. ;
  406. ;--
  407. ENTER_DR_ASSIST Hi13_a, Hi13_t
  408. cPublicProc _HalpIrq13Handler,0
  409. ;
  410. ; Save machine state in trap frame
  411. ;
  412. ENTER_INTERRUPT Hi13_a, Hi13_t ; (ebp) -> Trap frame
  413. ;
  414. ; Save previous IRQL
  415. ;
  416. push 13 + PRIMARY_VECTOR_BASE ; Vector
  417. sub esp, 4 ; space for OldIrql
  418. ;
  419. ; Dismiss interrupt.
  420. ; location for OldIrql
  421. ; Vector
  422. ; Irql
  423. stdCall _HalBeginSystemInterrupt,<IPI_LEVEL,13+PRIMARY_VECTOR_BASE,esp>
  424. stdCall _KiCoprocessorError ; call CoprocessorError handler
  425. ;
  426. ; Do interrupt exit processing
  427. ;
  428. INTERRUPT_EXIT ; will return to caller
  429. stdENDP _HalpIrq13Handler
  430. ;LSX5030 end
  431. _TEXT ENDS
  432. END