PCI-Interrupts aktivieren / deaktivieren

8

Ich implementiere einen PCIe-Treiber und möchte verstehen, auf welcher Ebene die Interrupts aktiviert / deaktiviert werden können oder sollten. Ich gebe absichtlich kein Betriebssystem an, da ich davon ausgehe, dass es für jede Plattform relevant sein sollte. Mit Levels meine ich Folgendes:

  • Betriebssystemspezifisches Interrupt-Handling-Framework
  • Interrupts können in den PCI / PCIe-Konfigurationsraumregistern, z. B. dem COMMAND-Register, deaktiviert oder aktiviert werden
  • Interrupts können auch auf Geräteebene maskiert werden. Beispielsweise können wir das Gerät so konfigurieren, dass bestimmte Interrupts für den Host nicht ausgelöst werden

Ich verstehe, dass jeder Interrupt-Typ, der auf PCIe verwendet wird (INTx-Emulation, MSI oder MSI-X), an das Host-Betriebssystem geliefert werden muss.

Meine Frage ist also: Müssen wir tatsächlich Interrupts auf jeder Ebene aktivieren oder deaktivieren, oder reicht dies nur auf der Hardware aus, die der Hardware am nächsten liegt, z. B. in relevanten PCI-Registern?

Kennzeichen
quelle
1
In Windows-KMDF-Treibern geben Sie in der Treiber-INF-Datei an, welche Art von Interrupts verwendet werden sollen (MSI vs INTx vs MSI-x), und das Treiberframework konfiguriert den PCIe-Konfigurationsbereich selbst beim Laden korrekt. Ich weiß nichts über andere Betriebssysteme, aber da .infs Windows-spezifisch sind, denke ich, dass es wahrscheinlich vom Betriebssystem abhängig ist.
Tom Carpenter
2
Sie müssen sie im Allgemeinen vollständig aktivieren , indem Sie die Konfiguration für die Ausführung des Interrupts bereitstellen. Sobald dies erledigt ist , befindet sich die Deaktivierung nur für kurze Zeiträume unterbrechungsfreier Datenverarbeitung auf der CPU, bis Sie das Gerät dekonfigurieren (z. B. zum Energiesparen)
pjc50
1
Wenn Sie Linux verwenden, können Sie das DMA-Framework für Ihre Anwendung verwenden? Es ist sehr schön, dass Sie die Transaktion erstellen und sie mit einem optionalen Timeout zurückgibt, wenn die Transaktion abgeschlossen ist - Sie müssen sich nicht mit dem eigentlichen Interrupt
täuschen
@ pjc50: Wenn ein Treiber die Verwendung eines bestimmten Interrupt-Typs auswählt, z. B. INTx, muss er die Übermittlung von MSI / MSI-X-Interrupts über MSI_CAP-PCI-Register deaktivieren? (Und umgekehrt - disable INTx bei der Verwendung von MSI)
Mark

Antworten:

1

Betriebssysteme beschweren sich im Allgemeinen lautstark über unerwartete Interrupts, da dies leicht erkennbare Programmierfehler in Treibern sind.

Normalerweise startet Ihre Hardware nach dem Zurücksetzen in einem ziemlich inerten Zustand, in dem sie auf die Konfiguration wartet. In diesem Zustand gibt es keine sinnvolle Möglichkeit, einen Interrupt zu generieren, da noch keine Zuordnung hergestellt wurde und Sie nicht wissen, welcher Interrupt vorliegt.

Während der Konfiguration wird die Interrupt-Zuordnung eingerichtet, und der Karte wird mitgeteilt, welche Interrupt-Leitung verwendet werden soll (INTA..INTD als Legacy-PCI oder MSI / MSI-X). Es ist jedoch noch kein Treiber für Interrupts vorhanden. Linux hat hier einen Standardhandler, der sich beim Systemprotokoll beschwert und dann die Interruptquelle deaktiviert, da die Hardware fehlerhaft zu sein scheint (dh standardmäßig sind alle Interrupts aktiviert, aber nur diejenigen, bei denen ein Handler registriert ist, werden voraussichtlich tatsächlich auftreten). .

Der Treiber registriert schließlich Interrupt-Handler und aktiviert die Interrupts, an denen er interessiert ist. Wenn der Treiber nicht mehr an einer bestimmten Bedingung interessiert ist, muss er den Interrupt im Gerät deaktivieren, da dort die gerätespezifischen Interrupt-Ursachen maskiert werden. Die unteren Schichten wissen nur, dass "etwas passiert ist".

Simon Richter
quelle