logo intel

Architecture de pilote de périphérique Intel OPAE FPGA Linux

Intel-OPAE-FPGA-Linux-Device-Driver-Architecture-produit

Architecture de pilote de périphérique Linux FPGA Intel OPAE

Le pilote OPAE Intel FPGA fournit des interfaces permettant aux applications de l'espace utilisateur de configurer, d'énumérer, d'ouvrir et d'accéder aux accélérateurs FPGA sur des plates-formes équipées de solutions Intel FPGA et permet des fonctions de gestion au niveau du système telles que la reconfiguration FPGA, la gestion de l'alimentation et la virtualisation.

Architecture matérielle

Du point de vue du système d'exploitation view, le matériel FPGA apparaît comme un périphérique PCIe normal. La mémoire du dispositif FPGA est organisée à l'aide d'une structure de données prédéfinie (Device Feature List). Les fonctionnalités prises en charge par le périphérique FPGA sont exposées via ces structures de données, comme illustré ci-dessous dans la figure suivante :

Périphérique PCIe FPGA

intel-OPAE-FPGA-Linux-Device-Driver-Architecture-fig- (1)

Le pilote prend en charge PCIe SR-IOV pour créer des fonctions virtuelles (VF) qui peuvent être utilisées pour attribuer des accélérateurs individuels aux machines virtuelles.

Société intel. Tous les droits sont réservés. Intel, le logo Intel et les autres marques Intel sont des marques commerciales d'Intel Corporation ou de ses filiales. Intel garantit les performances de ses produits FPGA et semi-conducteurs selon les spécifications actuelles conformément à la garantie standard d'Intel, mais se réserve le droit d'apporter des modifications à tout produit et service à tout moment et sans préavis. Intel n'assume aucune responsabilité découlant de l'application ou de l'utilisation de toute information, produit ou service décrit dans le présent document, sauf accord exprès et écrit d'Intel. Il est conseillé aux clients d'Intel d'obtenir la dernière version des spécifications de l'appareil avant de se fier aux informations publiées et avant de passer des commandes de produits ou de services.

D’autres noms et marques peuvent être revendiqués comme étant la propriété d’autrui.

Périphérique PCIe FPGA virtualisé

intel-OPAE-FPGA-Linux-Device-Driver-Architecture-fig- (2)

Moteur de gestion FPGA (FME)
Le moteur de gestion FPGA effectue la gestion de l'alimentation et de la température, le rapport d'erreurs, la reconfiguration, le rapport de performances et d'autres fonctions d'infrastructure. Chaque FPGA a un FME, qui est toujours accessible via la fonction physique (PF). Les applications de l'espace utilisateur peuvent acquérir un accès exclusif au FME en utilisant open() et le libérer en utilisant close() en tant qu'utilisateur privilégié (root).

Port
Un port représente l'interface entre la structure FPGA statique (le « gestionnaire d'interface FPGA (FIM) ») et une région partiellement reconfigurable contenant une fonction d'accélération (AF). Le port contrôle la communication entre le logiciel et l'accélérateur et expose des fonctionnalités telles que la réinitialisation et le débogage. Un périphérique PCIe peut avoir plusieurs ports, et chaque port peut être exposé via un VF en l'attribuant à l'aide de l'ioctl FPGA_FME_PORT_ASSIGN sur le périphérique FME.

Unité de fonction d'accélérateur (AF)

  • Une unité de fonction d'accélérateur (AF) est attachée à un port et expose une région MMIO 256K à utiliser pour les registres de contrôle spécifiques à l'accélérateur.
  • Les applications de l'espace utilisateur peuvent acquérir un accès exclusif à une AFU attachée à un port en utilisant open() sur le périphérique du port, et le libérer en utilisant close().
  • Les applications de l'espace utilisateur peuvent également accélérer mmap() les régions MMIO.

Reconfiguration partielle
Comme mentionné ci-dessus, les accélérateurs peuvent être reconfigurés par reconfiguration partielle d'une fonction d'accélérateur (AF) file. La fonction d'accélérateur (AF) doit avoir été générée pour le FIM exact et la région statique ciblée (port) du FPGA ; sinon, l'opération de reconfiguration échouera et entraînera éventuellement une instabilité du système. Cette compatibilité peut être vérifiée en comparant l'ID d'interface noté dans l'en-tête AF avec l'ID d'interface exposé par le FME via sysfs. Cette vérification est généralement effectuée par l'espace utilisateur avant d'appeler l'IOCTL de reconfiguration.

