Intel-Logo

Intel OPAE FPGA Linux-Gerätetreiberarchitektur

Intel-OPAE-FPGA-Linux-Gerätetreiber-Architektur-Produkt

OPAE Intel FPGA Linux-Gerätetreiberarchitektur

Der OPAE Intel FPGA-Treiber bietet Schnittstellen für User-Space-Anwendungen zum Konfigurieren, Auflisten, Öffnen und Zugreifen auf FPGA-Beschleuniger auf Plattformen, die mit Intel FPGA-Lösungen ausgestattet sind, und ermöglicht Verwaltungsfunktionen auf Systemebene wie FPGA-Neukonfiguration, Energieverwaltung und Virtualisierung.

Hardwarearchitektur

Aus Sicht des Betriebssystems viewerscheint die FPGA-Hardware als normales PCIe-Gerät. Der Speicher des FPGA-Geräts ist mithilfe einer vordefinierten Datenstruktur (Device Feature List) organisiert. Vom FPGA-Gerät unterstützte Funktionen werden durch diese Datenstrukturen bereitgestellt, wie unten in der folgenden Abbildung dargestellt:

FPGA-PCIe-Gerät

Intel-OPAE-FPGA-Linux-Gerätetreiber-Architektur-fig- (1)

Der Treiber unterstützt PCIe SR-IOV zum Erstellen virtueller Funktionen (VFs), die verwendet werden können, um virtuellen Maschinen individuelle Beschleuniger zuzuweisen.

Intel Corporation. Alle Rechte vorbehalten. Intel, das Intel-Logo und andere Intel-Marken sind Marken der Intel Corporation oder ihrer Tochtergesellschaften. Intel garantiert die Leistung seiner FPGA- und Halbleiterprodukte gemäß den aktuellen Spezifikationen gemäß der Standardgarantie von Intel, behält sich jedoch das Recht vor, jederzeit ohne Vorankündigung Änderungen an Produkten und Diensten vorzunehmen. Intel übernimmt keine Verantwortung oder Haftung, die sich aus der Anwendung oder Verwendung von hierin beschriebenen Informationen, Produkten oder Diensten ergeben, es sei denn, Intel hat ausdrücklich schriftlich zugestimmt. Intel-Kunden wird empfohlen, die neueste Version der Gerätespezifikationen zu beschaffen, bevor sie sich auf veröffentlichte Informationen verlassen und bevor sie Produkte oder Dienstleistungen bestellen.

Bei anderen Namen und Marken kann es sich um das Eigentum Dritter handeln.

Virtualisiertes FPGA-PCIe-Gerät

Intel-OPAE-FPGA-Linux-Gerätetreiber-Architektur-fig- (2)

FPGA-Management-Engine (FME)
Die FPGA-Management-Engine führt Energie- und Wärmemanagement, Fehlerberichte, Neukonfiguration, Leistungsberichte und andere Infrastrukturfunktionen durch. Jedes FPGA hat einen FME, auf den immer über die Physical Function (PF) zugegriffen wird. User-Space-Anwendungen können mit open() exklusiven Zugriff auf die FME erlangen und sie mit close() als privilegierter Benutzer (Root) freigeben.

Hafen
Ein Port stellt die Schnittstelle zwischen dem statischen FPGA-Fabric (dem „FPGA Interface Manager (FIM)“) und einem teilweise rekonfigurierbaren Bereich dar, der eine Accelerator Function (AF) enthält. Der Port steuert die Kommunikation von der Software zum Beschleuniger und stellt Funktionen wie Reset und Debug bereit. Ein PCIe-Gerät kann mehrere Ports haben, und jeder Port kann durch eine VF verfügbar gemacht werden, indem er mithilfe des FPGA_FME_PORT_ASSIGN-ioctl auf dem FME-Gerät zugewiesen wird.

Beschleunigerfunktion (AF) Einheit

  • Eine Accelerator Function (AF) Unit ist an einen Port angeschlossen und legt einen 256K-MMIO-Bereich frei, der für beschleunigerspezifische Steuerregister verwendet werden soll.
  • User-Space-Anwendungen können exklusiven Zugriff auf eine an einen Port angeschlossene AFU erhalten, indem sie open() auf dem Port-Gerät verwenden, und sie mit close() freigeben.
  • User-Space-Anwendungen können auch MMIO-Regionen mit mmap() beschleunigen.

Teilweise Neukonfiguration
Wie oben erwähnt, können Beschleuniger durch teilweise Rekonfiguration einer Beschleunigerfunktion (AF) neu konfiguriert werden. file. Die Beschleunigerfunktion (AF) muss für die genaue FIM und den angestrebten statischen Bereich (Port) des FPGA generiert worden sein; Andernfalls schlägt die Neukonfiguration fehl und verursacht möglicherweise Systeminstabilität. Diese Kompatibilität kann überprüft werden, indem die im AF-Header vermerkte Schnittstellen-ID mit der von der FME über sysfs offengelegten Schnittstellen-ID verglichen wird. Diese Prüfung wird normalerweise vom Benutzerbereich durchgeführt, bevor die Rekonfiguration IOCTL aufgerufen wird.

