I’m currently developing a KMDF driver for a PCIe FPGA card. I am a newbie to modern Windows drivers but have a lot of experience in driver development in Unix, Linux and others.
My problem is with mapping the devices memory into kernel virtual address space.
Some background:
- The board and platform work on Linux. I developed the Linux driver for this card.
- The contents of the PCI config space look correct under both environments. The physical address being assigned is the same.
I am using a Windows pcidrv sample as my starting point.
My problem is pretty fundamental. In my EvtDevicePrepareHardware pnpPower Event callback I iterate over the ResourcesTranslated() List and when I see CmResourceTypeMemory I issue a MmMapIoSpace( descriptor->u.Memory.Start,descriptor->u.Memory.Length, MmNonCached);
I get what appears to be a valid pointer KVA back but when I examine the contents of the region it does not contain what I expect. In fact it appears invalid (all ff using the “D” debugger command). Accessing the area in code will fault on some machines (I have several test platforms available). I have tried accessing the memory in the D0Entry routine with the same results.
Issuing a “!dd uc” debugger command on the physical address I am provided in the resource list also returns unexpected contents. As I’ve said the the physical address I am given in the Resource List is the same as I see in the BAR and is also the exact same address I get when I boot under Linux where it works. Logically my Windows code should be performing the same basic steps I do in the Linux Probe() callback.
Am I missing something?
As you said that you are new, let me check few things.
Are you sure that your device uses memory mapped IO and not Port mapped IO, if it is then you need to use a different case statement.
What example of physical address are you getting to map?
Pradish - Yes I am sure I use memory mapped IO but have cases for CmResourceTypePort just in case. I developed the Linux driver stack for this device and am using MmMapIoSpace() as I used ioremap_uncache() in Linux.
Alex -
descriptor->u.Memory.Start.LowPart = 0xb1bff000 - Is the phys address I am getting from the Translated Resource List and this jives with what I see in the PCI config as well as what I get when I boot Linux and run my Linux driver
Highpart is 0 and length is 0x1000 what I expect.
MmMapIoSpace returns 0xfffff880`07827000. I am expecting to be able to use this pointer directly by my driver but doing a D on this address in Kd window fails
Does your PCIe config space have all the required power management capability descriptors? Try to run the driver under checked OS, or, at least, checked PCI.SYS.
Run !pci config dump for the device in the debugger.
Use !pte on the mapped range to get the actually mapped physical addresses. Are they correct?
!pci is IIRC the way to read the BARs to compare with the !pte output.
–
Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com
wrote in message news:xxxxx@ntdev…
> I’m currently developing a KMDF driver for a PCIe FPGA card. I am a newbie to modern Windows drivers but have a lot of experience in driver development in Unix, Linux and others.
>
> My problem is with mapping the devices memory into kernel virtual address space.
> Some background:
> - The board and platform work on Linux. I developed the Linux driver for this card.
> - The contents of the PCI config space look correct under both environments. The physical address being assigned is the same.
>
> I am using a Windows pcidrv sample as my starting point.
>
> My problem is pretty fundamental. In my EvtDevicePrepareHardware pnpPower Event callback I iterate over the ResourcesTranslated() List and when I see CmResourceTypeMemory I issue a MmMapIoSpace( descriptor->u.Memory.Start,descriptor->u.Memory.Length, MmNonCached);
>
> I get what appears to be a valid pointer KVA back but when I examine the contents of the region it does not contain what I expect. In fact it appears invalid (all ff using the “D” debugger command). Accessing the area in code will fault on some machines (I have several test platforms available). I have tried accessing the memory in the D0Entry routine with the same results.
>
> Issuing a “!dd uc” debugger command on the physical address I am provided in the resource list also returns unexpected contents. As I’ve said the the physical address I am given in the Resource List is the same as I see in the BAR and is also the exact same address I get when I boot under Linux where it works. Logically my Windows code should be performing the same basic steps I do in the Linux Probe() callback.
>
> Am I missing something?
>
Thanks to the folks that replied to my post. I just wanted to follow-up as I personally hate threads that end unresolved. It turns out that my driver was working all along but that I was given misinformation from my HW team. The variant of device I am using no longer has readable memory in the area I was looking at. Of course my test was simply a sanity check of my driver and not required to control the device. It resulted in quite a bit of INSANITY on my part. A simple bit of debug code in my known working Linux driver validated my suspicions.
Don’t you love when the ASIC guys pull the chair from under you?