Note:
Actuellement, tout programme logiciel accédant au FPGA, y compris ceux exécutés sur un hôte virtualisé, doit être fermé avant de tenter une reconfiguration partielle. Les étapes seraient :

  1. Décharger le pilote de l'invité
  2. Débranchez le VF de l'invité
  3. Désactiver SR-IOV
  4. Effectuer une reconfiguration partielle
  5. Activer SR-IOV
  6. Branchez le VF à l'invité
  7. Charger le pilote dans l'invité

Virtualisation FPGA
Pour activer l'accès à un accélérateur à partir d'applications s'exécutant sur une machine virtuelle, le port de l'AFU respectif doit être attribué à une VF en procédant comme suit :

  1. Le PF possède tous les ports AFU par défaut. Tout port qui doit être réaffecté à un VF doit d'abord être libéré du PF via l'ioctl FPGA_FME_PORT_RELEASE sur le périphérique FME.
  2. Une fois que N ports sont libérés du PF, la commande ci-dessous peut être utilisée pour activer SRIOV et VF. Chaque VF possède un seul port avec AFU. echo N > PCI_DEVICE_PATH/sriov_numvfs
  3. Transmettez les VF aux VM.
  4. L'AFU sous VF est accessible depuis les applications en VM (en utilisant le même pilote à l'intérieur de la VF).

Note:
Un FME ne peut pas être affecté à un VF, ainsi PR et d'autres fonctions de gestion ne sont disponibles que via le PF.

Organisation des chauffeurs

Pilote de périphérique de module PCIe

Organisation des chauffeurs

intel-OPAE-FPGA-Linux-Device-Driver-Architecture-fig- (3)

Les périphériques FPGA apparaissent comme des périphériques PCIe normaux ; ainsi, le pilote de périphérique FPGA PCIe (intel-FPGA-PCI.ko) est toujours chargé en premier une fois qu'un FPGA PCIe PF ou VF est détecté. Ce pilote joue un rôle d'infrastructure dans l'architecture du pilote. Il:

  • Crée un périphérique de conteneur FPGA en tant que parent des périphériques de fonctionnalité.
  • Parcourt la liste des fonctionnalités du périphérique, qui est implémentée dans la mémoire BAR du périphérique PCIe, pour découvrir les périphériques de fonctionnalité et leurs sous-fonctionnalités et créer des périphériques de plate-forme pour eux sous le périphérique de conteneur.
  • Prend en charge SR-IOV.
  • Présente l'infrastructure de périphérique de fonctionnalité, qui résume les opérations pour les sous-fonctionnalités et expose les fonctions communes aux pilotes de périphérique de fonctionnalité.

Fonctions du pilote de périphérique du module PCIe

  • Contient la découverte PCIe, l'énumération des périphériques et la découverte des fonctionnalités.
  • Crée des répertoires sysfs pour le périphérique parent, le moteur de gestion FPGA (FME) et le port.
  • Crée les instances de pilote de plate-forme, obligeant le noyau Linux à charger leurs pilotes de module de plate-forme respectifs.

Pilote de périphérique du module de plate-forme FME

  • Gestion de l'alimentation et thermique, rapports d'erreurs, rapports de performances et autres fonctions d'infrastructure. Vous pouvez accéder à ces fonctions via les interfaces sysfs exposées par le pilote FME.
  • Reconfiguration partielle. Le pilote FME enregistre un gestionnaire FPGA lors de l'initialisation de la sous-fonctionnalité PR ; une fois qu'il reçoit un ioctl FPGA_FME_PORT_PR de votre part, il invoque la fonction d'interface commune du gestionnaire FPGA pour terminer la reconfiguration partielle du flux binaire vers le port donné.
  • Gestion des ports pour la virtualisation. Le pilote FME introduit deux ioctls, FPGA_FME_PORT_RELEASE, qui libèrent le port donné de PF ; et FPGA_FME_PORT_ASSIGN, qui attribue le port à PF. Une fois le port libéré du PF, il peut être attribué au VF via les interfaces SR-IOV fournies par le pilote PCIe. Pour plus d'informations, reportez-vous à « Virtualisation FPGA ».

Fonctions du pilote de périphérique du module de plate-forme FME

  • Crée le nœud de périphérique de caractère FME.
  • Crée le FME sysfs files et implémente le FME sysfs file accesseurs.
  • Implémente les sous-pilotes de fonctionnalités privées FME.
  • Sous-pilotes de fonctionnalités privées FME :
    • En-tête FME
    • Gestion thermique
    • Gestion de l'alimentation
    • Erreur globale
    • Reconfiguration partielle
    • Performances globales