Notiz:
Derzeit muss jedes Softwareprogramm, das auf das FPGA zugreift, einschließlich derjenigen, die auf einem virtualisierten Host ausgeführt werden, geschlossen werden, bevor eine teilweise Neukonfiguration versucht wird. Die Schritte wären:

  1. Entladen Sie den Treiber vom Gast
  2. Trennen Sie das VF vom Gast
  3. Deaktivieren Sie SR-IOV
  4. Führen Sie eine teilweise Neukonfiguration durch
  5. Aktivieren Sie SR-IOV
  6. Schließen Sie das VF an den Gast an
  7. Laden Sie den Treiber im Gast

FPGA-Virtualisierung
Um den Zugriff auf einen Beschleuniger von Anwendungen aus zu ermöglichen, die in einer VM ausgeführt werden, muss der Port der jeweiligen AFU mithilfe der folgenden Schritte einer VF zugewiesen werden:

  1. Der PF besitzt standardmäßig alle AFU-Ports. Jeder Port, der einem VF neu zugewiesen werden muss, muss zuerst vom PF durch das ioctl FPGA_FME_PORT_RELEASE auf dem FME-Gerät freigegeben werden.
  2. Sobald N Ports vom PF freigegeben sind, kann der folgende Befehl verwendet werden, um SRIOV und VFs zu aktivieren. Jede VF besitzt nur einen Port mit AFU. echo N > PCI_DEVICE_PATH/sriov_numvfs
  3. Übergeben Sie die VFs an VMs.
  4. Auf die AFU unter VF kann von Anwendungen in VM zugegriffen werden (unter Verwendung desselben Treibers innerhalb der VF).

Notiz:
Ein FME kann keinem VF zugeordnet werden, daher sind PR und andere Verwaltungsfunktionen nur über den PF verfügbar.

Fahrerorganisation

PCIe-Modul-Gerätetreiber

Fahrerorganisation

Intel-OPAE-FPGA-Linux-Gerätetreiber-Architektur-fig- (3)

Die FPGA-Geräte erscheinen als normale PCIe-Geräte; Daher wird der FPGA-PCIe-Gerätetreiber (intel-FPGA-PCI.ko) immer zuerst geladen, sobald ein FPGA-PCIe-PF oder -VF erkannt wird. Dieser Treiber spielt eine infrastrukturelle Rolle in der Treiberarchitektur. Es:

  • Erstellt ein FPGA-Containergerät als übergeordnetes Element der Funktionsgeräte.
  • Durchläuft die Gerätefunktionsliste, die im BAR-Speicher des PCIe-Geräts implementiert ist, um Funktionsgeräte und ihre Unterfunktionen zu erkennen und Plattformgeräte für sie unter dem Containergerät zu erstellen.
  • Unterstützt SR-IOV.
  • Stellt die Feature-Geräteinfrastruktur vor, die Vorgänge für Unterfunktionen abstrahiert und allgemeine Funktionen für Feature-Gerätetreiber verfügbar macht.

PCIe-Modul-Gerätetreiberfunktionen

  • Enthält PCIe-Erkennung, Geräteaufzählung und Funktionserkennung.
  • Erstellt sysfs-Verzeichnisse für das übergeordnete Gerät, die FPGA-Management-Engine (FME) und den Port.
  • Erstellt die Plattformtreiberinstanzen und veranlasst den Linux-Kernel, ihre jeweiligen Plattformmodultreiber zu laden.

Gerätetreiber für das FME-Plattformmodul

  • Energie- und Wärmemanagement, Fehlerberichterstattung, Leistungsberichterstattung und andere Infrastrukturfunktionen. Sie können auf diese Funktionen über sysfs-Schnittstellen zugreifen, die vom FME-Treiber verfügbar gemacht werden.
  • Teilweise Neukonfiguration. Der FME-Treiber registriert einen FPGA-Manager während der Initialisierung der PR-Unterfunktion; Sobald es ein FPGA_FME_PORT_PR ioctl von Ihnen erhält, ruft es die Common-Interface-Funktion vom FPGA-Manager auf, um die teilweise Neukonfiguration des Bitstroms zum angegebenen Port abzuschließen.
  • Portverwaltung für Virtualisierung. Der FME-Treiber führt zwei ioctls ein, FPGA_FME_PORT_RELEASE, die den angegebenen Port von PF freigibt; und FPGA_FME_PORT_ASSIGN, das den Port wieder PF zuweist. Nachdem der Port vom PF freigegeben wurde, kann er dem VF über die vom PCIe-Treiber bereitgestellten SR-IOV-Schnittstellen zugewiesen werden. Weitere Informationen finden Sie unter „FPGA-Virtualisierung“.

Gerätetreiberfunktionen des FME-Plattformmoduls

  • Erstellt den FME-Zeichengeräteknoten.
  • Erstellt die FME-sysfs files und implementiert das FME-sysfs file Accessoire.
  • Implementiert die Untertreiber der privaten FME-Funktion.
  • Untertreiber für private FME-Funktionen:
    • FME-Header
    • Wärmemanagement
    • Energieverwaltung
    • Globaler Fehler
    • Teilweise Neukonfiguration
    • Globale Leistung

