Technical Document #74

Technical Document #74
How do I access the memory on my PCI card using WinDriver?

First, locate the slot to which your card is connected, using WD_PciScanCards().

Then get the card's information by calling WD_PciGetCardInfo().
This information includes the memory range chosen for the card by the Plug and Play system.

Now call WD_CardRegister() to install the memory range and map it into both kernel and user mode virtual address spaces.

You can then either access the memory directly from your user mode application (more efficient), by using the user mode mapping of the physical address — returned by WD_CardRegister() in cardReg.Card.Item[i].I.Mem.pUserDirectAddr (where 'i' is the index number of the memory range in the Item array) — or pass the kernel mode mapping of the memory — returned by WD_CardRegister() in cardReg.Card.Item[i].I.Mem.pTransAddr — to WD_Transfer() (/ WD_MultiTransfer()), in order to access the memory in the kernel.

This is demonstrated, for example, in the sample code found in the WinDriver/samples/pci_diag directory, and in the diagnostics DriverWizard code that you can generate for your PCI card.
Please also refer to the description of the WinDriver PCI API in the WinDriver PCI Low-Level API Reference (available under the WinDriver/doc/ directory) or in the Function Reference chapter of the WinDriver User's Manual (in earlier versions) for a better understanding of these functions and the related structures.

NOTE: To access memory directly in the kernel, from within a Kernel PlugIn project, you must use the kernel mode mapping of the physical memory address — returned by WD_CardRegister() in cardReg.Card.Item[i].I.Mem.pTransAddr — and not the user mode mapping that is used to access the memory directly from your user-mode application.

Version Notes
The API references in this document may not match the API in earlier versions of WinDriver. In version 11.8.0 the following WD_ITEMS I.Mem field name and type changes were made:
DWORD dwTransAddr –> KPTR pTransAddr
UPTR dwUserDirectAddr –> UPTR pUserDirectAddr