intel OPAE FPGA Linux Device Driver Architecture
OPAE Intel FPGA Linux Device Driver Architecture
Το πρόγραμμα οδήγησης OPAE Intel FPGA παρέχει διεπαφές για εφαρμογές χώρου χρήστη για διαμόρφωση, απαρίθμηση, άνοιγμα και πρόσβαση σε επιταχυντές FPGA σε πλατφόρμες εξοπλισμένες με λύσεις Intel FPGA και ενεργοποιεί λειτουργίες διαχείρισης σε επίπεδο συστήματος, όπως αναδιαμόρφωση FPGA, διαχείριση ενέργειας και εικονικοποίηση.
Αρχιτεκτονική υλικού
Από την πλευρά του ΛΣ view, το υλικό FPGA εμφανίζεται ως κανονική συσκευή PCIe. Η μνήμη της συσκευής FPGA οργανώνεται χρησιμοποιώντας μια προκαθορισμένη δομή δεδομένων (Λίστα δυνατοτήτων συσκευής). Οι δυνατότητες που υποστηρίζονται από τη συσκευή FPGA εκτίθενται μέσω αυτών των δομών δεδομένων, όπως φαίνεται παρακάτω στην παρακάτω εικόνα:
Συσκευή FPGA PCIe
Το πρόγραμμα οδήγησης υποστηρίζει PCIe SR-IOV για τη δημιουργία Virtual Functions (VF) που μπορούν να χρησιμοποιηθούν για την εκχώρηση μεμονωμένων επιταχυντών σε εικονικές μηχανές.
Intel Corporation. Με την επιφύλαξη παντός δικαιώματος. Η ονομασία Intel, το λογότυπο Intel και άλλα σήματα Intel είναι εμπορικά σήματα της Intel Corporation ή των θυγατρικών της. Η Intel εγγυάται την απόδοση των προϊόντων FPGA και ημιαγωγών της σύμφωνα με τις τρέχουσες προδιαγραφές σύμφωνα με την τυπική εγγύηση της Intel, αλλά διατηρεί το δικαίωμα να κάνει αλλαγές σε οποιαδήποτε προϊόντα και υπηρεσίες ανά πάσα στιγμή χωρίς προειδοποίηση. Η Intel δεν αναλαμβάνει καμία ευθύνη ή ευθύνη που απορρέει από την εφαρμογή ή τη χρήση οποιασδήποτε πληροφορίας, προϊόντος ή υπηρεσίας που περιγράφεται στο παρόν, εκτός εάν συμφωνηθεί ρητά εγγράφως από την Intel. Συνιστάται στους πελάτες της Intel να λαμβάνουν την πιο πρόσφατη έκδοση των προδιαγραφών της συσκευής προτού βασιστούν σε οποιεσδήποτε δημοσιευμένες πληροφορίες και προτού υποβάλουν παραγγελίες για προϊόντα ή υπηρεσίες.
Άλλα ονόματα και επωνυμίες μπορούν να διεκδικηθούν ως ιδιοκτησία άλλων.
Εικονική συσκευή FPGA PCIe
Μηχανή διαχείρισης FPGA (FME)
Το FPGA Management Engine εκτελεί διαχείριση ισχύος και θερμικής ενέργειας, αναφορά σφαλμάτων, επαναδιαμόρφωση, αναφορά απόδοσης και άλλες λειτουργίες υποδομής. Κάθε FPGA έχει ένα FME, το οποίο είναι πάντα προσβάσιμο μέσω της Φυσικής Λειτουργίας (PF). Οι εφαρμογές χώρου χρήστη μπορούν να αποκτήσουν αποκλειστική πρόσβαση στο FME χρησιμοποιώντας το open() και να το απελευθερώσουν χρησιμοποιώντας το close() ως προνομιούχο χρήστη (root).
Λιμάνι
Μια Θύρα αντιπροσωπεύει τη διασύνδεση μεταξύ του στατικού υφάσματος FPGA (το "FPGA Interface Manager (FIM)") και μιας μερικώς αναδιαμορφώσιμης περιοχής που περιέχει μια Λειτουργία Επιταχυντή (AF). Η Θύρα ελέγχει την επικοινωνία από το λογισμικό στον επιταχυντή και εκθέτει λειτουργίες όπως η επαναφορά και ο εντοπισμός σφαλμάτων. Μια συσκευή PCIe μπορεί να έχει πολλές θύρες και κάθε θύρα μπορεί να εκτεθεί μέσω ενός VF εκχωρώντας το χρησιμοποιώντας το FPGA_FME_PORT_ASSIGN ioctl στη συσκευή FME.
Μονάδα Λειτουργίας Επιταχυντή (AF).
- Μια μονάδα Λειτουργίας Επιταχυντή (AF) είναι συνδεδεμένη σε μια Θύρα και εκθέτει μια περιοχή MMIO 256K που θα χρησιμοποιηθεί για καταχωρητές ελέγχου ειδικούς για τον επιταχυντή.
- Οι εφαρμογές χώρου χρήστη μπορούν να αποκτήσουν αποκλειστική πρόσβαση σε μια AFU συνδεδεμένη σε μια θύρα χρησιμοποιώντας την open() στη συσκευή Port και να την απελευθερώσουν χρησιμοποιώντας την close().
- Οι εφαρμογές χώρου χρήστη μπορούν επίσης να επιταχύνουν τις περιοχές MMIO mmap().
Μερική αναδιαμόρφωση
Όπως αναφέρθηκε παραπάνω, οι επιταχυντές μπορούν να διαμορφωθούν εκ νέου μέσω μερικής επαναδιαμόρφωσης μιας Λειτουργίας Επιταχυντή (AF) file. Η Λειτουργία Επιταχυντή (AF) πρέπει να έχει δημιουργηθεί για το ακριβές FIM και τη στοχευμένη στατική περιοχή (Θύρα) του FPGA. Διαφορετικά, η λειτουργία επαναδιαμόρφωσης θα αποτύχει και πιθανώς θα προκαλέσει αστάθεια του συστήματος. Αυτή η συμβατότητα μπορεί να ελεγχθεί συγκρίνοντας το αναγνωριστικό διεπαφής που σημειώνεται στην κεφαλίδα AF με το αναγνωριστικό διεπαφής που εκτίθεται από το FME μέσω του sysfs. Αυτός ο έλεγχος γίνεται συνήθως από το χώρο χρήστη πριν καλέσετε την αναδιαμόρφωση IOCTL.
Σημείωμα:
Επί του παρόντος, κάθε πρόγραμμα λογισμικού που έχει πρόσβαση στο FPGA, συμπεριλαμβανομένων εκείνων που εκτελούνται σε έναν εικονικοποιημένο κεντρικό υπολογιστή, πρέπει να κλείσει πριν από την προσπάθεια μερικής αναδιάρθρωσης. Τα βήματα θα ήταν:
- Ξεφορτώστε το πρόγραμμα οδήγησης από τον επισκέπτη
- Αποσυνδέστε το VF από τον επισκέπτη
- Απενεργοποιήστε το SR-IOV
- Εκτελέστε μερική αναδιαμόρφωση
- Ενεργοποίηση SR-IOV
- Συνδέστε το VF στον επισκέπτη
- Φορτώστε τον οδηγό στον επισκέπτη
Εικονικοποίηση FPGA
Για να ενεργοποιήσετε την πρόσβαση σε έναν επιταχυντή από εφαρμογές που εκτελούνται σε VM, η αντίστοιχη θύρα AFU πρέπει να αντιστοιχιστεί σε ένα VF χρησιμοποιώντας τα ακόλουθα βήματα:
- Το PF κατέχει όλες τις θύρες AFU από προεπιλογή. Οποιαδήποτε θύρα πρέπει να αντιστοιχιστεί εκ νέου σε ένα VF πρέπει πρώτα να αποδεσμευτεί από το PF μέσω του FPGA_FME_PORT_RELEASE ioctl στη συσκευή FME.
- Μόλις απελευθερωθούν N θύρες από το PF, η παρακάτω εντολή μπορεί να χρησιμοποιηθεί για την ενεργοποίηση των SRIOV και VF. Κάθε VF διαθέτει μόνο μία θύρα με AFU. echo N > PCI_DEVICE_PATH/sriov_numvfs
- Περάστε μέσα από τα VF στα VM.
- Το AFU υπό VF είναι προσβάσιμο από εφαρμογές σε VM (χρησιμοποιώντας το ίδιο πρόγραμμα οδήγησης μέσα στο VF).
Σημείωμα:
Ένα FME δεν μπορεί να εκχωρηθεί σε ένα VF, επομένως το PR και άλλες λειτουργίες διαχείρισης είναι διαθέσιμες μόνο μέσω του PF.
Οργάνωση οδηγών
Πρόγραμμα οδήγησης συσκευής PCIe Module
Οργάνωση οδηγών
Οι συσκευές FPGA εμφανίζονται ως κανονικές συσκευές PCIe. Έτσι, το πρόγραμμα οδήγησης συσκευής FPGA PCIe (intel-FPGA-PCI.ko) φορτώνεται πάντα πρώτο μόλις εντοπιστεί ένα FPGA PCIe PF ή VF. Αυτό το πρόγραμμα οδήγησης παίζει έναν ρόλο υποδομής στην αρχιτεκτονική του προγράμματος οδήγησης. Το:
- Δημιουργεί μια συσκευή κοντέινερ FPGA ως γονέα των συσκευών χαρακτηριστικών.
- Περπατάει στη Λίστα δυνατοτήτων συσκευής, η οποία υλοποιείται στη μνήμη BAR της συσκευής PCIe, για να ανακαλύψει τις συσκευές χαρακτηριστικών και τις δευτερεύουσες δυνατότητες τους και να δημιουργήσει συσκευές πλατφόρμας για αυτές κάτω από τη συσκευή κοντέινερ.
- Υποστηρίζει SR-IOV.
- Παρουσιάζει την υποδομή συσκευών χαρακτηριστικών, η οποία αφαιρεί λειτουργίες για δευτερεύουσες δυνατότητες και εκθέτει κοινές λειτουργίες σε προγράμματα οδήγησης συσκευών χαρακτηριστικών.
Λειτουργίες προγράμματος οδήγησης συσκευής PCIe Module
- Περιέχει ανακάλυψη PCIe, απαρίθμηση συσκευών και ανακάλυψη χαρακτηριστικών.
- Δημιουργεί καταλόγους sysfs για τη γονική συσκευή, το FPGA Management Engine (FME) και τη Θύρα.
- Δημιουργεί τις παρουσίες προγραμμάτων οδήγησης πλατφόρμας, αναγκάζοντας τον πυρήνα του Linux να φορτώσει τα αντίστοιχα προγράμματα οδήγησης της μονάδας πλατφόρμας.
Πρόγραμμα οδήγησης συσκευής μονάδας πλατφόρμας FME
- Διαχείριση ισχύος και θερμικής ενέργειας, αναφορά σφαλμάτων, αναφορά απόδοσης και άλλες λειτουργίες υποδομής. Μπορείτε να έχετε πρόσβαση σε αυτές τις λειτουργίες μέσω διεπαφών sysfs που εκτίθενται από το πρόγραμμα οδήγησης FME.
- Μερική αναδιαμόρφωση. Το πρόγραμμα οδήγησης FME καταχωρεί έναν διαχειριστή FPGA κατά την προετοιμασία της δευτερεύουσας δυνατότητας PR. Μόλις λάβει ένα FPGA_FME_PORT_PR ioctl από εσάς, καλεί την κοινή συνάρτηση διεπαφής από το FPGA Manager για να ολοκληρώσει τη μερική επαναδιαμόρφωση της ροής bit στη δεδομένη θύρα.
- Διαχείριση θυρών για εικονικοποίηση. Το πρόγραμμα οδήγησης FME εισάγει δύο ioctls, FPGA_FME_PORT_RELEASE, τα οποία απελευθερώνουν τη δεδομένη θύρα από το PF. και FPGA_FME_PORT_ASSIGN, που εκχωρεί τη Θύρα πίσω στο PF. Μόλις η Θύρα απελευθερωθεί από το PF, μπορεί να αντιστοιχιστεί στο VF μέσω των διασυνδέσεων SR-IOV που παρέχονται από το πρόγραμμα οδήγησης PCIe. Για περισσότερες πληροφορίες, ανατρέξτε στην ενότητα «Εικονικοποίηση FPGA».
Λειτουργίες προγράμματος οδήγησης συσκευής μονάδας πλατφόρμας FME
- Δημιουργεί τον κόμβο συσκευής χαρακτήρων FME.
- Δημιουργεί το FME sysfs files και υλοποιεί το FME sysfs file αξεσουάρ.
- Υλοποιεί τα δευτερεύοντα προγράμματα οδήγησης ιδιωτικών χαρακτηριστικών FME.
- Υποπρογράμματα οδήγησης ιδιωτικών δυνατοτήτων FME:
- Κεφαλίδα FME
- Θερμική Διαχείριση
- Διαχείριση ενέργειας
- Παγκόσμιο Σφάλμα
- Μερική αναδιαμόρφωση
- Παγκόσμια Απόδοση
Πρόγραμμα οδήγησης συσκευής Port Platform Module
Παρόμοια με το πρόγραμμα οδήγησης FME, το πρόγραμμα οδήγησης θύρας FPGA (και AFU) (intel-fpga-afu. ko) εξετάζεται μόλις δημιουργηθεί η συσκευή πλατφόρμας Port. Η κύρια λειτουργία αυτής της ενότητας είναι να παρέχει μια διεπαφή για εφαρμογές χώρου χρήστη για πρόσβαση στους μεμονωμένους επιταχυντές, συμπεριλαμβανομένου του βασικού ελέγχου επαναφοράς στη θύρα, της εξαγωγής περιοχής AFU MMIO, της υπηρεσίας χαρτογράφησης buffer DMA, της ειδοποίησης UMsg(1) και των λειτουργιών απομακρυσμένου εντοπισμού σφαλμάτων ( βλέπε παραπάνω).
Το UMsg υποστηρίζεται μόνο μέσω του Acceleration Stack για επεξεργαστή Intel Xeon® με ενσωματωμένο FPGA.
Port Platform Module Device Driver Λειτουργίες
- Δημιουργεί τον κόμβο συσκευής χαρακτήρων Port.
- Δημιουργεί το Port sysfs files και υλοποιεί το Port sysfs file αξεσουάρ.
- Υλοποιεί τα δευτερεύοντα προγράμματα οδήγησης χαρακτηριστικών Port private.
- Υποπρογράμματα οδήγησης ιδιωτικών δυνατοτήτων θύρας:
- Port Header
- AFU
- Σφάλμα θύρας
- UMsg(2)
- Πατήστε σήματος
Εφαρμογή FPGA Device Enumeration
Αυτή η ενότητα εισάγει τον τρόπο με τον οποίο οι εφαρμογές απαριθμούν τη συσκευή FPGA από την ιεραρχία sysfs στο /sys/class/fpga. Στην πρampΠαρακάτω, δύο συσκευές Intel FPGA είναι εγκατεστημένες στον κεντρικό υπολογιστή. Κάθε συσκευή FPGA έχει μία FME και δύο Θύρες (AFU). Για κάθε συσκευή FPGA, δημιουργείται ένας κατάλογος συσκευών στο /sys/class/fpga:
/sys/class/fpga/intel-fpga-dev.0
/sys/class/fpga/intel-fpga-dev.1
Κάθε κόμβος έχει ένα FME και δύο Θύρες (AFU) ως θυγατρικές συσκευές:
/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
Γενικά, οι διεπαφές FME/Port sysfs ονομάζονται ως εξής:
/sys/class/fpga/intel-fpga-dev.i/intel-fpga-fme.j/
/sys/class/fpga/intel-fpga-dev.i/intel-fpga-port.k/
με I να αριθμεί διαδοχικά όλες τις συσκευές κοντέινερ, j να αριθμεί διαδοχικά τα FME και k να αριθμεί διαδοχικά όλες τις θύρες.
Οι κόμβοι της συσκευής που χρησιμοποιούνται για ioctl() και mmap() μπορούν να αναφέρονται μέσω:
/dev/intel-fpga-fme.j
/dev/intel-fpga-port.k
Αριθμός προγραμμάτων οδήγησης PCIe
Αυτή η ενότητα δίνει ένα overview της ροής κώδικα για την απαρίθμηση συσκευών που εκτελείται από το intel-fpga-pci.ko. Επισημαίνονται οι κύριες δομές και λειτουργίες δεδομένων. Αυτή η ενότητα ακολουθείται καλύτερα όταν viewμε τον συνοδευτικό πηγαίο κώδικα (pcie.c).
Αριθμητικές Δομές Δεδομένων
enum fpga_id_type {
PARENT_ID,
FME_ID,
PORT_ID,
FPGA_ID_MAX
};
στατική δομή idr fpga_ids[FPGA_ID_MAX];
struct fpga_chardev_info {
const char *όνομα;
dev_t devt;
};
struct fpga_chardev_info fpga_chrdevs[] = {
{ .name = FPGA_FEATURE_DEV_FME },
{ .name = FPGA_FEATURE_DEV_PORT },
};
static struct class *fpga_class;
στατική δομή 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,}
};
στατική κατασκευή 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 συσκευή *fme_dev;
struct mutex κλειδαριά?
struct list_head port_dev_list;
int release_port_num;
struct list_head περιοχές?
};
struct build_feature_devs_info {
struct pci_dev *pdev;
void __iomem *ioaddr;
void __iomem *ioend;
int current_bar;
void __iomem *pfme_hdr;
struct συσκευή *parent_dev;
struct platform_device *feature_dev;
};
Ροή απαρίθμησης
- ccidrv_init()
- Αρχικοποιήστε τα fpga_ids χρησιμοποιώντας idr_init().
- Αρχικοποιήστε το fpga_chrdevs[i].devt χρησιμοποιώντας alloc_chrdev_region().
- Εκκινήστε το fpga_class χρησιμοποιώντας class_create().
- pci_register_driver(&cci_pci_driver);
- cci_pci_probe()
- Ενεργοποιήστε τη συσκευή PCI, ζητήστε πρόσβαση στις περιοχές της, ορίστε την κύρια λειτουργία PCI και διαμορφώστε το DMA.
- cci_pci_create_feature_devs() build_info_alloc_and_init()
- Εκχωρήστε μια δομή build_feature_devs_info, αρχικοποιήστε την.
Το .parent_dev έχει οριστεί σε έναν γονικό κατάλογο sysfs (intel-fpga-dev.id) που περιέχει τους καταλόγους FME και Port sysfs.
- Εκχωρήστε μια δομή build_feature_devs_info, αρχικοποιήστε την.
- parse_feature_list()
- Περπατήστε στη λίστα δυνατοτήτων συσκευής BAR0 για να ανακαλύψετε το FME, τη θύρα και τις ιδιωτικές τους λειτουργίες.
- parse_feature() parse_feature_afus() parse_feature_fme()
- Όταν αντιμετωπίζετε ένα FME:
- build_info_create_dev()
- Εκχωρήστε μια συσκευή πλατφόρμας για το FME, που αποθηκεύεται στο build_feature_devs_info.feature_dev.
- Το feature_dev.id αρχικοποιείται στο αποτέλεσμα του idr_alloc(fpga_ids[FME_ID],
- Το feature_dev.parent έχει οριστεί σε build_feature_devs_info.parent_dev.
- Εκχωρήστε έναν πίνακα πόρων struct στο feature_dev.resource.
- Εκχωρήστε μια δομή feature_platform_data, αρχικοποιήστε την και αποθηκεύστε έναν δείκτη στο feature_dev.dev.platform_data
- create_feature_instance() build_info_add_sub_feature()
- Εκκινήστε το feature_dev.resource[FME_FEATURE_ID_HEADER].
- feature_platform_data_add()
- Ξεκινήστε το feature_platform_data.features[FME_FEATURE_ID_HEADER], τα πάντα εκτός από .fops.
- parse_feature() parse_feature_afus() parse_feature_port()
- Όταν συναντήσετε μια θύρα:
- build_info_create_dev()
- Εκχωρήστε μια συσκευή πλατφόρμας για τη Θύρα, η οποία αποθηκεύεται στο build_feature_devs_info.feature_dev.
- Το feature_dev.id αρχικοποιείται στο αποτέλεσμα του idr_alloc(fpga_ids[PORT_ID],
- Το feature_dev.parent έχει οριστεί σε build_feature_devs_info.parent_dev.
- Εκχωρήστε έναν πίνακα πόρων struct στο feature_dev.resource.
- Εκχωρήστε μια δομή feature_platform_data, αρχικοποιήστε την και αποθηκεύστε έναν δείκτη στο feature_dev.dev.platform_data
- build_info_commit_dev()
- Προσθέστε το struct feature_platform_data.node για το Port στη λίστα των Ports στο struct cci_drvdata.port_dev_list
- create_feature_instance() build_info_add_sub_feature()
- Εκκινήστε το feature_dev.resource[PORT_FEATURE_ID_HEADER].
- feature_platform_data_add()
- Αρχικοποιήστε το feature_platform_data.features[PORT_FEATURE_ID_HEADER], τα πάντα εκτός από .fops.
- parse_feature() parse_feature_afus() parse_feature_port_uafu()
- Όταν αντιμετωπίζεται μια AFU:
- create_feature_instance() build_info_add_sub_feature()
- Εκκινήστε το feature_dev.resource[PORT_FEATURE_ID_UAFU].
- feature_platform_data_add()
- Ξεκινήστε το feature_platform_data.features[PORT_FEATURE_ID_UAFU], τα πάντα εκτός από .fops.
- parse_feature() parse_feature_private() parse_feature_fme_private()
- Όταν αντιμετωπίζετε μια ιδιωτική δυνατότητα FME:
- create_feature_instance() build_info_add_sub_feature()
- Αρχικοποίηση feature_dev.resource[id].
- feature_platform_data_add()
- Ξεκινήστε το feature_platform_data.features[id], τα πάντα εκτός από το .fops.
- parse_feature() parse_feature_private() parse_feature_port_private()
- Όταν αντιμετωπίζεται μια ιδιωτική δυνατότητα Port: * create_feature_instance() build_info_add_sub_feature() * Initialize feature_dev.resource[id]. * feature_platform_data_add() Εκκίνηση feature_platform_data.features[id], τα πάντα εκτός από .fops.
- parse_ports_from_fme()
- Εάν το πρόγραμμα οδήγησης είναι φορτωμένο στο Physical Function (PF), τότε:
- Εκτελέστε τη ροή parse_feature_list() σε κάθε θύρα που περιγράφεται στην κεφαλίδα FME.
- Χρησιμοποιήστε τη BAR που αναφέρεται σε κάθε καταχώρηση Port στην κεφαλίδα.
Αρχικοποίηση συσκευής πλατφόρμας FME
Αυτή η ενότητα δίνει ένα overview της ροής κώδικα για την προετοιμασία της συσκευής FME που εκτελείται από το intel-fpga-fme.ko. Οι κύριες δομές και λειτουργίες δεδομένων επισημαίνονται. Αυτή η ενότητα ακολουθείται καλύτερα όταν viewμε τον συνοδευτικό πηγαίο κώδικα (fme-main.c).
Δομές δεδομένων συσκευής πλατφόρμας 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,
ανυπόγραφο int cmd, ανυπόγραφο μακρύ arg).
int (*test)(struct platform_device *pdev, struct feature *feature);
};
struct χαρακτηριστικό {
const char *όνομα;
int resource_index;
void __iomem *ioaddr;
struct feature_ops *ops;
};
struct feature_platform_data {
struct list_head node.
struct mutex κλειδαριά?
ανυπόγραφο long dev_status.
struct cdev cdev;
struct platform_device *dev;
ανυπόγραφο int disable_count;
void *private;
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 *)); struct
χαρακτηριστικά γνωρίσματα[0];
};
struct perf_object {
int id?
const struct χαρακτηριστικό_ομάδα **attr_groups;
struct συσκευή *fme_dev;
struct list_head node.
struct list_head παιδιά?
struct kobject kobj;
};
struct fpga_fme {
u8 port_id;
u64 pr_err;
struct συσκευή *dev_err;
struct perf_object *perf_dev;
struct feature_platform_data *pdata;
};
Ροή εκκίνησης συσκευής πλατφόρμας FME
Ροή εκκίνησης FME
- fme_probe() fme_dev_init()
- Αρχικοποιήστε μια δομή fpga_fme και αποθηκεύστε την στο πεδίο feature_platform_data.private.
- fme_probe() fpga_dev_feature_init() feature_instance_init()
- Αποθηκεύστε μια δομή feature_ops στα feature_platform_data.features για κάθε συμπληρωμένη δυνατότητα.
- Καλέστε τη συνάρτηση δοκιμής, εάν υπάρχει, από τη δομή.
- Καλέστε τη συνάρτηση init από τη δομή.
- fme_probe() fpga_register_dev_ops()
- Δημιουργήστε τον κόμβο συσκευής χαρακτήρων FME, καταχωρώντας μια δομή file_λειτουργίες.
Αρχικοποίηση συσκευής πλατφόρμας θύρας
Αυτή η ενότητα δίνει ένα overview της ροής κώδικα για την προετοιμασία της συσκευής θύρας που εκτελείται από το intel-fpga-afu.ko. Επισημαίνονται οι κύριες δομές και λειτουργίες δεδομένων. Αυτή η ενότητα ακολουθείται καλύτερα όταν viewμε τον συνοδευτικό πηγαίο κώδικα (afu.c).
Δομές δεδομένων συσκευής πλατφόρμας λιμένων
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,
ανυπόγραφο int cmd, ανυπόγραφο μακρύ arg).
int (*test)(struct platform_device *pdev, struct feature *feature);
};
struct χαρακτηριστικό {
const char *όνομα;
int resource_index;
void __iomem *ioaddr;
struct feature_ops *ops;
};
struct feature_platform_data {
struct list_head node.
struct mutex κλειδαριά?
ανυπόγραφο long dev_status.
struct cdev cdev;
struct platform_device *dev;
ανυπόγραφο int disable_count;
void *private;
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 *));
struct χαρακτηριστικά γνωρίσματα[0];
};
δομή fpga_afu_region {
ευρετήριο u32;
σημαίες u32?
μέγεθος u64;
μετατόπιση u64;
u64 φυσ.
struct list_head node.
};
struct fpga_afu_dma_region {
u64 user_addr;
u64 μήκος?
u64 iova;
struct σελίδα **σελίδες;
struct rb_node node;
bool in_use;
};
δομή fpga_afu {
u64 region_cur_offset;
int num_regions;
u8 num_umsgs;
struct list_head περιοχές?
struct rb_root dma_regions;
struct feature_platform_data *pdata;
};
Ροή εκκίνησης συσκευής πλατφόρμας θύρας
Ροή εκκίνησης θύρας
- afu_probe() afu_dev_init()
- Αρχικοποιήστε μια δομή fpga_afu και αποθηκεύστε την στο πεδίο feature_platform_data.private.
- afu_probe() fpga_dev_feature_init() feature_instance_init()
- Αποθηκεύστε μια δομή feature_ops στα feature_platform_data.features για κάθε συμπληρωμένη δυνατότητα.
- Καλέστε τη συνάρτηση δοκιμής, εάν υπάρχει, από τη δομή.
- Καλέστε τη συνάρτηση init από τη δομή.
- afu_probe() fpga_register_dev_ops()
- Δημιουργήστε τον κόμβο συσκευής χαρακτήρων Port, καταχωρώντας μια δομή file_λειτουργίες.
FME IOCTLs
IOCTL που καλούνται σε ανοιχτό file περιγραφέας για /dev/intel-fpga-fme.j FPGA_GET_API_VERSION—επιστρέφετε την τρέχουσα έκδοση ως ακέραιο, ξεκινώντας από το 0.
FPGA_CHECK_EXTENSION—δεν υποστηρίζεται αυτήν τη στιγμή.
FPGA_FME_PORT_RELEASE—το arg είναι δείκτης σε:
struct fpga_fme_port_release {
__u32 argsz; // σε: sizeof(struct fpga_fme_port_release)
__u32 σημαίες; // σε: πρέπει να είναι 0
__u32 port_id; // σε: αναγνωριστικό θύρας (από 0) για απελευθέρωση.
};
FPGA_FME_PORT_ASSIGN—το arg είναι ένας δείκτης σε ένα:
struct fpga_fme_port_assign {
__u32 argsz; // σε: sizeof(struct fpga_fme_port_assign)
__u32 σημαίες; // σε: πρέπει να είναι 0
__u32 port_id; // σε: αναγνωριστικό θύρας (από 0) για εκχώρηση. (πρέπει να ήταν
κυκλοφόρησε προηγουμένως από την FPGA_FME_PORT_RELEASE)
};
FPGA_FME_PORT_PR—το arg είναι δείκτης σε:
struct fpga_fme_port_pr {
__u32 argsz; // σε: sizeof(struct fpga_fme_port_pr)
__u32 σημαίες; // σε: πρέπει να είναι 0
__u32 port_id; // σε: αναγνωριστικό θύρας (από 0)
__u32 buffer_size; // σε: μέγεθος buffer ροής bit σε byte. Πρέπει να είναι 4 byte
ευθυγραμμισμένος.
__u64 buffer_address; // in: διεύθυνση διεργασίας της προσωρινής μνήμης bitstream
__u64 κατάσταση; // out: κατάσταση σφάλματος (bitmask)
};
Λιμάνι IOCTLs
IOCTL που καλούνται σε ανοιχτό file περιγραφέας για /dev/intel-fpga-port.k FPGA_GET_API_VERSION—επιστρέφετε την τρέχουσα έκδοση ως ακέραιο αριθμό, ξεκινώντας από το 0. FPGA_CHECK_EXTENSION—δεν υποστηρίζεται αυτήν τη στιγμή.
FPGA_PORT_GET_INFO—το arg είναι δείκτης σε:
struct fpga_port_info {
__u32 argsz; // σε: sizeof(struct fpga_port_info)
__u32 σημαίες; // out: επιστρέφει 0
__u32 num_regions; // out: αριθμός περιοχών MMIO, 2 (1 για AFU και 1 για
STP)
__u32 num_umsgs; // out: αριθμός των UMsg που υποστηρίζονται από το υλικό
};
FPGA_PORT_GET_REGION_INFO—το arg είναι ένας δείκτης σε:
struct fpga_port_region_info {
__u32 argsz; // σε: sizeof(struct fpga_port_region_info)
__u32 σημαίες; // out: (bitmask) { FPGA_REGION_READ, FPGA_REGION_WRITE,
FPGA_REGION_MMAP }
__u32 ευρετήριο; // σε: FPGA_PORT_INDEX_UAFU ή FPGA_PORT_INDEX_STP
__u32 padding; // σε: πρέπει να είναι 0
__u64 μέγεθος; // out: μέγεθος της περιοχής MMIO σε byte
__u64 μετατόπιση; // out: μετατόπιση της περιοχής MMIO από την έναρξη της συσκευής fd
};
FPGA_PORT_DMA_MAP—το arg είναι ένας δείκτης σε ένα:
struct fpga_port_dma_map {
__u32 argsz; // σε: sizeof(struct fpga_port_dma_map)
__u32 σημαίες; // in: πρέπει να είναι 0 __u64 user_addr; // σε: εικονική διαδικασία
διεύθυνση. Πρέπει να είναι ευθυγραμμισμένη με τη σελίδα.
__u64 μήκος; // σε: μήκος αντιστοίχισης σε byte. Πρέπει να είναι πολλαπλάσιο της σελίδας
μέγεθος.
__u64 iova; // out: εικονική διεύθυνση IO };
FPGA_PORT_DMA_UNMAP—το arg είναι ένας δείκτης σε ένα:
struct fpga_port_dma_unmap {
__u32 argsz; // σε: sizeof(struct fpga_port_dma_unmap)
__u32 σημαίες; // σε: πρέπει να είναι 0
__u64 iova; // in: Εικονική διεύθυνση IO που επιστράφηκε από προηγούμενη
FPGA_PORT_DMA_MAP };
- FPGA_PORT_RESET—το arg πρέπει να είναι NULL.
- FPGA_PORT_UMSG_ENABLE—το arg πρέπει να είναι NULL.
- FPGA_PORT_UMSG_DISABLE—τα όρκια πρέπει να είναι NULL.
FPGA_PORT_UMSG_SET_MODE—το arg είναι δείκτης σε:
struct fpga_port_umsg_cfg {
__u32 argsz; // σε: sizeof(struct fpga_port_umsg_cfg)
__u32 σημαίες; // σε: πρέπει να είναι 0
__u32 hint_bitmap; // σε: UMsg bitmap λειτουργίας υπόδειξης. Υποδηλώνει ποια είναι τα UMsg
ενεργοποιημένη.
};
FPGA_PORT_UMSG_SET_BASE_ADDR—
- Το UMsg πρέπει να είναι απενεργοποιημένο πριν από την έκδοση αυτού του ioctl.
- Το πεδίο iova πρέπει να είναι για ένα buffer αρκετά μεγάλο για όλα τα UMsg (αριθμός_umsgs * PAGE_SIZE).
- Το buffer επισημαίνεται ως "σε χρήση" από τη διαχείριση buffer του προγράμματος οδήγησης.
- Εάν το iova είναι NULL, οποιαδήποτε προηγούμενη περιοχή δεν επισημαίνεται ως "σε χρήση".
- Το arg είναι ένας δείκτης σε:
struct fpga_port_umsg_base_addr {- u32 argsz; // σε: sizeof(struct fpga_port_umsg_base_addr)
- σημαίες u32? // σε: πρέπει να είναι 0
- u64 iova; // σε: εικονική διεύθυνση IO από FPGA_PORT_DMA_MAP. };
Σημείωμα:
- Για να διαγράψετε τα σφάλματα της θύρας, πρέπει να γράψετε την ακριβή μάσκα bitmask των τρεχόντων σφαλμάτων, π.χ.ample, λάθη γάτας > σαφές
- Το UMsg υποστηρίζεται μόνο μέσω του Acceleration Stack για επεξεργαστή Intel Xeon με ενσωματωμένο FPGA.
sysfs Files
Κεφαλίδα FME sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/
sysfs file | πεδίο mmio | τύπος | πρόσβαση |
ports_num | fme_header.capability.num_ports | δεκαδικός ενθ | Μόνο για ανάγνωση |
cache_size | fme_header.capability.cache_size | δεκαδικός ενθ | Μόνο για ανάγνωση |
εκδοχή | fme_header.capability.fabric_verid | δεκαδικός ενθ | Μόνο για ανάγνωση |
socket_id | fme_header.capability.socket_id | δεκαδικός ενθ | Μόνο για ανάγνωση |
bitstream_id | fme_header.bitstream_id | εξάγωνο uint64_t | Μόνο για ανάγνωση |
bitstream_metadata | fme_header.bitstream_md | εξάγωνο uint64_t | Μόνο για ανάγνωση |
FME Thermal Management sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/thermal_mgmt/
sysfs file | πεδίο mmio | τύπος | πρόσβαση |
κατώφλι 1 | thermal.threshold.tmp_thshold1 | δεκαδικός ενθ | Χρήστης: Root μόνο για ανάγνωση: Read-write |
κατώφλι 2 | thermal.threshold.tmp_thshold2 | δεκαδικός ενθ | Χρήστης: Root μόνο για ανάγνωση: Read-write |
threshold_trip | thermal.threshold.therm_trip_thshold | δεκαδικός ενθ | Μόνο για ανάγνωση |
threshold1_reached | thermal.threshold.thshold1_status | δεκαδικός ενθ | Μόνο για ανάγνωση |
threshold2_reached | thermal.threshold.thshold2_status | δεκαδικός ενθ | Μόνο για ανάγνωση |
threshold1_policy | θερμικός. threshold.thshold_policy | δεκαδικός ενθ | Χρήστης: Root μόνο για ανάγνωση: Read-write |
θερμοκρασία | thermal.rdsensor_fm1.fpga_temp | δεκαδικός ενθ | Μόνο για ανάγνωση |
FME Power Management sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/power_mgmt/
sysfs file | πεδίο mmio | τύπος | πρόσβαση |
καταναλώνεται | power.status.pwr_consumed | εξάγωνο uint64_t | Μόνο για ανάγνωση |
κατώφλι 1 | δύναμη.κατώφλι.κατώφλι1 | εξάγωνο uint64_t | Χρήστης: Root μόνο για ανάγνωση: Read-write |
κατώφλι 2 | δύναμη.κατώφλι.κατώφλι2 | εξάγωνο uint64_t | Χρήστης: Root μόνο για ανάγνωση: Read-write |
threshold1_status | power.threshold.threshold1_status | δεκαδικό ανυπόγραφο | Μόνο για ανάγνωση |
threshold2_status | power.threshold.threshold2_status | δεκαδικό ανυπόγραφο | Μόνο για ανάγνωση |
rtl | power.status.fpga_latency_report | δεκαδικό ανυπόγραφο | Μόνο για ανάγνωση |
FME Global Error sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/errors/
sysfs file | πεδίο mmio | τύπος | πρόσβαση |
pcie0_errors | gerror.pcie0_err | εξάγωνο uint64_t | Διαβάζω γράφω |
pcie1_errors | gerror.pcie1_err | εξάγωνο uint64_t | Διαβάζω γράφω |
inject_error | gerror.ras_error_inj | εξάγωνο uint64_t | Διαβάζω γράφω |
intel-fpga-dev.i/intel-fpga-fme.j/errors/fme-errors/
sysfs file | πεδίο mmio | τύπος | πρόσβαση |
λάθη | gerror.fme_err | εξάγωνο uint64_t | Μόνο για ανάγνωση |
first_error | gerror.fme_first_err.err_reg_status | εξάγωνο uint64_t | Μόνο για ανάγνωση |
επόμενο_σφάλμα | gerror.fme_next_err.err_reg_status | εξάγωνο uint64_t | Μόνο για ανάγνωση |
σαφής | Διαγράφει σφάλματα, first_error, next_error | διάφορα uint64_t | Μόνο εγγραφή |
Σημείωμα:
Για να διαγράψετε τα σφάλματα FME, πρέπει να γράψετε την ακριβή μάσκα bitmask των τρεχόντων σφαλμάτων, π.χ.ample cat errors > σαφής.
FME Μερική αναδιαμόρφωση sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/pr/
sysfs file | πεδίο mmio | τύπος | πρόσβαση |
interface_id | pr.fme_pr_intfc_id0_h, pr.fme_pre_intfc_id0_l | εξάγωνο 16 byte | Μόνο για ανάγνωση |
FME Global Performance sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/dperf/clock
sysfs file | πεδίο mmio | τύπος | πρόσβαση |
ρολόι | gperf.clk.afu_interf_clock | εξάγωνο uint64_t | Μόνο για ανάγνωση |
intel-fpga-dev.i/intel-fpga-fme.j/dperf/cache/ (Δεν ισχύει για Acceleration Stack για Intel Xeon CPU με FPGA)
sysfs file | πεδίο mmio | τύπος | πρόσβαση |
πάγωμα | gperf.ch_ctl.freeze | δεκαδικός ενθ | Διαβάζω γράφω |
read_hit | gperf.CACHE_RD_HIT | εξάγωνο uint64_t | Μόνο για ανάγνωση |
read_miss | gperf.CACHE_RD_MISS | εξάγωνο uint64_t | Μόνο για ανάγνωση |
write_hit | gperf.CACHE_WR_HIT | εξάγωνο uint64_t | Μόνο για ανάγνωση |
write_miss | gperf.CACHE_WR_MISS | εξάγωνο uint64_t | Μόνο για ανάγνωση |
hold_request | gperf.CACHE_HOLD_REQ | εξάγωνο uint64_t | Μόνο για ανάγνωση |
tx_req_stall | gperf.CACHE_TX_REQ_STALL | εξάγωνο uint64_t | Μόνο για ανάγνωση |
sysfs file | πεδίο mmio | τύπος | πρόσβαση |
rx_req_stall | gperf.CACHE_RX_REQ_STALL | εξάγωνο uint64_t | Μόνο για ανάγνωση |
data_write_port_contention | gperf.CACHE_DATA_WR_PORT_CONTEN | εξάγωνο uint64_t | Μόνο για ανάγνωση |
tag_write_port_contention | gperf.CACHE_TAG_WR_PORT_CONTEN | εξάγωνο uint64_t | Μόνο για ανάγνωση |
intel-fpga-dev.i/intel-fpga-fme.j/dperf/iommu/ (Δεν ισχύει για Acceleration Stack για επεξεργαστή Intel Xeon με FPGA)
sysfs file | πεδίο mmio | τύπος | πρόσβαση |
πάγωμα | gperf.vtd_ctl.freeze | δεκαδικός ενθ | Χρήστης: Root μόνο για ανάγνωση: Read-write |
intel-fpga-dev.i/intel-fpga-fme.j/dperf/iommu/afuk/ (Δεν ισχύει για Acceleration Stack για Intel Xeon CPU με FPGA)
sysfs file | πεδίο mmio | τύπος | πρόσβαση |
read_transaction | gperf.VTD_AFU0_MEM_RD_TRANS | εξάγωνο uint64_t | Μόνο για ανάγνωση |
write_transaction | gperf.VTD_AFU0_MEM_WR_TRANS | εξάγωνο uint64_t | Μόνο για ανάγνωση |
tlb_read_hit | gperf.VTD_AFU0_TLB_RD_HIT | εξάγωνο uint64_t | Μόνο για ανάγνωση |
tlb_write_hit | gperf.VTD_AFU0_TLB_WR_HIT | εξάγωνο uint64_t | Μόνο για ανάγνωση |
intel-fpga-dev.i/intel-fpga-fme.j/dperf/fabric/
sysfs file | πεδίο mmio | τύπος | πρόσβαση |
καθιστώ ικανό | gperf.fab_ctl.(ενεργοποιημένο) | δεκαδικός ενθ | Χρήστης: Root μόνο για ανάγνωση: Read-write |
πάγωμα | gperf.fab_ctl.freeze | δεκαδικός ενθ | Χρήστης: Root μόνο για ανάγνωση: Read-write |
pcie0_read | gperf.FAB_PCIE0_RD | εξάγωνο uint64_t | Μόνο για ανάγνωση |
pcie0_write | gperf.FAB_PCIE0_WR | εξάγωνο uint64_t | Μόνο για ανάγνωση |
pcie1_read | gperf.FAB_PCIE1_RD | εξάγωνο uint64_t | Μόνο για ανάγνωση |
pcie1_write | gperf.FAB_PCIE1_WR | εξάγωνο uint64_t | Μόνο για ανάγνωση |
upi_read | gperf.FAB_UPI_RD | εξάγωνο uint64_t | Μόνο για ανάγνωση |
upi_write | gperf.FAB_UPI_WR | εξάγωνο uint64_t | Μόνο για ανάγνωση |
intel-fpga-ev.i/intel-fpga/fme.j/dperf/fabric/portk/
sysfs file | πεδίο mmio | τύπος | πρόσβαση |
pcie0_read | gperf.FAB_PCIE0_RD | εξάγωνο uint64_t | Μόνο για ανάγνωση |
pcie0_write | gperf.FAB_PCIE0_WR | εξάγωνο uint64_t | Μόνο για ανάγνωση |
pcie1_read | gperf.FAB_PCIE1_RD | εξάγωνο uint64_t | Μόνο για ανάγνωση |
pcie1_write | gperf.FAB_PCIE1_WR | εξάγωνο uint64_t | Μόνο για ανάγνωση |
upi_read | gperf.FAB_UPI_RD | εξάγωνο uint64_t | Μόνο για ανάγνωση |
upi_write | gperf.FAB_UPI_WR | εξάγωνο uint64_t | Μόνο για ανάγνωση |
Port Header sysfs files
intel-fpga-dev.i/intel-fpga-port.k/
sysfs file | πεδίο mmio | τύπος | πρόσβαση |
id | port_header.capability.port_number | δεκαδικός ενθ | Μόνο για ανάγνωση |
ltr | port_header.control.latency_tolerance | δεκαδικός ενθ | Μόνο για ανάγνωση |
Port AFU Header sysfs files
intel-fpga-dev.i/intel-fpga-port.k/
sysfs file | πεδίο mmio | τύπος | πρόσβαση |
afu_id | afu_header.guid | εξάγωνο 16 byte | Μόνο για ανάγνωση |
Σφάλμα θύρας sysfs files
intel-fpga-dev.i/intel-fpga-port.k/errors/
sysfs file | πεδίο mmio | τύπος | πρόσβαση |
λάθη | perror.port_error | εξάγωνο uint64_t | Μόνο για ανάγνωση |
first_error | perror.port_first_error | εξάγωνο uint64_t | Μόνο για ανάγνωση |
first_malformed_req | πλάκα.malreq | εξάγωνο 16 byte | Μόνο για ανάγνωση |
σαφής | λάθος. (όλα τα λάθη) | διάφορα uint64_t | Μόνο εγγραφή |
Σημείωμα:
Για να διαγράψετε τα σφάλματα Port, πρέπει να γράψετε την ακριβή μάσκα bitmask των τρεχόντων σφαλμάτων, π.χample cat errors > σαφής.
Ιστορικό αναθεώρησης
Έκδοση εγγράφου | Αλλαγές |
2017.10.02 | Αρχική Έκδοση. |
OPAE Intel FPGA Linux Device Driver Architecture Guide
Έγγραφα / Πόροι
![]() |
intel OPAE FPGA Linux Device Driver Architecture [pdf] Οδηγός χρήστη OPAE FPGA Linux Device Driver Architecture, OPAE FPGA, Linux Device Driver Architecture, Driver Architecture, Architecture |