Port-Plattform-Modul-Gerätetreiber
Ähnlich wie beim FME-Treiber wird der FPGA-Port- (und AFU-)Treiber (intel-fpga-afu.ko) geprüft, sobald das Port-Plattformgerät erstellt wurde. Die Hauptfunktion dieses Moduls besteht darin, eine Schnittstelle für User-Space-Anwendungen bereitzustellen, um auf die einzelnen Beschleuniger zuzugreifen, einschließlich grundlegender Reset-Steuerung auf Port, AFU-MMIO-Regionsexport, DMA-Pufferzuordnungsdienst, UMsg(1)-Benachrichtigung und Remote-Debug-Funktionen ( siehe oben).

UMsg wird nur durch Acceleration Stack für Intel Xeon® Prozessoren mit integriertem FPGA unterstützt.

Gerätetreiberfunktionen des Port-Plattform-Moduls

  • Erstellt den Geräteknoten für Portzeichen.
  • Erstellt die Port-sysfs files und implementiert den Port sysfs file Accessoire.
  • Implementiert die Untertreiber für die Port-Private-Funktion.
  • Untertreiber für private Funktionen portieren:
    • Port-Header
    • AFU
    • Port-Fehler
    • UMsg(2)
    • Signal tippen

Anwendungs-FPGA-Geräteaufzählung
Dieser Abschnitt stellt vor, wie Anwendungen das FPGA-Gerät aus der sysfs-Hierarchie unter /sys/class/fpga auflisten. Im Bspample unten sind zwei Intel FPGA-Geräte im Host installiert. Jedes FPGA-Gerät hat eine FME und zwei Ports (AFUs). Für jedes FPGA-Gerät wird ein Geräteverzeichnis unter /sys/class/fpga erstellt:

/sys/class/fpga/intel-fpga-dev.0
/sys/class/fpga/intel-fpga-dev.1

Jeder Knoten hat eine FME und zwei Ports (AFUs) als untergeordnete Geräte:
/sys/class/fpga/intel-fpga-dev.0/intel-fpga-fme.0
/sys/class/fpga/intel-fpga-dev.0/intel-fpga-port.0
/sys/class/fpga/intel-fpga-dev.0/intel-fpga-port.1
/sys/class/fpga/intel-fpga-dev.1/intel-fpga-fme.1
/sys/class/fpga/intel-fpga-dev.1/intel-fpga-port.2
/sys/class/fpga/intel-fpga-dev.1/intel-fpga-port.3

Im Allgemeinen werden die FME/Port sysfs-Schnittstellen wie folgt benannt:
/sys/class/fpga/intel-fpga-dev.i/intel-fpga-fme.j/
/sys/class/fpga/intel-fpga-dev.i/intel-fpga-port.k/

wobei I alle Containergeräte fortlaufend nummeriert, j die FMEs fortlaufend nummeriert und k alle Ports fortlaufend nummeriert.

Die für ioctl() und mmap() verwendeten Geräteknoten können referenziert werden durch:
/dev/intel-fpga-fme.j
/dev/intel-fpga-port.k

PCIe-Treiberaufzählung
Dieser Abschnitt gibt ein Overview des Codeflusses für die Geräteaufzählung, die von intel-fpga-pci.ko durchgeführt wird. Die wichtigsten Datenstrukturen und Funktionen sind hervorgehoben. Dieser Abschnitt wird am besten befolgt, wenn viewden begleitenden Quellcode (pcie.c).

Aufzählungsdatenstrukturen

Aufzählung fpga_id_type {
ELTERN ID,
FME_ID,
PORT_ID,
FPGA_ID_MAX
};
statische Struktur idr fpga_ids [FPGA_ID_MAX];
struct fpga_chardev_info {
const char *name;
dev_t devt;
};
struct fpga_chardev_info fpga_chrdevs[] = {
{ .name = FPGA_FEATURE_DEV_FME },
{ .name = FPGA_FEATURE_DEV_PORT },
};
statische Strukturklasse *fpga_class;
statische Struktur pci_device_id cci_pcie_id_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIe_DEVICE_ID_RCiEP0_MCP),},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIe_DEVICE_ID_VF_MCP),},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIe_DEVICE_ID_RCiEP0_SKX_P),},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIe_DEVICE_ID_VF_SKX_P),},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIe_DEVICE_ID_RCiEP0_DCP),},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIe_DEVICE_ID_VF_DCP),},
{0,}
};
statische Struktur pci_driver cci_pci_driver = {
.name = DRV_NAME,
.id_table = cci_pcie_id_tbl,
.probe = cci_pci_probe,
.remove = cci_pci_remove,
.sriov_configure = cci_pci_sriov_configure
};
struct cci_drvdata {
int Geräte-ID;
Strukturgerät *fme_dev;
struct Mutex-Sperre;
struct list_head port_dev_list;
int freigegebene_port_nummer;
struct list_head Regionen;
};
struct build_feature_devs_info {
struct pci_dev *pdev;
void __iomem *ioaddr;
void __iomem *ioend;
int aktueller_bar;
void __iomem *pfme_hdr;
Strukturgerät *parent_dev;
struct platform_device *feature_dev;
};

