Hello all,
I’m writing a KMDF driver for a PCIe device that is capable of sending 16 different MSIs.
Inside the My_EvtDriverDeviceAdd() callback, I do:
WDF_INTERRUPT_CONFIG_INIT(&InterruptConfig, My_EvtInterruptIsr, My_EvtInterruptDpc);
InterruptConfig.EvtInterruptEnable = My_EvtInterruptEnable;
InterruptConfig.EvtInterruptDisable = My_EvtInterruptDisable;
InterruptConfig.AutomaticSerialization = TRUE;
for (Index = 0; Index < 16; Index++)
{
Status = WdfInterruptCreate(DeviceContext->Device, &InterruptConfig, WDF_NO_OBJECT_ATTRIBUTES, &(DeviceContext->Interrupt[Index]));
}
Status is always success.
Inside the My_EvtDevicePrepareHardware() callback, I go through the CM_PARTIAL_RESOURCE_DESCRIPTOR structure (extracted from ResourcesTranslated) and I see only one CmResourceTypeInterrupt.
I expected to have 16 CmResourceTypeInterrupt, but I’m not sure about that.
The flag is equal to (CM_RESOURCE_INTERRUPT_LATCHED | CM_RESOURCE_INTERRUPT_MESSAGE), which is correct.
Here is a TraceView extract when I activate the driver:
01 My_EvtDriverDeviceAdd(---->)
02 My_EvtDriverDeviceAdd(<----)
03 My_EvtDevicePrepareHardware(---->)
04 PartialResourceDescriptor->Type == 0x3
05 PartialResourceDescriptor->ShareDisposition == 0x1
06 PartialResourceDescriptor->Flags == 0x84
07 PartialResourceDescriptor->u.Memory.Start == 0xfcaff000
08 PartialResourceDescriptor->u.Memory.Length == 0x1000
09 PartialResourceDescriptor->Type == 0x81
10 PartialResourceDescriptor->ShareDisposition == 0x1
11 PartialResourceDescriptor->Flags == 0x0
12 PartialResourceDescriptor->Type == 0x3
13 PartialResourceDescriptor->ShareDisposition == 0x1
14 PartialResourceDescriptor->Flags == 0x84
15 PartialResourceDescriptor->u.Memory.Start == 0xfcafe000
16 PartialResourceDescriptor->u.Memory.Length == 0x1000
17 PartialResourceDescriptor->Type == 0x81
18 PartialResourceDescriptor->ShareDisposition == 0x1
19 PartialResourceDescriptor->Flags == 0x0
20 PartialResourceDescriptor->Type == 0x2
21 PartialResourceDescriptor->ShareDisposition == 0x1
22 PartialResourceDescriptor->Flags == 0x3
23 PartialResourceDescriptor->u.MessageInterrupt.Raw.MessageCount == 0x0
24 PartialResourceDescriptor->u.MessageInterrupt.Raw.Vector == 0x62
25 PartialResourceDescriptor->u.MessageInterrupt.Raw.Affinity == 0x1
26 PartialResourceDescriptor->u.MessageInterrupt.Translated.Level == 0x5
27 PartialResourceDescriptor->u.MessageInterrupt.Translated.Vector == 0x62
28 PartialResourceDescriptor->u.MessageInterrupt.Translated.Affinity == 0x1
29 My_EvtDevicePrepareHardware(<----)
30 My_EvtInterruptEnable(---->)
31 My_EvtInterruptEnable(<----)
Here is a TraceView extract when I receive an interrupt (the device sends a message number equal to 0x3, and Message ID received is always 0x0):
32 My_EvtInterruptIsr(---->)
33 MessageID = 0x0
34 My_EvtInterruptIsr(<----)
35 My_EvtInterruptDpc(---->)
36 My_EvtInterruptDpc(<----)
When I read the MSI capability structure of the PCI configuration space, I see:
00896005 (Message Control + Next Pointer + Capability ID)
FFE01000 (Message Address)
00000000 (Message Upper Address)
xxxx40B0 (Message Data)
The Capability ID (0x05) is correct (corresponds to MSI per PCI specification).
The Next Pointer (0x60) is strange because it doesn’t seem to point on another structure…
The Message Control (0x89) means:
- Per-vector masking capable = 0
- 64 bit address capable = 1
- Multiple Message Enable = 000 (ONLY 1 MESSAGE ALLOCATED BY WINDOWS)
- Multiple Message Capable = 100 (the 16 messages asked by the device)
The Message Address seems correct.
The Message Data doesn’t mean anything for me
In summary, my device asks 16 MSIs and Windows allocates only 1 MSI.
And I don’t understand why, since this is the only PCIe device in the system.
And there are not a lot of devices in that system (tiny portable system).
Do you have an idea to help understand that issue?
Sorry for this huge post, but I want you to have as much information as possible.
Thanks a lot.
Best regards,
Vincent