XFree86 server 4.x Design (DRAFT) : The vgahw module
Previous: Helper Functions
Next: Some notes about writing a driver

## 19. The vgahw module

The vgahw modules provides an interface for saving, restoring and programming the standard VGA registers, and for handling VGA colourmaps.

### 19.1. Data Structures

The public data structures used by the vgahw module are `vgaRegRec` and `vgaHWRec`. They are defined in `vgaHW.h.`

### 19.2. General vgahw Functions

> `Bool vgaHWGetHWRec(ScrnInfoPtr pScrn)`

> > This function allocates a `vgaHWRec` structure, and hooks it into the `ScrnInfoRec`'s `privates`. Like all information hooked into the `privates`, it is persistent, and only needs to be allocated once per screen. This function should normally be called from the driver's `ChipPreInit()` function. The `vgaHWRec` is zero-allocated, and the following fields are explicitly initialised:

> > `ModeReg.DAC[]`

> > > initialised with a default colourmap

> > `ModeReg.Attribute[0x11]`

> > > initialised with the default overscan index

> > `ShowOverscan`

> > > initialised according to the "ShowOverscan" option

> > `paletteEnabled`

> > > initialised to FALSE

> > `cmapSaved`

> > > initialised to FALSE

> > `pScrn`

> > > initialised to pScrn

> > In addition to the above, `vgaHWSetStdFuncs()` is called to initialise the register access function fields with the standard VGA set of functions.

> > Once allocated, a pointer to the `vgaHWRec` can be obtained from the `ScrnInfoPtr` with the `VGAHWPTR(pScrn)` macro.

> `void vgaHWFreeHWRec(ScrnInfoPtr pScrn)`

> > This function frees a `vgaHWRec` structure. It should be called from a driver's `ChipFreeScreen()` function.

> `Bool vgaHWSetRegCounts(ScrnInfoPtr pScrn, int numCRTC,
> int numSequencer, int numGraphics, int numAttribute)`

> > This function allows the number of CRTC, Sequencer, Graphics and Attribute registers to be changed. This makes it possible for extended registers to be saved and restored with `vgaHWSave()` and `vgaHWRestore()`. This function should be called after a `vgaHWRec` has been allocated with `vgaHWGetHWRec()`. The default values are defined in `vgaHW.h` as follows:

> > >     #define VGA_NUM_CRTC 25
> > >     #define VGA_NUM_SEQ   5
> > >     #define VGA_NUM_GFX   9
> > >     #define VGA_NUM_ATTR 21

> `Bool vgaHWCopyReg(vgaRegPtr dst, vgaRegPtr src)`

> > This function copies the contents of the VGA saved registers in `src` to `dst`. Note that it isn't possible to simply do this with `memcpy()` (or similar). This function returns `TRUE` unless there is a problem allocating space for the `CRTC` and related fields in `dst`.

> `void vgaHWSetStdFuncs(vgaHWPtr hwp)`

> > This function initialises the register access function fields of `hwp` with the standard VGA set of functions. This is called by `vgaHWGetHWRec()`, so there is usually no need to call this explicitly. The register access functions are described below. If the registers are shadowed in some other port I/O space (for example a PCI I/O region), these functions can be used to access the shadowed registers if `hwp->PIOOffset` is initialised with `offset`, calculated in such a way that when the standard VGA I/O port value is added to it the correct offset into the PIO area results. This value is initialised to zero in `vgaHWGetHWRec()`. (Note: the PIOOffset functionality is present in XFree86 4.1.0 and later.)

> `void vgaHWSetMmioFuncs(vgaHWPtr hwp, CARD8 *base, int offset)`

> > This function initialised the register access function fields of hwp with a generic MMIO set of functions. `hwp->MMIOBase` is initialised with `base`, which must be the virtual address that the start of MMIO area is mapped to. `hwp->MMIOOffset` is initialised with `offset`, which must be calculated in such a way that when the standard VGA I/O port value is added to it the correct offset into the MMIO area results. That means that these functions are only suitable when the VGA I/O ports are made available in a direct mapping to the MMIO space. If that is not the case, the driver will need to provide its own register access functions. The register access functions are described below.

