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.

478 lines
14 KiB

4 years ago
  1. title "MP primitives for Compaq SystemPro"
  2. ;++
  3. ;
  4. ;Copyright (c) 1991 Microsoft Corporation
  5. ;
  6. ;Module Name:
  7. ;
  8. ; oliproca.asm
  9. ;
  10. ;Abstract:
  11. ;
  12. ; SystemPro Start Next Processor assemble code
  13. ;
  14. ; This module along with mpspro.c implement the code to start
  15. ; off the second processor on the Compaq SystemPro.
  16. ;
  17. ;Author:
  18. ;
  19. ; Ken Reneris (kenr) 12-Jan-1992
  20. ;
  21. ; Bruno Sartirana (o-obruno) 3-Mar-92
  22. ; Added support for the Olivetti LSX5030.
  23. ;
  24. ;Revision History:
  25. ;
  26. ;--
  27. .386p
  28. .xlist
  29. include hal386.inc
  30. include callconv.inc
  31. include i386\kimacro.inc
  32. include mac386.inc
  33. ;LSX5030 start
  34. include i386\ix8259.inc
  35. include i386\olimp.inc
  36. ;LSX5030 end
  37. .list
  38. EXTRNP _HalpBuildTiledCR3,1
  39. EXTRNP _HalpFreeTiledCR3,0
  40. extrn _MppIDT:DWORD
  41. extrn _MpLowStub:DWORD
  42. extrn _MpLowStubPhysicalAddress:DWORD
  43. extrn ProcessorControlPort:WORD
  44. ;LSX5030 start
  45. extrn _CpuLeft:DWORD
  46. extrn _NextCpuToStart:DWORD
  47. extrn DbgDelay:DWORD
  48. ;LSX5030 end
  49. ;
  50. ; Internal defines and structures
  51. ;
  52. PxParamBlock struc
  53. SPx_flag dd ?
  54. SPx_TiledCR3 dd ?
  55. SPx_P0EBP dd ?
  56. SPx_ControlPort dd ?
  57. SPx_PB db processorstatelength dup (?)
  58. PxParamBlock ends
  59. _TEXT SEGMENT PARA PUBLIC 'CODE' ; Start 32 bit code
  60. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  61. ;++
  62. ;
  63. ; BOOLEAN
  64. ; HalStartNextProcessor (
  65. ; IN PLOADER_BLOCK pLoaderBlock,
  66. ; IN PKPROCESSOR_STATE pProcessorState
  67. ; )
  68. ;
  69. ; Routine Description:
  70. ;
  71. ; This routine is called by the kernel durning kernel initialization
  72. ; to obtain more processors. It is called until no more processors
  73. ; are available.
  74. ;
  75. ; If another processor exists this function is to initialize it to
  76. ; the passed in processorstate structure, and return TRUE.
  77. ;
  78. ; If another processor does not exists, then a FALSE is returned.
  79. ;
  80. ; Also note that the loader block has been setup for the next processor.
  81. ; The new processor logical thread number can be obtained from it, if
  82. ; required.
  83. ;
  84. ; Arguments:
  85. ; pLoaderBlock, - Loader block which has been intialized for the
  86. ; next processor.
  87. ;
  88. ; pProcessorState - The processor state which is to be loaded into
  89. ; the next processor.
  90. ;
  91. ;
  92. ; Return Value:
  93. ;
  94. ; TRUE - ProcessorNumber was dispatched.
  95. ; FALSE - A processor was not dispatched. no other processors exists.
  96. ;
  97. ;--
  98. pLoaderBlock equ dword ptr [ebp+8] ; zero based
  99. pProcessorState equ dword ptr [ebp+12]
  100. ;
  101. ; Local variables
  102. ;
  103. PxFrame equ [ebp - size PxParamBlock]
  104. cPublicProc _HalStartNextProcessor ,2
  105. push ebp ; save ebp
  106. mov ebp, esp ;
  107. sub esp, size PxParamBlock ; Make room for local vars
  108. DBG_DISPLAY 0f0h
  109. push esi
  110. push edi
  111. push ebx
  112. xor eax, eax
  113. mov PxFrame.SPx_flag, eax
  114. cmp _CpuLeft, eax
  115. je snp_exit ; exit FALSE
  116. mov esi, OFFSET FLAT:StartPx_RMStub
  117. mov ecx, StartPx_RMStub_Len
  118. mov edi, _MpLowStub ; Copy RMStub to low memory
  119. add edi, size PxParamBlock
  120. rep movsb
  121. lea edi, PxFrame.SPx_PB
  122. mov esi, pProcessorState
  123. mov ecx, processorstatelength ; Copy processorstate
  124. rep movsb ; to PxFrame
  125. stdCall _HalpBuildTiledCR3,<pProcessorState>
  126. mov PxFrame.SPx_TiledCR3, eax
  127. mov PxFrame.SPx_P0EBP, ebp
  128. mov eax, pLoaderBlock ; lookup processor # we are
  129. mov eax, [eax].LpbPrcb ; starting
  130. movzx eax, byte ptr [eax].PbNumber
  131. movzx edx, ProcessorControlPort[eax*2] ; Get processor's control port
  132. mov PxFrame.SPx_ControlPort, edx ; Pass it along
  133. mov ecx, size PxParamBlock ; copy param block
  134. lea esi, PxFrame ; to low memory stub
  135. mov edi, _MpLowStub
  136. mov eax, edi
  137. rep movsb
  138. add eax, size PxParamBlock
  139. mov ebx, OFFSET FLAT:StartPx_RMStub
  140. sub eax, ebx ; (eax) = adjusted pointer
  141. mov bx, word ptr [PxFrame.SPx_PB.PsContextFrame.CsSegCs]
  142. mov [eax.SPrxFlatCS], bx ; patch realmode stub with
  143. mov [eax.SPrxPMStub], offset _StartPx_PMStub ; valid long jump
  144. mov ebx, _MppIDT
  145. add ebx, WarmResetVector
  146. cli
  147. push dword ptr [ebx] ; Save current vector
  148. mov eax, _MpLowStubPhysicalAddress
  149. shl eax, 12 ; seg:0
  150. add eax, size PxParamBlock
  151. mov dword ptr [ebx], eax ; start Px here
  152. ;LSX5030 start
  153. mov eax, _NextCpuToStart
  154. mov dx, word ptr ProcessorControlPort[eax*2]
  155. in al, dx
  156. or al, RESET ; assert RESET
  157. out dx, al
  158. and al, not RESET ; the 1-0 transition of PCR
  159. ; reset bit resets the
  160. ; processor
  161. out dx, al ; reset processor
  162. ;LSX5030 end
  163. @@:
  164. cmp PxFrame.SPx_flag, 0 ; wait for Px to get it's
  165. jz @b ; info
  166. pop dword ptr [ebx] ; restore WarmResetVector
  167. sti
  168. stdCall _HalpFreeTiledCR3 ; free memory used for tiled
  169. ; CR3
  170. ;LSX5030 start
  171. DBG_DISPLAY 0ffh
  172. dec _CpuLeft ; one less
  173. inc _NextCpuToStart ; next CPU # to start
  174. ;LSX5030 end
  175. mov eax, 1 ; return TRUE
  176. snp_exit:
  177. DBG_DISPLAY 0feh
  178. pop ebx
  179. pop edi
  180. pop esi
  181. mov esp, ebp
  182. pop ebp
  183. stdRET _HalStartNextProcessor
  184. _HalStartNextProcessor endp
  185. _TEXT ends ; end 32 bit code
  186. _TEXT16 SEGMENT DWORD PUBLIC USE16 'CODE' ; start 16 bit code
  187. ;++
  188. ;
  189. ; VOID
  190. ; StartPx_RMStub
  191. ;
  192. ; Routine Description:
  193. ;
  194. ; When a new processor is started, it starts in real-mode and is
  195. ; sent to a copy of this function which has been copied into low memory.
  196. ; (below 1m and accessable from real-mode).
  197. ;
  198. ; Once CR0 has been set, this function jmp's to a StartPx_PMStub
  199. ;
  200. ; Arguments:
  201. ; none
  202. ;
  203. ; Return Value:
  204. ; does not return, jumps to StartPx_PMStub
  205. ;
  206. ;--
  207. cPublicProc StartPx_RMStub,0
  208. cli
  209. db 066h ; load the GDT
  210. lgdt fword ptr cs:[SPx_PB.PsSpecialRegisters.SrGdtr]
  211. db 066h ; load the IDT
  212. lidt fword ptr cs:[SPx_PB.PsSpecialRegisters.SrIdtr]
  213. mov eax, cs:[SPx_TiledCR3]
  214. mov cr3, eax
  215. mov ebp, dword ptr cs:[SPx_P0EBP]
  216. mov ecx, dword ptr cs:[SPx_PB.PsContextFrame.CsSegDs]
  217. mov ebx, dword ptr cs:[SPx_PB.PsSpecialRegisters.SrCr3]
  218. mov eax, dword ptr cs:[SPx_PB.PsSpecialRegisters.SrCr0]
  219. mov cr0, eax ; into prot mode
  220. db 066h
  221. db 0eah ; reload cs:eip
  222. SPrxPMStub dd 0
  223. SPrxFlatCS dw 0
  224. StartPx_RMStub_Len equ $ - StartPx_RMStub
  225. stdENDP StartPx_RMStub
  226. _TEXT16 ends ; End 16 bit code
  227. _TEXT SEGMENT ; Start 32 bit code
  228. ;++
  229. ;
  230. ; VOID
  231. ; StartPx_PMStub
  232. ;
  233. ; Routine Description:
  234. ;
  235. ; This function completes the processor's state loading, and signals
  236. ; the requesting processor that the state has been loaded.
  237. ;
  238. ; Arguments:
  239. ; ebx - requested CR3 for this processors_state
  240. ; cx - requested ds for this processors_state
  241. ; ebp - EBP of P0
  242. ;
  243. ; Return Value:
  244. ; does not return - completes the loading of the processors_state
  245. ;
  246. ;--
  247. align 16 ; to make sure we don't cross a page boundry
  248. ; before reloading CR3
  249. public _StartPx_PMStub
  250. _StartPx_PMStub proc
  251. ; process is now in the load image copy of this function.
  252. ; (ie, it's not the low memory copy)
  253. mov cr3, ebx ; get real CR3
  254. mov ds, cx ; set real ds
  255. lea esi, PxFrame.SPx_PB.PsSpecialRegisters
  256. lldt word ptr ds:[esi].SrLdtr ; load ldtr
  257. ltr word ptr ds:[esi].SrTr ; load tss
  258. lea edi, PxFrame.SPx_PB.PsContextFrame
  259. mov es, word ptr ds:[edi].CsSegEs ; Set other selectors
  260. mov fs, word ptr ds:[edi].CsSegFs
  261. mov gs, word ptr ds:[edi].CsSegGs
  262. mov ss, word ptr ds:[edi].CsSegSs
  263. add esi, SrKernelDr0
  264. .errnz (SrKernelDr1 - SrKernelDr0 - 1 * 4)
  265. .errnz (SrKernelDr2 - SrKernelDr0 - 2 * 4)
  266. .errnz (SrKernelDr3 - SrKernelDr0 - 3 * 4)
  267. .errnz (SrKernelDr6 - SrKernelDr0 - 4 * 4)
  268. .errnz (SrKernelDr7 - SrKernelDr0 - 5 * 4)
  269. lodsd
  270. mov dr0, eax ; load dr0-dr7
  271. lodsd
  272. mov dr1, eax
  273. lodsd
  274. mov dr2, eax
  275. lodsd
  276. mov dr3, eax
  277. lodsd
  278. mov dr6, eax
  279. lodsd
  280. mov dr7, eax
  281. mov esp, dword ptr ds:[edi].CsEsp
  282. mov esi, dword ptr ds:[edi].CsEsi
  283. mov ecx, dword ptr ds:[edi].CsEcx
  284. push dword ptr ds:[edi].CsEflags
  285. popfd ; load eflags
  286. push dword ptr ds:[edi].CsEip ; make a copy of remaining
  287. push dword ptr ds:[edi].CsEax ; registers which need
  288. push dword ptr ds:[edi].CsEbx ; loaded
  289. push dword ptr ds:[edi].CsEdx
  290. push dword ptr ds:[edi].CsEdi
  291. push dword ptr ds:[edi].CsEbp
  292. ; eax, ebx, edx are still free
  293. ;LSX5030 start
  294. mov eax, _NextCpuToStart
  295. mov dx, word ptr ProcessorControlPort[eax*2]
  296. in al, dx ; Get register
  297. and al, not IPI_EN ; disable PINTs for now
  298. out dx, al
  299. ;and dx, Px_SLOT_MASK ; get processor slot (olibus)
  300. ;or dx, LEV2_CACHE_REG ; calculate address of the 2nd
  301. ; level cache policy register
  302. ; for this processor
  303. ;in al, dx ; Get register
  304. ;and al, not LEV2_CACHE_ON ; turn cache off
  305. ;or al, LEV2_CACHE_ON ; turn cache on
  306. ;out dx, al
  307. ;and dx, Px_SLOT_MASK ; get processor slot (olibus)
  308. ;or dx, SLOT_CONFIG_REG_0 ; calculate address of
  309. ; configuration register 0 for
  310. ; this processor
  311. ;in al, dx ; get register
  312. ;and al, not INTERNAL_CACHE_ON ; turn internal cache off
  313. ;or al, INTERNAL_CACHE_ON ; turn processor's internal
  314. ; cache on
  315. ;out dx, al
  316. ;DBG_DISPLAY 0b0h
  317. ; sti
  318. inc [PxFrame.SPx_flag] ; Signal p0 that we are
  319. ; done with its data
  320. ;DBG_DISPLAY 0bfh
  321. ;LSX5030 end
  322. ; Set remaining registers
  323. pop ebp
  324. pop edi
  325. pop edx
  326. pop ebx
  327. pop eax
  328. ret ; Set eip
  329. _StartPx_PMStub endp
  330. ;LSX5030 start
  331. ;++
  332. ;
  333. ; ULONG
  334. ; HalpGetNumberOfProcessors()
  335. ;
  336. ; Routine Description:
  337. ;
  338. ; This routine queries the CMOS to determine the number of processors
  339. ; that can be started.
  340. ; Also, it rearranges the ProcessorControlPort array to make it
  341. ; non-sparse. This means that, eventually, ProcessorControlPort[n]
  342. ; will contain the slot # of the processor n, where n=0,1,2,3.
  343. ; For example, if the machine has two processors, one in slot 0 and
  344. ; the other in slot 3, only the ProcessorControlPort array elements
  345. ; #0 and #1 will be meaningful.
  346. ;
  347. ; Arguments:
  348. ;
  349. ; None.
  350. ;
  351. ; Return Value:
  352. ;
  353. ; The number of available processors in register eax.
  354. ;
  355. ;--
  356. cPublicProc _HalpGetNumberOfProcessors,0
  357. push ebx
  358. push ecx
  359. push edx
  360. mov al, CMOS_GET_MP_STATUS
  361. CMOS_READ
  362. mov ch, al ; al[7-4] = CPU card present bits
  363. ; al[3-0] = CPU diagnostics passed bits
  364. shr al, 4 ; al[3-0] = CPU card present bits
  365. mov cl, al ; ch[3-0] = CPU card diag passed bits
  366. ; cl[3-0] = CPU card present bits
  367. and cl, ch ; CPUs actually available (bit mapped)
  368. mov edx, 1 ; there's always the CPU0, so skip it
  369. mov eax, 1 ; logical processor #
  370. NextCPU:
  371. bt ecx, edx
  372. jnc IncLoopCounter
  373. mov bx, word ptr ProcessorControlPort[edx*2] ; get address of
  374. ; PCP #edx
  375. mov word ptr ProcessorControlPort[eax*2], bx ; set PCP address
  376. ; for processor #eax
  377. inc eax
  378. IncLoopCounter:
  379. inc edx
  380. cmp edx, MAX_NUMBER_PROCESSORS
  381. jl NextCPU
  382. pop edx
  383. pop ecx
  384. pop ebx
  385. stdRET _HalpGetNumberOfProcessors
  386. stdENDP _HalpGetNumberOfProcessors
  387. ;LSX5030 end
  388. _TEXT ends ; end 32 bit code
  389. end