Aufzählungsfluss

  • ccidrv_init()
    • Initialisieren Sie fpga_ids mit idr_init().
    • Initialisieren Sie fpga_chrdevs[i].devt mit alloc_chrdev_region().
    • Initialisieren Sie fpga_class mit class_create().
    • pci_register_driver(&cci_pci_driver);
  • cci_pci_probe()
    • Aktivieren Sie das PCI-Gerät, fordern Sie Zugriff auf seine Regionen an, legen Sie den PCI-Mastermodus fest und konfigurieren Sie DMA.
  • cci_pci_create_feature_devs() build_info_alloc_and_init()
    • Ordnen Sie ein struct build_feature_devs_info zu, initialisieren Sie es.
      .parent_dev wird auf ein übergeordnetes sysfs-Verzeichnis (intel-fpga-dev.id) gesetzt, das die FME- und Port-sysfs-Verzeichnisse enthält.
  • parse_feature_list()
    • Gehen Sie die BAR0-Gerätefunktionsliste durch, um die FME, den Port und ihre privaten Funktionen zu entdecken.
  • parse_feature() parse_feature_afus() parse_feature_fme()
    • Wenn ein FME auftritt:
  • build_info_create_dev()
    • Weisen Sie der FME ein Plattformgerät zu und speichern Sie es in build_feature_devs_info.feature_dev.
    • feature_dev.id wird mit dem Ergebnis von idr_alloc(fpga_ids[FME_ID],
    • feature_dev.parent ist auf build_feature_devs_info.parent_dev gesetzt.
    • Ordnen Sie ein Array von Struct-Ressourcen in feature_dev.resource zu.
  • Ordnen Sie eine Struktur feature_platform_data zu, initialisieren Sie sie und speichern Sie einen Zeiger in feature_dev.dev.platform_data
    • create_feature_instance() build_info_add_sub_feature()
    • Feature_dev.resource[FME_FEATURE_ID_HEADER] initialisieren.
    • feature_platform_data_add()
    • Initialisieren Sie feature_platform_data.features[FME_FEATURE_ID_HEADER], alles außer .fops.
  • parse_feature() parse_feature_afus() parse_feature_port()
    • Wenn ein Port angetroffen wird:
  • build_info_create_dev()
    • Weisen Sie dem Port ein Plattformgerät zu und speichern Sie es in build_feature_devs_info.feature_dev.
    • feature_dev.id wird mit dem Ergebnis von idr_alloc(fpga_ids[PORT_ID],
    • feature_dev.parent ist auf build_feature_devs_info.parent_dev gesetzt.
    • Ordnen Sie ein Array von Struct-Ressourcen in feature_dev.resource zu.
    • Ordnen Sie eine Struktur feature_platform_data zu, initialisieren Sie sie und speichern Sie einen Zeiger in feature_dev.dev.platform_data
  • build_info_commit_dev()
    • Fügen Sie die Struktur feature_platform_data.node für den Port zur Liste der Ports in struct cci_drvdata.port_dev_list hinzu
  • create_feature_instance() build_info_add_sub_feature()
    • Feature_dev.resource[PORT_FEATURE_ID_HEADER] initialisieren.
  • feature_platform_data_add()
    • Initialisieren Sie feature_platform_data.features[PORT_FEATURE_ID_HEADER], alles außer .fops.
  • parse_feature() parse_feature_afus() parse_feature_port_uafu()
    • Wenn eine AFU angetroffen wird:
  • create_feature_instance() build_info_add_sub_feature()
    • Feature_dev.resource[PORT_FEATURE_ID_UAFU] initialisieren.
  • feature_platform_data_add()
    • Initialisieren Sie feature_platform_data.features[PORT_FEATURE_ID_UAFU], alles außer .fops.
  • parse_feature() parse_feature_private() parse_feature_fme_private()
    • Wenn ein privates FME-Feature angetroffen wird:
  • create_feature_instance() build_info_add_sub_feature()
    • Initialisieren Sie feature_dev.resource[id].
  • feature_platform_data_add()
    • Initialisieren Sie feature_platform_data.features[id], alles außer .fops.
  • parse_feature() parse_feature_private() parse_feature_port_private()
  • Wenn ein privates Port-Feature angetroffen wird: * create_feature_instance() build_info_add_sub_feature() * feature_dev.resource[id] initialisieren. * feature_platform_data_add() initialisiert feature_platform_data.features[id], alles außer .fops.
  • parse_ports_from_fme()
    • Wenn der Treiber auf die Physikalische Funktion (PF) geladen wird, dann:
  • Führen Sie den Fluss parse_feature_list() auf jedem im FME-Header beschriebenen Port aus.
  • Verwenden Sie die BAR, die in jedem Port-Eintrag in der Kopfzeile erwähnt wird.

Geräteinitialisierung der FME-Plattform
Dieser Abschnitt gibt ein Overview des Codeflusses für die FME-Geräteinitialisierung, die von intel-fpga-fme.ko durchgeführt wird. Die wichtigsten Datenstrukturen und Funktionen sind hervorgehoben. Dieser Abschnitt wird am besten befolgt, wenn viewden begleitenden Quellcode (fme-main.c).

Gerätedatenstrukturen der FME-Plattform

struct feature_ops {
int (*init)(struct platform_device *pdev, struct feature *feature);
int (*uinit)(struct platform_device *pdev, struct feature *feature);
long (*ioctl)(struct platform_device *pdev, struct feature *feature,
unsigned int cmd, unsigned long arg);
int (*test)(struct platform_device *pdev, struct feature *feature);
};
Strukturfunktion {
const char *name;
int Ressourcenindex;
void __iomem *ioaddr;
struct feature_ops *ops;
};
struct feature_platform_data {
struct list_head Knoten;
struct Mutex-Sperre;
unsigned long dev_status;
struct cdev cdev;
struct Plattformgerät *dev;
unsigned intdisable_count;
ungültig *privat;
int-num;
int (*config_port)(struct platform_device *, u32, bool);
struct platform_device *(*fpga_for_each_port)(struct platform_device *,
void *, int (*match)(struct platform_device *, void *)); Struktur
Feature-Features[0];
};
struct perf_object {
int-ID;
const struct attribute_group **attr_groups;
Strukturgerät *fme_dev;
struct list_head Knoten;
struct list_head Kinder;
struct kobject kobj;
};
struct fpga_fme {
u8 port_id;
u64 pr_err;
struct device *dev_err;
struct perf_object *perf_dev;
struct feature_platform_data *pdata;
};

Ablauf der Geräteinitialisierung der FME-Plattform

FME-InitialisierungsablaufIntel-OPAE-FPGA-Linux-Gerätetreiber-Architektur-fig- (4)

  • fme_probe() fme_dev_init()
    • Initialisieren Sie eine Struktur fpga_fme und speichern Sie sie im Feld feature_platform_data.private.
  • fme_probe() fpga_dev_feature_init() feature_instance_init()
    • Speichern Sie eine Struktur feature_ops in der Datei feature_platform_data.features für jedes ausgefüllte Feature.
    • Rufen Sie die Testfunktion, falls vorhanden, aus der Struktur auf.
    • Rufen Sie die Init-Funktion aus der Struktur auf.
  • fme_probe() fpga_register_dev_ops()
    • Erstellen Sie den FME-Zeichengeräteknoten und registrieren Sie eine Struktur file_operationen.

Port-Plattform-Geräteinitialisierung
Dieser Abschnitt gibt ein Overview des Codeflusses für die von intel-fpga-afu.ko durchgeführte Portgeräteinitialisierung. Die wichtigsten Datenstrukturen und Funktionen sind hervorgehoben. Dieser Abschnitt wird am besten befolgt, wenn viewden begleitenden Quellcode (afu.c).

Gerätedatenstrukturen der Port-Plattform

struct feature_ops {
int (*init)(struct platform_device *pdev, struct feature *feature);
int (*uinit)(struct platform_device *pdev, struct feature *feature);
long (*ioctl)(struct platform_device *pdev, struct feature *feature,
unsigned int cmd, unsigned long arg);
int (*test)(struct platform_device *pdev, struct feature *feature);
};
Strukturfunktion {
const char *name;
int Ressourcenindex;
void __iomem *ioaddr;
struct feature_ops *ops;
};
struct feature_platform_data {
struct list_head Knoten;
struct Mutex-Sperre;
unsigned long dev_status;
struct cdev cdev;
struct Plattformgerät *dev;
unsigned intdisable_count;
ungültig *privat;
int-num;
int (*config_port)(struct platform_device *, u32, bool);
struct platform_device *(*fpga_for_each_port)(struct platform_device *,
void *, int (*match)(struct platform_device *, void *));
Strukturfeature Features[0];
};
struct fpga_afu_region {
u32-Index;
u32-Flags;
u64-Größe;
u64-Offset;
u64-Physik;
struct list_head Knoten;
};
struct fpga_afu_dma_region {
u64 user_addr;
u64-Länge;
u64 Iova;
struct page **Seiten;
struct rb_node Knoten;
bool in_use;
};
struct fpga_afu {
u64 region_cur_offset;
int num_regionen;
u8 num_umsgs;
struct list_head Regionen;
struct rb_root dma_regionen;
struct feature_platform_data *pdata;
};

Ablauf der Geräteinitialisierung für die Port-Plattform

Ablauf der Port-InitialisierungIntel-OPAE-FPGA-Linux-Gerätetreiber-Architektur-fig- (5)

  • afu_probe() afu_dev_init()
    • Initialisieren Sie eine Struktur fpga_afu und speichern Sie sie im Feld feature_platform_data.private.
  • afu_probe() fpga_dev_feature_init() feature_instance_init()
    • Speichern Sie eine Struktur feature_ops in der Datei feature_platform_data.features für jedes ausgefüllte Feature.
    • Rufen Sie die Testfunktion, falls vorhanden, aus der Struktur auf.
    • Rufen Sie die Init-Funktion aus der Struktur auf.
  • afu_probe() fpga_register_dev_ops()
    • Erstellen Sie den Port-Zeichengeräteknoten, indem Sie eine Struktur registrieren file_operationen.

FME-IOCTLs
IOCTLs, die bei einem Open aufgerufen werden file Deskriptor für /dev/intel-fpga-fme.j FPGA_GET_API_VERSION – gibt die aktuelle Version als Ganzzahl zurück, beginnend bei 0.

FPGA_CHECK_EXTENSION – derzeit nicht unterstützt.

FPGA_FME_PORT_RELEASE – arg ist ein Zeiger auf:

struct fpga_fme_port_release {
__u32 argsz; // in: sizeof(struct fpga_fme_port_release)
__u32-Flags; // in: muss 0 sein
__u32 port_id; // in: Port-ID (von 0) bis zur Freigabe.
};

FPGA_FME_PORT_ASSIGN – arg ist ein Zeiger auf:

struct fpga_fme_port_assign {
__u32 argsz; // in: sizeof(struct fpga_fme_port_assign)
__u32-Flags; // in: muss 0 sein
__u32 port_id; // in: zuzuweisende Port-ID (ab 0). (muss gewesen sein
zuvor freigegeben von FPGA_FME_PORT_RELEASE)
};

FPGA_FME_PORT_PR – arg ist ein Zeiger auf:

struct fpga_fme_port_pr {
__u32 argsz; // in: sizeof(struct fpga_fme_port_pr)
__u32-Flags; // in: muss 0 sein
__u32 port_id; // in: Port-ID (ab 0)
__u32 Puffergröße; // in: Größe des Bitstream-Puffers in Bytes. Muss 4 Byte sein
ausgerichtet.
__u64 Puffer_Adresse; // in: Prozessadresse des Bitstream-Puffers
__u64-Status; // out: Fehlerstatus (Bitmaske)
};

IOCTLs portieren
IOCTLs, die bei einem Open aufgerufen werden file Deskriptor für /dev/intel-fpga-port.k FPGA_GET_API_VERSION – gibt die aktuelle Version als Ganzzahl zurück, beginnend bei 0. FPGA_CHECK_EXTENSION – derzeit nicht unterstützt.

FPGA_PORT_GET_INFO – arg ist ein Zeiger auf:

struct fpga_port_info {
__u32 argsz; // in: sizeof(struct fpga_port_info)
__u32-Flags; // out: gibt 0 zurück
__u32 num_regionen; // out: Anzahl der MMIO-Regionen, 2 (1 für AFU und 1 für
STP)
__u32 num_umsgs; // out: Anzahl der von der Hardware unterstützten UMsgs
};