> `Bool vgaHWMapMem(ScrnInfoPtr pScrn)`

> > This function maps the VGA memory window. It requires that the `vgaHWRec` be allocated. If a driver requires non-default `MapPhys` or `MapSize` settings (the physical location and size of the VGA memory window) then those fields of the `vgaHWRec` must be initialised before calling this function. Otherwise, this function initialiases the default values of `0xA0000` for `MapPhys` and `(64 * 1024)` for `MapSize`. This function must be called before attempting to save or restore the VGA state. If the driver doesn't call it explicitly, the `vgaHWSave()` and `vgaHWRestore()` functions may call it if they need to access the VGA memory (in which case they will also call `vgaHWUnmapMem()` to unmap the VGA memory before exiting).

> `void vgaHWUnmapMem(ScrnInfoPtr pScrn)`

> > This function unmaps the VGA memory window. It must only be called after the memory has been mapped. The `Base` field of the `vgaHWRec` field is set to `NULL` to indicate that the memory is no longer mapped.

> `void vgaHWGetIOBase(vgaHWPtr hwp)`

> > This function initialises the `IOBase` field of the `vgaHWRec`. This function must be called before using any other functions that access the video hardware.

> > A macro `VGAHW_GET_IOBASE()` is also available in `vgaHW.h` that returns the I/O base, and this may be used when the vgahw module is not loaded (for example, in the `ChipProbe()` function).

> `void vgaHWUnlock(vgaHWPtr hwp)`

> > This function unlocks the VGA `CRTC[0-7]` registers, and must be called before attempting to write to those registers.

> `void vgaHWLock(vgaHWPtr hwp)`

> > This function locks the VGA `CRTC[0-7]` registers.

> `void vgaHWEnable(vgaHWPtr hwp)`

> > This function enables the VGA subsystem. (Note, this function is present in XFree86 4.1.0 and later.).

> `void vgaHWDisable(vgaHWPtr hwp)`

> > This function disables the VGA subsystem. (Note, this function is present in XFree86 4.1.0 and later.).

> `void vgaHWSave(ScrnInfoPtr pScrn, vgaRegPtr save, int flags)`

> > This function saves the VGA state. The state is written to the `vgaRegRec` pointed to by `save`. `flags` is set to one or more of the following flags ORed together:

> > `VGA_SR_MODE`

> > > the mode setting registers are saved

> > `VGA_SR_FONTS`

> > > the text mode font/text data is saved

> > `VGA_SR_CMAP`

> > > the colourmap (LUT) is saved

> > `VGA_SR_ALL`

> > > all of the above are saved

> > The `vgaHWRec` and its `IOBase` fields must be initialised before this function is called. If `VGA_SR_FONTS` is set in `flags`, the VGA memory window must be mapped. If it isn't then `vgaHWMapMem()` will be called to map it, and `vgaHWUnmapMem()` will be called to unmap it afterwards. `vgaHWSave()` uses the three functions below in the order `vgaHWSaveColormap()`, `vgaHWSaveMode()`, `vgaHWSaveFonts()` to carry out the different save phases. It is undecided at this stage whether they will remain part of the vgahw module's public interface or not.

> `void vgaHWSaveMode(ScrnInfoPtr pScrn, vgaRegPtr save)`

> > This function saves the VGA mode registers. They are saved to the `vgaRegRec` pointed to by `save`. The registers saved are:

> > > `MiscOut
> > > CRTC[0-0x18]
> > > Attribute[0-0x14]
> > > Graphics[0-8]
> > > Sequencer[0-4]`

> > The number of registers actually saved may be modified by a prior call to `vgaHWSetRegCounts()`.

> `void vgaHWSaveFonts(ScrnInfoPtr pScrn, vgaRegPtr save)`

