Intel OPAE FPGA Linux Device Driver Architecture
OPAE Intel FPGA Linux Device Driver Architecture
Driverul OPAE Intel FPGA oferă interfețe pentru aplicațiile din spațiul utilizatorului pentru a configura, enumera, deschide și accesa acceleratoare FPGA pe platforme echipate cu soluții Intel FPGA și permite funcții de management la nivel de sistem, cum ar fi reconfigurarea FPGA, managementul energiei și virtualizarea.
Arhitectura Hardware
Din punctul de vedere al sistemului de operare view, hardware-ul FPGA apare ca un dispozitiv PCIe obișnuit. Memoria dispozitivului FPGA este organizată folosind o structură de date predefinită (Device Feature List). Caracteristicile acceptate de dispozitivul FPGA sunt expuse prin aceste structuri de date, așa cum este ilustrat mai jos în figura următoare:
Dispozitiv FPGA PCIe
Driverul acceptă PCIe SR-IOV pentru a crea funcții virtuale (VF) care pot fi folosite pentru a atribui acceleratoare individuale mașinilor virtuale.
Intel Corporation. Toate drepturile rezervate. Intel, sigla Intel și alte mărci Intel sunt mărci comerciale ale Intel Corporation sau ale subsidiarelor sale. Intel garantează performanța produselor sale FPGA și semiconductoare conform specificațiilor actuale, în conformitate cu garanția standard Intel, dar își rezervă dreptul de a face modificări oricăror produse și servicii în orice moment, fără notificare. Intel nu își asumă nicio responsabilitate sau răspundere care decurg din aplicarea sau utilizarea oricăror informații, produse sau servicii descrise aici, cu excepția cazului în care Intel a convenit în mod expres în scris. Clienții Intel sunt sfătuiți să obțină cea mai recentă versiune a specificațiilor dispozitivului înainte de a se baza pe orice informații publicate și înainte de a plasa comenzi pentru produse sau servicii.
Alte nume și mărci pot fi revendicate ca fiind proprietatea altora.
Dispozitiv PCIe FPGA virtualizat
Motor de management FPGA (FME)
Motorul de management FPGA realizează managementul energiei și termice, raportarea erorilor, reconfigurarea, raportarea performanței și alte funcții ale infrastructurii. Fiecare FPGA are un FME, care este întotdeauna accesat prin funcția fizică (PF). Aplicațiile din spațiul utilizatorului pot obține acces exclusiv la FME folosind open() și îl pot elibera folosind close() ca utilizator privilegiat (rădăcină).
Port
Un port reprezintă interfața dintre structura statică FPGA („FPGA Interface Manager (FIM)”) și o regiune parțial reconfigurabilă care conține o funcție de accelerare (AF). Portul controlează comunicarea de la software la accelerator și expune caracteristici precum resetarea și depanarea. Un dispozitiv PCIe poate avea mai multe porturi, iar fiecare port poate fi expus printr-un VF prin alocarea acestuia folosind FPGA_FME_PORT_ASSIGN ioctl pe dispozitivul FME.
Unitate cu funcția de accelerație (AF).
- O unitate cu funcție de accelerație (AF) este atașată la un port și expune o regiune MMIO de 256K pentru a fi utilizată pentru registrele de control specifice acceleratorului.
- Aplicațiile din spațiul utilizatorului pot obține acces exclusiv la un AFU atașat la un Port utilizând open() pe dispozitivul Port și îl eliberează folosind close().
- Aplicațiile din spațiul utilizatorului pot, de asemenea, accelerare mmap() regiuni MMIO.
Reconfigurare parțială
După cum sa menționat mai sus, acceleratoarele pot fi reconfigurate prin reconfigurarea parțială a unei funcții de accelerație (AF) file. Funcția Accelerator (AF) trebuie să fi fost generată pentru FIM exact și regiunea statică vizată (Port) a FPGA; în caz contrar, operația de reconfigurare va eșua și poate cauza instabilitate a sistemului. Această compatibilitate poate fi verificată comparând ID-ul interfeței notat în antetul AF cu ID-ul interfeței expus de FME prin sysfs. Această verificare se face de obicei de către spațiul utilizatorului înainte de a apela reconfigurarea IOCTL.
Nota:
În prezent, orice program software care accesează FPGA, inclusiv cele care rulează într-o gazdă virtualizată, trebuie să fie închis înainte de a încerca o reconfigurare parțială. Pașii ar fi:
- Descărcați șoferul de la oaspete
- Deconectați VF-ul de la invitat
- Dezactivați SR-IOV
- Efectuați reconfigurarea parțială
- Activați SR-IOV
- Conectați VF la oaspete
- Încărcați șoferul în oaspete
Virtualizare FPGA
Pentru a permite accesarea unui accelerator din aplicațiile care rulează într-o VM, portul AFU respectiv trebuie să fie alocat unui VF utilizând următorii pași:
- PF deține toate porturile AFU în mod implicit. Orice port care trebuie reatribuit unui VF trebuie mai întâi eliberat din PF prin FPGA_FME_PORT_RELEASE ioctl de pe dispozitivul FME.
- Odată ce N porturi sunt eliberate din PF, comanda de mai jos poate fi folosită pentru a activa SRIOV și VF-uri. Fiecare VF deține un singur port cu AFU. echo N > PCI_DEVICE_PATH/sriov_numvfs
- Treceți prin VF-uri către VM.
- AFU sub VF este accesibil din aplicațiile din VM (folosind același driver în interiorul VF).
Nota:
Un FME nu poate fi atribuit unui VF, astfel PR și alte funcții de management sunt disponibile numai prin PF.
Organizația șoferilor
Driver de dispozitiv pentru modulul PCIe
Organizația șoferilor
Dispozitivele FPGA apar ca dispozitive PCIe obișnuite; astfel, driverul de dispozitiv FPGA PCIe (intel-FPGA-PCI.ko) este întotdeauna încărcat primul odată ce este detectat un FPGA PCIe PF sau VF. Acest șofer joacă un rol de infrastructură în arhitectura șoferului. Acesta:
- Creează un dispozitiv container FPGA ca părinte al dispozitivelor caracteristice.
- Parcurge lista de caracteristici ale dispozitivului, care este implementată în memoria BAR a dispozitivului PCIe, pentru a descoperi dispozitivele cu caracteristici și subfuncțiile acestora și pentru a crea dispozitive platformă pentru acestea sub dispozitivul container.
- Suporta SR-IOV.
- Prezintă infrastructura dispozitivelor cu caracteristici, care rezumă operațiunile pentru subfuncții și expune funcțiile comune driverelor de dispozitive caracteristice.
Funcțiile driverului de dispozitiv al modulului PCIe
- Conține descoperirea PCIe, enumerarea dispozitivelor și descoperirea caracteristicilor.
- Creează directoare sysfs pentru dispozitivul părinte, FPGA Management Engine (FME) și Port.
- Creează instanțele driverului platformei, determinând kernel-ul Linux să încarce driverele modulului platformei respective.
Driver de dispozitiv pentru modulul platformei FME
- Managementul energiei și termice, raportarea erorilor, raportarea performanței și alte funcții de infrastructură. Puteți accesa aceste funcții prin interfețele sysfs expuse de driverul FME.
- Reconfigurare parțială. Driverul FME înregistrează un Manager FPGA în timpul inițializării subfuncției PR; odată ce primește un ioctl FPGA_FME_PORT_PR de la dvs., invocă funcția de interfață comună de la FPGA Manager pentru a finaliza reconfigurarea parțială a fluxului de biți la portul dat.
- Managementul porturilor pentru virtualizare. Driverul FME introduce două ioctls, FPGA_FME_PORT_RELEASE, care eliberează portul dat de la PF; și FPGA_FME_PORT_ASSIGN, care atribuie portul înapoi la PF. Odată ce portul este eliberat de la PF, acesta poate fi alocat VF-ului prin interfețele SR-IOV furnizate de driverul PCIe. Pentru mai multe informații, consultați „Virtualizarea FPGA”.
Funcțiile driverului dispozitivului FME Platform Module
- Creează nodul de dispozitiv de caractere FME.
- Creează sysfs FME files și implementează FME sysfs file accesorii.
- Implementează sub-driverele pentru caracteristicile private FME.
- Sub-drivere pentru funcții private FME:
- Antet FME
- Managementul termic
- Managementul energiei
- Eroare globală
- Reconfigurare parțială
- Performanță globală
Driver de dispozitiv pentru modulul platformei porturi
Similar cu driverul FME, driverul FPGA Port (și AFU) (intel-fpga-afu. ko) este testat odată ce dispozitivul platformei Port este creat. Funcția principală a acestui modul este de a oferi o interfață pentru aplicațiile din spațiul utilizatorului pentru a accesa acceleratoarele individuale, inclusiv controlul de bază de resetare pe port, exportul regiunii AFU MMIO, serviciul de cartografiere buffer DMA, notificarea UMsg(1) și funcțiile de depanare la distanță ( vezi mai sus).
UMsg este acceptat numai prin Acceleration Stack pentru procesorul Intel Xeon® cu FPGA integrat.
Port Platform Module Device Driver Funcții
- Creează nodul de dispozitiv de caractere Port.
- Creează port sysfs files și implementează Port sysfs file accesorii.
- Implementează sub-driverele pentru caracteristica privată Port.
- Sub-drivere pentru funcții private de port:
- Antet port
- AFU
- Eroare de port
- UMsg(2)
- Atingeți semnal
Aplicație FPGA Device Enumeration
Această secțiune prezintă modul în care aplicațiile enumeră dispozitivul FPGA din ierarhia sysfs sub /sys/class/fpga. În exampmai jos, două dispozitive Intel FPGA sunt instalate în gazdă. Fiecare dispozitiv FPGA are un FME și două porturi (AFU). Pentru fiecare dispozitiv FPGA, un director de dispozitiv este creat sub /sys/class/fpga:
/sys/class/fpga/intel-fpga-dev.0
/sys/class/fpga/intel-fpga-dev.1
Fiecare nod are un FME și două porturi (AFU) ca dispozitive copil:
/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
În general, interfețele FME/Port sysfs sunt denumite după cum urmează:
/sys/class/fpga/intel-fpga-dev.i/intel-fpga-fme.j/
/sys/class/fpga/intel-fpga-dev.i/intel-fpga-port.k/
cu I numerotând consecutiv toate dispozitivele container, j numerotând consecutiv FME-urile și k numerotând consecutiv toate porturile.
Nodurile de dispozitiv utilizate pentru ioctl() și mmap() pot fi referite prin:
/dev/intel-fpga-fme.j
/dev/intel-fpga-port.k
Enumerarea driverului PCIe
Această secțiune oferă un pesteview a fluxului de cod pentru enumerarea dispozitivelor efectuată de intel-fpga-pci.ko. Sunt evidențiate principalele structuri și funcții de date. Această secțiune este cel mai bine urmată când viewcodul sursă însoțitor (pcie.c).
Structuri de date de enumerare
enumerare fpga_id_type {
PARENT_ID,
FME_ID,
PORT_ID,
FPGA_ID_MAX
};
static struct idr fpga_ids[FPGA_ID_MAX];
struct fpga_chardev_info {
const char *nume;
dev_t devt;
};
struct fpga_chardev_info fpga_chrdevs[] = {
{ .name = FPGA_FEATURE_DEV_FME },
{ .name = FPGA_FEATURE_DEV_PORT },
};
clasă struct static *fpga_class;
struct static 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,}
};
struct static 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 device_id;
struct device *fme_dev;
struct mutex lock;
struct list_head port_dev_list;
int eliberat_port_num;
struct list_head regiuni;
};
struct build_feature_devs_info {
struct pci_dev *pdev;
void __iomem *ioaddr;
void __iomem *ioend;
int bara_curente;
void __iomem *pfme_hdr;
struct device *parent_dev;
struct platform_device *feature_dev;
};
Fluxul de enumerare
- ccidrv_init()
- Inițializați fpga_ids folosind idr_init().
- Inițializați fpga_chrdevs[i].devt folosind alloc_chrdev_region().
- Inițializați fpga_class folosind class_create().
- pci_register_driver(&cci_pci_driver);
- cci_pci_probe()
- Activați dispozitivul PCI, solicitați accesul la regiunile sale, setați modul PCI master și configurați DMA.
- cci_pci_create_feature_devs() build_info_alloc_and_init()
- Alocați o structură build_feature_devs_info, inițializați-o.
.parent_dev este setat la un director sysfs părinte (intel-fpga-dev.id) care conține directoarele FME și Port sysfs.
- Alocați o structură build_feature_devs_info, inițializați-o.
- parse_feature_list()
- Parcurgeți Lista de caracteristici ale dispozitivului BAR0 pentru a descoperi FME, portul și caracteristicile lor private.
- parse_feature() parse_feature_afus() parse_feature_fme()
- Când se întâlnește un FME:
- build_info_create_dev()
- Alocați un dispozitiv de platformă pentru FME, stocându-l în build_feature_devs_info.feature_dev.
- feature_dev.id este inițializat la rezultatul idr_alloc(fpga_ids[FME_ID],
- feature_dev.parent este setat la build_feature_devs_info.parent_dev.
- Alocați o serie de resurse struct în feature_dev.resource.
- Alocați un struct feature_platform_data, inițializați-l și stocați un pointer în feature_dev.dev.platform_data
- create_feature_instance() build_info_add_sub_feature()
- Inițializați feature_dev.resource[FME_FEATURE_ID_HEADER].
- feature_platform_data_add()
- Inițializați feature_platform_data.features[FME_FEATURE_ID_HEADER], totul, cu excepția .fops.
- parse_feature() parse_feature_afus() parse_feature_port()
- Când se întâlnește un port:
- build_info_create_dev()
- Alocați un dispozitiv de platformă pentru Port, stocându-l în build_feature_devs_info.feature_dev.
- feature_dev.id este inițializat la rezultatul idr_alloc(fpga_ids[PORT_ID],
- feature_dev.parent este setat la build_feature_devs_info.parent_dev.
- Alocați o matrice de resurse struct în feature_dev.resource.
- Alocați un struct feature_platform_data, inițializați-l și stocați un pointer în feature_dev.dev.platform_data
- build_info_commit_dev()
- Adăugați struct feature_platform_data.node pentru Port la lista de porturi din struct cci_drvdata.port_dev_list
- create_feature_instance() build_info_add_sub_feature()
- Inițializați feature_dev.resource[PORT_FEATURE_ID_HEADER].
- feature_platform_data_add()
- Inițializați feature_platform_data.features[PORT_FEATURE_ID_HEADER], totul, cu excepția .fops.
- parse_feature() parse_feature_afus() parse_feature_port_uafu()
- Când se întâlnește o AFU:
- create_feature_instance() build_info_add_sub_feature()
- Inițializați feature_dev.resource[PORT_FEATURE_ID_UAFU].
- feature_platform_data_add()
- Inițializați feature_platform_data.features[PORT_FEATURE_ID_UAFU], totul, cu excepția .fops.
- parse_feature() parse_feature_private() parse_feature_fme_private()
- Când se întâlnește o caracteristică privată FME:
- create_feature_instance() build_info_add_sub_feature()
- Inițializați feature_dev.resource[id].
- feature_platform_data_add()
- Inițializați feature_platform_data.features[id], totul în afară de .fops.
- parse_feature() parse_feature_private() parse_feature_port_private()
- Când este întâlnită o caracteristică privată Port: * create_feature_instance() build_info_add_sub_feature() * Inițializați feature_dev.resource[id]. * feature_platform_data_add() Inițializați feature_platform_data.features[id], totul în afară de .fops.
- parse_ports_from_fme()
- Dacă driverul este încărcat pe funcția fizică (PF), atunci:
- Rulați fluxul parse_feature_list() pe fiecare port descris în antetul FME.
- Utilizați BAR-ul menționat în fiecare intrare Port din antet.
Inițializarea dispozitivului platformei FME
Această secțiune oferă un pesteview a fluxului de cod pentru inițializarea dispozitivului FME realizat de intel-fpga-fme.ko. Principalele structuri și funcții de date sunt evidențiate. Această secțiune este cel mai bine urmată când viewcodul sursă însoțitor (fme-main.c).
Structuri de date ale dispozitivelor platformei FME
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);
};
struct feature {
const char *nume;
int index_resursa;
void __iomem *ioaddr;
struct feature_ops *ops;
};
struct feature_platform_data {
struct list_head nod;
struct mutex lock;
dev_status lung nesemnat;
struct cdev cdev;
struct platform_device *dev;
unsigned int disable_count;
void *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 platforma_dispozitiv *, void *)); struct
caracteristici caracteristice[0];
};
struct perf_object {
int id;
const struct attribute_group **attr_groups;
struct device *fme_dev;
struct list_head nod;
struct list_head copii;
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;
};
Fluxul de inițializare a dispozitivului platformei FME
Fluxul de inițializare FME
- fme_probe() fme_dev_init()
- Inițializați o structură fpga_fme și stocați-o în câmpul feature_platform_data.private.
- fme_probe() fpga_dev_feature_init() feature_instance_init()
- Salvați un struct feature_ops în feature_platform_data.features pentru fiecare caracteristică populată.
- Apelați funcția de testare, dacă există, din struct.
- Apelați funcția init din struct.
- fme_probe() fpga_register_dev_ops()
- Creați nodul dispozitiv de caractere FME, înregistrând o structură file_operații.
Inițializarea dispozitivului platformei porturi
Această secțiune oferă un pesteview a fluxului de cod pentru inițializarea dispozitivului port realizat de intel-fpga-afu.ko. Sunt evidențiate principalele structuri și funcții de date. Această secțiune este cel mai bine urmată când viewcodul sursă însoțitor (afu.c).
Port Platformă Dispozitiv Structuri de date
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);
};
struct feature {
const char *nume;
int index_resursa;
void __iomem *ioaddr;
struct feature_ops *ops;
};
struct feature_platform_data {
struct list_head nod;
struct mutex lock;
dev_status lung nesemnat;
struct cdev cdev;
struct platform_device *dev;
unsigned int disable_count;
void *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 platforma_dispozitiv *, void *));
caracteristici de struct[0];
};
struct fpga_afu_region {
indicele u32;
steaguri u32;
dimensiune u64;
offset u64;
u64 fizic;
struct list_head nod;
};
struct fpga_afu_dma_region {
u64 adresa_utilizator;
lungime u64;
u64 iova;
struct page **pagini;
struct rb_node node;
bool in_use;
};
struct fpga_afu {
u64 region_cur_offset;
int num_regions;
u8 num_umsgs;
struct list_head regiuni;
struct rb_root dma_regions;
struct feature_platform_data *pdata;
};
Flux de inițializare a dispozitivului platformei porturi
Fluxul de inițializare a portului
- afu_probe() afu_dev_init()
- Inițializați o structură fpga_afu și stocați-o în câmpul feature_platform_data.private.
- afu_probe() fpga_dev_feature_init() feature_instance_init()
- Salvați un struct feature_ops în feature_platform_data.features pentru fiecare caracteristică populată.
- Apelați funcția de testare, dacă există, din struct.
- Apelați funcția init din struct.
- afu_probe() fpga_register_dev_ops()
- Creați nodul dispozitiv de caractere Port, înregistrând o structură file_operații.
IOCTL-uri FME
IOCTL-uri care sunt apelate la o deschidere file descriptor pentru /dev/intel-fpga-fme.j FPGA_GET_API_VERSION — returnează versiunea curentă ca număr întreg, începând de la 0.
FPGA_CHECK_EXTENSION—nu este acceptat în prezent.
FPGA_FME_PORT_RELEASE—arg este un pointer către:
struct fpga_fme_port_release {
__u32 argsz; // în: sizeof(struct fpga_fme_port_release)
__u32 steaguri; // în: trebuie să fie 0
__u32 port_id; // în: ID-ul portului (de la 0) pentru eliberare.
};
FPGA_FME_PORT_ASSIGN — arg este un pointer către:
struct fpga_fme_port_assign {
__u32 argsz; // în: sizeof(struct fpga_fme_port_assign)
__u32 steaguri; // în: trebuie să fie 0
__u32 port_id; // în: ID-ul portului (de la 0) de atribuit. (trebuie să fi fost
lansat anterior de FPGA_FME_PORT_RELEASE)
};
FPGA_FME_PORT_PR—arg este un pointer către:
struct fpga_fme_port_pr {
__u32 argsz; // în: sizeof(struct fpga_fme_port_pr)
__u32 steaguri; // în: trebuie să fie 0
__u32 port_id; // în: ID-ul portului (de la 0)
__u32 buffer_size; // în: dimensiunea bufferului de flux de biți în octeți. Trebuie să aibă 4 octeți
aliniat.
__u64 adresa_tampon; // în: adresa de proces a bufferului de flux de biți
starea __u64; // ieșire: starea erorii (mască de bit)
};
Port IOCTL-uri
IOCTL-uri care sunt apelate la o deschidere file descriptor pentru /dev/intel-fpga-port.k FPGA_GET_API_VERSION — returnează versiunea curentă ca număr întreg, începând de la 0. FPGA_CHECK_EXTENSION — nu este suportat în prezent.
FPGA_PORT_GET_INFO—arg este un pointer către:
struct fpga_port_info {
__u32 argsz; // în: sizeof(struct fpga_port_info)
__u32 steaguri; // out: returnează 0
__u32 num_regions; // ieșire: număr de regiuni MMIO, 2 (1 pentru AFU și 1 pentru
STP)
__u32 num_umsgs; // out: numărul de UMsg acceptate de hardware
};
FPGA_PORT_GET_REGION_INFO—arg este un pointer către:
struct fpga_port_region_info {
__u32 argsz; // în: sizeof(struct fpga_port_region_info)
__u32 steaguri; // ieșire: (mască de biți) { FPGA_REGION_READ, FPGA_REGION_WRITE,
FPGA_REGION_MMAP }
__u32 index; // în: FPGA_PORT_INDEX_UAFU sau FPGA_PORT_INDEX_STP
__u32 umplutură; // în: trebuie să fie 0
__u64 dimensiune; // out: dimensiunea regiunii MMIO în octeți
__u64 offset; // out: offset al regiunii MMIO de la începutul dispozitivului fd
};
FPGA_PORT_DMA_MAP — arg este un pointer către:
struct fpga_port_dma_map {
__u32 argsz; // în: sizeof(struct fpga_port_dma_map)
__u32 steaguri; // în: trebuie să fie 0 __u64 user_addr; // în: proces virtual
adresa. Trebuie să fie aliniat la pagină.
__u64 lungime; // în: lungimea mapării în octeți. Trebuie să fie un multiplu de pagină
dimensiune.
__u64 iova; // ieșire: adresa virtuală IO };
FPGA_PORT_DMA_UNMAP — arg este un pointer către:
struct fpga_port_dma_unmap {
__u32 argsz; // în: sizeof(struct fpga_port_dma_unmap)
__u32 steaguri; // în: trebuie să fie 0
__u64 iova; // în: Adresă virtuală IO returnată de o anterioară
FPGA_PORT_DMA_MAP };
- FPGA_PORT_RESET—arg trebuie să fie NULL.
- FPGA_PORT_UMSG_ENABLE—arg trebuie să fie NULL.
- FPGA_PORT_UMSG_DISABLE — argumentele trebuie să fie NULL.
FPGA_PORT_UMSG_SET_MODE—arg este un pointer către:
struct fpga_port_umsg_cfg {
__u32 argsz; // în: sizeof(struct fpga_port_umsg_cfg)
__u32 steaguri; // în: trebuie să fie 0
__u32 hint_bitmap; // în: bitmap în modul indiciu UMsg. Indică care sunt UMsg
activat.
};
FPGA_PORT_UMSG_SET_BASE_ADDR—
- UMsg trebuie dezactivat înainte de a emite acest ioctl.
- Câmpul iova trebuie să fie pentru un buffer suficient de mare pentru toate mesajele UMsg (num_umsgs * PAGE_SIZE).
- Buffer-ul este marcat ca „în uz” de către managementul buffer-ului șoferului.
- Dacă iova este NULL, orice regiune anterioară este nemarcată ca „în uz”.
- arg este un pointer către a:
struct fpga_port_umsg_base_addr {- u32 argsz; // în: sizeof(struct fpga_port_umsg_base_addr)
- steaguri u32; // în: trebuie să fie 0
- u64 iova; // în: adresa virtuală IO din FPGA_PORT_DMA_MAP. };
Nota:
- Pentru a șterge erorile de port, trebuie să scrieți masca de biți exactă a erorilor curente, de example, cat erori > clear
- UMsg este acceptat numai prin Acceleration Stack pentru procesorul Intel Xeon cu FPGA integrat.
sysfs Files
Antet FME sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/
sysfs file | câmp mmio | tip | acces |
ports_num | fme_header.capability.num_ports | zecimal int | Numai citire |
cache_size | fme_header.capability.cache_size | zecimal int | Numai citire |
versiune | fme_header.capability.fabric_verid | zecimal int | Numai citire |
socket_id | fme_header.capability.socket_id | zecimal int | Numai citire |
bitstream_id | fme_header.bitstream_id | hex uint64_t | Numai citire |
metadate_bitstream | fme_header.bitstream_md | hex uint64_t | Numai citire |
Sisteme de management termic FME files
intel-fpga-dev.i/intel-fpga-fme.j/thermal_mgmt/
sysfs file | câmp mmio | tip | acces |
pragul 1 | prag.termic.tmp_thshold1 | zecimal int | Utilizator: numai citire Rădăcină: citire-scriere |
pragul 2 | prag.termic.tmp_thshold2 | zecimal int | Utilizator: numai citire Rădăcină: citire-scriere |
threshold_trip | prag.termic.term_trip_thshold | zecimal int | Numai citire |
pragul1_atins | thermal.threshold.thshold1_status | zecimal int | Numai citire |
pragul2_atins | thermal.threshold.thshold2_status | zecimal int | Numai citire |
threshold1_policy | termic. threshold.thshold_policy | zecimal int | Utilizator: numai citire Rădăcină: citire-scriere |
temperatură | termice.rdsensor_fm1.fpga_temp | zecimal int | Numai citire |
Sisteme de gestionare a energiei FME files
intel-fpga-dev.i/intel-fpga-fme.j/power_mgmt/
sysfs file | câmp mmio | tip | acces |
consumat | putere.status.pwr_consumed | hex uint64_t | Numai citire |
pragul 1 | putere.prag.prag1 | hex uint64_t | Utilizator: numai citire Rădăcină: citire-scriere |
pragul 2 | putere.prag.prag2 | hex uint64_t | Utilizator: numai citire Rădăcină: citire-scriere |
threshold1_status | power.threshold.threshold1_status | zecimală fără semn | Numai citire |
threshold2_status | power.threshold.threshold2_status | zecimală fără semn | Numai citire |
rtl | power.status.fpga_latency_report | zecimală fără semn | Numai citire |
Eroare globală FME sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/errors/
sysfs file | câmp mmio | tip | acces |
pcie0_errors | gerror.pcie0_err | hex uint64_t | Citeste, scrie |
pcie1_errors | gerror.pcie1_err | hex uint64_t | Citeste, scrie |
inject_error | gerror.ras_error_inj | hex uint64_t | Citeste, scrie |
intel-fpga-dev.i/intel-fpga-fme.j/errors/fme-errors/
sysfs file | câmp mmio | tip | acces |
erori | gerror.fme_err | hex uint64_t | Numai citire |
prima_eroare | gerror.fme_first_err.err_reg_status | hex uint64_t | Numai citire |
următoarea_eroare | gerror.fme_next_err.err_reg_status | hex uint64_t | Numai citire |
clar | Șterge erorile, first_error, next_error | diverse uint64_t | Numai pentru scriere |
Nota:
Pentru a șterge erorile FME, trebuie să scrieți masca de biți exactă a erorilor curente, de example cat errors > clear.
FME Reconfigurare parțială sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/pr/
sysfs file | câmp mmio | tip | acces |
interfață_id | pr.fme_pr_intfc_id0_h, pr.fme_pre_intfc_id0_l | hex de 16 octeți | Numai citire |
FME Global Performance sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/dperf/clock
sysfs file | câmp mmio | tip | acces |
ceas | gperf.clk.afu_interf_clock | hex uint64_t | Numai citire |
intel-fpga-dev.i/intel-fpga-fme.j/dperf/cache/ (Nu este valabil pentru Acceleration Stack pentru procesorul Intel Xeon cu FPGA)
sysfs file | câmp mmio | tip | acces |
îngheţa | gperf.ch_ctl.freeze | zecimal int | Citeste, scrie |
read_hit | gperf.CACHE_RD_HIT | hex uint64_t | Numai citire |
read_miss | gperf.CACHE_RD_MISS | hex uint64_t | Numai citire |
write_hit | gperf.CACHE_WR_HIT | hex uint64_t | Numai citire |
write_miss | gperf.CACHE_WR_MISS | hex uint64_t | Numai citire |
hold_request | gperf.CACHE_HOLD_REQ | hex uint64_t | Numai citire |
tx_req_stall | gperf.CACHE_TX_REQ_STALL | hex uint64_t | Numai citire |
sysfs file | câmp mmio | tip | acces |
rx_req_stall | gperf.CACHE_RX_REQ_STALL | hex uint64_t | Numai citire |
data_write_port_contention | gperf.CACHE_DATA_WR_PORT_CONTEN | hex uint64_t | Numai citire |
tag_write_port_contention | gperf.CACHE_TAG_WR_PORT_CONTEN | hex uint64_t | Numai citire |
intel-fpga-dev.i/intel-fpga-fme.j/dperf/iommu/ (nu este valabil pentru stiva de accelerare pentru procesorul Intel Xeon cu FPGA)
sysfs file | câmp mmio | tip | acces |
îngheţa | gperf.vtd_ctl.freeze | zecimal int | Utilizator: numai citire Rădăcină: citire-scriere |
intel-fpga-dev.i/intel-fpga-fme.j/dperf/iommu/afuk/ (Nu este valabil pentru Acceleration Stack pentru CPU Intel Xeon cu FPGA)
sysfs file | câmp mmio | tip | acces |
read_transaction | gperf.VTD_AFU0_MEM_RD_TRANS | hex uint64_t | Numai citire |
scrie_tranzacție | gperf.VTD_AFU0_MEM_WR_TRANS | hex uint64_t | Numai citire |
tlb_read_hit | gperf.VTD_AFU0_TLB_RD_HIT | hex uint64_t | Numai citire |
tlb_write_hit | gperf.VTD_AFU0_TLB_WR_HIT | hex uint64_t | Numai citire |
intel-fpga-dev.i/intel-fpga-fme.j/dperf/fabric/
sysfs file | câmp mmio | tip | acces |
permite | gperf.fab_ctl.(activat) | zecimal int | Utilizator: numai citire Rădăcină: citire-scriere |
îngheţa | gperf.fab_ctl.freeze | zecimal int | Utilizator: numai citire Rădăcină: citire-scriere |
pcie0_read | gperf.FAB_PCIE0_RD | hex uint64_t | Numai citire |
pcie0_write | gperf.FAB_PCIE0_WR | hex uint64_t | Numai citire |
pcie1_read | gperf.FAB_PCIE1_RD | hex uint64_t | Numai citire |
pcie1_write | gperf.FAB_PCIE1_WR | hex uint64_t | Numai citire |
upi_read | gperf.FAB_UPI_RD | hex uint64_t | Numai citire |
upi_write | gperf.FAB_UPI_WR | hex uint64_t | Numai citire |
intel-fpga-ev.i/intel-fpga/fme.j/dperf/fabric/portk/
sysfs file | câmp mmio | tip | acces |
pcie0_read | gperf.FAB_PCIE0_RD | hex uint64_t | Numai citire |
pcie0_write | gperf.FAB_PCIE0_WR | hex uint64_t | Numai citire |
pcie1_read | gperf.FAB_PCIE1_RD | hex uint64_t | Numai citire |
pcie1_write | gperf.FAB_PCIE1_WR | hex uint64_t | Numai citire |
upi_read | gperf.FAB_UPI_RD | hex uint64_t | Numai citire |
upi_write | gperf.FAB_UPI_WR | hex uint64_t | Numai citire |
Antet port sysfs files
intel-fpga-dev.i/intel-fpga-port.k/
sysfs file | câmp mmio | tip | acces |
id | port_header.capability.port_number | zecimal int | Numai citire |
ltr | port_header.control.latency_tolerance | zecimal int | Numai citire |
Port AFU Antet sysfs files
intel-fpga-dev.i/intel-fpga-port.k/
sysfs file | câmp mmio | tip | acces |
afu_id | afu_header.guid | hex de 16 octeți | Numai citire |
Eroare port sysfs files
intel-fpga-dev.i/intel-fpga-port.k/errors/
sysfs file | câmp mmio | tip | acces |
erori | perror.port_error | hex uint64_t | Numai citire |
prima_eroare | perror.port_first_error | hex uint64_t | Numai citire |
first_malformed_req | perror.malreq | hex de 16 octeți | Numai citire |
clar | eroare.(toate erorile) | diverse uint64_t | Numai pentru scriere |
Nota:
Pentru a șterge erorile de port, trebuie să scrieți masca de biți exactă a erorilor curente, de example cat errors > clear.
Istoricul revizuirilor
Versiunea documentului | Schimbări |
2017.10.02 | Lansare inițială. |
Ghid de arhitectură a driverului de dispozitiv OPAE Intel FPGA Linux
Documente/Resurse
![]() |
Intel OPAE FPGA Linux Device Driver Architecture [pdfGhid de utilizare OPAE FPGA Linux Device Driver Architecture, OPAE FPGA, Linux Device Driver Architecture, Driver Architecture, Architecture |