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.

314 lines
8.0 KiB

  1. title "MP primitives for MP+AT Systems"
  2. ;++
  3. ;
  4. ;Copyright (c) 1991 Microsoft Corporation
  5. ;Copyright (c) 1992 Intel Corporation
  6. ;All rights reserved
  7. ;
  8. ;INTEL CORPORATION PROPRIETARY INFORMATION
  9. ;
  10. ;This software is supplied to Microsoft under the terms
  11. ;of a license agreement with Intel Corporation and may not be
  12. ;copied nor disclosed except in accordance with the terms
  13. ;of that agreement.
  14. ;
  15. ;
  16. ;Module Name:
  17. ;
  18. ; mpsproca.asm
  19. ;
  20. ;Abstract:
  21. ;
  22. ; PC+MP Start Next Processor assemble code
  23. ;
  24. ; This module along with mpspro.c implement the code to start
  25. ; processors on MP+AT Systems.
  26. ;
  27. ;Author:
  28. ;
  29. ; Ken Reneris (kenr) 12-Jan-1992
  30. ;
  31. ;Revision History:
  32. ;
  33. ; Ron Mosgrove (Intel) - Modified to support PC+MP Systems
  34. ;
  35. ;--
  36. .386p
  37. .xlist
  38. include i386\ixcmos.inc
  39. include hal386.inc
  40. include callconv.inc ; calling convention macros
  41. include i386\kimacro.inc
  42. include mac386.inc
  43. include apic.inc
  44. include ntapic.inc
  45. include i386\ixslpctx.inc
  46. .list
  47. ifndef NT_UP
  48. EXTRNP _HalpBuildTiledCR3,1
  49. EXTRNP _HalpFreeTiledCR3,0
  50. EXTRNP _HalpStartProcessor,2
  51. endif
  52. EXTRNP _HalpAcquireCmosSpinLock
  53. EXTRNP _HalpReleaseCmosSpinLock
  54. EXTRNP _HalDisplayString,1
  55. EXTRNP _HalpMarkProcessorStarted,2
  56. EXTRNP _StartPx_BuildRealModeStart,1
  57. EXTRNP _KeStallExecutionProcessor, 1
  58. extrn _Halp1stPhysicalPageVaddr:DWORD
  59. extrn _HalpLowStub:DWORD
  60. extrn _HalpLowStubPhysicalAddress:DWORD
  61. extrn _HalpHiberInProgress:BYTE
  62. extrn _CurTiledCr3LowPart:DWORD
  63. ;
  64. ; Internal defines and structures
  65. ;
  66. WarmResetVector equ 467h ; warm reset vector in ROM data segment
  67. PAGELK SEGMENT PARA PUBLIC 'CODE' ; Start 32 bit code
  68. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  69. ;++
  70. ;
  71. ; BOOLEAN
  72. ; HalStartNextProcessor (
  73. ; IN PLOADER_BLOCK pLoaderBlock,
  74. ; IN PKPROCESSOR_STATE pProcessorState
  75. ; )
  76. ;
  77. ; Routine Description:
  78. ;
  79. ; This routine is called by the kernel durning kernel initialization
  80. ; to obtain more processors. It is called until no more processors
  81. ; are available.
  82. ;
  83. ; If another processor exists this function is to initialize it to
  84. ; the passed in processorstate structure, and return TRUE.
  85. ;
  86. ; If another processor does not exists or if the processor fails to
  87. ; start, then a FALSE is returned.
  88. ;
  89. ; Also note that the loader block has been setup for the next processor.
  90. ; The new processor logical thread number can be obtained from it, if
  91. ; required.
  92. ;
  93. ; In order to use the Startup IPI the real mode startup code must be
  94. ; page aligned. The HalpLowStubPhysicalAddress has always been page
  95. ; aligned but because the PxParamBlock was placed first in this
  96. ; segment the real mode code has been something other than page aligned.
  97. ; This has been changed by making the first entry in the PxParamBlock
  98. ; a jump instruction to the real mode startup code.
  99. ;
  100. ; Arguments:
  101. ; pLoaderBlock, - Loader block which has been intialized for the
  102. ; next processor.
  103. ;
  104. ; pProcessorState - The processor state which is to be loaded into
  105. ; the next processor.
  106. ;
  107. ;
  108. ; Return Value:
  109. ;
  110. ; TRUE - ProcessorNumber was dispatched.
  111. ; FALSE - A processor was not dispatched. no other processors exists.
  112. ;
  113. ;--
  114. pLoaderBlock equ dword ptr [ebp+8] ; zero based
  115. pProcessorState equ dword ptr [ebp+12]
  116. ;
  117. ; Local variables
  118. ;
  119. PxFrame equ [ebp - size PxParamBlock]
  120. LWarmResetVector equ [ebp - size PxParamBlock - 4]
  121. LStatusCode equ [ebp - size PxParamBlock - 8]
  122. LCmosValue equ [ebp - size PxParamBlock - 12]
  123. Prcb equ [ebp - size PxParamBlock - 16]
  124. cPublicProc _HalStartNextProcessor ,2
  125. ifdef NT_UP
  126. xor eax, eax ; up build of hal, no processors to
  127. stdRET _HalStartNextProcessor ; start
  128. else
  129. push ebp ; save ebp
  130. mov ebp, esp ; Save Frame
  131. sub esp, size PxParamBlock + 16 ; Make room for local vars
  132. push esi ; Save required registers
  133. push edi
  134. push ebx
  135. pushfd
  136. xor eax, eax
  137. mov LStatusCode, eax
  138. mov PxFrame.SPx_flag, eax ; Initialize the MP Completion flag
  139. ;
  140. ; Copy Processor state into the stack based Parameter Block
  141. ;
  142. lea edi, PxFrame.SPx_PB ; Destination on stack
  143. mov esi, pProcessorState ; Input parameter address
  144. mov ecx, ProcessorStateLength ; Structure length
  145. rep movsb
  146. ;
  147. ; Build a CR3 for the starting processor. If returning
  148. ; from hibernation, then use setup tiled CR3 else
  149. ; create a new map
  150. ;
  151. mov al, _HalpHiberInProgress
  152. or al, al
  153. jz Hpsnp_Hiber
  154. mov eax, _CurTiledCr3LowPart
  155. jmp Hpsnp_TiledCr3_done
  156. Hpsnp_Hiber:
  157. stdCall _HalpBuildTiledCR3, <pProcessorState>
  158. Hpsnp_TiledCr3_done:
  159. ;
  160. ; Save the special registers
  161. ;
  162. mov PxFrame.SPx_TiledCR3, eax ; Newly contructed CR3
  163. mov PxFrame.SPx_P0EBP, ebp ; Stack pointer
  164. lea eax, PxFrame
  165. stdCall _StartPx_BuildRealModeStart, <eax>
  166. ;
  167. ; Set the BIOS warm reset vector to our routine in Low Memory
  168. ;
  169. mov ebx, _Halp1stPhysicalPageVaddr
  170. add ebx, WarmResetVector
  171. cli
  172. mov eax, [ebx] ; Get current vector
  173. mov LWarmResetVector, eax ; Save it
  174. ;
  175. ; Actually build the vector (Seg:Offset)
  176. ;
  177. mov eax, _HalpLowStubPhysicalAddress
  178. shl eax, 12 ; seg:0
  179. mov dword ptr [ebx], eax ; start Px at Seg:0
  180. ;
  181. ; Tell BIOS to Jump Via The Vector we gave it
  182. ; By setting the Reset Code in CMOS
  183. ;
  184. stdCall _HalpAcquireCmosSpinLock
  185. mov al, 0fh
  186. CMOS_READ
  187. mov LCmosValue, eax
  188. mov eax, 0a0fh
  189. CMOS_WRITE
  190. stdCall _HalpReleaseCmosSpinLock
  191. ;
  192. ; Start the processor
  193. ;
  194. mov eax, pLoaderBlock ; lookup processor # we are
  195. mov eax, [eax].LpbPrcb ; starting
  196. mov Prcb, eax ; save this away for later
  197. movzx eax, byte ptr [eax].PbNumber
  198. stdCall _HalpStartProcessor < _HalpLowStubPhysicalAddress, eax >
  199. or eax, eax
  200. jnz short WaitTilPnOnline
  201. ;
  202. ; Zero Return Value means couldn't kick start the processor
  203. ; so there's no point in waiting for it.
  204. ;
  205. jmp NotWaitingOnProcessor
  206. WaitTilPnOnline:
  207. dec eax ; Local APIC ID
  208. mov ecx, Prcb
  209. mov [ecx].PbHalReserved.PrcbPCMPApicId, al
  210. ;
  211. ; We can't proceed until the started processor gives us the OK
  212. ;
  213. mov edi, 200
  214. mov esi, _HalpLowStub
  215. WaitAbit:
  216. cmp [esi].SPx_flag, 0 ; wait for Px to get it's
  217. jne short ProcessorStarted ; info
  218. stdCall _KeStallExecutionProcessor, <2000>
  219. dec edi
  220. cmp edi, 0
  221. jne short WaitAbit
  222. jmp short NotWaitingOnProcessor
  223. ProcessorStarted:
  224. mov LStatusCode, 1 ; Return TRUE
  225. mov ecx, Prcb ; save this away for later
  226. movzx ecx, byte ptr [ecx].PbNumber
  227. stdCall _HalpMarkProcessorStarted, <eax, ecx>
  228. NotWaitingOnProcessor:
  229. mov al, _HalpHiberInProgress
  230. or al, al
  231. jnz short Hpsnp_ResetVector
  232. stdCall _HalpFreeTiledCR3 ; free memory used for tiled CR3
  233. Hpsnp_ResetVector:
  234. mov eax, LWarmResetVector
  235. mov [ebx], eax ; Restore reset vector
  236. stdCall _HalpAcquireCmosSpinLock
  237. mov eax, LCmosValue ; Restore the Cmos setting
  238. shl eax, 8
  239. mov al, 0fh
  240. CMOS_WRITE
  241. stdCall _HalpReleaseCmosSpinLock
  242. mov eax, LStatusCode
  243. snp_exit:
  244. popfd
  245. pop ebx
  246. pop edi
  247. pop esi
  248. mov esp, ebp
  249. pop ebp
  250. stdRET _HalStartNextProcessor
  251. endif
  252. stdENDP _HalStartNextProcessor
  253. PAGELK ends ; end 32 bit code
  254. end