Pilote de périphérique du module de plate-forme de port
Semblable au pilote FME, le pilote de port FPGA (et AFU) (intel-fpga-afu. ko) est sondé une fois que le périphérique de plate-forme de port est créé. La fonction principale de ce module est de fournir une interface permettant aux applications de l'espace utilisateur d'accéder aux accélérateurs individuels, y compris le contrôle de réinitialisation de base sur le port, l'exportation de la région AFU MMIO, le service de mappage de tampon DMA, la notification UMsg(1) et les fonctions de débogage à distance ( voir au dessus).

UMsg est uniquement pris en charge via Acceleration Stack pour processeur Intel Xeon® avec FPGA intégré.

Fonctions du pilote de périphérique du module de plate-forme de port

  • Crée le nœud de périphérique de caractère de port.
  • Crée le port sysfs files et implémente le port sysfs file accesseurs.
  • Implémente les sous-pilotes de la fonctionnalité Port privé.
  • Sous-pilotes de fonctionnalité de port privé :
    • En-tête de port
    • AFU
    • Erreur de port
    • UMsg(2)
    • Prise de signal

Énumération des appareils FPGA d'application
Cette section présente comment les applications énumèrent le périphérique FPGA à partir de la hiérarchie sysfs sous /sys/class/fpga. Dans l'exampci-dessous, deux périphériques Intel FPGA sont installés dans l'hôte. Chaque périphérique FPGA possède un FME et deux ports (AFU). Pour chaque périphérique FPGA, un répertoire de périphérique est créé sous /sys/class/fpga :

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

Chaque nœud a un FME et deux ports (AFU) en tant que périphériques enfants :
/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

En général, les interfaces FME/Port sysfs sont nommées comme suit :
/sys/class/fpga/intel-fpga-dev.i/intel-fpga-fme.j/
/sys/class/fpga/intel-fpga-dev.i/intel-fpga-port.k/

avec I numérotant consécutivement tous les dispositifs de conteneur, j numérotant consécutivement les FME et k numérotant consécutivement tous les ports.

Les nœuds de périphérique utilisés pour ioctl() et mmap() peuvent être référencés via :
/dev/intel-fpga-fme.j
/dev/intel-fpga-port.k

Énumération des pilotes PCIe
Cette section donne un surview du flux de code pour l'énumération des périphériques effectuée par intel-fpga-pci.ko. Les principales structures et fonctions de données sont mises en évidence. Cette section est mieux suivie lorsque viewavec le code source qui l'accompagne (pcie.c).

Structures de données d'énumération

énumération fpga_id_type {
PARENT_ID,
FME_ID,
ID_PORT,
FPGA_ID_MAX
};
ID de structure statique fpga_ids[FPGA_ID_MAX] ;
struct fpga_chardev_info {
const char *nom;
dev_t devt ;
};
structure fpga_chardev_info fpga_chrdevs[] = {
{ .name = FPGA_FEATURE_DEV_FME },
{ .name = FPGA_FEATURE_DEV_PORT },
};
classe de structure statique *fpga_class ;
structure statique 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,}
};
structure statique 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
};
structure cci_drvdata {
int device_id ;
périphérique de structure *fme_dev ;
struct mutex lock ;
struct list_head port_dev_list ;
int release_port_num ;
struct list_head régions ;
};
structure build_feature_devs_info {
struct pci_dev *pdev;
void __iomem *ioaddr ;
void __iomem *ioend ;
int barre_actuelle ;
void __iomem *pfme_hdr;
périphérique de structure *parent_dev ;
struct platform_device *feature_dev ;
};

