Message signaled interrupt with IoConnectInterruptEx

That’s because you don’t understand the architecture. It’s true that the “interrupt endpoint” has nothing to do with bus interrupts.

Actually, the whole nonsense reminds me of a thread where the OP from some “outsourcing location” was just desperate to handle interrupts in his USB driver, and fiercely resisted all our futile attempts to explain to him that USB drivers just don’t handle interrupts…

IIRC, it was that thread when Mr. Aseltine had reached the point of explicitly telling him “Look - you just cannot be THAT obtuse, can you”. OTOH, I am not sure whether we had heard a mantra about “everyone having had been inexperienced once” on that particular occasion…

Anton Bassov

Hi, dear friends
Thank you for your help.
I am testing message-based interrupt on a software_only driver. Test of USB is going to be made afterwards.
I would report the progress to you.
The test is based on echo project of Windows-driver-samples-master.
I added below code to the inf file and create an interrupt with WdfInterruptCreate in EchoDeviceCreate subroutine. I can verify that MSI is supported after the driver is installed. The screen shot is attached.


[ECHO_Device.NT.HW]
[MSI_Interrupts]
HKR,Interrupt Management,0x00000010
HKR,Interrupt Management\MessageSignaledInterruptProperties,0x00000010
HKR,Interrupt Management\MessageSignaledInterruptProperties,MSISupported,0x00010001,1


WDF_INTERRUPT_CONFIG_INIT(&InterruptConfiguration,
InterruptServiceRoutine,
DrvInterruptDpc);

InterruptConfiguration.EvtInterruptEnable = TimerInterruptEnable;
InterruptConfiguration.EvtInterruptDisable = TimerInterruptDisable;
InterruptConfiguration.AutomaticSerialization = TRUE;

status = WdfInterruptCreate(device,
	&InterruptConfiguration,
	WDF_NO_OBJECT_ATTRIBUTES,
	&deviceContext->WdfInterrupt);

I can be sure that EVT_WDF_DEVICE_PREPARE_HARDWARE is called.
But WDFCMRESLIST ResourcesRaw and ResourcesTranslated are empty. Both WdfCmResourceListGetCount(ResourcesTranslated) and WdfCmResourceListGetCount(ResourcesRaw) return 0.

I do not know what is the problem.
I think I should test with a WDM project of software_only driver.
Could anyone tell me where I can get an example WDM project of software_only driver with an inf file?

Thanks.

I am testing message-based interrupt on a software_only driver.

…and this part is reminiscent of Alberto’s attempts to “raise MSI” by the CPU by means of writing to the local APIC’s ICR…

Anton Bassov

The problem is you don’t have a device with the hardware capability necessary to generate the MSI.

You need MSI-capable hardware to generate MSIs. Not every device is MSI capable.

Peter

tatuo wrote:

I am testing message-based interrupt on a software_only driver. Test of USB is going to be made afterwards.

Peter and Anton have already correctly pointed out that hardware is
required for interrupts, but before you waste any more time on this, I
want to address your second sentence.  YOU do not get to handle USB
interrupts.  It’s true that the USB host controller generates interrupts
for certain events, but those interrupts are all handled at the lowest
level by the host controller driver. Higher level drivers just submit
URBs and wait for them to be completed.  When an interrupt does occur,
the host controller driver will figure out what work has been completed,
and will send the completed requests back to the drivers that made them.

But WDFCMRESLIST ResourcesRaw and ResourcesTranslated are empty. Both WdfCmResourceListGetCount(ResourcesTranslated) and WdfCmResourceListGetCount(ResourcesRaw) return 0.

Of course they are empty.  Resources come from hardware.  You have no
hardware, so PnP has no resources for you to handle.  What did you
expect here?  Those MSI registry entries just tell the system “I am
prepared to handle MSIs if my hardware is prepared to generate them.”

I do not know what is the problem.
I think I should test with a WDM project of software_only driver.

No, you should not.  What you need is a better understanding of the
low-level system architecture.  Unless you are the lowest level driver
for a PCI or PCIExpress device, you will not handle interrupts of any kind.

YOU do not get to handle USB interrupts.

OMG…

I was holding my breath in anticipation, waiting for the OP’s next “inquiry” - I bet he would be asking why he does not get an interrupt for his USB device despite having had called IoConnectInterruptEx(). However, now it looks like it may not happen.

What a frustration (unless the OP ignores all your explanations and decides that he has to handle interrupts for his USB device no matter what and no matter how, of course).

Anton Bassov

Dear Tim

