VGA-Compatible Miniport's SvgaHwIoPortXxx
VGA-compatible miniport drivers in x86-based machines replace the system-supplied VGA […]
VGA-Compatible Miniport's SvgaHwIoPortXxx
VGA-compatible miniport drivers in x86-based machines replace the system-supplied VGA miniport driver. Therefore, VGA-compatible miniports must have a set of SvgaHwIoPortXxx functions to support full-screen MS-DOS applications as the system-supplied VGA miniport driver does.
The designer of a new VGA-compatible SVGA miniport driver should adapt one of the system-supplied SVGA miniport's SvgaHwIoPortXxx functions to the adapter's features. As already mentioned in VGA-compatible x86 Based Miniports, miniport drivers for other types of adapters in x86-based machines can have a set of SvgaHwIoPortXxx routines and provide the same support at the discretion of the miniport designer or if the miniport cannot be loaded while the system VGA miniport is loaded.
Windowed VDMs in x86-Based Machines
Each MS-DOS application runs as a Windows VDM, which in turn, runs as a Console Manager application in the Win32 protected subsystem.
In Windows NT platforms, a kernel-mode component called the V86 emulator traps I/O instructions issued by MS-DOS applications. As long as such an application runs within a window, its attempts to access video adapter ports are trapped and reflected back to the system-supplied video VDD, which emulates the behavior of the adapter for the application.
In other words, the display driver retains control of the video adapter while a VDM runs in a window.
Full-Screen VDMs in x86-based Machines
For performance reasons, when the user switches an MS-DOS application to full-screen mode in an x86-based machine, the display driver yields control of the adapter. The system VGA or a VGA-compatible miniport driver then hooks out from the V86 emulator all I/O instructions, such as application-issued IN, REP INSB/INSW/INSD, OUT, and REP OUTSB/OUTSW/OUTSD instructions, to the video I/O ports. These hooked I/O operations are forwarded to the VGA-compatible miniport's SvgaHwIoPortXxx functions.
However, for faster performance, a miniport can call VideoPortSetTrappedEmulatorPorts to allow some I/O ports to be accessed directly by the application. The miniport continues to hook other I/O ports with its SvgaHwIoPortXxx to validate the application-issued instruction stream to those ports.
To prevent a full-screen application from issuing a sequence of instructions that might hang the machine, the SvgaHwIoPortXxx functions monitor the application instruction stream to a driver-determined set of adapter registers. A miniport driver must enable direct access only to I/O ports that are completely safe. For example, ports for the sequencer and miscellaneous output registers should always be hooked by the V86 emulator and trapped to the miniport-supplied SvgaHwIoPortXxx functions for validation.
Direct access to I/O ports for the application is determined by the IOPM (named for the x86 I/O permission map) that the VGA-compatible miniport sets by calling VideoPortSetTrappedEmulatorPorts. Note that the miniport can adjust the IOPM by calling this function to have access ranges, describing I/O ports, released for direct access by the application or re-trapped to an SvgaHwIoPortXxx. The current IOPM determines which ports can be accessed directly by the application and which remain hooked by the V86 emulator and trapped to an SvgaHwIoPortXxx function for validation.
By default, all I/O ports set up in such a miniport's emulator access ranges array are trapped to the corresponding SvgaHwIoPortXxx. However, VGA-compatible miniport drivers usually call VideoPortSetTrappedEmulatorPorts on receipt of an IOCTL_VIDEO_ENABLE_VDM request to reset the IOPM for the VDM to allow direct access to some of these I/O ports. Usually, such a driver allows direct access to all video adapter registers except the VGA sequencer registers and the miscellaneous output register, plus any SVGA adapter-specific registers that the driver writer has determined should always be validated by an SvgaHwIoPortXxx.
VGA-Compatible Miniport's HwVidFindAdapter
A VGA-compatible miniport's HwVidFindAdapter function (or registry HwVid..Callback) must set up the following in the VIDEO_PORT_CONFIG_INFO buffer:
· NumEmulatorAccessEntries, indicating the number of entries in the EmulatorAccessEntries array
· EmulatorAccessEntries, pointing to a static array containing the given number of EMULATOR_ACCESS_ENTRY-type elements, each describing a range of I/O ports hooked from the V86 emulator and, by default, forwarded to an SvgaHwIoPortXxx
Each entry includes a starting I/O address, a range length, the size of access to be trapped (UCHAR, USHORT, or ULONG), whether the miniport supports input or output of string data through the I/O port(s), and the miniport-supplied SvgaHwIoPortXxx that actually validates and, possibly, transfers the data. Each SvgaHwIoPortXxx function handles read (IN or REP INSB/INSW/INSD) and/or write (OUT or REP OUTSB/OUTSW/OUTSD) transfers of UCHAR-, USHORT-, or ULONG-sized data.
· EmulatorAccessEntriesContext, a pointer to storage, such as an area in the miniport's device extension, in which the miniport's SvgaHwIoPortXxx can batch a sequence of application-issued instructions that require validation
· VdmPhysicalVideoMemoryAddress and VdmPhysicalVideoMemoryLength, describing a range of video memory that must be mapped into the VDM address space to support BIOS INT10 calls from full-screen MS-DOS applications
The miniport driver can call the VideoPortInt10 function when such an application changes the video mode to one that the miniport driver's adapter can support.
· HardwareStateSize, describing the minimum number of bytes required to store the hardware state for the adapter in response to an IOCTL_VIDEO_SAVE_HARDWARE_STATE request
When the user switches a full-screen MS-DOS application to run in a window, the miniport driver must save the adapter state before the display driver regains control of the video adapter. Note that a VGA-compatible miniport driver also must support the reciprocal IOCTL_VIDEO_RESTORE_HARDWARE_STATE request because the user might switch the windowed application back to full-screen mode.
A VGA-compatible miniport's emulator access entries specify subsets of its access ranges array for the adapter. The emulator access entries can be and usually are all I/O ports in the mapped access ranges array set up by its HwVidFindAdapter function. The access ranges it passes in calls to VideoPortSetTrappedEmulatorPorts, defining the current IOPM and determining the I/O ports that are directly accessible by a full-screen MS-DOS application, specify subsets of the miniport's emulator access entries.
Validating Instructions in SvgaHwIoPortXxx
As already mentioned in VGA-Compatible Miniports HwFindAdapter, the IOPM set for directly accessible I/O ports usually includes all SVGA registers except the sequencer registers and the miscellaneous output register, which the VGA-compatible miniport continues to monitor with its SvgaHwIoPortXxx functions. The sequencer registers control internal chip timing on VGA-compatible video adapters. If a full-screen MS-DOS application touches other adapter registers during a synchronous reset, the machine can hang. Likewise, if the miscellaneous output register is set to select a nonexistent clock, the machine can hang.
VGA-compatible miniport drivers must ensure that full-screen MS-DOS applications do not issue instructions that cause the machine to hang. Each such miniport driver must supply SvgaHwIoPortXxx function that monitor application-issued instructions to the I/O ports for the adapter sequencer registers and miscellaneous output register. Each new VGA-compatible miniport driver for an adapter with special features also must monitor and continue to validate any I/O ports to which an application might send any instruction sequence that could hang the machine.
Whenever an application attempts to access the sequencer clock register, the SvgaHwIoPortXxx must change the IOPM in order to trap all instructions coming in during a synchronous reset. As soon as an application sends an instruction that affects the sequencer or attempts to write to the miscellaneous output register, the SvgaHwIoPortXxx should adjust the IOPM by calling VideoPortSetTrappedEmulatorPorts to disable direct access to all adapter registers.
The miniport-supplied SvgaHwIoPortXxx functions should buffer subsequent IN (or INSB/INSW/INSD) and/or OUT (or OUTSB/OUTSW/OUTSD) instructions in the EmulatorAccessEntriesContext area it set up in the VIDEO_PORT_CONFIG_INFO (see VGA-Compatible Miniports HwFindAdapter ) until the synchronous reset is done, or until the application either restores the miscellaneous output register or resets it to a "safe" clock.
Then, the miniport driver is responsible for checking that the buffered instructions cannot hang the machine. If not, the miniport should process the buffered instructions, usually by calling VideoPortSynchronizeExecution with a driver-supplied HwVidSynchronizeExecutionCallback function. Otherwise, the miniport driver should discard the buffered instructions.
VGA-Compatible Miniport's HwVidStartIO
When the user switches a full-screen MS-DOS application back to running in a window, a VGA-compatible miniport's HwVidStartIO function is sent a VRP with the I/O control code IOCTL_VIDEO_SAVE_HARDWARE_STATE. The miniport must store the state of the adapter in case the user switches the application to full-screen mode again.
Note that the miniport's SvgaHwIoPortXxx might have buffered a sequence of application INs and/or OUTs, as described in Validating Instructions in SvgaHwIoPortXxx, when its HwVidStartIO routine is called to save the adapter state. In these circumstances, the miniport should save the current state, including the buffered instructions, so that the SvgaHwIoPortXxx can resume validation operations exactly where they left off if the user switches the application to full-screen mode again.
When the miniport completes a save operation, the port driver automatically disables the current IOPM for VDMs and the miniport's SvgaHwIoPortXxx functions. The port driver restores the IOPM automatically if the application is switched to full-screen mode again. It also resumes calling the miniport's SvgaHwIoPortXxx, after it calls the miniport's HwVidStartIO routine with the IOCTL_VIDEO_RESTORE_HARDWARE_STATE request.