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.

905 lines
21 KiB

  1. /*--
  2. Copyright (c) 1990-2000 Microsoft Corporation
  3. Module Name:
  4. portia64.c
  5. Abstract:
  6. This is the IA64 specific part of the video port driver.
  7. Author:
  8. William K. Cheung (wcheung)
  9. based on Andre Vachon (andreva) 10-Jan-1991
  10. Environment:
  11. kernel mode only
  12. Notes:
  13. This module is a driver which implements OS dependant functions on the
  14. behalf of the video drivers
  15. Revision History:
  16. --*/
  17. #include "videoprt.h"
  18. #include "emulate.h"
  19. #define LOW_MEM_SEGMET 0
  20. #define LOW_MEM_OFFSET 0
  21. #define SIZE_OF_VECTOR_TABLE 0x400
  22. #define SIZE_OF_BIOS_DATA_AREA 0x400
  23. VOID
  24. InitIoMemoryBase(
  25. VOID
  26. );
  27. extern XM_STATUS x86BiosExecuteInterrupt (
  28. IN UCHAR Number,
  29. IN OUT PXM86_CONTEXT Context,
  30. IN PVOID BiosIoSpace OPTIONAL,
  31. IN PVOID BiosIoMemory OPTIONAL
  32. );
  33. extern PVOID x86BiosTranslateAddress (
  34. IN USHORT Segment,
  35. IN USHORT Offset
  36. );
  37. BOOLEAN
  38. CallBiosEx (
  39. IN ULONG BiosCommand,
  40. IN OUT PULONG Eax,
  41. IN OUT PULONG Ebx,
  42. IN OUT PULONG Ecx,
  43. IN OUT PULONG Edx,
  44. IN OUT PULONG Esi,
  45. IN OUT PULONG Edi,
  46. IN OUT PULONG Ebp,
  47. IN OUT PUSHORT SegDs,
  48. IN OUT PUSHORT SegEs
  49. );
  50. VOID
  51. InitializeX86Int10CallEx(
  52. PUCHAR BiosTransferArea,
  53. ULONG BiosTransferLength
  54. );
  55. VOID
  56. InitializeX86Int10Call(
  57. PUCHAR BiosTransferArea,
  58. ULONG BiosTransferLength
  59. );
  60. #ifdef ALLOC_PRAGMA
  61. #pragma alloc_text(PAGE,InitIoMemoryBase)
  62. #pragma alloc_text(PAGE,pVideoPortEnableVDM)
  63. #pragma alloc_text(PAGE,VideoPortInt10)
  64. #pragma alloc_text(PAGE,pVideoPortRegisterVDM)
  65. #pragma alloc_text(PAGE,pVideoPortSetIOPM)
  66. #pragma alloc_text(PAGE,VideoPortSetTrappedEmulatorPorts)
  67. #pragma alloc_text(PAGE,pVideoPortInitializeInt10)
  68. #pragma alloc_text(PAGE,CallBiosEx)
  69. #pragma alloc_text(PAGE,InitializeX86Int10Call)
  70. #pragma alloc_text(PAGE,VpInt10AllocateBuffer)
  71. #pragma alloc_text(PAGE,VpInt10FreeBuffer)
  72. #pragma alloc_text(PAGE,VpInt10ReadMemory)
  73. #pragma alloc_text(PAGE,VpInt10WriteMemory)
  74. #pragma alloc_text(PAGE,VpInt10CallBios)
  75. #endif
  76. //
  77. // Initialize Default X86 bios spaces
  78. //
  79. PVOID IoControlBase = NULL;
  80. PVOID IoMemoryBase = NULL;
  81. PVOID IoFrameBufferBase = NULL;
  82. PVOID IoLowMemoryBase = NULL;
  83. #define VGA_FRAMEBUFFER_SIZE (0xc0000 - 0xa0000)
  84. //
  85. // Define global data.
  86. //
  87. ULONG X86BiosInitialized = FALSE;
  88. ULONG EnableInt10Calls = FALSE;
  89. VOID
  90. InitIoMemoryBase(
  91. VOID
  92. )
  93. /*++
  94. Routine Description:
  95. Arguements:
  96. Return Value:
  97. --*/
  98. {
  99. PHYSICAL_ADDRESS COMPATIBLE_LOW_PHYSICAL_BASE_ADDRESS = { 0x0000};
  100. PHYSICAL_ADDRESS COMPATIBLE_PCI_PHYSICAL_BASE_ADDRESS = { 0xC0000};
  101. PHYSICAL_ADDRESS VGA_FRAMEBUFFER_PHYSICAL_BASE_ADDRESS = { 0xa0000 };
  102. MEMORY_CACHING_TYPE legacyBiosMapping = MmNonCached;
  103. MEMORY_CACHING_TYPE vgaFrameBufferMapping = MmNonCached;
  104. IoLowMemoryBase = (PUCHAR)MmMapIoSpace (
  105. COMPATIBLE_LOW_PHYSICAL_BASE_ADDRESS,
  106. PAGE_SIZE,
  107. legacyBiosMapping
  108. );
  109. ASSERT(IoLowMemoryBase);
  110. IoMemoryBase = (PUCHAR)MmMapIoSpace (
  111. COMPATIBLE_PCI_PHYSICAL_BASE_ADDRESS,
  112. 0x100000-0XC0000,
  113. legacyBiosMapping
  114. );
  115. ASSERT(IoMemoryBase);
  116. if (IoMemoryBase != NULL) {
  117. IoMemoryBase = (PVOID)((ULONG64)IoMemoryBase - 0xC0000);
  118. }
  119. IoFrameBufferBase = (PUCHAR)MmMapIoSpace (
  120. VGA_FRAMEBUFFER_PHYSICAL_BASE_ADDRESS,
  121. (ULONG) VGA_FRAMEBUFFER_SIZE,
  122. vgaFrameBufferMapping
  123. );
  124. ASSERT(IoFrameBufferBase);
  125. if (IoFrameBufferBase != NULL) {
  126. IoFrameBufferBase = (PVOID)((ULONG64)IoFrameBufferBase - 0xA0000);
  127. }
  128. }
  129. NTSTATUS
  130. pVideoPortEnableVDM(
  131. IN PFDO_EXTENSION DeviceExtension,
  132. IN BOOLEAN Enable,
  133. IN PVIDEO_VDM VdmInfo,
  134. IN ULONG VdmInfoSize
  135. )
  136. /*++
  137. Routine Description:
  138. This routine allows the kernel video driver to unhook I/O ports or
  139. specific interrupts from the V86 fault handler. Operations on the
  140. specified ports will be forwarded back to the user-mode VDD once
  141. disconnection is completed.
  142. Arguments:
  143. DeviceExtension - Pointer to the port driver's device extension.
  144. Enable - Determines if the VDM should be enabled (TRUE) or disabled
  145. (FALSE).
  146. VdmInfo - Pointer to the VdmInfo passed by the caller.
  147. VdmInfoSize - Size of the VdmInfo struct passed by the caller.
  148. Return Value:
  149. STATUS_NOT_IMPLEMENTED
  150. --*/
  151. {
  152. UNREFERENCED_PARAMETER(DeviceExtension);
  153. UNREFERENCED_PARAMETER(VdmInfo);
  154. UNREFERENCED_PARAMETER(VdmInfoSize);
  155. return STATUS_NOT_IMPLEMENTED;
  156. } // pVideoPortEnableVDM()
  157. VP_STATUS
  158. VideoPortInt10(
  159. PVOID HwDeviceExtension,
  160. PVIDEO_X86_BIOS_ARGUMENTS BiosArguments
  161. )
  162. /*++
  163. Routine Description:
  164. This function allows a miniport driver to call the kernel to perform
  165. an int10 operation.
  166. This will execute natively the BIOS ROM code on the device.
  167. THIS FUNCTION IS FOR X86 ONLY.
  168. Arguments:
  169. HwDeviceExtension - Pointer to the miniport driver's device extension.
  170. BiosArguments - Pointer to a structure containing the value of the
  171. basic x86 registers that should be set before calling the BIOS routine.
  172. 0 should be used for unused registers.
  173. Return Value:
  174. ERROR_INVALID_PARAMETER
  175. ERROR_INVALID_FUNCTION - in case HAL call is failed
  176. --*/
  177. {
  178. BOOLEAN bStatus;
  179. PFDO_EXTENSION deviceExtension = GET_FDO_EXT(HwDeviceExtension);
  180. ULONG inIoSpace = 0;
  181. PVOID virtualAddress;
  182. ULONG length;
  183. CONTEXT context;
  184. //
  185. // Must make sure the caller is a trusted subsystem with the
  186. // appropriate address space set up.
  187. //
  188. if (!SeSinglePrivilegeCheck(RtlConvertLongToLuid(
  189. SE_TCB_PRIVILEGE),
  190. deviceExtension->CurrentIrpRequestorMode)) {
  191. return ERROR_INVALID_PARAMETER;
  192. }
  193. //
  194. // Now call the HAL to actually perform the int 10 operation.
  195. //
  196. pVideoDebugPrint
  197. ((3, "VIDEOPRT: Int10: edi %x esi %x eax %x ebx %x \n\t ecx %x edx %x ebp %x\n",
  198. BiosArguments->Edi,
  199. BiosArguments->Esi,
  200. BiosArguments->Eax,
  201. BiosArguments->Ebx,
  202. BiosArguments->Ecx,
  203. BiosArguments->Edx,
  204. BiosArguments->Ebp ));
  205. //
  206. // Need to protect HalCallBios fro reentrance
  207. //
  208. KeWaitForSingleObject(&VpInt10Mutex,
  209. Executive,
  210. KernelMode,
  211. FALSE,
  212. (PTIME)NULL);
  213. bStatus = HalCallBios (0x10,
  214. &(BiosArguments->Eax),
  215. &(BiosArguments->Ebx),
  216. &(BiosArguments->Ecx),
  217. &(BiosArguments->Edx),
  218. &(BiosArguments->Esi),
  219. &(BiosArguments->Edi),
  220. &(BiosArguments->Ebp));
  221. KeReleaseMutex(&VpInt10Mutex, FALSE);
  222. if (bStatus) {
  223. pVideoDebugPrint ((3, "VIDEOPRT: Int10: Int 10 succeded properly\n"));
  224. return NO_ERROR;
  225. } else {
  226. pVideoDebugPrint ((0, "VIDEOPRT: Int10: Int 10 failed\n"));
  227. return ERROR_INVALID_FUNCTION;
  228. }
  229. } // end VideoPortInt10()
  230. NTSTATUS
  231. pVideoPortRegisterVDM(
  232. IN PFDO_EXTENSION DeviceExtension,
  233. IN PVIDEO_VDM VdmInfo,
  234. IN ULONG VdmInfoSize,
  235. OUT PVIDEO_REGISTER_VDM RegisterVdm,
  236. IN ULONG RegisterVdmSize,
  237. OUT PULONG_PTR OutputSize
  238. )
  239. /*++
  240. Routine Description:
  241. This routine is used to register a VDM when it is started up.
  242. What this routine does is map the VIDEO BIOS into the VDM address space
  243. so that DOS apps can use it directly. Since the BIOS is READ_ONLY, we
  244. have no problem in mapping it as many times as we want.
  245. It returns the size of the save state buffer that must be allocated by
  246. the caller.
  247. Arguments:
  248. Return Value:
  249. STATUS_NOT_IMPLEMENTED
  250. --*/
  251. {
  252. UNREFERENCED_PARAMETER(DeviceExtension);
  253. UNREFERENCED_PARAMETER(VdmInfo);
  254. UNREFERENCED_PARAMETER(VdmInfoSize);
  255. UNREFERENCED_PARAMETER(RegisterVdm);
  256. UNREFERENCED_PARAMETER(RegisterVdmSize);
  257. UNREFERENCED_PARAMETER(OutputSize);
  258. return STATUS_NOT_IMPLEMENTED;
  259. } // end pVideoPortRegisterVDM()
  260. NTSTATUS
  261. pVideoPortSetIOPM(
  262. IN ULONG NumAccessRanges,
  263. IN PVIDEO_ACCESS_RANGE AccessRange,
  264. IN BOOLEAN Enable,
  265. IN ULONG IOPMNumber
  266. )
  267. /*++
  268. Routine Description:
  269. This routine is used to change the IOPM.
  270. This routine is x86 specific.
  271. Arguments:
  272. Return Value:
  273. STATUS_NOT_IMPLEMENTED
  274. --*/
  275. {
  276. UNREFERENCED_PARAMETER(NumAccessRanges);
  277. UNREFERENCED_PARAMETER(AccessRange);
  278. UNREFERENCED_PARAMETER(Enable);
  279. UNREFERENCED_PARAMETER(IOPMNumber);
  280. return STATUS_NOT_IMPLEMENTED;
  281. } // end pVideoPortSetIOPM()
  282. VP_STATUS
  283. VideoPortSetTrappedEmulatorPorts(
  284. PVOID HwDeviceExtension,
  285. ULONG NumAccessRanges,
  286. PVIDEO_ACCESS_RANGE AccessRange
  287. )
  288. /*++
  289. Routine Description:
  290. VideoPortSetTrappedEmulatorPorts (x86 machines only) allows a miniport
  291. driver to dynamically change the list of I/O ports that are trapped when
  292. a VDM is running in full-screen mode. The default set of ports being
  293. trapped by the miniport driver is defined to be all ports in the
  294. EMULATOR_ACCESS_ENTRY structure of the miniport driver.
  295. I/O ports not listed in the EMULATOR_ACCESS_ENTRY structure are
  296. unavailable to the MS-DOS application. Accessing those ports causes a
  297. trap to occur in the system, and the I/O operation to be reflected to a
  298. user-mode virtual device driver.
  299. The ports listed in the specified VIDEO_ACCESS_RANGE structure will be
  300. enabled in the I/O Permission Mask (IOPM) associated with the MS-DOS
  301. application. This will enable the MS-DOS application to access those I/O
  302. ports directly, without having the IO instruction trap and be passed down
  303. to the miniport trap handling functions (for example EmulatorAccessEntry
  304. functions) for validation. However, the subset of critical IO ports must
  305. always remain trapped for robustness.
  306. All MS-DOS applications use the same IOPM, and therefore the same set of
  307. enabled/disabled I/O ports. Thus, on each switch of application, the
  308. set of trapped I/O ports is reinitialized to be the default set of ports
  309. (all ports in the EMULATOR_ACCESS_ENTRY structure).
  310. Arguments:
  311. HwDeviceExtension - Points to the miniport driver's device extension.
  312. NumAccessRanges - Specifies the number of entries in the VIDEO_ACCESS_RANGE
  313. structure specified in AccessRange.
  314. AccessRange - Points to an array of access ranges (VIDEO_ACCESS_RANGE)
  315. defining the ports that can be untrapped and accessed directly by
  316. the MS-DOS application.
  317. Return Value:
  318. This function returns the final status of the operation.
  319. Environment:
  320. This routine cannot be called from a miniport routine synchronized with
  321. VideoPortSynchronizeRoutine or from an ISR.
  322. --*/
  323. {
  324. UNREFERENCED_PARAMETER(HwDeviceExtension);
  325. UNREFERENCED_PARAMETER(NumAccessRanges);
  326. UNREFERENCED_PARAMETER(AccessRange);
  327. return ERROR_INVALID_PARAMETER;
  328. } // end VideoPortSetTrappedEmulatorPorts()
  329. VOID
  330. VideoPortZeroDeviceMemory(
  331. IN PVOID Destination,
  332. IN ULONG Length
  333. )
  334. /*++
  335. Routine Description:
  336. VideoPortZeroDeviceMemory zeroes a block of device memory of a certain
  337. length (Length) located at the address specified in Destination.
  338. Arguments:
  339. Destination - Specifies the starting address of the block of memory to be
  340. zeroed.
  341. Length - Specifies the length, in bytes, of the memory to be zeroed.
  342. Return Value:
  343. None.
  344. --*/
  345. {
  346. RtlZeroMemory(Destination,Length);
  347. }
  348. VOID
  349. pVideoPortInitializeInt10(
  350. PFDO_EXTENSION FdoExtension
  351. )
  352. {
  353. if (ServerBiosAddressSpaceInitialized) {
  354. return;
  355. }
  356. BiosTransferArea = ExAllocatePool(PagedPool, 0x1000 + 3);
  357. InitializeX86Int10Call(BiosTransferArea, 0x1000);
  358. ServerBiosAddressSpaceInitialized = TRUE;
  359. }
  360. BOOLEAN
  361. CallBiosEx (
  362. IN ULONG BiosCommand,
  363. IN OUT PULONG Eax,
  364. IN OUT PULONG Ebx,
  365. IN OUT PULONG Ecx,
  366. IN OUT PULONG Edx,
  367. IN OUT PULONG Esi,
  368. IN OUT PULONG Edi,
  369. IN OUT PULONG Ebp,
  370. IN OUT PUSHORT SegDs,
  371. IN OUT PUSHORT SegEs
  372. )
  373. /*++
  374. Routine Description:
  375. This function provides the platform specific interface between a device
  376. driver and the execution of the x86 ROM bios code for the specified ROM
  377. bios command.
  378. Arguments:
  379. BiosCommand - Supplies the ROM bios command to be emulated.
  380. Eax to Ebp - Supplies the x86 emulation context.
  381. Return Value:
  382. A value of TRUE is returned if the specified function is executed.
  383. Otherwise, a value of FALSE is returned.
  384. --*/
  385. {
  386. XM86_CONTEXT Context;
  387. //
  388. // If the x86 BIOS Emulator has not been initialized, then return FALSE.
  389. //
  390. if (X86BiosInitialized == FALSE) {
  391. return FALSE;
  392. }
  393. //
  394. // If the Adapter BIOS initialization failed and an Int10 command is
  395. // specified, then return FALSE.
  396. //
  397. if ((BiosCommand == 0x10) && (EnableInt10Calls == FALSE)) {
  398. return FALSE;
  399. }
  400. //
  401. // Copy the x86 bios context and emulate the specified command.
  402. //
  403. Context.Eax = *Eax;
  404. Context.Ebx = *Ebx;
  405. Context.Ecx = *Ecx;
  406. Context.Edx = *Edx;
  407. Context.Esi = *Esi;
  408. Context.Edi = *Edi;
  409. Context.Ebp = *Ebp;
  410. Context.SegDs = *SegDs;
  411. Context.SegEs = *SegEs;
  412. if (x86BiosExecuteInterruptShadowed((UCHAR)BiosCommand,
  413. &Context,
  414. (PVOID)IoControlBase,
  415. (PVOID)IoMemoryBase,
  416. (PVOID)IoFrameBufferBase
  417. )
  418. != XM_SUCCESS) {
  419. return FALSE;
  420. }
  421. //
  422. // Copy the x86 bios context and return TRUE.
  423. //
  424. *Eax = Context.Eax;
  425. *Ebx = Context.Ebx;
  426. *Ecx = Context.Ecx;
  427. *Edx = Context.Edx;
  428. *Esi = Context.Esi;
  429. *Edi = Context.Edi;
  430. *Ebp = Context.Ebp;
  431. *SegDs = Context.SegDs;
  432. *SegEs = Context.SegEs;
  433. return TRUE;
  434. }
  435. VOID
  436. InitializeX86Int10Call(
  437. PUCHAR BiosTransferArea,
  438. ULONG BiosTransferLength
  439. )
  440. /*++
  441. Routine Description:
  442. This function initializes x86 bios emulator, display data area and
  443. interrupt vector area.
  444. Arguments:
  445. None.
  446. Return Value:
  447. None.
  448. --*/
  449. {
  450. XM86_CONTEXT State;
  451. PXM86_CONTEXT Context;
  452. PULONG x86BiosLowMemoryPtr, PhysicalMemoryPtr;
  453. InitIoMemoryBase();
  454. //
  455. // Initialize the x86 bios emulator.
  456. //
  457. x86BiosInitializeBiosEx(IoControlBase,
  458. IoMemoryBase,
  459. IoFrameBufferBase,
  460. BiosTransferArea,
  461. BiosTransferLength);
  462. x86BiosLowMemoryPtr = (PULONG)(x86BiosTranslateAddress(LOW_MEM_SEGMET, LOW_MEM_OFFSET));
  463. //
  464. // Copy the VECTOR TABLE from 0 to 2k. This is because we are not executing
  465. // the initialization of Adapter since SAL takes care of it. However, the
  466. // emulation memory needs to be updated from the interrupt vector and BIOS
  467. // data area.
  468. //
  469. RtlCopyMemory(x86BiosLowMemoryPtr,
  470. IoLowMemoryBase,
  471. (SIZE_OF_VECTOR_TABLE+SIZE_OF_BIOS_DATA_AREA)
  472. );
  473. X86BiosInitialized = TRUE;
  474. //
  475. // Check to see if a video bios appears to be present and int10 vector
  476. // points somewhere inside of the video bios
  477. //
  478. {
  479. PUSHORT pBiosSignature = (PUSHORT)(x86BiosTranslateAddress(0xc000, // VIDEO_BIOS_SEGMENT
  480. 0x0000));
  481. ULONG Address = *(PULONG)(x86BiosTranslateAddress(0x0, 0x40));
  482. Address = ((Address & 0xFFFF0000) >> 12) + (Address & 0xFFFF); // Normalize
  483. EnableInt10Calls = (*pBiosSignature == 0xAA55) &&
  484. (Address >= 0xC0000) && (Address < 0xD0000);
  485. #if DBG
  486. pVideoDebugPrint ((0, "VIDEOPRT: EnableInt10Calls is %d\n", EnableInt10Calls ));
  487. #endif
  488. }
  489. return;
  490. }
  491. VP_STATUS
  492. VpInt10AllocateBuffer(
  493. IN PVOID Context,
  494. OUT PUSHORT Seg,
  495. OUT PUSHORT Off,
  496. IN OUT PULONG Length
  497. )
  498. {
  499. VP_STATUS Status = STATUS_INSUFFICIENT_RESOURCES;
  500. if (Int10BufferAllocated == FALSE) {
  501. if (*Length <= 0x1000) {
  502. *Seg = VDM_TRANSFER_SEGMENT;
  503. *Off = VDM_TRANSFER_OFFSET;
  504. Int10BufferAllocated = TRUE;
  505. Status = NO_ERROR;
  506. }
  507. }
  508. *Length = VDM_TRANSFER_LENGTH;
  509. return Status;
  510. }
  511. VP_STATUS
  512. VpInt10FreeBuffer(
  513. IN PVOID Context,
  514. IN USHORT Seg,
  515. IN USHORT Off
  516. )
  517. {
  518. VP_STATUS Status = STATUS_INVALID_PARAMETER;
  519. if ((VDM_TRANSFER_SEGMENT == Seg) && (VDM_TRANSFER_OFFSET == Off)) {
  520. if (Int10BufferAllocated == TRUE) {
  521. Int10BufferAllocated = FALSE;
  522. Status = NO_ERROR;
  523. }
  524. }
  525. return Status;
  526. }
  527. VP_STATUS
  528. VpInt10ReadMemory(
  529. IN PVOID Context,
  530. IN USHORT Seg,
  531. IN USHORT Off,
  532. OUT PVOID Buffer,
  533. IN ULONG Length
  534. )
  535. {
  536. ULONG_PTR Address = ((Seg << 4) + Off);
  537. if ((Address >= (VDM_TRANSFER_SEGMENT << 4)) &&
  538. ((Address + Length) <= ((VDM_TRANSFER_SEGMENT << 4) + VDM_TRANSFER_LENGTH))) {
  539. PUCHAR Memory = BiosTransferArea + Address - (VDM_TRANSFER_SEGMENT << 4);
  540. RtlCopyMemory(Buffer, Memory, Length);
  541. } else {
  542. RtlCopyMemory(Buffer, (PUCHAR)IoMemoryBase + Address, Length);
  543. }
  544. return NO_ERROR;
  545. }
  546. VP_STATUS
  547. VpInt10WriteMemory(
  548. IN PVOID Context,
  549. IN USHORT Seg,
  550. IN USHORT Off,
  551. IN PVOID Buffer,
  552. IN ULONG Length
  553. )
  554. {
  555. ULONG_PTR Address = ((Seg << 4) + Off);
  556. if ((Address >= (VDM_TRANSFER_SEGMENT << 4)) &&
  557. ((Address + Length) <= ((VDM_TRANSFER_SEGMENT << 4) + VDM_TRANSFER_LENGTH))) {
  558. PUCHAR Memory = BiosTransferArea + Address - (VDM_TRANSFER_SEGMENT << 4);
  559. RtlCopyMemory(Memory, Buffer, Length);
  560. } else {
  561. return STATUS_INVALID_PARAMETER;
  562. }
  563. return NO_ERROR;
  564. }
  565. VP_STATUS
  566. VpInt10CallBios(
  567. PVOID HwDeviceExtension,
  568. PINT10_BIOS_ARGUMENTS BiosArguments
  569. )
  570. /*++
  571. Routine Description:
  572. This function allows a miniport driver to call the kernel to perform
  573. an int10 operation.
  574. This will execute natively the BIOS ROM code on the device.
  575. THIS FUNCTION IS FOR X86 ONLY.
  576. Arguments:
  577. HwDeviceExtension - Pointer to the miniport driver's device extension.
  578. BiosArguments - Pointer to a structure containing the value of the
  579. basic x86 registers that should be set before calling the BIOS routine.
  580. 0 should be used for unused registers.
  581. Return Value:
  582. ERROR_INVALID_PARAMETER
  583. --*/
  584. {
  585. BOOLEAN bStatus;
  586. PFDO_EXTENSION deviceExtension = GET_FDO_EXT(HwDeviceExtension);
  587. ULONG inIoSpace = 0;
  588. PVOID virtualAddress;
  589. ULONG length;
  590. CONTEXT context;
  591. //
  592. // Must make sure the caller is a trusted subsystem with the
  593. // appropriate address space set up.
  594. //
  595. if (!SeSinglePrivilegeCheck(RtlConvertLongToLuid(
  596. SE_TCB_PRIVILEGE),
  597. deviceExtension->CurrentIrpRequestorMode)) {
  598. return ERROR_INVALID_PARAMETER;
  599. }
  600. if (ServerBiosAddressSpaceInitialized == 0) {
  601. ASSERT(FALSE);
  602. return ERROR_INVALID_PARAMETER;
  603. }
  604. //
  605. // Now call the HAL to actually perform the int 10 operation.
  606. //
  607. pVideoDebugPrint
  608. ((3, "VIDEOPRT: Int10: edi %x esi %x eax %x ebx %x \n\t ecx %x edx %x ebp %x ds %x es %x\n",
  609. BiosArguments->Edi,
  610. BiosArguments->Esi,
  611. BiosArguments->Eax,
  612. BiosArguments->Ebx,
  613. BiosArguments->Ecx,
  614. BiosArguments->Edx,
  615. BiosArguments->Ebp,
  616. BiosArguments->SegDs,
  617. BiosArguments->SegEs ));
  618. KeWaitForSingleObject(&VpInt10Mutex,
  619. Executive,
  620. KernelMode,
  621. FALSE,
  622. (PTIME)NULL);
  623. bStatus = CallBiosEx (0x10,
  624. &(BiosArguments->Eax),
  625. &(BiosArguments->Ebx),
  626. &(BiosArguments->Ecx),
  627. &(BiosArguments->Edx),
  628. &(BiosArguments->Esi),
  629. &(BiosArguments->Edi),
  630. &(BiosArguments->Ebp),
  631. &(BiosArguments->SegDs),
  632. &(BiosArguments->SegEs));
  633. KeReleaseMutex(&VpInt10Mutex, FALSE);
  634. if (bStatus) {
  635. pVideoDebugPrint ((3, "VIDEOPRT: Int10: Int 10 succeded properly\n"));
  636. return NO_ERROR;
  637. } else {
  638. pVideoDebugPrint ((0, "VIDEOPRT: Int10: Int 10 failed\n"));
  639. return ERROR_INVALID_PARAMETER;
  640. }
  641. }