FPGA_PORT_GET_REGION_INFO – arg ist ein Zeiger auf:

struct fpga_port_region_info {
__u32 argsz; // in: sizeof(struct fpga_port_region_info)
__u32-Flags; // aus: (Bitmaske) { FPGA_REGION_READ, FPGA_REGION_WRITE,
FPGA_REGION_MMAP }
__u32-Index; // in: FPGA_PORT_INDEX_UAFU oder FPGA_PORT_INDEX_STP
__u32 Polsterung; // in: muss 0 sein
__u64-Größe; // out: Größe der MMIO-Region in Bytes
__u64-Offset; // out: Offset der MMIO-Region vom Start des Geräts fd
};

FPGA_PORT_DMA_MAP – arg ist ein Zeiger auf:
struct fpga_port_dma_map {
__u32 argsz; // in: sizeof(struct fpga_port_dma_map)
__u32-Flags; // in: muss 0 sein __u64 user_addr; // in: virtuell verarbeiten
die Anschrift. Muss seitenausgerichtet sein.
__u64 Länge; // in: Länge des Mappings in Bytes. Muss ein Vielfaches der Seite sein
Größe.
__u64 iova; // out: IO virtuelle Adresse };

FPGA_PORT_DMA_UNMAP – arg ist ein Zeiger auf:
struct fpga_port_dma_unmap {
__u32 argsz; // in: sizeof(struct fpga_port_dma_unmap)
__u32-Flags; // in: muss 0 sein
__u64 iova; // in: Virtuelle IO-Adresse, die von einem vorherigen zurückgegeben wird
FPGA_PORT_DMA_MAP };