Flux d'énumération

  • ccidrv_init()
    • Initialisez fpga_ids en utilisant idr_init().
    • Initialisez fpga_chrdevs[i].devt en utilisant alloc_chrdev_region().
    • Initialisez fpga_class en utilisant class_create().
    • pci_register_driver(&cci_pci_driver);
  • cci_pci_probe()
    • Activez le périphérique PCI, demandez l'accès à ses régions, définissez le mode maître PCI et configurez DMA.
  • cci_pci_create_feature_devs() build_info_alloc_and_init()
    • Allouez une structure build_feature_devs_info, initialisez-la.
      .parent_dev est défini sur un répertoire sysfs parent (intel-fpga-dev.id) qui contient les répertoires FME et Port sysfs.
  • parse_feature_list()
    • Parcourez la liste des fonctionnalités du périphérique BAR0 pour découvrir le FME, le port et leurs fonctionnalités privées.
  • parse_feature() parse_feature_afus() parse_feature_fme()
    • Lorsqu'un FME est rencontré :
  • build_info_create_dev()
    • Allouez un périphérique de plate-forme pour le FME, en le stockant dans build_feature_devs_info.feature_dev.
    • feature_dev.id est initialisé au résultat de idr_alloc(fpga_ids[FME_ID],
    • feature_dev.parent est défini sur build_feature_devs_info.parent_dev.
    • Allouez un tableau de ressources de structure dans feature_dev.resource.
  • Allouez une structure feature_platform_data, initialisez-la et stockez un pointeur dans feature_dev.dev.platform_data
    • create_feature_instance() build_info_add_sub_feature()
    • Initialisez feature_dev.resource[FME_FEATURE_ID_HEADER].
    • feature_platform_data_add()
    • Initialisez feature_platform_data.features[FME_FEATURE_ID_HEADER], tout sauf .fops.
  • parse_feature() parse_feature_afus() parse_feature_port()
    • Lorsqu'un port est rencontré :
  • build_info_create_dev()
    • Allouez un périphérique de plate-forme pour le port, en le stockant dans build_feature_devs_info.feature_dev.
    • feature_dev.id est initialisé au résultat de idr_alloc(fpga_ids[PORT_ID],
    • feature_dev.parent est défini sur build_feature_devs_info.parent_dev.
    • Allouez un tableau de ressources struct dans feature_dev.resource.
    • Allouez une structure feature_platform_data, initialisez-la et stockez un pointeur dans feature_dev.dev.platform_data
  • build_info_commit_dev()
    • Ajoutez la structure feature_platform_data.node pour le port à la liste des ports dans la structure cci_drvdata.port_dev_list
  • create_feature_instance() build_info_add_sub_feature()
    • Initialisez feature_dev.resource[PORT_FEATURE_ID_HEADER].
  • feature_platform_data_add()
    • Initialisez feature_platform_data.features[PORT_FEATURE_ID_HEADER], tout sauf .fops.
  • parse_feature() parse_feature_afus() parse_feature_port_uafu()
    • Lorsqu'un AFU est rencontré :
  • create_feature_instance() build_info_add_sub_feature()
    • Initialisez feature_dev.resource[PORT_FEATURE_ID_UAFU].
  • feature_platform_data_add()
    • Initialisez feature_platform_data.features[PORT_FEATURE_ID_UAFU], tout sauf .fops.
  • parse_feature() parse_feature_private() parse_feature_fme_private()
    • Lorsqu'une fonction privée FME est rencontrée :
  • create_feature_instance() build_info_add_sub_feature()
    • Initialisez feature_dev.resource[id].
  • feature_platform_data_add()
    • Initialisez feature_platform_data.features[id], tout sauf .fops.
  • parse_feature() parse_feature_private() parse_feature_port_private()
  • Lorsqu'une fonctionnalité de port privé est rencontrée : * create_feature_instance() build_info_add_sub_feature() * Initialize feature_dev.resource[id]. * feature_platform_data_add() Initialise feature_platform_data.features[id], tout sauf .fops.
  • parse_ports_from_fme()
    • Si le driver est chargé sur la Fonction Physique (PF), alors :
  • Exécutez le flux parse_feature_list() sur chaque port décrit dans l'en-tête FME.
  • Utilisez la BARRE mentionnée dans chaque entrée de port dans l'en-tête.

Initialisation de l'appareil de la plate-forme FME
Cette section donne un surview du flux de code pour l'initialisation du périphérique FME effectuée par intel-fpga-fme.ko. Les principales structures et fonctions de données sont mises en évidence. Cette section est mieux suivie lorsque viewen utilisant le code source qui l'accompagne (fme-main.c).

Structures de données des appareils de la plate-forme FME

structure 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, fonctionnalité struct *feature,
int cmd non signé, argument long non signé);
int (*test)(struct platform_device *pdev, struct feature *feature);
};
fonctionnalité de structure {
const char *nom;
int ressource_index ;
void __iomem *ioaddr ;
structure feature_ops *ops ;
};
structure feature_platform_data {
nœud struct list_head ;
struct mutex lock ;
dev_status long non signé ;
structure cdev cdev;
struct platform_device *dev;
entier non signé disable_count ;
vide *privé ;
nombre entier;
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 *)); structure
caractéristiques des fonctionnalités[0] ;
};
struct perf_object {
ID entier ;
const struct groupe_attributs **attr_groups ;
périphérique de structure *fme_dev ;
nœud struct list_head ;
struct list_head enfants ;
struct kobject kobj;
};
structure fpga_fme {
id_port u8 ;
u64 pr_err ;
périphérique de structure *dev_err ;
struct perf_object *perf_dev;
structure feature_platform_data *pdata;
};