> > This function saves the text mode font and text data held in the video memory. If called while in a graphics mode, no save is done. The VGA memory window must be mapped with `vgaHWMapMem()` before to calling this function.

> > On some platforms, one or more of the font/text plane saves may be no-ops. This is the case when the platform's VC driver already takes care of this.

> `void vgaHWSaveColormap(ScrnInfoPtr pScrn, vgaRegPtr save)`

> > This function saves the VGA colourmap (LUT). Before saving it, it attempts to verify that the colourmap is readable. In rare cases where it isn't readable, a default colourmap is saved instead.

> `void vgaHWRestore(ScrnInfoPtr pScrn, vgaRegPtr restore, int flags)`

> > This function programs the VGA state. The state programmed is that contained in the `vgaRegRec` pointed to by `restore`. `flags` is the same as described above for the `vgaHWSave()` function.

> > The `vgaHWRec` and its `IOBase` fields must be initialised before this function is called. If `VGA_SR_FONTS` is set in `flags`, the VGA memory window must be mapped. If it isn't then `vgaHWMapMem()` will be called to map it, and `vgaHWUnmapMem()` will be called to unmap it afterwards. `vgaHWRestore()` uses the three functions below in the order `vgaHWRestoreFonts()`, `vgaHWRestoreMode()`, `vgaHWRestoreColormap()` to carry out the different restore phases. It is undecided at this stage whether they will remain part of the vgahw module's public interface or not.

> `void vgaHWRestoreMode(ScrnInfoPtr pScrn, vgaRegPtr restore)`

> > This function restores the VGA mode registers. They are restored from the data in the `vgaRegRec` pointed to by `restore`. The registers restored are:

> > > `MiscOut
> > > CRTC[0-0x18]
> > > Attribute[0-0x14]
> > > Graphics[0-8]
> > > Sequencer[0-4]`

> > The number of registers actually restored may be modified by a prior call to `vgaHWSetRegCounts()`.

> `void vgaHWRestoreFonts(ScrnInfoPtr pScrn, vgaRegPtr restore)`

> > This function restores the text mode font and text data to the video memory. The VGA memory window must be mapped with `vgaHWMapMem()` before to calling this function.

> > On some platforms, one or more of the font/text plane restores may be no-ops. This is the case when the platform's VC driver already takes care of this.

> `void vgaHWRestoreColormap(ScrnInfoPtr pScrn, vgaRegPtr restore)`

> > This function restores the VGA colourmap (LUT).

> `void vgaHWInit(ScrnInfoPtr pScrn, DisplayModePtr mode)`

> > This function fills in the `vgaHWRec`'s `ModeReg` field with the values appropriate for programming the given video mode. It requires that the `ScrnInfoRec`'s `depth` field is initialised, which determines how the registers are programmed.

> `void vgaHWSeqReset(vgaHWPtr hwp, Bool start)`

> > Do a VGA sequencer reset. If start is `TRUE`, the reset is started. If start is `FALSE`, the reset is ended.

> `void vgaHWProtect(ScrnInfoPtr pScrn, Bool on)`

> > This function protects VGA registers and memory from corruption during loads. It is typically called with on set to `TRUE` before programming, and with on set to `FALSE` after programming.

> `Bool vgaHWSaveScreen(ScreenPtr pScreen, int mode)`

> > This function blanks and unblanks the screen. It is blanked when `mode` is `SCREEN_SAVER_ON` or `SCREEN_SAVER_CYCLE`, and unblanked when `mode` is `SCREEN_SAVER_OFF` or `SCREEN_SAVER_FORCER`.

> `void vgaHWBlankScreen(ScrnInfoPtr pScrn, Bool on)`

> > This function blanks and unblanks the screen. It is blanked when `on` is `FALSE`, and unblanked when `on` is `TRUE`. This function is provided for use in cases where the `ScrnInfoRec` can't be derived from the `ScreenRec` (while probing for clocks, for example).

### 19.3. VGA Colormap Functions