Thank you very much for your help.
The reason that I test MSI first is very simple. If interrupt can be done with MSI of HPET, we would not need any hardware. And I can test it shortly.
Now, I nearly give up with MSI.

Can you give me some more deteal information about USB interrupt?
Is it a host controller driver using xHCI?
Where can I download a sample project to start with?

Thanks again.

On May 13, 2019, at 12:28 AM, tatuo wrote:
>
> Can you give me some more deteal information about USB interrupt?
> Is it a host controller driver using xHCI?
> Where can I download a sample project to start with?

There are many, many little USB experimenter’s kits that you could play with. You’ll want to get one that does high speed (USB 2.0) to get sub-millisecond resolution.

But, again, you need to remember that you aren’t literally handling interrupts. That’s all done by the host controller driver. The term “interrupt pipe” is just a way of saying “periodic pipe”. You’d set up your descriptors so your interrupt endpoint has an interval of 2 microframes, which is 250 microseconds. You would need to write a little application using WinUSB that submits a couple of read requests on the interrupt endpoint. When the request is completed, you’ll know another 250us have elapsed.

Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Dear Tim

Thank you very much for your help.
I can conceive, that using “interrupt pipe” , my program would run in DPC, not in ISR.
It is something different to my expectation.
I think if MessageData and MessageAddress are returned successfully from IoConnectInterruptEx I can use them to configurate HPET.
Then HPET would trigger the interrupt.
The problem is that IoConnectInterruptEx failed.
I modified my source code so that I can use IoConnectInterruptEx after I install my driver with an inf file which enable MSISupported.

InterruptParams.MessageBased.PhysicalDeviceObject = WdfDeviceWdmGetPhysicalDevice(device);

Then IoConnectInterruptEx returns 0xC0000034L, which means “Object Name not found”.
(Before modification, it returned 0xC0000225L, “The object was not found”.)

What is the “Object Name”? What is lack of condition?

Thanks again.

On May 13, 2019, at 10:43 PM, tatuo wrote:
>
> I can conceive, that using “interrupt pipe” , my program would run in DPC, not in ISR.
> It is something different to my expectation.

You need to adjust your expectations, because Windows does not work the way you think it does.

By the way, WHY do you need 250us timer ticks? What is the use case?

> I think if MessageData and MessageAddress are returned successfully from IoConnectInterruptEx I can use them to configurate HPET.
> Then HPET would trigger the interrupt.

No, it doesn’t work that way. You seem to be thinking that IoConnectInterruptEx is going to allocate unattached MSI addresses which you can then assign. That’s not correct. You pass your PDO’s address to IoConnectInterruptEx, and that PDO already has to have MSIs. The system looks up the MSIs that were already assigned to you. In your case, with a virtual device, your PDO doesn’t have any resources, so the system is never going to hook up the MSIs.

> Then IoConnectInterruptEx returns 0xC0000034L, which means “Object Name not found”.
> (Before modification, it returned 0xC0000225L, “The object was not found”.)

Basically the same thing. You tried to connect to interrupts, but your driver had not been assigned any interrupts to connect to.

Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Dear Tim
Thank you very much for your help.
I got it.
The key point is that system does not assign MSI resource to virtual device.
I was misled by the output direction of IoConnectInterruptEx’s InterruptMessageTable.



I want to send some data at constant time interval using ethernet network. (All work in kernel mode).
250us is expected. 1ms is acceptable too.
The severest request is that the jitter should be less than 50us.
I worked with ExSetTimer and WdfTimerStart. I was disappointed.
I think a program run in DPC cannot meet the request.

Yours sincerely.

The key point is that system does not assign MSI resource to virtual device.

“The key point” is that drivers for the virtual devices just don’t handle interrupts, in the first place. Certainly, interrupts may be virtualised as well, as as it happens,for example, when the target paravirtualised OS runs as an unprivileged guest under XEN or Hyper-V. In such case a
driver for the target device is aware that both device and interrupt are virtual, but this is not the scenario we are speaking about here.

I was misled by the output direction of IoConnectInterruptEx’s InterruptMessageTable.

Actually, I would rather say that you are “mislead” by the lack of profound understanding of the architectural concepts…

I think a program run in DPC cannot meet the request.

True, because the precise timing of DPC execution may depend on the “external” factors like the size of DPC queue at the moment. Therefore, 250us precision cannot be guaranteed here…

Anton Bassov

Dear Anton

Actually, I would rather say that you are “mislead” by the lack of profound understanding of the architectural concepts…