Flux d'initialisation de l'appareil de la plate-forme FME

Flux d'initialisation de FMEintel-OPAE-FPGA-Linux-Device-Driver-Architecture-fig- (4)

  • fme_probe() fme_dev_init()
    • Initialisez une structure fpga_fme et stockez-la dans le champ feature_platform_data.private.
  • fme_probe() fpga_dev_feature_init() feature_instance_init()
    • Enregistrez une structure feature_ops dans feature_platform_data.features pour chaque fonctionnalité peuplée.
    • Appelez la fonction de test, le cas échéant, à partir de la structure.
    • Appelez la fonction init à partir de la structure.
  • fme_probe() fpga_register_dev_ops()
    • Créez le nœud de périphérique de caractère FME, en enregistrant une structure file_opérations.

Initialisation du périphérique de la plate-forme de port
Cette section donne un surview du flux de code pour l'initialisation du périphérique de port effectuée par intel-fpga-afu.ko. Les principales structures et fonctions de données sont mises en évidence. Cette section est mieux suivie lorsque viewen utilisant le code source qui l'accompagne (afu.c).

Structures de données des appareils de la plate-forme portuaire

structure 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, fonctionnalité struct *feature,
int cmd non signé, argument long non signé);
int (*test)(struct platform_device *pdev, struct feature *feature);
};
fonctionnalité de structure {
const char *nom;
int ressource_index ;
void __iomem *ioaddr ;
structure feature_ops *ops ;
};
structure feature_platform_data {
nœud struct list_head ;
struct mutex lock ;
dev_status long non signé ;
structure cdev cdev;
struct platform_device *dev;
entier non signé disable_count ;
vide *privé ;
nombre entier;
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 *));
struct feature features[0] ;
};
structure fpga_afu_region {
indice u32 ;
drapeaux u32 ;
taille u64 ;
décalage u64 ;
phys u64 ;
nœud struct list_head ;
};
structure fpga_afu_dma_region {
u64 user_addr ;
longueur u64 ;
u64 iova;
structurer la page **pages ;
struct rb_node nœud ;
booléen in_use ;
};
structure fpga_afu {
u64 region_cur_offset ;
int num_regions ;
u8 num_umsgs ;
struct list_head régions ;
struct rb_root dma_regions ;
structure feature_platform_data *pdata;
};

Flux d'initialisation de périphérique de plate-forme de port

Flux d'initialisation du portintel-OPAE-FPGA-Linux-Device-Driver-Architecture-fig- (5)

  • afu_probe() afu_dev_init()
    • Initialisez une structure fpga_afu et stockez-la dans le champ feature_platform_data.private.
  • afu_probe() fpga_dev_feature_init() feature_instance_init()
    • Enregistrez une structure feature_ops dans feature_platform_data.features pour chaque fonctionnalité peuplée.
    • Appelez la fonction de test, le cas échéant, à partir de la structure.
    • Appelez la fonction init à partir de la structure.
  • afu_probe() fpga_register_dev_ops()
    • Créez le nœud de périphérique de caractère de port, en enregistrant une structure file_opérations.

FME IOCTL
IOCTL qui sont appelés sur un open file descripteur pour /dev/intel-fpga-fme.j FPGA_GET_API_VERSION : renvoie la version actuelle sous forme d'entier, en commençant par 0.

FPGA_CHECK_EXTENSION—non pris en charge actuellement.

FPGA_FME_PORT_RELEASE—arg est un pointeur vers un :

structure fpga_fme_port_release {
__u32 argsz ; // dans : sizeof(struct fpga_fme_port_release)
__u32 drapeaux ; // dans : doit être 0
__u32 port_id ; // in : ID du port (de 0) à libérer.
};

FPGA_FME_PORT_ASSIGN—arg est un pointeur vers un :

structure fpga_fme_port_assign {
__u32 argsz ; // dans : sizeof(struct fpga_fme_port_assign)
__u32 drapeaux ; // dans : doit être 0
__u32 port_id ; // in : ID du port (à partir de 0) à attribuer. (doit avoir été
précédemment publié par FPGA_FME_PORT_RELEASE)
};

FPGA_FME_PORT_PR—arg est un pointeur vers un :