The vgahw module uses the standard colormap support (see the Colormap Handling section. This is initialised with the following function:

> `Bool vgaHWHandleColormaps(ScreenPtr pScreen)`

### 19.4. VGA Register Access Functions

The vgahw module abstracts access to the standard VGA registers by using a set of functions held in the `vgaHWRec`. When the `vgaHWRec` is created these function pointers are initialised with the set of standard VGA I/O register access functions. In addition to these, the vgahw module includes a basic set of MMIO register access functions, and the `vgaHWRec` function pointers can be initialised to these by calling the `vgaHWSetMmioFuncs()` function described above. Some drivers/platforms may require a different set of functions for VGA access. The access functions are described here.

> `void writeCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)`

> > Write `value` to CRTC register `index`.

> `CARD8 readCrtc(vgaHWPtr hwp, CARD8 index)`

> > Return the value read from CRTC register `index`.

> `void writeGr(vgaHWPtr hwp, CARD8 index, CARD8 value)`

> > Write `value` to Graphics Controller register `index`.

> `CARD8 readGR(vgaHWPtr hwp, CARD8 index)`

> > Return the value read from Graphics Controller register `index`.

> `void writeSeq(vgaHWPtr hwp, CARD8 index, CARD8, value)`

> > Write `value` to Sequencer register `index`.

> `CARD8 readSeq(vgaHWPtr hwp, CARD8 index)`

> > Return the value read from Sequencer register `index`.

> `void writeAttr(vgaHWPtr hwp, CARD8 index, CARD8, value)`

> > Write `value` to Attribute Controller register `index`. When writing out the index value this function should set bit 5 (`0x20`) according to the setting of `hwp->paletteEnabled` in order to preserve the palette access state. It should be cleared when `hwp->paletteEnabled` is `TRUE` and set when it is `FALSE`.

> `CARD8 readAttr(vgaHWPtr hwp, CARD8 index)`

> > Return the value read from Attribute Controller register `index`. When writing out the index value this function should set bit 5 (`0x20`) according to the setting of `hwp->paletteEnabled` in order to preserve the palette access state. It should be cleared when `hwp->paletteEnabled` is `TRUE` and set when it is `FALSE`.

> `void writeMiscOut(vgaHWPtr hwp, CARD8 value)`

> > Write ``value`' to the Miscellaneous Output register.

> `CARD8 readMiscOut(vgwHWPtr hwp)`

> > Return the value read from the Miscellaneous Output register.

> `void enablePalette(vgaHWPtr hwp)`

> > Clear the palette address source bit in the Attribute Controller index register and set `hwp->paletteEnabled` to `TRUE`.

> `void disablePalette(vgaHWPtr hwp)`

> > Set the palette address source bit in the Attribute Controller index register and set `hwp->paletteEnabled` to `FALSE`.

> `void writeDacMask(vgaHWPtr hwp, CARD8 value)`

> > Write `value` to the DAC Mask register.

> `CARD8 readDacMask(vgaHWptr hwp)`

> > Return the value read from the DAC Mask register.

> `void writeDacReadAddress(vgaHWPtr hwp, CARD8 value)`

> > Write `value` to the DAC Read Address register.

> `void writeDacWriteAddress(vgaHWPtr hwp, CARD8 value)`

> > Write `value` to the DAC Write Address register.

> `void writeDacData(vgaHWPtr hwp, CARD8 value)`

> > Write `value` to the DAC Data register.

> `CARD8 readDacData(vgaHWptr hwp)`

> > Return the value read from the DAC Data register.

> `CARD8 readEnable(vgaHWptr hwp)`

> > Return the value read from the VGA Enable register. (Note: This function is present in XFree86 4.1.0 and later.)

> `void writeEnable(vgaHWPtr hwp, CARD8 value)`

> > Write `value` to the VGA Enable register. (Note: This function is present in XFree86 4.1.0 and later.)

XFree86 server 4.x Design (DRAFT) : The vgahw module
Previous: Helper Functions
Next: Some notes about writing a driver