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.

296 lines
8.7 KiB

  1. TITLE "Call Bios support"
  2. ;++
  3. ;
  4. ; Copyright (c) 1989 Microsoft Corporation
  5. ;
  6. ; Module Name:
  7. ;
  8. ; spinlock.asm
  9. ;
  10. ; Abstract:
  11. ;
  12. ; This module implements the support routines for executing int bios
  13. ; call in v86 mode.
  14. ;
  15. ; Author:
  16. ;
  17. ; Shie-Lint Tzong (shielint) Sept 10, 1992
  18. ;
  19. ; Environment:
  20. ;
  21. ; Kernel mode only.
  22. ;
  23. ; Revision History:
  24. ;
  25. ;--
  26. .386p
  27. include ks386.inc
  28. include callconv.inc ; calling convention macros
  29. include i386\kimacro.inc
  30. VdmStartExecution EQU 0
  31. V86_STACK_POINTER equ 11ffeh ; see BIOSC.C
  32. EXTRNP _NtVdmControl,2
  33. extrn _KiExceptionExit:PROC
  34. _TEXT SEGMENT DWORD PUBLIC 'CODE'
  35. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  36. PAGE
  37. SUBTTL "Switch to V86 mode"
  38. ;++
  39. ;
  40. ; VOID
  41. ; Ki386SetupAndExitToV86Code (
  42. ; VOID
  43. ; )
  44. ;
  45. ; Routine Description:
  46. ;
  47. ; This function sets up return trap frame, switch stack and
  48. ; calls VdmStartExecution routine to put vdm context to
  49. ; base trap frame and causes the system to execute in v86 mode by
  50. ; doing a KiExceptionExit.
  51. ;
  52. ; Arguments:
  53. ;
  54. ; BiosArguments - Supplies a pointer to a structure which contains
  55. ; the arguments for v86 int function.
  56. ;
  57. ; Return Value:
  58. ;
  59. ; None.
  60. ;
  61. ;--
  62. cPublicProc _Ki386SetupAndExitToV86Code,1
  63. NewTEB equ [ecx+32] ; location of the parameter based on
  64. ; the ecx stack pointer.
  65. KsaeInitialStack equ [ecx]
  66. OriginalThTeb equ [ecx+4]
  67. OriginalPcTeb equ [ecx+8]
  68. ;
  69. ; Allocate TRAP FRAME at the bottom of the stack.
  70. ;
  71. push ebp
  72. push ebx
  73. push esi
  74. push edi
  75. sub esp, 12 ; 12 bytes for local variable
  76. mov ecx, esp ; (ecx) = saved esp
  77. sub esp, NPX_FRAME_LENGTH
  78. and esp, 0fffffff0h ; FXSAVE 16 byte alignment requirement
  79. sub esp, KTRAP_FRAME_LENGTH ; (esp)-> new trap frame
  80. mov eax, esp ; (eax)->New base trap frame
  81. ;
  82. ; Initialize newly allocated trap frame to caller's nonvolatle context.
  83. ; Note that it is very important that the trap frame we are going to create
  84. ; is a USER mode frame. The system expects the top trap frame for user
  85. ; mode thread is a user mode frame. (Get/SetContext enforce the rule.)
  86. ;
  87. ; (eax)-> Base of trap frame.
  88. ;
  89. mov dword ptr [eax].TsSegCs, KGDT_R0_CODE OR RPL_MASK
  90. ; an invalid cs to trap it back to kernel
  91. mov dword ptr [eax].TsSegEs, 0
  92. mov dword ptr [eax].TsSegDs, 0
  93. mov dword ptr [eax].TsSegFs, 0
  94. mov dword ptr [eax].TsSegGs, 0
  95. mov dword ptr [eax].TsErrCode, 0
  96. mov ebx, PCR[PcSelfPcr] ; (ebx)->Pcr
  97. mov edi, [ebx]+PcPrcbData+PbCurrentThread ; (edi)->CurrentThread
  98. mov edx, [edi].ThInitialStack
  99. sub edx, NPX_FRAME_LENGTH ; space for NPX_FRAME
  100. mov KsaeInitialStack, edx ; Thread InitialSack
  101. mov edx, [edi].ThTeb
  102. mov OriginalThTeb, edx
  103. mov edx, PCR[PcTeb]
  104. mov OriginalPcTeb, edx
  105. mov edi, offset Ki386BiosCallReturnAddress
  106. mov [eax].TsEsi, ecx ; Saved esp
  107. mov [eax].TsEip, edi ; set up return address
  108. pushfd
  109. pop edi
  110. and edi, 60dd7h
  111. or edi, 200h ; sanitize EFLAGS
  112. mov dword ptr [eax].TsHardwareSegSs, KGDT_R3_DATA OR RPL_MASK
  113. mov dword ptr [eax].TsHardwareEsp, V86_STACK_POINTER
  114. mov [eax].TsEflags, edi
  115. mov [eax].TsExceptionList, EXCEPTION_CHAIN_END
  116. mov [eax].TsPreviousPreviousMode, 0ffffffffh ; No previous mode
  117. and [eax].TsDr7, 0
  118. if DBG
  119. mov [eax].TsDbgArgMark, 0BADB0D00h ; set trap frame mark
  120. endif
  121. add eax, KTRAP_FRAME_LENGTH
  122. ;
  123. ; Disable interrupt and change the stack pointer to make the new
  124. ; trap frame be the current thread's base trap frame.
  125. ;
  126. ; (eax)->Npx save area
  127. ;
  128. cli
  129. ;
  130. ; Set up various stack pointers
  131. ;
  132. ; Low | |
  133. ; |-----------| <- New esp
  134. ; | New Base |
  135. ; |Trap Frame |
  136. ; |-----------| <- Tss.Esp0
  137. ; |V86 segs |
  138. ; |-----------| <- Pcr.InitialStack
  139. ; |Npx Area |
  140. ; |-----------| <- Old Esp = Thread.InitialStack
  141. ; | |
  142. ; High | |
  143. ;
  144. ;
  145. ; Copy the FP state to the new FP state save area (NPX frame)
  146. ;
  147. push ecx ; save ecx (saved esp)
  148. mov edi, [ebx]+PcPrcbData+PbCurrentThread ; (edi)->CurrentThread
  149. mov esi, [edi].ThInitialStack
  150. sub esi, NPX_FRAME_LENGTH
  151. mov ecx, NPX_FRAME_LENGTH/4
  152. mov edi, eax
  153. rep movsd
  154. pop ecx ; restore ecx
  155. mov edi, [ebx]+PcPrcbData+PbCurrentThread ; (edi)->CurrentThread
  156. mov esi,[ebx]+PcTss ; (esi)->TSS
  157. sub eax,TsV86Gs - TsHardwareSegSs ; bias for missing fields
  158. mov [ebx].PcExceptionList, EXCEPTION_CHAIN_END
  159. mov [esi]+TssEsp0,eax
  160. add eax, NPX_FRAME_LENGTH + (TsV86Gs - TsHardwareSegSs)
  161. mov [edi].ThInitialStack, eax
  162. ;
  163. ; Set up the pointers to the fake TEB so we can execute the int10
  164. ; call
  165. ;
  166. mov eax, NewTeb
  167. mov PCR[PcTeb], eax
  168. mov [edi].ThTeb, eax
  169. mov ebx, PCR[PcGdt]
  170. mov [ebx]+(KGDT_R3_TEB+KgdtBaseLow), ax
  171. shr eax, 16
  172. mov [ebx]+(KGDT_R3_TEB+KgdtBaseMid), al
  173. mov [ebx]+(KGDT_R3_TEB+KgdtBaseHi), ah
  174. sti
  175. ; Now call VdmControl to save return 32bit frame and put vdm context
  176. ; to new base trap frame
  177. stdCall _NtVdmControl, <VdmStartExecution, 0>
  178. if 0
  179. ;
  180. ; Now call _VdmpStartExecution to save return 32bit frame and put vdm context
  181. ; to new base trap frame
  182. ;
  183. mov eax, ExecAddr
  184. stdCall _VdmpStartExecution, <eax>
  185. endif
  186. ;
  187. ; Call KiexceptionExit to 'exit' to v86 code.
  188. ;
  189. mov ebp, esp ; (ebp)->Exit trap frame
  190. jmp _KiExceptionExit ; go execute int 10
  191. public Ki386BiosCallReturnAddress
  192. Ki386BiosCallReturnAddress:
  193. ;
  194. ; After ROM BIOS int completes, the bop instruction gets executed.
  195. ; This results in a trap to kernel mode bop handler where the
  196. ; 16 bit Vdm context will be saved to VdmTib->VdmCOntext, and
  197. ; the faked 32 bit user mode context (i.e. the one we created earlier)
  198. ; be restored. Since the faked user mode context does NOT have a valid
  199. ; iret address, the 'iret' instruction of the EXIT_ALL will be trapped to
  200. ; our GP fault handler which recognizes this and transfers control back to
  201. ; here.
  202. ;
  203. ; when we come back here, all the segment registers are set up properly
  204. ; Interrupts are disabled.
  205. ;
  206. ;
  207. ; restore all the pointers.
  208. ;
  209. mov eax, PCR[PcSelfPcr] ; (eax)->Pcr
  210. mov edi, [ebp].TsEsi ; Fetch previous stack address
  211. mov edi, [edi] ; Initial Stack is saved at stack top
  212. ;
  213. ; Copy the FP state back down to the default stack
  214. ;
  215. mov ecx, [eax]+PcPrcbData+PbCurrentThread ; (ecx)->CurrentThread
  216. mov esi, [ecx].ThInitialStack
  217. sub esi, NPX_FRAME_LENGTH
  218. mov ecx, NPX_FRAME_LENGTH/4
  219. rep movsd ; copy FP state
  220. ; (n.b. edi+= NPX_FRAME_LENGTH)
  221. mov esp, [ebp].TsEsi ; Shink stack
  222. add esp, 4 ; drop saved stack address
  223. mov ecx, [eax]+PcPrcbData+PbCurrentThread ; (ecx)->CurrentThread
  224. mov [ecx].ThInitialStack, edi ; Restore Thread.InitialStack
  225. mov eax,[eax]+PcTss ; (eax)->TSS
  226. sub edi, (TsV86Gs - TsHardwareSegSs) + NPX_FRAME_LENGTH
  227. mov [eax]+TssEsp0,edi
  228. ;
  229. ; restore pointers to the original TEB
  230. ;
  231. pop edx ; (edx) = OriginalThTeb
  232. mov [ecx].ThTeb, edx
  233. pop edx ; (edx) = OriginalPcTeb
  234. mov PCR[PcTeb], edx
  235. mov ebx, PCR[PcGdt]
  236. mov [ebx]+(KGDT_R3_TEB+KgdtBaseLow), dx
  237. shr edx, 16
  238. mov [ebx]+(KGDT_R3_TEB+KgdtBaseMid), dl
  239. mov [ebx]+(KGDT_R3_TEB+KgdtBaseHi), dh
  240. sti
  241. pop edi
  242. pop esi
  243. pop ebx
  244. pop ebp
  245. stdRET _Ki386SetupAndExitToV86Code
  246. stdENDP _Ki386SetupAndExitToV86Code
  247. _TEXT ends
  248. end