structure fpga_fme_port_pr {
__u32 argsz ; // dans : sizeof(struct fpga_fme_port_pr)
__u32 drapeaux ; // dans : doit être 0
__u32 port_id ; // dans : ID du port (à partir de 0)
__u32 buffer_size ; // in : taille du tampon de flux binaire en octets. Doit être de 4 octets
aligné.
__u64 buffer_address; // in : adresse de processus du tampon de flux binaire
__u64 statut ; // out : état d'erreur (masque de bits)
};

IOCTL portuaires
IOCTL qui sont appelés sur un open file descripteur pour /dev/intel-fpga-port.k FPGA_GET_API_VERSION : renvoie la version actuelle sous forme d'entier, en commençant par 0. FPGA_CHECK_EXTENSION : non pris en charge actuellement.

FPGA_PORT_GET_INFO—arg est un pointeur vers un :

structure fpga_port_info {
__u32 argsz ; // dans : sizeof(struct fpga_port_info)
__u32 drapeaux ; // out : renvoie 0
__u32 num_regions ; // out : nombre de régions MMIO, 2 (1 pour AFU et 1 pour
STP)
__u32 num_umsgs ; // out : nombre d'UMsg pris en charge par le matériel
};

FPGA_PORT_GET_REGION_INFO—arg est un pointeur vers un :

structure fpga_port_region_info {
__u32 argsz ; // dans : sizeof(struct fpga_port_region_info)
__u32 drapeaux ; // en sortie : (masque binaire) { FPGA_REGION_READ, FPGA_REGION_WRITE,
FPGA_REGION_MMAP }
indice __u32 ; // dans : FPGA_PORT_INDEX_UAFU ou FPGA_PORT_INDEX_STP
rembourrage __u32 ; // dans : doit être 0
__taille u64 ; // out : taille de la région MMIO en octets
__u64 décalage ; // out : décalage de la région MMIO à partir du début de l'appareil fd
};

