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.

433 lines
6.8 KiB

  1. TITLE "AMD64 Support Routines"
  2. ;++
  3. ;
  4. ; Copyright (c) 2000 Microsoft Corporation
  5. ;
  6. ; Module Name:
  7. ;
  8. ; miscs.asm
  9. ;
  10. ; Abstract:
  11. ;
  12. ; This module implements various routines for the AMD64 that must be
  13. ; written in assembler.
  14. ;
  15. ; Author:
  16. ;
  17. ; Forrest Foltz (forrestf) 14-Oct-2000
  18. ;
  19. ; Environment:
  20. ;
  21. ; Kernel mode only.
  22. ;
  23. ;--
  24. include kxamd64.inc
  25. include ksamd64.inc
  26. extern HalpMcaExceptionHandler:proc
  27. ;++
  28. ;
  29. ; ULONG
  30. ; HalpGetprocessorFlags(
  31. ; VOID
  32. ; )
  33. ;
  34. ; Routine Description:
  35. ;
  36. ; This function retrieves and returns the contents of the processor's
  37. ; flag register.
  38. ;
  39. ; Arguments:
  40. ;
  41. ; None.
  42. ;
  43. ; Return Value:
  44. ;
  45. ; The contents of the processor's flag register.
  46. ;
  47. ;--
  48. HdiFrame struct
  49. FlagsLow dd ? ; processor flags, low
  50. FlagsHi dd ? ; processor flags, high
  51. HdiFrame ends
  52. NESTED_ENTRY HalpGetProcessorFlags, _TEXT$00
  53. push_eflags ; get processor flags
  54. END_PROLOGUE
  55. pop rax
  56. ret
  57. NESTED_END HalpGetProcessorFlags, _TEXT$00
  58. ;++
  59. ;
  60. ; VOID
  61. ; HalProcessorIdle(
  62. ; VOID
  63. ; )
  64. ;
  65. ; Routine Description:
  66. ;
  67. ; This function is called when the current processor is idle.
  68. ;
  69. ; This function is called with interrupts disabled, and the processor
  70. ; is idle until it receives an interrupt. The does not need to return
  71. ; until an interrupt is received by the current processor.
  72. ;
  73. ; This is the lowest level of processor idle. It occurs frequently,
  74. ; and this function (alone) should not put the processor into a
  75. ; power savings mode which requeres large amount of time to enter & exit.
  76. ;
  77. ; Return Value:
  78. ;
  79. ;--
  80. LEAF_ENTRY HalProcessorIdle, _TEXT$00
  81. ;
  82. ; the following code sequence "sti-halt" puts the processor
  83. ; into a Halted state, with interrupts enabled, without processing
  84. ; an interrupt before halting. The STI instruction has a delay
  85. ; slot such that it does not take effect until after the instruction
  86. ; following it - this has the effect of HALTing without allowing
  87. ; a possible interrupt and then enabling interrupts while HALTed.
  88. ;
  89. ;
  90. ; On an MP hal we don't stop the processor, since that causes
  91. ; the SNOOP to slow down as well
  92. ;
  93. sti
  94. ifdef NT_UP
  95. hlt
  96. endif
  97. ;
  98. ; Now return to the system. If there's still no work, then it
  99. ; will call us back to halt again.
  100. ;
  101. ret
  102. LEAF_END HalProcessorIdle, _TEXT$00
  103. ;++
  104. ;
  105. ; VOID
  106. ; HalpGenerateAPCInterrupt(
  107. ; VOID
  108. ; )
  109. ;
  110. ; Routine Description:
  111. ;
  112. ; This function generates an APC software interrupt.
  113. ;
  114. ; Arguments:
  115. ;
  116. ; None.
  117. ;
  118. ; Return Value:
  119. ;
  120. ; None.
  121. ;
  122. ;--
  123. LEAF_ENTRY HalpGenerateAPCInterrupt, _TEXT$00
  124. int 1
  125. ret
  126. LEAF_END HalpGenerateAPCInterrupt, _TEXT$00
  127. ;++
  128. ;
  129. ; VOID
  130. ; HalpGenerateDPCInterrupt(
  131. ; VOID
  132. ; )
  133. ;
  134. ; Routine Description:
  135. ;
  136. ; This function generates an DPC software interrupt.
  137. ;
  138. ; Arguments:
  139. ;
  140. ; None.
  141. ;
  142. ; Return Value:
  143. ;
  144. ; None.
  145. ;
  146. ;--
  147. LEAF_ENTRY HalpGenerateDPCInterrupt, _TEXT$00
  148. int 2
  149. ret
  150. LEAF_END HalpGenerateDPCInterrupt, _TEXT$00
  151. ;++
  152. ;
  153. ; VOID
  154. ; HalpGenerateUnexpectedInterrupt(
  155. ; VOID
  156. ; )
  157. ;
  158. ; Routine Description:
  159. ;
  160. ; This function generates an unexpected software interrupt.
  161. ;
  162. ; Arguments:
  163. ;
  164. ; None.
  165. ;
  166. ; Return Value:
  167. ;
  168. ; None.
  169. ;
  170. ;--
  171. LEAF_ENTRY HalpGenerateUnexpectedInterrupt, _TEXT$00
  172. int 0
  173. ret
  174. LEAF_END HalpGenerateUnexpectedInterrupt, _TEXT$00
  175. ;++
  176. ;
  177. ; VOID
  178. ; HalpHalt (
  179. ; VOID
  180. ; );
  181. ;
  182. ; Routine Description:
  183. ;
  184. ; Executes a hlt instruction. Should the hlt instruction execute,
  185. ; control is returned to the caller.
  186. ;
  187. ; Arguments:
  188. ;
  189. ; None.
  190. ;
  191. ; Return Value:
  192. ;
  193. ; None.
  194. ;
  195. ;--*/
  196. LEAF_ENTRY HalpHalt, _TEXT$0
  197. hlt
  198. ret
  199. LEAF_END HalpHalt, _TEXT$0
  200. ;++
  201. ;
  202. ; VOID
  203. ; HalpIoDelay (
  204. ; VOID
  205. ; );
  206. ;
  207. ; Routine Description:
  208. ;
  209. ; Generate a delay after port I/O.
  210. ;
  211. ; Arguments:
  212. ;
  213. ; None.
  214. ;
  215. ; Return Value:
  216. ;
  217. ; None.
  218. ;
  219. ;--
  220. LEAF_ENTRY HalpIoDelay, _TEXT$00
  221. jmp $+2
  222. jmp $+2
  223. ret
  224. LEAF_END HalpIoDelay, _TEXT$00
  225. ;++
  226. ;
  227. ; VOID
  228. ; HalpSerialize (
  229. ; VOID
  230. ; )
  231. ;
  232. ; Routine Description:
  233. ;
  234. ; This function implements the fence operation for out-of-order execution
  235. ;
  236. ; Arguments:
  237. ;
  238. ; None
  239. ;
  240. ; Return Value:
  241. ;
  242. ; None
  243. ;
  244. ;--
  245. HsFrame struct
  246. SavedRbx dq ? ; preserve RBX
  247. HsFrame ends
  248. NESTED_ENTRY HalpSerialize, _TEXT$00
  249. push_reg rbx
  250. END_PROLOGUE
  251. cpuid
  252. pop rbx
  253. ret
  254. NESTED_END HalpSerialize, _TEXT$00
  255. ;++
  256. ;
  257. ; StartPx_LMStub
  258. ;
  259. ; This routine is entered during startup of a secondary processor. We
  260. ; have just left StartPx_PMStub (xmstub.asm) and are running on an
  261. ; identity-mapped address space.
  262. ;
  263. ; Arguments:
  264. ;
  265. ; rdi -> idenity-mapped address of PROCESSOR_START_BLOCK
  266. ;
  267. ; Return Value:
  268. ;
  269. ; None
  270. ;
  271. ;--
  272. LEAF_ENTRY HalpLMStub, _TEXT$00
  273. ;
  274. ; Get the final CR3 value, set rdi to the self-map address of
  275. ; the processor start block, and set CR3. We are now executing
  276. ; in image-loaded code, rather than code that has been copied to
  277. ; low memory.
  278. ;
  279. mov rax, [rdi] + PsbProcessorState + PsCr3
  280. mov rdi, [rdi] + PsbSelfMap
  281. mov cr3, rax
  282. lea rsi, [rdi] + PsbProcessorState
  283. ltr WORD PTR [rsi] + SrTr
  284. ;
  285. ; Load this processor's GDT and IDT. Because PSB_GDDT32_CODE64 is
  286. ; identical to KGDT64_R0_CODE (asserted in mpsproca.c), no far jump
  287. ; is necessary to load a new CS.
  288. ;
  289. lgdt fword ptr [rsi] + PsSpecialRegisters + SrGdtr
  290. lidt fword ptr [rsi] + PsSpecialRegisters + SrIdtr
  291. ;
  292. ; Set rdx to point to the context frame and load the segment
  293. ; registers.
  294. ;
  295. lea rdx, [rdi] + PsbProcessorState + PsContextFrame
  296. mov es, [rdx] + CxSegES
  297. mov fs, [rdx] + CxSegFS
  298. mov gs, [rdx] + CxSegGS
  299. mov ss, [rdx] + CxSegSS
  300. ;
  301. ; Load the debug registers
  302. ;
  303. cld
  304. xor rax, rax
  305. mov dr7, rax
  306. add esi, SrKernelDr0
  307. .errnz (SrKernelDr1 - SrKernelDr0 - 1 * 8)
  308. .errnz (SrKernelDr2 - SrKernelDr0 - 2 * 8)
  309. .errnz (SrKernelDr3 - SrKernelDr0 - 3 * 8)
  310. .errnz (SrKernelDr6 - SrKernelDr0 - 4 * 8)
  311. .errnz (SrKernelDr7 - SrKernelDr0 - 5 * 8)
  312. lodsq
  313. mov dr0, rax
  314. lodsq
  315. mov dr1, rax
  316. lodsq
  317. mov dr2, rax
  318. lodsq
  319. mov dr3, rax
  320. lodsq
  321. mov dr6, rax
  322. lodsq
  323. mov dr7, rax
  324. ;
  325. ; Load the stack pointer, eflags and store the new IP in
  326. ; a return frame. Also push two registers that will be used
  327. ; to the very end.
  328. ;
  329. mov rsp, [rdx] + CxRsp
  330. pushq [rdx] + CxEflags
  331. popfq
  332. pushq [rdx] + CxRip
  333. push rdx
  334. push rdi
  335. mov rax, [rdx] + CxRax
  336. mov rbx, [rdx] + CxRbx
  337. mov rcx, [rdx] + CxRcx
  338. mov rsi, [rdx] + CxRsi
  339. mov rbp, [rdx] + CxRbp
  340. mov r8, [rdx] + CxR8
  341. mov r9, [rdx] + CxR9
  342. mov r10, [rdx] + CxR10
  343. mov r11, [rdx] + CxR11
  344. mov r12, [rdx] + CxR12
  345. mov r13, [rdx] + CxR13
  346. mov r14, [rdx] + CxR14
  347. mov r15, [rdx] + CxR15
  348. ;
  349. ; Indicate that we've started, pop the remaining two registers and
  350. ; return.
  351. ;
  352. inc DWORD PTR [rdi] + PsbCompletionFlag
  353. pop rdi
  354. pop rsi
  355. ret
  356. LEAF_END HalpLMStub, _TEXT$00
  357. END