I’m developing driver for PCIe board which support both MSI and MSI-X.
I should check both MSI types.
Quick question:
Is there any way in the device driver to enable JUST MSI not MSI-X if both are available?
Details:
WdfIoResourceRequirementsListGetCount returns 2 [lists].
First list contains only requirements for message signaled interrupts, the count of interrupt descriptors is the same as value MessageNumberLimit in registry. All descriptors are message signaled.
Second list contains 2 interrupt descriptors: first is message signaled and second is legacy.
I tried to remove first list. I received in ‘evtDevicePrepareHardware’ 1 Message Signaled Interrupt resource. I created a handler. Then I read a config space and saw: MSI is disabled, MSIX is enabled.
I think you cannot enable both MSI and MSIX at a given instance. I’ve not done MSI/MSIX on windows but in Linux there are separate apis to enable MSI/MSIX, pci_enable_msi()/ pci_enable_msix().
Join Date: 08 May 2012
Posts To This List: 13
MSI vs MSI-X
I think you cannot enable both MSI and MSIX at a given instance. I’ve not done
MSI/MSIX on windows but in Linux there are separate apis to enable MSI/MSIX,
pci_enable_msi()/ pci_enable_msix().
I got following on msdn, please see if it helps you if not tried earlier:
To receive message-signaled interrupts (MSIs), a driver’s INF file must enable MSIs in the registry during installation.
Use the Interrupt Management\MessageSignaledInterruptProperties subkey of the device’s hardware key to enable MSI support.
complete details at: https://msdn.microsoft.com/en-us/library/windows/hardware/ff544246(v=vs.85).aspx
when device suppports both MSI and MSIX windows kernel automatically uses MSI-X. I think in your case thats what might be happening.
Thanks for links. I tried to play with INF file - it didn’t help.
mht> when device suppports both MSI and MSIX windows kernel automatically uses MSI-X.
Looks so. How I can enable manual mode?
You can try to rebuild the resource descriptor in FILTER_RESOURCE_REQUIREMENTS. MSI descriptor has different contents in MinimumVector/MaximumVector. Remove MSI-X descriptors (with MinimumVector=MaximumVector=CM_RESOURCE_INTERRUPT_MESSAGE_TOKEN) and insert a single MSI descriptor with u.Interrupt.MinimumVector = CM_RESOURCE_INTERRUPT_MESSAGE_TOKEN - MessageCount + 1
Peter,
Sorry I don’t know how to make dump of WDFIORESREQLIST.
When I tried use wdfkd.wdfhandle I received:
kd> !wdfkd.wdfhandle IoResourceRequirementsList
Treating handle as a UMDF handle!
wudfhost could not be found in the module list! Either symbols for wudfhost.exe are not loaded or the process context is not correct
kd> !wdfkd.wdfdriverinfo
using default driver name “SimpleDriver”
FxDriverGlobals 0xffffe001ce301eb0
WdfBindInfo 0x0000000000000000
Driver Handles is NULL
I have my dump of resources:
–> evtDeviceFilterRemoveResourceRequirements status
Found IoResList 0/2
IoResList 0/2 contain desc 0/11 with type 3-memory flags 0x84 share 0x1
IoResList 0/2 contain desc 1/11 with type 3-memory flags 0x84 share 0x1
IoResList 0/2 contain desc 2/11 with type 129-private flags 0x0 share 0x1
IoResList 0/2 contain desc 3/11 with type 1-another flags 0x131 share 0x1
IoResList 0/2 contain desc 4/11 with type 1-another flags 0x131 share 0x1
IoResList 0/2 contain desc 5/11 with type 129-private flags 0x0 share 0x1
IoResList 0/2 contain desc 6/11 with type 3-memory flags 0x84 share 0x1
IoResList 0/2 contain desc 7/11 with type 3-memory flags 0x84 share 0x1
IoResList 0/2 contain desc 8/11 with type 129-private flags 0x0 share 0x1
IoResList 0/2 contain desc 9/11 with type 2-interrupt flags 0x7 share 0x1
Interrupt: minVec 0xFFFFFFFE maxVec 0xFFFFFFFE TP 0x0000000000000001
IoResList 0/2 contain desc 10/11 with type 2-interrupt flags 0x7 share 0x1
Interrupt: minVec 0xFFFFFFFE maxVec 0xFFFFFFFE TP 0x0000000000000001
Remove current IoResList as MSI-X List
Found IoResList 0/1
IoResList 0/1 contain desc 0/11 with type 3-memory flags 0x84 share 0x1
IoResList 0/1 contain desc 1/11 with type 3-memory flags 0x84 share 0x1
IoResList 0/1 contain desc 2/11 with type 129-private flags 0x0 share 0x1
IoResList 0/1 contain desc 3/11 with type 1-another flags 0x131 share 0x1
IoResList 0/1 contain desc 4/11 with type 1-another flags 0x131 share 0x1
IoResList 0/1 contain desc 5/11 with type 129-private flags 0x0 share 0x1
IoResList 0/1 contain desc 6/11 with type 3-memory flags 0x84 share 0x1
IoResList 0/1 contain desc 7/11 with type 3-memory flags 0x84 share 0x1
IoResList 0/1 contain desc 8/11 with type 129-private flags 0x0 share 0x1
IoResList 0/1 contain desc 9/11 with type 2-interrupt flags 0x3 share 0x1
Interrupt: minVec 0xFFFFFFFE maxVec 0xFFFFFFFE TP 0x0000000000000000
Apply new MSI interrupt count 2 current count 1
IoResList 0/1 contain desc 10/11 with type 2-interrupt flags 0x0 share 0x3
Interrupt: minVec 0x00000000 maxVec 0xFFFFFFFF TP 0x0000000000000000
<– evtDeviceFilterRemoveResourceRequirements status STATUS_SUCCESS
–> evtDevicePrepareHardware 2, resources count 7
Registers FFFFD00020C00000, length 2097152
Memory Resource [F0200000-F0400000]
Port Resource [0000E020-0000E040]
SRAM FFFFD00035D54000, length 16384
Memory Resource [F0404000-F0408000]
–> configureInterrupts
Message Interrupt level 0x7, Vector 0x72, MessageCount 1
Create new interrupt handler 0x00001FFF412B09A8. Timer 0x00001FFF416EFA28. Vector 0
<– configureInterrupts status STATUS_SUCCESS
<– evtDevicePrepareHardware 2, status STATUS_SUCCESS
–> evtDeviceFilterRemoveResourceRequirements status
Found IoResList 0/2
IoResList 0/2 contain desc 0/11 with type 3-memory flags 0x84 share 0x1
IoResList 0/2 contain desc 1/11 with type 3-memory flags 0x84 share 0x1
IoResList 0/2 contain desc 2/11 with type 129-private flags 0x0 share 0x1
IoResList 0/2 contain desc 3/11 with type 1-another flags 0x131 share 0x1
IoResList 0/2 contain desc 4/11 with type 1-another flags 0x131 share 0x1
IoResList 0/2 contain desc 5/11 with type 129-private flags 0x0 share 0x1
IoResList 0/2 contain desc 6/11 with type 3-memory flags 0x84 share 0x1
IoResList 0/2 contain desc 7/11 with type 3-memory flags 0x84 share 0x1
IoResList 0/2 contain desc 8/11 with type 129-private flags 0x0 share 0x1
IoResList 0/2 contain desc 9/11 with type 2-interrupt flags 0x7 share 0x1
Interrupt: minVec 0xFFFFFFFE maxVec 0xFFFFFFFE TP 0x0000000000000001
IoResList 0/2 contain desc 10/11 with type 2-interrupt flags 0x7 share 0x1
Interrupt: minVec 0xFFFFFFFE maxVec 0xFFFFFFFE TP 0x0000000000000001
Remove current IoResList as MSI-X List
Found IoResList 0/1
IoResList 0/1 contain desc 0/11 with type 3-memory flags 0x84 share 0x1
IoResList 0/1 contain desc 1/11 with type 3-memory flags 0x84 share 0x1
IoResList 0/1 contain desc 2/11 with type 129-private flags 0x0 share 0x1
IoResList 0/1 contain desc 3/11 with type 1-another flags 0x131 share 0x1
IoResList 0/1 contain desc 4/11 with type 1-another flags 0x131 share 0x1
IoResList 0/1 contain desc 5/11 with type 129-private flags 0x0 share 0x1
IoResList 0/1 contain desc 6/11 with type 3-memory flags 0x84 share 0x1
IoResList 0/1 contain desc 7/11 with type 3-memory flags 0x84 share 0x1
IoResList 0/1 contain desc 8/11 with type 129-private flags 0x0 share 0x1
IoResList 0/1 contain desc 9/11 with type 2-interrupt flags 0x3 share 0x1
Interrupt: minVec 0xFFFFFFFE maxVec 0xFFFFFFFE TP 0x0000000000000000
Apply new MSI interrupt count 2 current count 1
IoResList 0/1 contain desc 10/11 with type 2-interrupt flags 0x0 share 0x3
Interrupt: minVec 0x00000000 maxVec 0xFFFFFFFF TP 0x0000000000000000
<– evtDeviceFilterRemoveResourceRequirements status STATUS_SUCCESS
–> evtDevicePrepareHardware 2, resources count 7
mht, Maxim S. Shatskih, I should check all types of interrupt: MSI, MSI-X, Legacy.
I know how to switch between Legacy and MSI-X, but I cannot do the same for MSI.
I’m wondering that it’s impossible under Windows OS.
As I posted in a previous thread: I looked this up for the community.
At least in Windows 8.1, there is no way to disable MSI-X if it’s supported and the device has a valid MSI-X configuration. There’s no registry or INF setting – at least not one I can find anywhere – that allows you to bypass this. Which, as I said at the time and I’ll say again now, is really too bad… because, like Mr. Pomozov, I agree that this would be valuable for testing (if for nothing else).
mht, Maxim S. Shatskih, I should check all types of interrupt: MSI, MSI-X, Legacy.
I know how to switch between Legacy and MSI-X, but I cannot do the same for MSI.
I’m wondering that it’s impossible under Windows OS.
As Alex G. already advised, just use for your testing some
older Windows version that does not support MSI-X.
PCI drivers have not changed much since Vista/2008,
so you will be able to test everything.