FPGA_PORT_DMA_MAP—arg est un pointeur vers un :
structure fpga_port_dma_map {
__u32 argsz ; // dans : sizeof(struct fpga_port_dma_map)
__u32 drapeaux ; // dans : doit être 0 __u64 user_addr ; // dans : processus virtuel
adresse. Doit être aligné sur la page.
__u64 longueur ; // in : longueur du mappage en octets. Doit être un multiple de page
taille.
__u64 iova; // out : adresse virtuelle IO } ;

FPGA_PORT_DMA_UNMAP—arg est un pointeur vers un :
structure fpga_port_dma_unmap {
__u32 argsz ; // dans : sizeof(struct fpga_port_dma_unmap)
__u32 drapeaux ; // dans : doit être 0
__u64 iova; // in : adresse virtuelle IO retournée par un précédent
FPGA_PORT_DMA_MAP } ;

  • FPGA_PORT_RESET—l'argument doit être NULL.
  • FPGA_PORT_UMSG_ENABLE—l'argument doit être NULL.
  • FPGA_PORT_UMSG_DISABLE—les arguments doivent être NULL.

FPGA_PORT_UMSG_SET_MODE—arg est un pointeur vers un :

structure fpga_port_umsg_cfg {
__u32 argsz ; // dans : sizeof(struct fpga_port_umsg_cfg)
__u32 drapeaux ; // dans : doit être 0
__u32 indice_bitmap ; // dans : bitmap du mode d'indication UMsg. Indique quels sont les UMsg
activé.
};

FPGA_PORT_UMSG_SET_BASE_ADDR—

  • UMsg doit être désactivé avant d'émettre cet ioctl.
  • Le champ iova doit être pour un tampon suffisamment grand pour tous les UMsg (num_umsgs * PAGE_SIZE).
    • Le tampon est marqué comme « en cours d'utilisation » par la gestion des tampons du pilote.
    • Si iova est NULL, toute région précédente n'est pas marquée comme "en cours d'utilisation".
  • arg est un pointeur vers un :
    structure fpga_port_umsg_base_addr {
    • u32 argsz ; // dans : sizeof(struct fpga_port_umsg_base_addr)
    • drapeaux u32 ; // dans : doit être 0
    • u64 iova; // dans : adresse virtuelle IO de FPGA_PORT_DMA_MAP. } ;

Note:

  • Pour effacer les erreurs de port, vous devez écrire le masque de bits exact des erreurs actuelles, par exempleample, erreurs de chat> effacer
  • UMsg est uniquement pris en charge via Acceleration Stack pour processeur Intel Xeon avec FPGA intégré.

système de fichiers Files

En-tête FME sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/

système de fichiers file champ mmio taper accéder
numéros_ports fme_header.capability.num_ports entier décimal Lecture seule
taille_cache fme_header.capability.cache_size entier décimal Lecture seule
version fme_header.capability.fabric_verid entier décimal Lecture seule
socket_id fme_header.capability.socket_id entier décimal Lecture seule
bitstream_id fme_header.bitstream_id hexadécimal uint64_t Lecture seule
bitstream_metadonnées fme_header.bitstream_md hexadécimal uint64_t Lecture seule

Système de gestion thermique FME files
intel-fpga-dev.i/intel-fpga-fme.j/thermal_mgmt/

système de fichiers file champ mmio taper accéder
seuil1 thermal.threshold.tmp_thshold1 entier décimal Utilisateur : Lecture seule Racine : Lecture-écriture
seuil2 thermal.threshold.tmp_thshold2 entier décimal Utilisateur : Lecture seule Racine : Lecture-écriture
seuil_voyage thermal.threshold.therm_trip_thshold entier décimal Lecture seule
seuil1_atteint thermal.threshold.thshold1_status entier décimal Lecture seule
seuil2_atteint thermal.threshold.thshold2_status entier décimal Lecture seule
seuil1_politique thermique. seuil.thshold_policy entier décimal Utilisateur : Lecture seule Racine : Lecture-écriture
température thermique.rdsensor_fm1.fpga_temp entier décimal Lecture seule

sysfs de gestion de l'alimentation FME files
intel-fpga-dev.i/intel-fpga-fme.j/power_mgmt/

système de fichiers file champ mmio taper accéder
consommé power.status.pwr_consumed hexadécimal uint64_t Lecture seule
seuil1 puissance.seuil.seuil1 hexadécimal uint64_t Utilisateur : Lecture seule Racine : Lecture-écriture
seuil2 puissance.seuil.seuil2 hexadécimal uint64_t Utilisateur : Lecture seule Racine : Lecture-écriture
seuil1_statut puissance.threshold.threshold1_status décimal non signé Lecture seule
seuil2_statut puissance.threshold.threshold2_status décimal non signé Lecture seule
rtl power.status.fpga_latency_report décimal non signé Lecture seule

Erreur globale FME sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/errors/

système de fichiers file champ mmio taper accéder
pcie0_erreurs gerror.pcie0_err hexadécimal uint64_t Lire écrire
pcie1_erreurs gerror.pcie1_err hexadécimal uint64_t Lire écrire
erreur_injection gerror.ras_error_inj hexadécimal uint64_t Lire écrire

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

système de fichiers file champ mmio taper accéder
erreurs gerror.fme_err hexadécimal uint64_t Lecture seule
première_erreur gerror.fme_first_err.err_reg_status hexadécimal uint64_t Lecture seule
erreur_suivante gerror.fme_next_err.err_reg_status hexadécimal uint64_t Lecture seule
clair Efface les erreurs, first_error, next_error divers uint64_t En écriture seule

Note:
Pour effacer les erreurs FME, vous devez écrire le masque de bits exact des erreurs actuelles, par exempleample chat erreurs> effacer.

Reconfiguration partielle FME sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/pr/

système de fichiers file champ mmio taper accéder
interface_id pr.fme_pr_intfc_id0_h, pr.fme_pre_intfc_id0_l hexadécimal de 16 octets Lecture seule

Systèmes FME Global Performance files
intel-fpga-dev.i/intel-fpga-fme.j/dperf/horloge

système de fichiers file champ mmio taper accéder
horloge gperf.clk.afu_interf_clock hexadécimal uint64_t Lecture seule

intel-fpga-dev.i/intel-fpga-fme.j/dperf/cache/ (Non valide pour Acceleration Stack pour processeur Intel Xeon avec FPGA)

système de fichiers file champ mmio taper accéder
geler gperf.ch_ctl.freeze entier décimal Lire écrire
lire_hit gperf.CACHE_RD_HIT hexadécimal uint64_t Lecture seule
read_miss gperf.CACHE_RD_MISS hexadécimal uint64_t Lecture seule
écrire_hit gperf.CACHE_WR_HIT hexadécimal uint64_t Lecture seule
écrire_miss gperf.CACHE_WR_MISS hexadécimal uint64_t Lecture seule
hold_request gperf.CACHE_HOLD_REQ hexadécimal uint64_t Lecture seule
tx_req_stall gperf.CACHE_TX_REQ_STALL hexadécimal uint64_t Lecture seule
système de fichiers file champ mmio taper accéder
rx_req_stall gperf.CACHE_RX_REQ_STALL hexadécimal uint64_t Lecture seule
data_write_port_contention gperf.CACHE_DATA_WR_PORT_CONTEN hexadécimal uint64_t Lecture seule
tag_write_port_contention gperf.CACHE_TAG_WR_PORT_CONTEN hexadécimal uint64_t Lecture seule

intel-fpga-dev.i/intel-fpga-fme.j/dperf/iommu/ (Non valide pour Acceleration Stack pour processeur Intel Xeon avec FPGA)

système de fichiers file champ mmio taper accéder
geler gperf.vtd_ctl.freeze entier décimal Utilisateur : Lecture seule Racine : Lecture-écriture

intel-fpga-dev.i/intel-fpga-fme.j/dperf/iommu/afuk/ (non valide pour la pile d'accélération pour processeur Intel Xeon avec FPGA)

système de fichiers file champ mmio taper accéder
lecture_transaction gperf.VTD_AFU0_MEM_RD_TRANS hexadécimal uint64_t Lecture seule
écriture_transaction gperf.VTD_AFU0_MEM_WR_TRANS hexadécimal uint64_t Lecture seule
tlb_read_hit gperf.VTD_AFU0_TLB_RD_HIT hexadécimal uint64_t Lecture seule
tlb_write_hit gperf.VTD_AFU0_TLB_WR_HIT hexadécimal uint64_t Lecture seule

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

système de fichiers file champ mmio taper accéder
activer gperf.fab_ctl.(activé) entier décimal Utilisateur : Lecture seule Racine : Lecture-écriture
geler gperf.fab_ctl.freeze entier décimal Utilisateur : Lecture seule Racine : Lecture-écriture
pcie0_read gperf.FAB_PCIE0_RD hexadécimal uint64_t Lecture seule
pcie0_write gperf.FAB_PCIE0_WR hexadécimal uint64_t Lecture seule
pcie1_read gperf.FAB_PCIE1_RD hexadécimal uint64_t Lecture seule
pcie1_write gperf.FAB_PCIE1_WR hexadécimal uint64_t Lecture seule
upi_read gperf.FAB_UPI_RD hexadécimal uint64_t Lecture seule
upi_write gperf.FAB_UPI_WR hexadécimal uint64_t Lecture seule

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

système de fichiers file champ mmio taper accéder
pcie0_read gperf.FAB_PCIE0_RD hexadécimal uint64_t Lecture seule
pcie0_write gperf.FAB_PCIE0_WR hexadécimal uint64_t Lecture seule
pcie1_read gperf.FAB_PCIE1_RD hexadécimal uint64_t Lecture seule
pcie1_write gperf.FAB_PCIE1_WR hexadécimal uint64_t Lecture seule
upi_read gperf.FAB_UPI_RD hexadécimal uint64_t Lecture seule
upi_write gperf.FAB_UPI_WR hexadécimal uint64_t Lecture seule

En-tête de port sysfs files
intel-fpga-dev.i/intel-fpga-port.k/

système de fichiers file champ mmio taper accéder
id port_header.capability.port_number entier décimal Lecture seule
ltr port_header.control.latency_tolerance entier décimal Lecture seule

Port AFU en-tête sysfs files
intel-fpga-dev.i/intel-fpga-port.k/

système de fichiers file champ mmio taper accéder
afu_id afu_header.guid hexadécimal de 16 octets Lecture seule

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

système de fichiers file champ mmio taper accéder
erreurs erreur.port_error hexadécimal uint64_t Lecture seule
première_erreur erreur.port_first_error hexadécimal uint64_t Lecture seule
first_malformed_req erreur.malreq hexadécimal de 16 octets Lecture seule
clair perror.(toutes les erreurs) divers uint64_t En écriture seule

Note:
Pour effacer les erreurs de port, vous devez écrire le masque de bits exact des erreurs actuelles, par exempleample chat erreurs> effacer.

Historique des révisions

Version du document Changements
2017.10.02 Version initiale.

Guide d'architecture du pilote de périphérique Linux OPAE Intel FPGA

Documents / Ressources

Architecture de pilote de périphérique Intel OPAE FPGA Linux [pdf] Guide de l'utilisateur
Architecture de pilote de périphérique Linux OPAE FPGA, FPGA OPAE, Architecture de pilote de périphérique Linux, Architecture de pilote, Architecture

Références

Laisser un commentaire

Votre adresse email ne sera pas publiée. Les champs obligatoires sont marqués *