Intel OPAE FPGA Linux-Gerätetreiberarchitektur
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
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
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:
- Entladen Sie den Treiber vom Gast
- Trennen Sie das VF vom Gast
- Deaktivieren Sie SR-IOV
- Führen Sie eine teilweise Neukonfiguration durch
- Aktivieren Sie SR-IOV
- Schließen Sie das VF an den Gast an
- 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:
- 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.
- 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
- Übergeben Sie die VFs an VMs.
- 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
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.
- Ordnen Sie ein struct build_feature_devs_info zu, initialisieren Sie es.
- 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-Initialisierungsablauf
- 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-Initialisierung
- 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 file | mmio-Feld | Typ | Zugang |
ports_num | fme_header.capability.num_ports | dezimal int | Schreibgeschützt |
Cachegröße | fme_header.capability.cache_size | dezimal int | Schreibgeschützt |
Version | fme_header.capability.fabric_verid | dezimal int | Schreibgeschützt |
socket_id | fme_header.capability.socket_id | dezimal int | Schreibgeschützt |
bitstream_id | fme_header.bitstream_id | hex uint64_t | Schreibgeschützt |
bitstream_metadata | fme_header.bitstream_md | hex uint64_t | Schreibgeschützt |
FME Thermal Management sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/thermal_mgmt/
sysfs file | mmio-Feld | Typ | Zugang |
Schwelle1 | Thermal.threshold.tmp_thshold1 | dezimal int | Benutzer: Nur-Lesen Root: Lesen-Schreiben |
Schwelle2 | Thermal.threshold.tmp_thshold2 | dezimal int | Benutzer: Nur-Lesen Root: Lesen-Schreiben |
Schwelle_Ausflug | thermische.threshold.therm_trip_thshold | dezimal int | Schreibgeschützt |
Schwelle1_erreicht | Thermal.threshold.thshold1_status | dezimal int | Schreibgeschützt |
Schwelle2_erreicht | Thermal.threshold.thshold2_status | dezimal int | Schreibgeschützt |
Schwelle1_Richtlinie | Thermal. Schwelle.thshold_policy | dezimal int | Benutzer: Nur-Lesen Root: Lesen-Schreiben |
Temperatur | Thermal.rdsensor_fm1.fpga_temp | dezimal int | Schreibgeschützt |
FME Power Management sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/power_mgmt/
sysfs file | mmio-Feld | Typ | Zugang |
verbraucht | power.status.pwr_consumed | hex uint64_t | Schreibgeschützt |
Schwelle1 | power.threshold.threshold1 | hex uint64_t | Benutzer: Nur-Lesen Root: Lesen-Schreiben |
Schwelle2 | power.threshold.threshold2 | hex uint64_t | Benutzer: Nur-Lesen Root: Lesen-Schreiben |
Schwelle1_Status | power.threshold.threshold1_status | dezimal vorzeichenlos | Schreibgeschützt |
Schwelle2_Status | power.threshold.threshold2_status | dezimal vorzeichenlos | Schreibgeschützt |
rtl | power.status.fpga_latency_report | dezimal vorzeichenlos | Schreibgeschützt |
Globaler FME-Fehler sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/errors/
sysfs file | mmio-Feld | Typ | Zugang |
pcie0_errors | gerror.pcie0_err | hex uint64_t | Lesen Schreiben |
pcie1_errors | gerror.pcie1_err | hex uint64_t | Lesen Schreiben |
inject_error | gerror.ras_error_inj | hex uint64_t | Lesen Schreiben |
intel-fpga-dev.i/intel-fpga-fme.j/errors/fme-errors/
sysfs file | mmio-Feld | Typ | Zugang |
Fehler | gerror.fme_err | hex uint64_t | Schreibgeschützt |
erster_fehler | gerror.fme_first_err.err_reg_status | hex uint64_t | Schreibgeschützt |
next_error | gerror.fme_next_err.err_reg_status | hex uint64_t | Schreibgeschützt |
klar | Löscht Fehler, first_error, next_error | verschiedene uint64_t | Schreibgeschü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 file | mmio-Feld | Typ | Zugang |
Schnittstellen-ID | pr.fme_pr_intfc_id0_h, pr.fme_pre_intfc_id0_l | Hex 16 Byte | Schreibgeschützt |
FME Global Performance sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/dperf/clock
sysfs file | mmio-Feld | Typ | Zugang |
Uhr | gperf.clk.afu_interf_clock | hex uint64_t | Schreibgeschü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 file | mmio-Feld | Typ | Zugang |
einfrieren | gperf.ch_ctl.freeze | dezimal int | Lesen Schreiben |
read_hit | gperf.CACHE_RD_HIT | hex uint64_t | Schreibgeschützt |
read_miss | gperf.CACHE_RD_MISS | hex uint64_t | Schreibgeschützt |
write_hit | gperf.CACHE_WR_HIT | hex uint64_t | Schreibgeschützt |
schreiben_miss | gperf.CACHE_WR_MISS | hex uint64_t | Schreibgeschützt |
hold_request | gperf.CACHE_HOLD_REQ | hex uint64_t | Schreibgeschützt |
tx_req_stall | gperf.CACHE_TX_REQ_STALL | hex uint64_t | Schreibgeschützt |
sysfs file | mmio-Feld | Typ | Zugang |
rx_req_stall | gperf.CACHE_RX_REQ_STALL | hex uint64_t | Schreibgeschützt |
data_write_port_contention | gperf.CACHE_DATA_WR_PORT_CONTEN | hex uint64_t | Schreibgeschützt |
tag_write_port_contention | gperf.CACHE_TAG_WR_PORT_CONTEN | hex uint64_t | Schreibgeschü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 file | mmio-Feld | Typ | Zugang |
einfrieren | gperf.vtd_ctl.freeze | dezimal int | Benutzer: 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 file | mmio-Feld | Typ | Zugang |
read_transaktion | gperf.VTD_AFU0_MEM_RD_TRANS | hex uint64_t | Schreibgeschützt |
schreibe_transaktion | gperf.VTD_AFU0_MEM_WR_TRANS | hex uint64_t | Schreibgeschützt |
tlb_read_hit | gperf.VTD_AFU0_TLB_RD_HIT | hex uint64_t | Schreibgeschützt |
tlb_write_hit | gperf.VTD_AFU0_TLB_WR_HIT | hex uint64_t | Schreibgeschützt |
intel-fpga-dev.i/intel-fpga-fme.j/dperf/fabric/
sysfs file | mmio-Feld | Typ | Zugang |
aktivieren | gperf.fab_ctl.(aktiviert) | dezimal int | Benutzer: Nur-Lesen Root: Lesen-Schreiben |
einfrieren | gperf.fab_ctl.freeze | dezimal int | Benutzer: Nur-Lesen Root: Lesen-Schreiben |
pcie0_read | gperf.FAB_PCIE0_RD | hex uint64_t | Schreibgeschützt |
pcie0_write | gperf.FAB_PCIE0_WR | hex uint64_t | Schreibgeschützt |
pcie1_read | gperf.FAB_PCIE1_RD | hex uint64_t | Schreibgeschützt |
pcie1_write | gperf.FAB_PCIE1_WR | hex uint64_t | Schreibgeschützt |
upi_read | gperf.FAB_UPI_RD | hex uint64_t | Schreibgeschützt |
upi_write | gperf.FAB_UPI_WR | hex uint64_t | Schreibgeschützt |
intel-fpga-ev.i/intel-fpga/fme.j/dperf/fabric/portk/
sysfs file | mmio-Feld | Typ | Zugang |
pcie0_read | gperf.FAB_PCIE0_RD | hex uint64_t | Schreibgeschützt |
pcie0_write | gperf.FAB_PCIE0_WR | hex uint64_t | Schreibgeschützt |
pcie1_read | gperf.FAB_PCIE1_RD | hex uint64_t | Schreibgeschützt |
pcie1_write | gperf.FAB_PCIE1_WR | hex uint64_t | Schreibgeschützt |
upi_read | gperf.FAB_UPI_RD | hex uint64_t | Schreibgeschützt |
upi_write | gperf.FAB_UPI_WR | hex uint64_t | Schreibgeschützt |
Port-Header sysfs files
intel-fpga-dev.i/intel-fpga-port.k/
sysfs file | mmio-Feld | Typ | Zugang |
id | port_header.capability.port_number | dezimal int | Schreibgeschützt |
ltr | port_header.control.latency_tolerance | dezimal int | Schreibgeschützt |
Port-AFU-Header sysfs files
intel-fpga-dev.i/intel-fpga-port.k/
sysfs file | mmio-Feld | Typ | Zugang |
afu_id | afu_header.guid | Hex 16 Byte | Schreibgeschützt |
Portfehler sysfs files
intel-fpga-dev.i/intel-fpga-port.k/errors/
sysfs file | mmio-Feld | Typ | Zugang |
Fehler | perror.port_error | hex uint64_t | Schreibgeschützt |
erster_fehler | perror.port_first_error | hex uint64_t | Schreibgeschützt |
first_malformed_req | perror.malreq | Hex 16 Byte | Schreibgeschützt |
klar | perror.(alle Fehler) | verschiedene uint64_t | Schreibgeschü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.02 | Erstverö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 |