Yes, I do not understand the architectural yet.
Can you be so kind to teach the architectural to me with an instance?
Anything leading to the resolution is appreciated very much.

Best regard.

tatuo wrote:

Yes, I do not understand the architectural yet.
Can you be so kind to teach the architectural to me with an instance?
Anything leading to the resolution is appreciated very much.

That is a reasonable request, but a difficult one to satisfy. Your
request spans multiple disciplines, including both the hardware, the
kernel, and the I/O buses, and all of those topics are very, very
large.  It’s possible to find reference sources for small aspects of the
kernel, but to a great extent, this stuff is learned “on the job”.

One thing that has been said in this thread that needs to be repeated is
that Windows is not a real-time system.  You’re never going to get
rock-solid interval timer interrupts.  The system design does not allow
it.  Fortunately, in almost every case where you think you need them,
you don’t.  For example, you said you wanted to send network packets
every 250us.  Surely you have to know that Ethernet itself is
unreliable.  There are unpredictable delays all through a network.  You
can certainly average 4,000 packets per second, but not with precision.

The Network Time Protocol that synchronizes most of the hosts on the
Internet doesn’t rely on absolute time signals.  Instead, as they
exchange messages, they measure the latency and the jitter to narrow in
on exact times.

I would like to find out more about your actual purpose here, to provide
better advice on a design that CAN be achieved.

Surely you have to know that Ethernet itself is unreliable. There are unpredictable delays all through a network. You
can certainly average 4,000 packets per second, but not with precision.

Please note that the term “Ethernet” does not necessarily imply the “conventional” networking (i.e LAN or SAN). Although your statement is 100% true as far as the “conventional” networking is concerned, it does not apply to so-called “Industrial Ethernet” with protocols that provide determinism and real-time control. Certainly, running the “conventional” TCPIP protocol suite on top of it may be “rather problematic”, but this is not what it is meant to be used for…

Anton Bassov

Dear Anton

Thank you for your help.
Our “Ethernet” is not a “conventional” network. The latency of communication is another topic. And it is not a problem in our project.
We are searching for just an interrupt which would call our ISR stably and periodically.

Best regard.

tatuo wrote:

Our “Ethernet” is not a “conventional” network. The latency of communication is another topic. And it is not a problem in our project.

How can you possibly argue that?  It HAS to be a consideration.
Remember, your goal is not to get periodic interrupts.  That’s just a
step.  Your goal (apparently) is to get regular packets to your
network.  In order to achieve that, you HAVE to look at the entire
infrastructure: not only the timer accuracy, but the network software
latency, the NIC latency, the network latency, collisions, delays on the
other end, etc.  It is a waste of time an energy to try to build a timer
with picosecond precision if your network transmission time varies
within a couple of milliseconds, as it probably does.  It’s a
statistical process.

We are searching for just an interrupt which would call our ISR stably and periodically.

There are many, many PCIExpress general purpose I/O boards with
countdown timers that can issue an interrupt.  Here’s one.

https://logical-co.com/product/dual-programmable-timer-pci-express/

Dear Tim
Thank you very much for your help.

It is a waste of time an energy to try to build a timer
with picosecond precision if your network transmission time varies
within a couple of milliseconds,

The period we need is 250~1000microseconds, and jitter is 50 microseconds or so. It is not so hard in some sense. It is not in picosecond.
It is true that the latency is composed of many and many factors. First we have to have a precise timer. It is the base of all. We will leave other problems to the hardware of network. It is doing its best. It is said to have a precision in nanosecond. Thing can become well only after all is perfect. We should do our best ourselves first.
I would appreciate it very much if you could give me some advice about registering an interrupt to ACPI with ASL.

There are many, many PCIExpress general purpose I/O boards with
countdown timers that can issue an interrupt. Here’s one.

After I have failed to all test of possibility, I shall change my design. I think it is not so long.

Thanks again.

On May 16, 2019, at 4:22 PM, tatuo wrote:
>
> The period we need is 250~1000microseconds, and jitter is 50 microseconds or so. It is not so hard in some sense. It is not in picosecond.

I know, I was exaggerating to make a point.

> I would appreciate it very much if you could give me some advice about registering an interrupt to ACPI with ASL.

Do you have the ability to modify the BIOS in your machine? If you have the source code, then you might be able to modify the DSDT in the BIOS to add a device for the HPET that you can provide an INF for. Such a driver would be assigned the appropriate interrupt by the system. No hackery.

However, that requires the BIOS source. Linux has the ability to add DSDT overrides during boot, but Windows (to my knowledge) does not.

Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.