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.

292 lines
8.2 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, fs:PcSelfPcr ; (ebx)->Pcr
  97. mov edx, [ebx].PcInitialStack
  98. mov KsaeInitialStack, edx ; (edx)->Pcr InitialSack
  99. mov edi, [ebx]+PcPrcbData+PbCurrentThread ; (edi)->CurrentThread
  100. mov edx, [edi].ThTeb
  101. mov OriginalThTeb, edx
  102. mov edx, fs:[PcTeb]
  103. mov OriginalPcTeb, edx
  104. mov edi, offset Ki386BiosCallReturnAddress
  105. mov [eax].TsEsi, ecx ; Saved esp
  106. mov [eax].TsEip, edi ; set up return address
  107. pushfd
  108. pop edi
  109. and edi, 60dd7h
  110. or edi, 200h ; sanitize EFLAGS
  111. mov dword ptr [eax].TsHardwareSegSs, KGDT_R3_DATA OR RPL_MASK
  112. mov dword ptr [eax].TsHardwareEsp, V86_STACK_POINTER
  113. mov [eax].TsEflags, edi
  114. mov [eax].TsExceptionList, EXCEPTION_CHAIN_END
  115. mov [eax].TsPreviousPreviousMode, 0ffffffffh ; No previous mode
  116. if DBG
  117. mov [eax].TsDbgArgMark, 0BADB0D00h ; set trap frame mark
  118. endif
  119. add eax, KTRAP_FRAME_LENGTH
  120. ;
  121. ; Disable interrupt and change the stack pointer to make the new
  122. ; trap frame be the current thread's base trap frame.
  123. ;
  124. ; (eax)->Npx save area
  125. ;
  126. cli
  127. ;
  128. ; Set up various stack pointers
  129. ;
  130. ; Low | |
  131. ; |-----------| <- New esp
  132. ; | New Base |
  133. ; |Trap Frame |
  134. ; |-----------| <- Tss.Esp0
  135. ; |V86 segs |
  136. ; |-----------| <- Pcr.InitialStack
  137. ; |Npx Area |
  138. ; |-----------| <- Old Esp = Thread.InitialStack
  139. ; | |
  140. ; High | |
  141. ;
  142. ;
  143. ; Copy the FP state to the new FP state save area (NPX frame)
  144. ;
  145. push ecx ; save ecx (saved esp)
  146. mov esi, [ebx].PcInitialStack
  147. mov ecx, NPX_FRAME_LENGTH/4
  148. mov edi, eax
  149. rep movsd
  150. pop ecx ; restore ecx
  151. mov edi, [ebx]+PcPrcbData+PbCurrentThread ; (edi)->CurrentThread
  152. mov [ebx].PcInitialStack, eax
  153. mov esi,[ebx]+PcTss ; (esi)->TSS
  154. sub eax,TsV86Gs - TsHardwareSegSs ; bias for missing fields
  155. mov [ebx].PcExceptionList, EXCEPTION_CHAIN_END
  156. mov [esi]+TssEsp0,eax
  157. add eax, NPX_FRAME_LENGTH + (TsV86Gs - TsHardwareSegSs)
  158. mov [edi].ThInitialStack, eax
  159. ;
  160. ; Set up the pointers to the fake TEB so we can execute the int10
  161. ; call
  162. ;
  163. mov eax, NewTeb
  164. mov fs:[PcTeb], eax
  165. mov [edi].ThTeb, eax
  166. mov ebx, PCR[PcGdt]
  167. mov [ebx]+(KGDT_R3_TEB+KgdtBaseLow), ax
  168. shr eax, 16
  169. mov [ebx]+(KGDT_R3_TEB+KgdtBaseMid), al
  170. mov [ebx]+(KGDT_R3_TEB+KgdtBaseHi), ah
  171. sti
  172. ; Now call VdmControl to save return 32bit frame and put vdm context
  173. ; to new base trap frame
  174. stdCall _NtVdmControl, <VdmStartExecution, 0>
  175. if 0
  176. ;
  177. ; Now call _VdmpStartExecution to save return 32bit frame and put vdm context
  178. ; to new base trap frame
  179. ;
  180. mov eax, ExecAddr
  181. stdCall _VdmpStartExecution, <eax>
  182. endif
  183. ;
  184. ; Call KiexceptionExit to 'exit' to v86 code.
  185. ;
  186. mov ebp, esp ; (ebp)->Exit trap frame
  187. jmp _KiExceptionExit ; go execute int 10
  188. public Ki386BiosCallReturnAddress
  189. Ki386BiosCallReturnAddress:
  190. ;
  191. ; After ROM BIOS int completes, the bop instruction gets executed.
  192. ; This results in a trap to kernel mode bop handler where the
  193. ; 16 bit Vdm context will be saved to VdmTib->VdmCOntext, and
  194. ; the faked 32 bit user mode context (i.e. the one we created earlier)
  195. ; be restored. Since the faked user mode context does NOT have a valid
  196. ; iret address, the 'iret' instruction of the EXIT_ALL will be trapped to
  197. ; our GP fault handler which recognizes this and transfers control back to
  198. ; here.
  199. ;
  200. ; when we come back here, all the segment registers are set up properly
  201. ; Interrupts are disabled.
  202. ;
  203. ;
  204. ; restore all the pointers.
  205. ;
  206. mov eax, fs:PcSelfPcr ; (eax)->Pcr
  207. mov edi, [ebp].TsEsi ; Fetch previous stack address
  208. mov edi, [edi] ; Initial Stack is saved at stack top
  209. ;
  210. ; Copy the FP state back down to the default stack
  211. ;
  212. mov esi, [eax].PcInitialStack
  213. mov ecx, NPX_FRAME_LENGTH/4
  214. mov [eax].PcInitialStack, edi ; Restore Pcr InitialStack
  215. rep movsd ; copy FP state
  216. ; (n.b. edi+= NPX_FRAME_LENGTH)
  217. mov esp, [ebp].TsEsi ; Shink stack
  218. add esp, 4 ; drop saved stack address
  219. mov ecx, [eax]+PcPrcbData+PbCurrentThread ; (ecx)->CurrentThread
  220. mov [ecx].ThInitialStack, edi ; Restore Thread.InitialStack
  221. mov eax,[eax]+PcTss ; (eax)->TSS
  222. sub edi, (TsV86Gs - TsHardwareSegSs) + NPX_FRAME_LENGTH
  223. mov [eax]+TssEsp0,edi
  224. ;
  225. ; restore pointers to the original TEB
  226. ;
  227. pop edx ; (edx) = OriginalThTeb
  228. mov [ecx].ThTeb, edx
  229. pop edx ; (edx) = OriginalPcTeb
  230. mov fs:[PcTeb], edx
  231. mov ebx, PCR[PcGdt]
  232. mov [ebx]+(KGDT_R3_TEB+KgdtBaseLow), dx
  233. shr edx, 16
  234. mov [ebx]+(KGDT_R3_TEB+KgdtBaseMid), dl
  235. mov [ebx]+(KGDT_R3_TEB+KgdtBaseHi), dh
  236. sti
  237. pop edi
  238. pop esi
  239. pop ebx
  240. pop ebp
  241. stdRET _Ki386SetupAndExitToV86Code
  242. stdENDP _Ki386SetupAndExitToV86Code
  243. _TEXT ends
  244. end