MSI vs MSI-X

Hello,

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().

For this moment I need only MSI (board support both) and I cannot find way to select it by Windows API.

mht
xxxxx@gmail.com

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

Alex, I tried. It doesn’t work.
I found the old branch:
http://www.osronline.com/showthread.cfm?link=260595
But I cannot understand how to disable MSI-X by ‘SetTableEntry’.

That’s very curious. Can you show us your resources before and after you’ve modified them? Perhaps dump them in WinDbg so we can see/help…

Peter
OSR
@OSRDrivers

SetTableEntry just disables/enables individual message at runtime, after it’s all configured for MSI-X.

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
  • 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

As I wrote: when I check the PCI config space: MSI is disabled, MSI-X is enabled.

Sorry, log was duplicated.

Alex, I understood that Jimmie Mayfield (from http://www.osronline.com/showthread.cfm?link=260595) found the solution with ‘SetTableEntry’

But looks like I understood wrong.

The problem in that article was that the reset was wiping the MSI-X table.

If you only need to test functionality with MSI, just run it under OS that only supports MSI (Windows 2008).

Ok, Alex, thanks for clarifying.
I want to switch between MSI and MSI-X without OS or HW changing.

MSI are kinda obsoleted by MSI-X, and are only used on downlevel OSes (2008).


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

wrote in message news:xxxxx@ntdev…
> Ok, Alex, thanks for clarifying.
> I want to switch between MSI and MSI-X without OS or HW changing.
>
>

can you not go along with MSI-X as MSI/MSI-X serves the same purpose?
MSI-X has more advantages over MSI.

Regards,
Mohan Tarole
HCL Technologies, Hyderabad, India.

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).

Peter
OSR
@OSRDrivers

On 04-Jun-2015 10:15, xxxxx@mail.ru wrote:

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.

– pa