  • FPGA_PORT_RESET – arg muss NULL sein.
  • FPGA_PORT_UMSG_ENABLE – arg muss NULL sein.
  • FPGA_PORT_UMSG_DISABLE – Argumente müssen NULL sein.

FPGA_PORT_UMSG_SET_MODE – arg ist ein Zeiger auf:

struct fpga_port_umsg_cfg {
__u32 argsz; // in: sizeof(struct fpga_port_umsg_cfg)
__u32-Flags; // in: muss 0 sein
__u32 hint_bitmap; // in: UMsg-Hinweismodus-Bitmap. Gibt an, welche UMsgs sind
ermöglicht.
};

FPGA_PORT_UMSG_SET_BASE_ADDR –

  • UMsg muss vor der Ausgabe dieses ioctl deaktiviert werden.
  • Das iova-Feld muss für einen Puffer groß genug für alle UMsgs sein (num_umsgs * PAGE_SIZE).
    • Der Puffer wird von der Pufferverwaltung des Treibers als „in Verwendung“ gekennzeichnet.
    • Wenn iova NULL ist, wird jede vorherige Region nicht als „in Verwendung“ markiert.
  • arg ist ein Zeiger auf a:
    struct fpga_port_umsg_base_addr {
    • u32 argsz; // in: sizeof(struct fpga_port_umsg_base_addr)
    • u32-Flags; // in: muss 0 sein
    • u64 Iova; // in: Virtuelle E/A-Adresse von FPGA_PORT_DMA_MAP. };

Notiz:

  • Um die Portfehler zu löschen, müssen Sie die genaue Bitmaske der aktuellen Fehler schreiben, zample, cat Fehler > löschen
  • UMsg wird nur durch Acceleration Stack für Intel Xeon-Prozessoren mit integriertem FPGA unterstützt.

sysfs Files

FME-Header sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/

sysfs filemmio-FeldTypZugang
ports_numfme_header.capability.num_portsdezimal intSchreibgeschützt
Cachegrößefme_header.capability.cache_sizedezimal intSchreibgeschützt
Versionfme_header.capability.fabric_veriddezimal intSchreibgeschützt
socket_idfme_header.capability.socket_iddezimal intSchreibgeschützt
bitstream_idfme_header.bitstream_idhex uint64_tSchreibgeschützt
bitstream_metadatafme_header.bitstream_mdhex uint64_tSchreibgeschützt

FME Thermal Management sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/thermal_mgmt/

sysfs filemmio-FeldTypZugang
Schwelle1Thermal.threshold.tmp_thshold1dezimal intBenutzer: Nur-Lesen Root: Lesen-Schreiben
Schwelle2Thermal.threshold.tmp_thshold2dezimal intBenutzer: Nur-Lesen Root: Lesen-Schreiben
Schwelle_Ausflugthermische.threshold.therm_trip_thsholddezimal intSchreibgeschützt
Schwelle1_erreichtThermal.threshold.thshold1_statusdezimal intSchreibgeschützt
Schwelle2_erreichtThermal.threshold.thshold2_statusdezimal intSchreibgeschützt
Schwelle1_RichtlinieThermal. Schwelle.thshold_policydezimal intBenutzer: Nur-Lesen Root: Lesen-Schreiben
TemperaturThermal.rdsensor_fm1.fpga_tempdezimal intSchreibgeschützt

FME Power Management sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/power_mgmt/

sysfs filemmio-FeldTypZugang
verbrauchtpower.status.pwr_consumedhex uint64_tSchreibgeschützt
Schwelle1power.threshold.threshold1hex uint64_tBenutzer: Nur-Lesen Root: Lesen-Schreiben
Schwelle2power.threshold.threshold2hex uint64_tBenutzer: Nur-Lesen Root: Lesen-Schreiben
Schwelle1_Statuspower.threshold.threshold1_statusdezimal vorzeichenlosSchreibgeschützt
Schwelle2_Statuspower.threshold.threshold2_statusdezimal vorzeichenlosSchreibgeschützt
rtlpower.status.fpga_latency_reportdezimal vorzeichenlosSchreibgeschützt

Globaler FME-Fehler sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/errors/

sysfs filemmio-FeldTypZugang
pcie0_errorsgerror.pcie0_errhex uint64_tLesen Schreiben
pcie1_errorsgerror.pcie1_errhex uint64_tLesen Schreiben
inject_errorgerror.ras_error_injhex uint64_tLesen Schreiben

intel-fpga-dev.i/intel-fpga-fme.j/errors/fme-errors/

sysfs filemmio-FeldTypZugang
Fehlergerror.fme_errhex uint64_tSchreibgeschützt
erster_fehlergerror.fme_first_err.err_reg_statushex uint64_tSchreibgeschützt
next_errorgerror.fme_next_err.err_reg_statushex uint64_tSchreibgeschützt
klarLöscht Fehler, first_error, next_errorverschiedene uint64_tSchreibgeschützt

Notiz:
Um die FME-Fehler zu löschen, müssen Sie die genaue Bitmaske der aktuellen Fehler schreiben, zample cat Fehler > löschen.

Teilweise FME-Neukonfiguration sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/pr/

sysfs filemmio-FeldTypZugang
Schnittstellen-IDpr.fme_pr_intfc_id0_h, pr.fme_pre_intfc_id0_lHex 16 ByteSchreibgeschützt

FME Global Performance sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/dperf/clock

sysfs filemmio-FeldTypZugang
Uhrgperf.clk.afu_interf_clockhex uint64_tSchreibgeschützt

intel-fpga-dev.i/intel-fpga-fme.j/dperf/cache/ (Nicht gültig für Acceleration Stack für Intel Xeon CPU mit FPGAs)

sysfs filemmio-FeldTypZugang
einfrierengperf.ch_ctl.freezedezimal intLesen Schreiben
read_hitgperf.CACHE_RD_HIThex uint64_tSchreibgeschützt
read_missgperf.CACHE_RD_MISShex uint64_tSchreibgeschützt
write_hitgperf.CACHE_WR_HIThex uint64_tSchreibgeschützt
schreiben_missgperf.CACHE_WR_MISShex uint64_tSchreibgeschützt
hold_requestgperf.CACHE_HOLD_REQhex uint64_tSchreibgeschützt
tx_req_stallgperf.CACHE_TX_REQ_STALLhex uint64_tSchreibgeschützt
sysfs filemmio-FeldTypZugang
rx_req_stallgperf.CACHE_RX_REQ_STALLhex uint64_tSchreibgeschützt
data_write_port_contentiongperf.CACHE_DATA_WR_PORT_CONTENhex uint64_tSchreibgeschützt
tag_write_port_contentiongperf.CACHE_TAG_WR_PORT_CONTENhex uint64_tSchreibgeschützt

intel-fpga-dev.i/intel-fpga-fme.j/dperf/iommu/ (Nicht gültig für Acceleration Stack für Intel Xeon CPU mit FPGAs)

sysfs filemmio-FeldTypZugang
einfrierengperf.vtd_ctl.freezedezimal intBenutzer: Nur-Lesen Root: Lesen-Schreiben

intel-fpga-dev.i/intel-fpga-fme.j/dperf/iommu/afuk/ (Nicht gültig für Acceleration Stack für Intel Xeon CPU mit FPGAs)

sysfs filemmio-FeldTypZugang
read_transaktiongperf.VTD_AFU0_MEM_RD_TRANShex uint64_tSchreibgeschützt
schreibe_transaktiongperf.VTD_AFU0_MEM_WR_TRANShex uint64_tSchreibgeschützt
tlb_read_hitgperf.VTD_AFU0_TLB_RD_HIThex uint64_tSchreibgeschützt
tlb_write_hitgperf.VTD_AFU0_TLB_WR_HIThex uint64_tSchreibgeschützt

intel-fpga-dev.i/intel-fpga-fme.j/dperf/fabric/

sysfs filemmio-FeldTypZugang
aktivierengperf.fab_ctl.(aktiviert)dezimal intBenutzer: Nur-Lesen Root: Lesen-Schreiben
einfrierengperf.fab_ctl.freezedezimal intBenutzer: Nur-Lesen Root: Lesen-Schreiben
pcie0_readgperf.FAB_PCIE0_RDhex uint64_tSchreibgeschützt
pcie0_writegperf.FAB_PCIE0_WRhex uint64_tSchreibgeschützt
pcie1_readgperf.FAB_PCIE1_RDhex uint64_tSchreibgeschützt
pcie1_writegperf.FAB_PCIE1_WRhex uint64_tSchreibgeschützt
upi_readgperf.FAB_UPI_RDhex uint64_tSchreibgeschützt
upi_writegperf.FAB_UPI_WRhex uint64_tSchreibgeschützt

intel-fpga-ev.i/intel-fpga/fme.j/dperf/fabric/portk/

sysfs filemmio-FeldTypZugang
pcie0_readgperf.FAB_PCIE0_RDhex uint64_tSchreibgeschützt
pcie0_writegperf.FAB_PCIE0_WRhex uint64_tSchreibgeschützt
pcie1_readgperf.FAB_PCIE1_RDhex uint64_tSchreibgeschützt
pcie1_writegperf.FAB_PCIE1_WRhex uint64_tSchreibgeschützt
upi_readgperf.FAB_UPI_RDhex uint64_tSchreibgeschützt
upi_writegperf.FAB_UPI_WRhex uint64_tSchreibgeschützt

Port-Header sysfs files
intel-fpga-dev.i/intel-fpga-port.k/

sysfs filemmio-FeldTypZugang
idport_header.capability.port_numberdezimal intSchreibgeschützt
ltrport_header.control.latency_tolerancedezimal intSchreibgeschützt

Port-AFU-Header sysfs files
intel-fpga-dev.i/intel-fpga-port.k/

sysfs filemmio-FeldTypZugang
afu_idafu_header.guidHex 16 ByteSchreibgeschützt

Portfehler sysfs files
intel-fpga-dev.i/intel-fpga-port.k/errors/

sysfs filemmio-FeldTypZugang
Fehlerperror.port_errorhex uint64_tSchreibgeschützt
erster_fehlerperror.port_first_errorhex uint64_tSchreibgeschützt
first_malformed_reqperror.malreqHex 16 ByteSchreibgeschützt
klarperror.(alle Fehler)verschiedene uint64_tSchreibgeschützt

Notiz:
Um die Port-Fehler zu löschen, müssen Sie die genaue Bitmaske der aktuellen Fehler schreiben, zample cat Fehler > löschen.

Änderungsverlauf

DokumentversionÄnderungen
2017.10.02Erstveröffentlichung.

OPAE Intel FPGA Linux Device Driver Architecture Guide

Dokumente / Ressourcen

Intel OPAE FPGA Linux-Gerätetreiberarchitektur [pdf] Benutzerhandbuch
OPAE FPGA Linux-Gerätetreiberarchitektur, OPAE FPGA, Linux-Gerätetreiberarchitektur, Treiberarchitektur, Architektur

Verweise

Hinterlasse einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Pflichtfelder sind markiert *