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.

648 lines
18 KiB

  1. PAGE 58,132
  2. ;******************************************************************************
  3. TITLE VFLATD.ASM - Virtual Flat Device
  4. ;******************************************************************************
  5. ;
  6. ; (C) Copyright MICROSOFT Corp., 1987, 1988, 1989
  7. ;
  8. ; Title: VFLATD.ASM - Virtual flat video buffer Device
  9. ;
  10. ; This virtual device simulates a flat video display buffer on
  11. ; hardware that is designed to map video memory 64k at a time
  12. ; at segment A000. The video card is assumed to have 512K VRAM
  13. ;
  14. ; It does this by alocating 512k of linear address space and
  15. ; handling the pages faults in this memory
  16. ;
  17. ; Our PageFault handler is last in the chain, it will only be called
  18. ; by Win386 on pages it does not reconize (ie PT_RESERVED2 pages)
  19. ; this keeps the PageFault overhead to a minimum.
  20. ;
  21. ; Only 16 pages are marked present at a time these corespond to
  22. ; the current 64k hunk of memory mapped by the video card at A0000.
  23. ;
  24. ; When a PageFault occurs the 16 curently present pages are marked
  25. ; not present and a new set of 16 are marked as present. The
  26. ; Video hardware is instructed to map in the 64k page that caused
  27. ; the page fault.
  28. ;
  29. ; PM API Services:
  30. ;
  31. ; Get_Ver (DX = 0000)
  32. ;
  33. ; returns
  34. ; AX version of VFLATD (1.0)
  35. ;
  36. ; Get_Video_Base (DX = 0001)
  37. ;
  38. ; returns
  39. ; AX selector to the video buffer
  40. ; EDX Linear Address of video buffer
  41. ;
  42. ; Reset (DX = 0002)
  43. ; Assume the hardware 64k bank has been modifed and readjust
  44. ; the PageTable mapping
  45. ;
  46. ; returns
  47. ; nothing
  48. ;
  49. ; Version: 1.00
  50. ;
  51. ; Date: 15-Sep-1989
  52. ;
  53. ; Author: LDS
  54. ;
  55. ;------------------------------------------------------------------------------
  56. ;
  57. ; Change log:
  58. ;
  59. ; DATE REV DESCRIPTION
  60. ; ----------- --- -----------------------------------------------------------
  61. ; 15-Sep-1989 LDS Original
  62. ;
  63. ;==============================================================================
  64. ;
  65. ; DESCRIPTION:
  66. ;
  67. ;
  68. ;******************************************************************************
  69. .386p
  70. ;******************************************************************************
  71. ; I N C L U D E S
  72. ;******************************************************************************
  73. IFDEF WIN31
  74. %OUT SUPPORT FOR Windows 3.1
  75. WIN31COMPAT=1
  76. ENDIF
  77. .XLIST
  78. INCLUDE VMM.Inc
  79. ;; INCLUDE Debug.Inc
  80. INCLUDE VFLATD.Inc
  81. .LIST
  82. ;******************************************************************************
  83. ; V I R T U A L D E V I C E D E C L A R A T I O N
  84. ;******************************************************************************
  85. Declare_Virtual_Device VflatD, \
  86. <VflatD_Version shr 8>, \
  87. <VflatD_Version and 255>,\
  88. VFLATD_Control, \
  89. VFLATD_Device_ID, \
  90. UNDEFINED_INIT_ORDER, \
  91. 0, \
  92. VFLATD_PM_API_Handler
  93. ;******************************************************************************
  94. ; L O C A L D A T A
  95. ;******************************************************************************
  96. VxD_LOCKED_DATA_SEG
  97. VFLATD_Video_Sel dw 0 ; GDT Selector to virtual frame buffer
  98. VFLATD_SlidingWindowBase dd ? ;base of 64k sliding window
  99. VFLATD_GDTBase df ? ;base of GDT
  100. VFLATD_VideoSelGDT dd ? ;ptr to video sel's GDT entry
  101. VxD_LOCKED_DATA_ENDS
  102. IFDEF WIN31
  103. VIDEO_BASE equ 0A0000h ; Physical start of VRAM
  104. VIDEO_LIMIT equ 0100000h-1 ; 1M VRAM
  105. VIDEO_NPAGES equ ((VIDEO_LIMIT + 4095) / 4096)
  106. ENDIF
  107. MAXBANKSWITCHSIZE equ 100 ;maximum size of bank switch code
  108. ;******************************************************************************
  109. ; D E V I C E C O N T R O L P R O C E D U R E
  110. ;******************************************************************************
  111. VxD_LOCKED_CODE_SEG
  112. ;******************************************************************************
  113. ;
  114. ; VFLATD_Control
  115. ;
  116. ; DESCRIPTION:
  117. ; This is the VFLATD's control procedure.
  118. ;
  119. ; ENTRY:
  120. ; EAX = Control call ID
  121. ;
  122. ; EXIT:
  123. ; If carry clear then
  124. ; Successful
  125. ; else
  126. ; Control call failed
  127. ;
  128. ; USES:
  129. ; EAX, EBX, ECX, EDX, ESI, EDI, Flags
  130. ;
  131. ;==============================================================================
  132. BeginProc VFLATD_Control
  133. Control_Dispatch Device_Init, VFLATD_Device_Init
  134. IFDEF DEBUG
  135. Control_Dispatch Debug_Query, VFLATD_Debug_Query
  136. ENDIF
  137. clc ; Ignore other control calls
  138. ret
  139. EndProc VFLATD_Control
  140. ;******************************************************************************
  141. ; A P I H A N D L E R S F O R P M V M ' S
  142. ;******************************************************************************
  143. VxD_DATA_SEG
  144. VFLATD_API_Call_Table LABEL DWORD
  145. dd OFFSET32 VFLATD_PM_API_Get_Ver
  146. dd OFFSET32 VFLATD_PM_API_Get_Video_Base
  147. dd OFFSET32 VFLATD_PM_API_Reset
  148. VFLATD_Max_API_Function = ($ - VFLATD_API_Call_Table) / 4 - 1
  149. VxD_DATA_ENDS
  150. ;******************************************************************************
  151. ;
  152. ; VFLATD_Device_Init
  153. ;
  154. ; DESCRIPTION:
  155. ;
  156. ; ENTRY:
  157. ;
  158. ; EXIT:
  159. ; C for error
  160. ;
  161. ; USES:
  162. ; All registers and flags
  163. ;
  164. ;==============================================================================
  165. BeginProc VFLATD_Device_Init
  166. clc
  167. ret
  168. EndProc VFLATD_Device_Init
  169. ;******************************************************************************
  170. ;
  171. ; VFLATD_PM_API_Handler
  172. ;
  173. ; DESCRIPTION:
  174. ;
  175. ; ENTRY:
  176. ; EBX = Handle of VM that called API
  177. ; EBP -> Client register structure
  178. ;
  179. ; EXIT:
  180. ; Client registers and flags may be altered
  181. ;
  182. ; USES:
  183. ; All registers and flags
  184. ;
  185. ;==============================================================================
  186. BeginProc VFLATD_PM_API_Handler
  187. movzx eax, [ebp.Client_DX]
  188. cmp eax, VFLATD_Max_API_Function ; Q: Is this a valid function?
  189. ja SHORT VFLATD_PM_API_Failed
  190. CallRet VFLATD_API_Call_Table[eax*4]
  191. VFLATD_PM_API_Failed:
  192. or [ebp.Client_EFlags], CF_Mask
  193. ret
  194. VFLATD_PM_API_Success:
  195. and [ebp.Client_EFlags], NOT CF_Mask
  196. ret
  197. EndProc VFLATD_PM_API_Handler
  198. ;******************************************************************************
  199. ;
  200. ; VFLATD_PM_API_Get_Ver
  201. ;
  202. ; DESCRIPTION:
  203. ; Return the VFLATD version
  204. ;
  205. ; ENTRY:
  206. ; Client_DX = 0
  207. ;
  208. ; EXIT:
  209. ; Client_AX = 200h
  210. ; Client carry flag clear
  211. ;
  212. ; USES:
  213. ; EAX, Flags, Client_AX, Client_Flags
  214. ;
  215. ;==============================================================================
  216. BeginProc VFLATD_PM_API_Get_Ver
  217. mov [ebp.Client_AX], VflatD_Version
  218. jmp VFLATD_PM_API_Success
  219. EndProc VFLATD_PM_API_Get_Ver
  220. ;******************************************************************************
  221. ;
  222. ; VFLATD_PM_API_Get_Video_Base
  223. ;
  224. ; DESCRIPTION:
  225. ; Return a GDT selector to the flat video buffer
  226. ;
  227. ; ENTRY:
  228. ; Client_DX = 1
  229. ; Client_AX = # of pages of video memory
  230. ; Client_CX = size of bank switch code
  231. ; Client_ES:DI -> bank switch code
  232. ;~~~~~ document guidlines for bank switch code
  233. ;
  234. ; EXIT:
  235. ; Client_AX = Selector to flat video buffer
  236. ; Client_EDX = Linear base of flat video buffer (not usable)
  237. ; Client carry flag clear
  238. ;
  239. ; USES:
  240. ; EAX, Flags, Client_AX, Client_Flags
  241. ;
  242. ;==============================================================================
  243. BeginProc VFLATD_PM_API_Get_Video_Base
  244. cmp [ebp.Client_CX],MAXBANKSWITCHSIZE
  245. ja VFLATD_PM_API_Failed ;bank switch code too big
  246. cmp [VFLATD_Video_sel], 0
  247. jne already_initialized
  248. IFNDEF WIN31
  249. movzx eax, [ebp.Client_AX]
  250. add eax, eax
  251. add eax, 64/4
  252. push eax
  253. VMMCall _MMReserve, <PR_SYSTEM, eax, PR_FIXED>
  254. pop ecx
  255. inc eax
  256. jz VFLATD_PM_API_Failed
  257. add eax, (64*1024-2)
  258. ELSE
  259. ; allocate a hunk of linear address space to use as a virtual
  260. ; frame buffer eax = handle, edx = linear addr
  261. ;
  262. VMMCall _MapPhysToLinear, <3*1024*1024*1024 - (2*1024*1024+64*1024),2*1024*1024+64*1024,0>
  263. or eax, eax
  264. jz VFLATD_PM_API_Failed
  265. add eax,(64*1024-1)
  266. ENDIF
  267. ; round up to 64Kb boundary
  268. and eax, 0FFFF0000h
  269. mov edx, eax
  270. ; Save linear addr of video buffer
  271. ;
  272. mov esi, edx
  273. IFNDEF WIN31
  274. mov [VFLATD_Video_Base], edx
  275. sub ecx, 64/4
  276. shl ecx, 12 ; # of bytes in allocated region
  277. dec ecx
  278. lea ecx, [edx+ecx]
  279. mov [VFLATD_Video_Top], ecx
  280. shr esi, 12 ; virt page # of start of region
  281. movzx ecx, [ebp.Client_AX]
  282. add esi, ecx
  283. VMMCall _MMCommitPhys, <esi, 16, 0A0h, PC_INCR+PC_USER+PC_WRITEABLE>
  284. or eax, eax
  285. jz VFLATD_PM_API_Failed
  286. ELSE
  287. mov [VFLATD_Video_Base],edx
  288. mov eax,edx
  289. add eax,2*VIDEO_LIMIT+1
  290. mov [VFLATD_Video_Top],eax
  291. ; NOTE I dont handle the case where the frame buffer
  292. ; crosses multiple page tables, if it does, FAIL
  293. ;
  294. shr edx,12
  295. and edx,3FFh ; edx = page number
  296. cmp edx,0400h - VIDEO_NPAGES
  297. jg VFLATD_PM_API_Failed
  298. ; find the PTE that describes the base of video memory
  299. ;
  300. mov eax,cr3 ; eax --> Physical base of page dir
  301. VMMCall _MapPhysToLinear, <eax,4*1024,0>
  302. mov edi,eax ; edi --> Linear base of page dir
  303. mov eax,esi ; eax = linear video buffer base
  304. shr eax,22 ; eax = page dir number
  305. mov edi,[edi + 4*eax] ; edi = page dir entry (PDE)
  306. and edi,not 0FFFh ; edi = physical addr of PT
  307. mov eax,esi ; eax = linear video buffer base
  308. shr eax,12
  309. and eax,3FFh ; eax = page number
  310. lea edi,[edi + 4*eax] ; edi = physical addr of PTE
  311. VMMCall _MapPhysToLinear, <edi,VIDEO_NPAGES*4,0>
  312. ; now eax contains the Linear addr of our page table
  313. ;
  314. ; mark all pages as not present and set the page type to PT_RESERVED2
  315. ;
  316. mov edi,eax
  317. mov eax,PG_RESERVED2 OR P_WRITE OR P_USER
  318. mov ecx,VIDEO_NPAGES
  319. rep stosd
  320. ; mark the next 64K present and map it to the 64k of video memory.
  321. m = 0
  322. n = 0
  323. REPT 16
  324. mov dword ptr [edi+m],((VIDEO_BASE+n) OR PG_RESERVED2 OR P_AVAIL)
  325. n = n + 1000h
  326. m = m + 4
  327. ENDM
  328. add edi,m
  329. ; mark the next (VIDEO_NPAGES - 16) pages as not present.
  330. mov eax,PG_RESERVED2 OR P_WRITE OR P_USER
  331. mov ecx,VIDEO_NPAGES - 16
  332. rep stosd
  333. ENDIF
  334. ; allocate a GDT selector to give to PM programs
  335. ;
  336. mov eax, [VFLATD_Video_Base]
  337. movzx ecx, [ebp.Client_AX]
  338. dec ecx
  339. VMMCall _BuildDescriptorDWORDs, <eax,ecx,RW_Data_Type,D_GRAN_PAGE,0>
  340. VMMCall _Allocate_GDT_Selector, <edx,eax,0>
  341. mov [VFLATD_Video_sel],ax
  342. or eax, eax
  343. jz VFLATD_PM_API_Failed
  344. mov edx, [VFLATD_Video_Base]
  345. shr edx, 16
  346. mov [VFLATD_SlidingWindowBase], edx
  347. add edx, (1024*1024 SHR 16)
  348. mov [VFLATD_PresentWindowBase], edx
  349. sgdt [VFLATD_GDTBase]
  350. mov edx, dword ptr [VFLATD_GDTBase+2]
  351. and eax, 0fff8h
  352. add edx, eax ;-> base of sel's GDT entry
  353. add edx, 4
  354. mov [VFLATD_VideoSelGDT_B2], edx
  355. add edx, 3
  356. mov [VFLATD_VideoSelGDT_B3], edx
  357. pushfd
  358. cli
  359. sidt [VFLATD_GDTBase]
  360. mov eax, dword ptr [VFLATD_GDTBase+2]
  361. add eax, 14*8
  362. mov esi, OFFSET32 VFLATD_Direct_PageFault_Handler
  363. xchg word ptr [eax], si ; LSW
  364. ror esi, 16
  365. xchg word ptr [eax+6], si ; MSW
  366. ror esi, 16 ; esi = old handler offset
  367. sub esi, OFFSET32 next_handler + 4
  368. mov [next_handler], esi
  369. popfd
  370. ; make space for copying in the device specific bank switch code in the page
  371. ; fault handler and copy the code in.
  372. mov esi, OFFSET32 VFLATD_EndOfDPH - 1
  373. movzx edi, [ebp.Client_CX]
  374. add edi, esi
  375. std
  376. mov ecx, VFLATD_EndOfDPH - VFLATD_DPH_BankSwitchCode
  377. rep movsb
  378. cld
  379. Client_Ptr_Flat esi, ES, DI
  380. mov edi, OFFSET32 VFLATD_DPH_BankSwitchCode
  381. movzx ecx, [ebp.Client_CX]
  382. rep movsb
  383. already_initialized:
  384. mov ax, [VFLATD_Video_Sel]
  385. mov [ebp.Client_AX], ax
  386. mov eax, [VFLATD_Video_Base]
  387. mov [ebp.Client_EDX], eax
  388. jmp VFLATD_PM_API_Success
  389. EndProc VFLATD_PM_API_Get_Video_Base
  390. ;******************************************************************************
  391. ;
  392. ; VFLATD_PM_API_Reset
  393. ;
  394. ; DESCRIPTION:
  395. ; Called when Video card 64k page mapping has changed by someone other
  396. ; than VFLATD, We mark not present any pages we think are currently
  397. ; mapped to the hardware.
  398. ;
  399. ; ENTRY:
  400. ; Client_DX = 2
  401. ;
  402. ; EXIT:
  403. ; Client carry flag clear
  404. ;
  405. ; USES:
  406. ; EAX, Flags, Client_AX, Client_Flags
  407. ;
  408. ;==============================================================================
  409. BeginProc VFLATD_PM_API_Reset
  410. ; pretend we got a page fault on page zero so the bank gets
  411. ; setup right.
  412. ;
  413. ; we need to fake up a fault frame, and jump into the
  414. ; fault handler.
  415. ; int 3
  416. pushfd ; iretd frame flags
  417. push cs
  418. push OFFSET32 VFLATD_PM_API_Success ; iretd frame return
  419. push 0 ; fault type
  420. push 0 ; saved eax (cr2)
  421. mov eax,[VFLATD_Video_Base] ; faulting address (fake cr2)
  422. jmp short VFLATD_Handle_Fault
  423. EndProc VFLATD_PM_API_Reset
  424. ;******************************************************************************
  425. ; H A R D W A R E I N T E R R U P T P R O C E D U R E S
  426. ;******************************************************************************
  427. ;******************************************************************************
  428. ;
  429. ; BeginProc VFLATD_Direct_PageFault_Handler
  430. ;
  431. ; DESCRIPTION:
  432. ;
  433. ; ENTRY:
  434. ;
  435. ; EXIT:
  436. ;
  437. ; USES:
  438. ;
  439. ;==============================================================================
  440. BeginProc VFLATD_Direct_PageFault_Handler, NO_PROLOG, HIGH_FREQ
  441. push eax
  442. mov eax,cr2
  443. ; Is the fault for us? or in other words does it fall in our
  444. ; virtual video buffer.
  445. ;
  446. cmp eax,12345678h
  447. VFLATD_Video_Base equ dword ptr $-4
  448. jb short VFLATD_Chain_Fault
  449. cmp eax,12345678h
  450. VFLATD_Video_Top equ dword ptr $-4
  451. jb short VFLATD_Handle_Fault
  452. VFLATD_Chain_Fault: ;Chain the PageFault to the next guy in the chain
  453. pop eax
  454. ;; jmp next_handler
  455. db 0E9h
  456. next_handler dd ?
  457. ; NOTE we jump here from VFLATD_PM_API_Reset
  458. VFLATD_Handle_Fault:
  459. push ds
  460. push es
  461. push edx
  462. ; Calculate what 64k bank the fault occured in.
  463. ;
  464. shr eax, 16
  465. sub eax, ss:[VFLATD_SlidingWindowBase] ; eax = bank #
  466. ;==============================================================================
  467. ; >>>>>>>>>>>>> BANK SWITCH CODE GETS INSERTED HERE <<<<<<<<<<<<<<<<<<
  468. ;==============================================================================
  469. VFLATD_DPH_BankSwitchCode label byte
  470. ; we shift the code from here upto the label "VFLATD_EndOfDPH" down to
  471. ; accomodate device specific bank switch code.
  472. ;==============================================================================
  473. mov edx, 12345678h
  474. VFLATD_PresentWindowBase equ dword ptr $-4
  475. sub edx, eax
  476. mov ss:[VFLATD_SlidingWindowBase], edx
  477. ;
  478. ; modify the selector base
  479. ;
  480. mov ss:[12345678h], dl
  481. VFLATD_VideoSelGDT_B2 equ dword ptr $-4
  482. mov ss:[12345678h], dh
  483. VFLATD_VideoSelGDT_B3 equ dword ptr $-4
  484. pop edx
  485. pop es
  486. pop ds
  487. pop eax
  488. add esp, 4
  489. iretd
  490. EndProc VFLATD_Direct_PageFault_Handler
  491. VFLATD_EndOfDPH label byte
  492. db MAXBANKSWITCHSIZE dup (?) ;space for handler to grow when bank
  493. ; switching
  494. VxD_LOCKED_CODE_ENDS
  495. ;******************************************************************************
  496. ; D E B U G G I N G C O D E
  497. ;******************************************************************************
  498. ;******************************************************************************
  499. ;
  500. ; VFLATD_Debug_Query
  501. ;
  502. ; DESCRIPTION:
  503. ; This procedure is only assembled in the debug version of VFLATD.
  504. ;
  505. ; Note that since this procedure can be called at any time by the
  506. ; debugger it is not allowed to call any non-asynchronous services and
  507. ; it must be in a LOCKED code segment.
  508. ;
  509. ; ENTRY:
  510. ; EAX = Debug_Query (equate)
  511. ;
  512. ; EXIT:
  513. ; None
  514. ;
  515. ; USES:
  516. ; EBX, ECX, EDX, ESI, Flags
  517. ;
  518. ;==============================================================================
  519. IFDEF DEBUG
  520. VxD_LOCKED_CODE_SEG
  521. BeginProc VFLATD_Debug_Query
  522. ; Trace_Out "******* VFLATD Debug_Query *******"
  523. mov eax, VFLATD_Video_Base
  524. ; Trace_Out "Video_Base: #EAX"
  525. mov ax, VFLATD_Video_Sel
  526. ; Trace_Out "Video_Sel: #AX"
  527. VFLATD_DQ_Exit:
  528. ret
  529. EndProc VFLATD_Debug_Query
  530. VxD_LOCKED_CODE_ENDS
  531. ENDIF
  532. END