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.

715 lines
17 KiB

  1. title "Abios Support Assembly Routines"
  2. ;++
  3. ;
  4. ; Copyright (c) 1989 Microsoft Corporation
  5. ;
  6. ; Module Name:
  7. ;
  8. ; abiosa.asm
  9. ;
  10. ; Abstract:
  11. ;
  12. ; This module implements assembley code for ABIOS support.
  13. ;
  14. ; Author:
  15. ;
  16. ; Shie-Lin Tzong (shielint) 25-May-1991
  17. ;
  18. ; Environment:
  19. ;
  20. ; Kernel mode only.
  21. ;
  22. ; Revision History:
  23. ;
  24. ;--
  25. .386p
  26. .xlist
  27. include ks386.inc
  28. include callconv.inc ; calling convention macros
  29. include i386\kimacro.inc
  30. include irqli386.inc
  31. .list
  32. extrn _DbgPrint:proc
  33. extrn _KiStack16GdtEntry:DWORD
  34. ;
  35. ; This should be either 0 or 1, if it's greater than 1, then we've re-entered the BIOS.
  36. ;
  37. extrn _KiInBiosCall:DWORD
  38. extrn _FlagState:DWORD
  39. extrn _KiBiosFrame:DWORD
  40. OPERAND_OVERRIDE equ 66h
  41. ADDRESS_OVERRIDE equ 67h
  42. KGDT_CDA16 equ 0E8h
  43. LocalStack equ 16 ; 4 DWORDS of slop for PnPBioses.
  44. if DBG
  45. extrn KiBiosReenteredAssert:DWORD
  46. endif
  47. ; Macro change note:
  48. ;
  49. ; This macro pair used to do an uncondtional sti coming back from the 16-bit
  50. ; side, this potentially caused problems in APM. Now we save and restore the
  51. ; flag state
  52. ;
  53. ;++
  54. ;
  55. ; STACK32_TO_STACK16
  56. ;
  57. ; Macro Description:
  58. ;
  59. ; This macro remaps current 32bit stack to 16bit stack.
  60. ;
  61. ; Arguments:
  62. ;
  63. ; None.
  64. ;
  65. ;--
  66. STACK32_TO_STACK16 macro
  67. pushfd
  68. mov ecx,[esp]
  69. mov _FlagState,ecx
  70. popfd
  71. mov eax, PCR[PcPrcbData+PbCurrentThread] ; get current thread address
  72. mov eax, [eax]+ThStackLimit ; get thread stack base
  73. mov edx, eax
  74. mov ecx, _KiStack16GdtEntry
  75. mov word ptr [ecx].KgdtBaseLow, ax
  76. shr eax, 16
  77. mov byte ptr [ecx].KgdtBaseMid, al
  78. mov byte ptr [ecx].KgdtBaseHi, ah
  79. cli
  80. sub esp, edx
  81. mov eax, KGDT_STACK16
  82. mov ss, ax
  83. ;
  84. ; NOTE that we MUST leave interrupts remain off.
  85. ; We'll turn it back on after we switch to 16 bit code.
  86. ;
  87. endm
  88. ;++
  89. ;
  90. ; STACK16_TO_STACK32
  91. ;
  92. ; Macro Description:
  93. ;
  94. ; This macro remaps current 32bit stack to 16bit stack.
  95. ;
  96. ; Arguments:
  97. ;
  98. ; None.
  99. ;
  100. ;--
  101. STACK16_TO_STACK32 macro Stack32
  102. db OPERAND_OVERRIDE
  103. db ADDRESS_OVERRIDE
  104. mov eax, PCR[PcPrcbData+PbCurrentThread] ; get current thread address
  105. db OPERAND_OVERRIDE
  106. db ADDRESS_OVERRIDE
  107. mov eax, [eax]+ThStackLimit ; get thread stack limit
  108. cli
  109. db OPERAND_OVERRIDE
  110. add esp, eax
  111. db OPERAND_OVERRIDE
  112. mov eax, KGDT_R0_DATA
  113. mov ss, ax
  114. db OPERAND_OVERRIDE
  115. db ADDRESS_OVERRIDE
  116. push ds:_FlagState
  117. db OPERAND_OVERRIDE
  118. popfd
  119. endm
  120. COPY_CALL_FRAME macro FramePtr
  121. mov [FramePtr].TsEax,eax
  122. mov [FramePtr].TsEbx,ebx
  123. mov [FramePtr].TsEcx,ecx
  124. mov [FramePtr].TsEdx,edx
  125. mov [FramePtr].TsEsi,esi
  126. mov [FramePtr].TsEdi,edi
  127. mov [FramePtr].TsEbp,ebp
  128. mov [FramePtr].TsHardwareEsp,esp
  129. mov [FramePtr].TsSegFs,fs
  130. mov [FramePtr].TsSegCs,cs
  131. endm
  132. page ,132
  133. subttl "Abios Support Code"
  134. _TEXT SEGMENT DWORD PUBLIC 'CODE'
  135. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  136. ;
  137. ; BBT cannot instrument code between this label and BBT_Exclude_Selector_Code_End
  138. ;
  139. public _BBT_Exclude_Selector_Code_Begin
  140. _BBT_Exclude_Selector_Code_Begin equ $
  141. int 3
  142. ;++
  143. ; ULONG
  144. ; KiAbiosGetGdt (
  145. ; VOID
  146. ; )
  147. ;
  148. ; Routine Description:
  149. ;
  150. ; This routine returns the starting address of GDT of current processor.
  151. ;
  152. ; Arguments:
  153. ;
  154. ; None.
  155. ;
  156. ; Return Value:
  157. ;
  158. ; return Pcr->GDT
  159. ;
  160. ;--
  161. cPublicProc _KiAbiosGetGdt,0
  162. mov eax, PCR[PcGdt]
  163. stdRET _KiAbiosGetGdt
  164. stdENDP _KiAbiosGetGdt
  165. ;++
  166. ; VOID
  167. ; KiI386CallAbios(
  168. ; IN KABIOS_POINTER AbiosFunction,
  169. ; IN KABIOS_POINTER DeviceBlockPointer,
  170. ; IN KABIOS_POINTER FunctionTransferTable,
  171. ; IN KABIOS_POINTER RequestBlock
  172. ; )
  173. ;
  174. ; Routine Description:
  175. ;
  176. ; This function invokes ABIOS service function for device driver. This
  177. ; routine is executing at DIAPTCH_LEVEL to prevent context swapping.
  178. ;
  179. ; N.B. We arrive here from the Ke386AbiosCall with a 32bit CS. That is,
  180. ; we're executing the code with cs:eip where cs contains a selector for a
  181. ; 32bit flat segment. We want to get to a 16bit cs. That is, cs:ip.
  182. ; The reason is that ABIOS is running at 16 bit segment.
  183. ; Before we can call ABIOS service we must load ss and cs segment
  184. ; registers with selectors for 16bit segments. We start by pushing a far
  185. ; pointer to a label in the macro and then doing a retf. This allows us
  186. ; to fall through to the next instruction, but we're now executing
  187. ; through cs:ip with a 16bit CS. Then, we remap our 32-bit stack to 16-bit
  188. ; stack.
  189. ;
  190. ; Arguments:
  191. ;
  192. ; AbiosFunction - a 16:16 pointer to the abios service function.
  193. ;
  194. ; DeviceBlockPointer - a 16:16 pointer to Device Block.
  195. ;
  196. ; FunctionTransferTable - a 16:16 pointer to Function Transfer Table.
  197. ;
  198. ; RequestBlock - a 16:16 pointer to device driver's request block.
  199. ;
  200. ; Return Value:
  201. ;
  202. ; None.
  203. ;--
  204. KacAbiosFunction equ [ebp + 8]
  205. KacDeviceBlock equ [ebp + 12]
  206. KacFunctionTable equ [ebp + 16]
  207. KacRequestBlock equ [ebp + 20]
  208. cPublicProc _KiI386CallAbios,4
  209. ;
  210. ; We're using a 32bit CS:EIP - go to a 16bit CS:IP
  211. ; Note the base of KiAbiosCallSelector is the flat address of _KiI386AbiosCall
  212. ; routine.
  213. ;
  214. push ebp
  215. mov ebp, esp
  216. push ebx
  217. COPY_CALL_FRAME _KiBiosFrame
  218. sub esp,LocalStack ; After C style frame
  219. CurrentIrql ; Local Variable
  220. push eax ; Local Varible
  221. cmp al, DISPATCH_LEVEL ; Is irql > Dispatch_level?
  222. jae short Kac00
  223. ; Raise to Dispatch Level
  224. RaiseIrql DISPATCH_LEVEL
  225. mov [esp], al
  226. Kac00:
  227. ;
  228. ; Set up parameters on stack before remapping stack.
  229. ;
  230. push word ptr KGDT_CDA16 ; CDA anchor selector
  231. push KacRequestBlock ; Request Block
  232. push KacFunctionTable ; Func transfer table
  233. push KacDeviceBlock ; Device Block
  234. mov ebx, KacAbiosFunction ; (ebx)-> Abios Entry
  235. ;
  236. ; Remap current stack to 16:16 stack. The base of the 16bit stack selector is
  237. ; the base of current kernel stack.
  238. ;
  239. inc _KiInBiosCall ; Set the 'In Bios' flag
  240. if DBG
  241. cmp _KiInBiosCall,2
  242. jb @F
  243. push offset FLAT:KiBiosReenteredAssert
  244. call _dbgPrint
  245. add esp, 4
  246. @@:
  247. endif
  248. STACK32_TO_STACK16 ; Switch to 16bit stack
  249. push word ptr KGDT_CODE16
  250. push word ptr (offset FLAT:Kac40 - offset FLAT:_KiI386CallAbios@16)
  251. push KGDT_CODE16
  252. push offset FLAT:Kac30 - offset FLAT:_KiI386CallAbios@16
  253. retf
  254. Kac30:
  255. ;
  256. ; Stack switching (from 32 to 16) turns interrupt off. We must turn it
  257. ; back on.
  258. ;
  259. sti
  260. push bx ; Yes, BX not EBX!
  261. retf
  262. Kac40:
  263. add esp, 14 ; pop out all the parameters
  264. STACK16_TO_STACK32 ; switch back to 32 bit stack
  265. ;
  266. ; Pull callers flat return address off stack and push the
  267. ; flat code selector followed by the return offset, then
  268. ; execute a far return and we'll be back in the 32-bit code space.
  269. ;
  270. db OPERAND_OVERRIDE
  271. push KGDT_R0_CODE
  272. db OPERAND_OVERRIDE
  273. push offset FLAT:Kac50
  274. db OPERAND_OVERRIDE
  275. retf
  276. Kac50:
  277. pop ecx ; [ecx] = OldIrql
  278. pop ebx ; restore ebx
  279. cmp cl, DISPATCH_LEVEL
  280. jae short Kac60
  281. LowerIrql cl
  282. Kac60:
  283. dec _KiInBiosCall ;Clear 'In Bios' Flag
  284. add esp,LocalStack ; subtract off the scratch space
  285. pop ebp
  286. stdRET _KiI386CallAbios
  287. stdENDP _KiI386CallAbios
  288. ;; ********************************************************
  289. ;;
  290. ;; BEGIN - power_management
  291. ;;
  292. ;;
  293. ;++
  294. ; VOID
  295. ; KeI386Call16BitFunction (
  296. ; IN OUT PCONTEXT Regs
  297. ; )
  298. ;
  299. ; Routine Description:
  300. ;
  301. ; This function calls the 16 bit function specified in the Regs.
  302. ;
  303. ; Parameters:
  304. ;
  305. ; Regs - supplies a pointer to register context to call 16 function.
  306. ;
  307. ; NOTE: Caller must be at DPC_LEVEL
  308. ;
  309. ;--
  310. cPublicProc _KeI386Call16BitFunction,1
  311. ; verify CurrentIrql
  312. ; verify context flags
  313. push ebp ; save nonvolatile registers
  314. push ebx
  315. push esi
  316. push edi
  317. mov ebx, dword ptr [esp + 20] ; (ebx)-> Context
  318. COPY_CALL_FRAME _KiBiosFrame
  319. sub esp,LocalStack ; After prolog
  320. inc _KiInBiosCall ; Set the 'In Bios' flag
  321. if DBG
  322. cmp _KiInBiosCall,2
  323. jb @F
  324. push offset FLAT:KiBiosReenteredAssert
  325. call _dbgPrint
  326. add esp, 4
  327. @@:
  328. endif
  329. ;
  330. ; We're using a 32bit CS:EIP - go to a 16bit CS:IP
  331. ; Note the base of KiAbiosCallSelector is the flat address of _KiI386AbiosCall
  332. ; routine.
  333. ;
  334. ;
  335. ; Remap current stack to 16:16 stack. The base of the 16bit stack selector is
  336. ; the base of current kernel stack.
  337. ;
  338. STACK32_TO_STACK16 ; Switch to 16bit stack
  339. ;
  340. ; Push return address from 16 bit function call to kernel
  341. ;
  342. push word ptr KGDT_CODE16
  343. push word ptr (offset FLAT:Kbf40 - offset FLAT:_KiI386CallAbios@16)
  344. ;
  345. ; Load context to call with
  346. ;
  347. push word ptr [ebx].CsEFlags
  348. push word ptr [ebx].CsSegCs
  349. push word ptr [ebx].CsEip
  350. mov eax, [ebx].CsEax
  351. mov ecx, [ebx].CsEcx
  352. mov edx, [ebx].CsEdx
  353. mov edi, [ebx].CsEdi
  354. mov esi, [ebx].CsEsi
  355. mov ebp, [ebx].CsEbp
  356. push [ebx].CsSegGs
  357. push [ebx].CsSegFs
  358. push [ebx].CsSegEs
  359. push [ebx].CsSegDs
  360. mov ebx, [ebx].CsEbx
  361. pop ds
  362. pop es
  363. pop fs
  364. pop gs
  365. ;
  366. ; Switch to 16bit CS
  367. ;
  368. push KGDT_CODE16
  369. push offset FLAT:Kbf30 - offset FLAT:_KiI386CallAbios@16
  370. retf
  371. Kbf30:
  372. ;
  373. ; "call" to 16 bit function
  374. ;
  375. iretd
  376. Kbf40:
  377. ;
  378. ; Push some of the returned context which will be needed to
  379. ; switch back to the 32 bit SS & CS.
  380. ;
  381. db OPERAND_OVERRIDE
  382. push ds
  383. db OPERAND_OVERRIDE
  384. push es
  385. db OPERAND_OVERRIDE
  386. push fs
  387. db OPERAND_OVERRIDE
  388. push gs
  389. db OPERAND_OVERRIDE
  390. push eax
  391. db OPERAND_OVERRIDE
  392. pushfd
  393. db OPERAND_OVERRIDE
  394. mov eax, KGDT_R0_PCR
  395. mov fs, ax
  396. db OPERAND_OVERRIDE
  397. mov eax, KGDT_R3_DATA OR RPL_MASK
  398. mov ds, ax
  399. mov es, ax
  400. xor eax, eax
  401. ;
  402. ; Switch back to 32 bit stack
  403. ;
  404. STACK16_TO_STACK32
  405. ;
  406. ; Push the flat code selector followed by the return offset, then
  407. ; execute a far return and we'll be back in the 32-bit code space.
  408. ;
  409. db OPERAND_OVERRIDE
  410. push KGDT_R0_CODE
  411. db OPERAND_OVERRIDE
  412. push offset FLAT:Kbf50
  413. db OPERAND_OVERRIDE
  414. retf
  415. Kbf50:
  416. ;
  417. ; Return resulting context
  418. ;
  419. mov eax, dword ptr [esp+44+LocalStack] ; (eax) = Context Record
  420. pop [eax].CsEflags
  421. pop [eax].CsEax
  422. pop [eax].CsSegGs
  423. pop [eax].CsSegFs
  424. pop [eax].CsSegEs
  425. pop [eax].CsSegDs
  426. mov [eax].CsEbx, ebx
  427. mov [eax].CsEcx, ecx
  428. mov [eax].CsEdx, edx
  429. mov [eax].CsEdi, edi
  430. mov [eax].CsEsi, esi
  431. mov [eax].CsEbp, ebp
  432. ;
  433. ; Restore regs & return
  434. ;
  435. dec _KiInBiosCall ; Clear the 'In Bios' flag
  436. add esp,LocalStack ;remove scratch space
  437. pop edi
  438. pop esi
  439. pop ebx
  440. pop ebp
  441. stdRET _KeI386Call16BitFunction
  442. stdENDP _KeI386Call16BitFunction
  443. ;++
  444. ; USHORT
  445. ; KeI386Call16BitCStyleFunction (
  446. ; IN ULONG EntryOffset,
  447. ; IN ULONG EntrySelector,
  448. ; IN PUCHAR Parameters,
  449. ; IN ULONG Size
  450. ; )
  451. ;
  452. ; Routine Description:
  453. ;
  454. ; This function calls the 16 bit function which supports C style calling convension.
  455. ;
  456. ; Parameters:
  457. ;
  458. ; EntryOffset and EntrySelector - specifies the entry point of the 16 bit function.
  459. ;
  460. ; Parameters - supplies a pointer to a parameter block which will be
  461. ; passed to 16 bit function as parameters.
  462. ;
  463. ; Size - supplies the size of the parameter block.
  464. ;
  465. ; NOTE: Caller must be at DPC_LEVEL
  466. ;
  467. ; Returned Value:
  468. ;
  469. ; AX returned by 16 bit function.
  470. ;
  471. ;--
  472. cPublicProc _KeI386Call16BitCStyleFunction,4
  473. ;
  474. ; verify CurrentIrql
  475. ; verify context flags
  476. ;
  477. push ebp ; save nonvolatile registers
  478. push ebx
  479. push esi
  480. push edi
  481. COPY_CALL_FRAME _KiBiosFrame
  482. inc _KiInBiosCall ; Set the 'In Bios' flag
  483. if DBG
  484. cmp _KiInBiosCall,2
  485. jb @F
  486. push offset FLAT:KiBiosReenteredAssert
  487. call _dbgPrint
  488. add esp, 4
  489. @@:
  490. endif
  491. mov edi, esp
  492. sub esp,LocalStack ; now, add in some scratch space
  493. mov esi, dword ptr [esp + LocalStack +28] ; (esi)->BiosParameters
  494. or esi, esi
  495. jz short @f
  496. mov ecx, [esp + LocalStack +32] ; (ecx) = parameter size
  497. sub esp, ecx ; allocate space on TOS to copy parameters
  498. mov edi, esp
  499. rep movsb ; (edi)-> Top of nonvolatile reg save area
  500. add edi, LocalStack ; edi now points to original stack
  501. @@:
  502. ;
  503. ; We're using a 32bit CS:EIP - go to a 16bit CS:IP
  504. ; Note the base of KiAbiosCallSelector is the flat address of _KiI386AbiosCall
  505. ; routine.
  506. ;
  507. ;
  508. ; Remap current stack to 16:16 stack. The base of the 16bit stack selector is
  509. ; the base of current kernel stack.
  510. ;
  511. STACK32_TO_STACK16 ; Switch to 16bit stack
  512. ;
  513. ; Push return address from 16 bit function call to kernel
  514. ;
  515. push word ptr KGDT_CODE16
  516. push word ptr (offset FLAT:Kbfex40 - offset FLAT:_KiI386CallAbios@16)
  517. push word ptr 0200h ; flags
  518. push word ptr [edi + 24 ] ; entry selector
  519. push word ptr [edi + 20 ] ; entry offset
  520. ;
  521. ; Switch to 16bit CS
  522. ;
  523. push KGDT_CODE16
  524. push offset FLAT:Kbfex30 - offset FLAT:_KiI386CallAbios@16
  525. retf
  526. Kbfex30:
  527. ;
  528. ; "call" to 16 bit function
  529. ;
  530. iretd
  531. Kbfex40:
  532. ;
  533. ; Save return value.
  534. ;
  535. db OPERAND_OVERRIDE
  536. push eax
  537. ;
  538. ; Restore Flat mode segment registers.
  539. ;
  540. db OPERAND_OVERRIDE
  541. mov eax, KGDT_R0_PCR
  542. mov fs, ax
  543. db OPERAND_OVERRIDE
  544. mov eax, KGDT_R3_DATA OR RPL_MASK
  545. mov ds, ax
  546. mov es, ax
  547. xor eax, eax
  548. ;
  549. ; Switch back to 32 bit stack
  550. ;
  551. STACK16_TO_STACK32
  552. ;
  553. ; Push the flat code selector followed by the return offset, then
  554. ; execute a far return and we'll be back in the 32-bit code space.
  555. ;
  556. db OPERAND_OVERRIDE
  557. push KGDT_R0_CODE
  558. db OPERAND_OVERRIDE
  559. push offset FLAT:Kbfex50
  560. db OPERAND_OVERRIDE
  561. retf
  562. Kbfex50:
  563. pop eax
  564. ;
  565. ; Restore regs & return
  566. ;
  567. dec _KiInBiosCall ; Clear the 'In Bios' flag
  568. mov esp, edi ; Also removes the scratch space!
  569. pop edi
  570. pop esi
  571. pop ebx
  572. pop ebp
  573. stdRET _KeI386Call16BitCStyleFunction
  574. stdENDP _KeI386Call16BitCStyleFunction
  575. ;
  576. ; BBT cannot instrument code between BBT_Exclude_Selector_Code_Begin and this label
  577. ;
  578. public _BBT_Exclude_Selector_Code_End
  579. _BBT_Exclude_Selector_Code_End equ $
  580. int 3
  581. ;;
  582. ;; END - power_management
  583. ;;
  584. ;; ********************************************************
  585. public _KiEndOfCode16
  586. _KiEndOfCode16 equ $
  587. _TEXT ends
  588. end