Intel OPAE FPGA Linux Device Driver Architecture
Architektura sterownika urządzenia OPAE Intel FPGA Linux
Sterownik Intel FPGA OPAE udostępnia interfejsy dla aplikacji przestrzeni użytkownika, umożliwiając konfigurację, enumerację, otwieranie i uzyskiwanie dostępu do akceleratorów FPGA na platformach wyposażonych w rozwiązania Intel FPGA. Ponadto umożliwia realizację funkcji zarządzania na poziomie systemu, takich jak rekonfiguracja FPGA, zarządzanie energią i wirtualizacja.
Architektura sprzętowa
Z punktu widzenia systemu operacyjnego view, sprzęt FPGA pojawia się jako zwykłe urządzenie PCIe. Pamięć urządzenia FPGA jest zorganizowana przy użyciu wstępnie zdefiniowanej struktury danych (Lista funkcji urządzenia). Funkcje obsługiwane przez urządzenie FPGA są udostępniane za pośrednictwem tych struktur danych, jak pokazano poniżej na poniższym rysunku:
Urządzenie FPGA PCIe
Sterownik obsługuje technologię PCIe SR-IOV, co pozwala na tworzenie funkcji wirtualnych (VF), za pomocą których można przypisywać poszczególne akceleratory do maszyn wirtualnych.
Korporacja intelektualna. Wszelkie prawa zastrzeżone. Intel, logo Intel i inne znaki Intel są znakami towarowymi firmy Intel Corporation lub jej podmiotów zależnych. Firma Intel gwarantuje wydajność swoich produktów FPGA i produktów półprzewodnikowych zgodnie z aktualnymi specyfikacjami zgodnie ze standardową gwarancją firmy Intel, ale zastrzega sobie prawo do wprowadzania zmian we wszelkich produktach i usługach w dowolnym czasie i bez powiadomienia. Firma Intel nie przyjmuje żadnej odpowiedzialności wynikającej z zastosowania lub wykorzystania jakichkolwiek informacji, produktów lub usług opisanych w niniejszym dokumencie, z wyjątkiem przypadków wyraźnie uzgodnionych na piśmie przez firmę Intel. Klientom firmy Intel zaleca się uzyskanie najnowszej wersji specyfikacji urządzenia przed poleganiem na opublikowanych informacjach oraz przed złożeniem zamówienia na produkty lub usługi.
Inne nazwy i marki mogą być własnością osób trzecich.
Wirtualizowane urządzenie FPGA PCIe
Silnik zarządzania FPGA (FME)
FPGA Management Engine wykonuje zarządzanie energią i temperaturą, raportowanie błędów, rekonfigurację, raportowanie wydajności i inne funkcje infrastruktury. Każdy FPGA ma jeden FME, do którego dostęp jest zawsze uzyskiwany za pośrednictwem Physical Function (PF). Aplikacje przestrzeni użytkownika mogą uzyskać wyłączny dostęp do FME za pomocą open() i zwolnić go za pomocą close() jako uprzywilejowany użytkownik (root).
Port
Port reprezentuje interfejs pomiędzy statyczną strukturą FPGA („FPGA Interface Manager (FIM)”) a częściowo rekonfigurowalnym regionem zawierającym funkcję akceleratora (AF). Port kontroluje komunikację oprogramowania z akceleratorem i udostępnia funkcje takie jak resetowanie i debugowanie. Urządzenie PCIe może mieć kilka portów, a każdy port można udostępnić za pomocą funkcji wirtualnej (VF), przypisując go za pomocą ioctl FPGA_FME_PORT_ASSIGN na urządzeniu FME.
Jednostka funkcji akceleratora (AF)
- Jednostka funkcji akceleratora (AF) jest podłączona do portu i udostępnia obszar MMIO o wielkości 256 KB, który będzie wykorzystywany do przechowywania rejestrów sterujących specyficznych dla akceleratora.
- Aplikacje przestrzeni użytkownika mogą uzyskać wyłączny dostęp do AFU podłączonego do portu za pomocą funkcji open() na urządzeniu portu i zwolnić go za pomocą funkcji close().
- Aplikacje przestrzeni użytkownika mogą także mmap() przyspieszać regiony MMIO.
Częściowa rekonfiguracja
Jak wspomniano powyżej, akceleratory można rekonfigurować poprzez częściową rekonfigurację funkcji akceleratora (AF) file. Funkcja akceleratora (AF) musi zostać wygenerowana dla dokładnego FIM i docelowego regionu statycznego (Port) FPGA; w przeciwnym razie operacja rekonfiguracji zakończy się niepowodzeniem i może spowodować niestabilność systemu. Tę zgodność można sprawdzić, porównując identyfikator interfejsu zanotowany w nagłówku AF z identyfikatorem interfejsu udostępnionym przez FME za pośrednictwem sysfs. To sprawdzenie jest zwykle wykonywane przez przestrzeń użytkownika przed wywołaniem rekonfiguracji IOCTL.
Notatka:
Obecnie każdy program uzyskujący dostęp do FPGA, w tym te działające na wirtualizowanym hoście, musi zostać zamknięty przed próbą częściowej rekonfiguracji. Kroki będą następujące:
- Odładuj sterownik z gościa
- Odłącz VF od gościa
- Wyłącz SR-IOV
- Wykonaj częściową rekonfigurację
- Włącz SR-IOV
- Podłącz VF do gościa
- Załaduj sterownik w gościu
Wirtualizacja FPGA
Aby umożliwić dostęp do akceleratora z aplikacji uruchomionych na maszynie wirtualnej, należy przypisać odpowiedni port AFU do funkcji wirtualnej (VF), wykonując następujące kroki:
- PF domyślnie posiada wszystkie porty AFU. Każdy port, który musi zostać ponownie przypisany do VF, musi najpierw zostać zwolniony z PF przez ioctl FPGA_FME_PORT_RELEASE na urządzeniu FME.
- Po zwolnieniu N portów z PF, poniższe polecenie może zostać użyte do włączenia SRIOV i VF. Każdy VF posiada tylko jeden port z AFU. echo N > PCI_DEVICE_PATH/sriov_numvfs
- Przekaż dane przez VF do maszyn wirtualnych.
- Dostęp do AFU w VF można uzyskać z aplikacji w VM (używając tego samego sterownika, który znajduje się w VF).
Notatka:
FME nie może zostać przypisane do VF, w związku z czym PR i inne funkcje zarządzania są dostępne wyłącznie za pośrednictwem PF.
Organizacja kierowców
Sterownik urządzenia modułu PCIe
Organizacja kierowców
Urządzenia FPGA pojawiają się jako zwykłe urządzenia PCIe; w związku z tym sterownik urządzenia FPGA PCIe (intel-FPGA-PCI.ko) jest zawsze ładowany jako pierwszy po wykryciu FPGA PCIe PF lub VF. Ten sterownik odgrywa infrastrukturalną rolę w architekturze sterownika. On:
- Tworzy urządzenie kontenerowe FPGA jako urządzenie nadrzędne urządzeń funkcyjnych.
- Przechodzi przez listę funkcji urządzeń, która jest zaimplementowana w pamięci BAR urządzenia PCIe, aby odkryć urządzenia funkcji i ich podfunkcje, a także utworzyć dla nich urządzenia platformy w ramach urządzenia kontenerowego.
- Obsługuje SR-IOV.
- Wprowadza infrastrukturę urządzeń funkcji, która abstrahuje operacje dla podfunkcji i udostępnia typowe funkcje sterownikom urządzeń funkcji.
Funkcje sterownika urządzenia modułu PCIe
- Zawiera wykrywanie PCIe, enumerację urządzeń i wykrywanie funkcji.
- Tworzy katalogi sysfs dla urządzenia nadrzędnego, FPGA Management Engine (FME) i portu.
- Tworzy wystąpienia sterownika platformy, powodując, że jądro Linux ładuje odpowiednie sterowniki modułów platformy.
Sterownik urządzenia modułu platformy FME
- Zarządzanie energią i temperaturą, raportowanie błędów, raportowanie wydajności i inne funkcje infrastruktury. Dostęp do tych funkcji można uzyskać za pośrednictwem interfejsów sysfs udostępnianych przez sterownik FME.
- Częściowa rekonfiguracja. Sterownik FME rejestruje FPGA Manager podczas inicjalizacji podfunkcji PR; po otrzymaniu od Ciebie ioctl FPGA_FME_PORT_PR wywołuje funkcję wspólnego interfejsu z FPGA Manager, aby ukończyć częściową rekonfigurację strumienia bitów do danego portu.
- Zarządzanie portami dla wirtualizacji. Sterownik FME wprowadza dwa ioctle, FPGA_FME_PORT_RELEASE, który zwalnia dany port z PF; i FPGA_FME_PORT_ASSIGN, który przypisuje port z powrotem do PF. Po zwolnieniu portu z PF można go przypisać do VF za pośrednictwem interfejsów SR-IOV dostarczonych przez sterownik PCIe. Aby uzyskać więcej informacji, zapoznaj się z „FPGA Virtualization”.
Funkcje sterownika urządzenia modułu platformy FME
- Tworzy węzeł urządzenia znakowego FME.
- Tworzy system plików FME filei implementuje system FME sysfs file akcesoria.
- Implementuje podsterowniki prywatnych funkcji FME.
- Podsterowniki funkcji prywatnych FME:
- Nagłówek FME
- Zarządzanie temperaturą
- Zarządzanie energią
- Błąd globalny
- Częściowa rekonfiguracja
- Globalna wydajność
Sterownik urządzenia modułu platformy portu
Podobnie jak sterownik FME, sterownik portu FPGA (i AFU) (intel-fpga-afu. ko) jest badany po utworzeniu urządzenia platformy Port. Główną funkcją tego modułu jest zapewnienie interfejsu dla aplikacji przestrzeni użytkownika w celu uzyskania dostępu do poszczególnych akceleratorów, w tym podstawowej kontroli resetowania portu, eksportu regionu MMIO AFU, usługi mapowania bufora DMA, powiadomień UMsg(1) i funkcji zdalnego debugowania (patrz powyżej).
UMsg jest obsługiwany wyłącznie poprzez Acceleration Stack dla procesora Intel Xeon® ze zintegrowanym układem FPGA.
Funkcje sterownika urządzenia modułu platformy portu
- Tworzy węzeł urządzenia znakowego portu.
- Tworzy port sysfs filei implementuje port sysfs file akcesoria.
- Implementuje podsterowniki funkcji portu prywatnego.
- Podsterowniki funkcji prywatnych portu:
- Nagłówek portu
- AFU
- Błąd portu
- UMsg(2)
- Dotknij sygnału
Numeracja urządzeń FPGA aplikacji
W tej sekcji przedstawiono sposób, w jaki aplikacje wyliczają urządzenie FPGA z hierarchii sysfs w /sys/class/fpga. W example poniżej, dwa urządzenia Intel FPGA są zainstalowane w hoście. Każde urządzenie FPGA ma jeden FME i dwa porty (AFU). Dla każdego urządzenia FPGA tworzony jest katalog urządzeń w /sys/class/fpga:
/sys/class/fpga/intel-fpga-dev.0
/sys/class/fpga/intel-fpga-dev.1
Każdy węzeł ma jeden FME i dwa porty (AFU) jako urządzenia podrzędne:
/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
Ogólnie rzecz biorąc, interfejsy FME/Port sysfs nazywane są następująco:
/sys/class/fpga/intel-fpga-dev.i/intel-fpga-fme.j/
/sys/class/fpga/intel-fpga-dev.i/intel-fpga-port.k/
przy czym I kolejno numeruje wszystkie urządzenia kontenerowe, j kolejno numeruje FME, a k kolejno numeruje wszystkie porty.
Do węzłów urządzeń używanych dla funkcji ioctl() i mmap() można odwoływać się za pomocą:
/dev/intel-fpga-fme.j
/dev/intel-fpga-port.k
Wyliczanie sterowników PCIe
Ta sekcja daje ponadview przepływu kodu dla enumeracji urządzeń wykonywanej przez intel-fpga-pci.ko. Podświetlono główne struktury danych i funkcje. Ta sekcja jest najlepsza, gdy viewkorzystając z dołączonego kodu źródłowego (pcie.c).
Struktury danych wyliczeniowe
wyliczenie fpga_id_type {
IDENTYFIKATOR_RODZICA,
Identyfikator FME,
PORT_ID,
FPGA_ID_MAX
};
struktura statyczna idr fpga_ids[FPGA_ID_MAX];
struktura fpga_chardev_info {
const char *nazwa;
dev_t devt;
};
struktura fpga_chardev_info fpga_chrdevs[] = {
{ .name = FPGA_FEATURE_DEV_FME },
{ .name = FPGA_FEATURE_DEV_PORT },
};
statyczna struktura klasy *fpga_class;
statyczna struktura 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,}
};
statyczna struktura pci_driver cci_pci_driver = {
.name = DRV_NAME,
.id_table = tabela_id_cci_pcie_tbl,
.probe = cci_pci_probe,
.usuń = cci_pci_remove,
.sriov_configure = cci_pci_sriov_configure
};
struktura cci_drvdata {
int identyfikator_urządzenia;
struktura urządzenia *fme_dev;
blokada struktury mutex;
struktura list_head port_dev_list;
int zwolniony_numer_portu;
struktura list_head regiony;
};
struktura build_feature_devs_info {
struktura pci_dev *pdev;
void __iomem *ioaddr;
void __iomem *ioend;
int bieżący_pasek;
pusta __iomem *pfme_hdr;
struktura urządzenia *parent_dev;
struktura platform_device *feature_dev;
};
Przepływ wyliczeń
- Funkcja init_ccid_init()
- Zainicjuj fpga_ids za pomocą idr_init().
- Zainicjuj fpga_chrdevs[i].devt za pomocą alloc_chrdev_region().
- Zainicjuj fpga_class za pomocą class_create().
- sterownik_rejestru_pci(&cci_pci_driver);
- cci_pci_probe()
- Włącz urządzenie PCI, poproś o dostęp do jego regionów, ustaw tryb główny PCI i skonfiguruj DMA.
- cci_pci_create_feature_devs() przydział_informacji_o_kompilacji_i_init()
- Przydziel strukturę build_feature_devs_info i zainicjuj ją.
.parent_dev jest ustawiony na nadrzędny katalog sysfs (intel-fpga-dev.id), który zawiera katalogi FME i Port sysfs.
- Przydziel strukturę build_feature_devs_info i zainicjuj ją.
- parse_feature_list()
- Zapoznaj się z listą funkcji urządzenia BAR0, aby poznać FME, port i ich prywatne funkcje.
- parse_feature() parse_feature_afus() parse_feature_fme()
- W przypadku napotkania FME:
- informacje o kompilacji_utwórz_dev()
- Przydziel urządzenie platformy dla FME, zapisując je w build_feature_devs_info.feature_dev.
- feature_dev.id jest inicjowany wynikiem idr_alloc(fpga_ids[FME_ID],
- feature_dev.parent jest ustawione na build_feature_devs_info.parent_dev.
- Przydziel tablicę zasobów struktury w feature_dev.resource.
- Przydziel strukturę feature_platform_data, zainicjuj ją i zapisz wskaźnik w feature_dev.dev.platform_data
- utwórz_instancję_funkcji() informacje_o_kompilacji_dodaj_pod_funkcję()
- Zainicjuj feature_dev.resource[FME_FEATURE_ID_HEADER].
- dodaj_dane_platformy_funkcji()
- Zainicjuj feature_platform_data.features[FME_FEATURE_ID_HEADER], wszystko oprócz .fops.
- parse_feature() parse_feature_afus() parse_feature_port()
- Gdy napotkany zostanie port:
- informacje o kompilacji_utwórz_dev()
- Przydziel urządzenie platformy dla portu i zapisz je w build_feature_devs_info.feature_dev.
- feature_dev.id jest inicjowany wynikiem idr_alloc(fpga_ids[PORT_ID],
- feature_dev.parent jest ustawione na build_feature_devs_info.parent_dev.
- Przydziel tablicę zasobów struktury w feature_dev.resource.
- Przydziel strukturę feature_platform_data, zainicjuj ją i zapisz wskaźnik w feature_dev.dev.platform_data
- informacje o kompilacji_zatwierdź_dev()
- Dodaj strukturę feature_platform_data.node dla portu do listy portów w strukturze cci_drvdata.port_dev_list
- utwórz_instancję_funkcji() informacje_o_kompilacji_dodaj_pod_funkcję()
- Zainicjuj feature_dev.resource[PORT_FEATURE_ID_HEADER].
- dodaj_dane_platformy_funkcji()
- Zainicjuj feature_platform_data.features[PORT_FEATURE_ID_HEADER], wszystko oprócz .fops.
- parse_feature() parse_feature_afus() parse_feature_port_uafu()
- W przypadku napotkania AFU:
- utwórz_instancję_funkcji() informacje_o_kompilacji_dodaj_pod_funkcję()
- Zainicjuj feature_dev.resource[PORT_FEATURE_ID_UAFU].
- dodaj_dane_platformy_funkcji()
- Zainicjuj feature_platform_data.features[PORT_FEATURE_ID_UAFU], wszystko oprócz .fops.
- parse_feature() parse_feature_private() parse_feature_fme_private()
- Gdy napotkana zostanie prywatna funkcja FME:
- utwórz_instancję_funkcji() informacje_o_kompilacji_dodaj_pod_funkcję()
- Zainicjuj feature_dev.resource[id].
- dodaj_dane_platformy_funkcji()
- Zainicjuj feature_platform_data.features[id], wszystko oprócz .fops.
- parse_feature() parse_feature_private() parse_feature_port_private()
- Gdy napotkana zostanie prywatna funkcja portu: * create_feature_instance() build_info_add_sub_feature() * Zainicjuj feature_dev.resource[id]. * feature_platform_data_add() Zainicjuj feature_platform_data.features[id], wszystko oprócz .fops.
- parse_ports_from_fme()
- Jeżeli sterownik jest ładowany w Funkcji Fizycznej (PF), to:
- Uruchom przepływ parse_feature_list() na każdym porcie opisanym w nagłówku FME.
- Użyj BAR wymienionego w każdym wpisie portu w nagłówku.
Inicjalizacja urządzenia platformy FME
Ta sekcja daje ponadview przepływu kodu dla inicjalizacji urządzenia FME wykonywanego przez intel-fpga-fme.ko. Główne struktury danych i funkcje są wyróżnione. Ta sekcja jest najlepsza, gdy viewkorzystając z dołączonego kodu źródłowego (fme-main.c).
Struktury danych urządzeń platformy FME
struktura feature_ops {
int (*init)(struktura urządzenia_platformowego *pdev, struktura funkcji *cecha);
int (*uinit)(struktura urządzenia_platformowego *pdev, struktura funkcji *cecha);
długie (*ioctl)(struktura urządzenia_platformowego *pdev, struktura funkcji *cecha,
unsigned int cmd, unsigned long arg);
int (*test)(struktura urządzenia_platformowego *pdev, struktura funkcji *cecha);
};
funkcja struktury {
const char *nazwa;
int indeks_zasobu;
void __iomem *ioaddr;
struktura feature_ops *ops;
};
struktura feature_platform_data {
struktura węzła list_head;
blokada struktury mutex;
unsigned long dev_status;
struktura cdev cdev;
struktura platform_device *dev;
unsigned int disable_count;
void *prywatny;
liczba całkowita;
int (*config_port)(struct platforma_device *, u32, bool);
struktura platformy_device *(*fpga_for_each_port)(struktura platformy_device *,
void *, int (*match)(struktura platform_device *, void *)); struktura
cecha cechy[0];
};
struktura perf_object {
identyfikator int;
const struct grupa_atrybutów **grupy_atrybutów;
struktura urządzenia *fme_dev;
struktura węzła list_head;
struktura list_head dzieci;
struktura kobject kobj;
};
struktura fpga_fme {
u8 identyfikator_portu;
u64 pr_err;
struktura urządzenia *dev_err;
struktura perf_object *perf_dev;
struktura feature_platform_data *pdata;
};
Przepływ inicjalizacji urządzenia platformy FME
Przepływ inicjalizacji FME
- Plik fme_probe()
- Zainicjuj strukturę fpga_fme i zapisz ją w polu feature_platform_data.private.
- fme_probe() fpga_dev_feature_init() wystąpienie_funkcji_init()
- Zapisz strukturę feature_ops w feature_platform_data.features dla każdej uzupełnionej funkcji.
- Wywołaj funkcję testową, jeśli taka istnieje, ze struktury.
- Wywołaj funkcję init ze struktury.
- fme_probe() fpga_register_dev_ops()
- Utwórz węzeł urządzenia znakowego FME, rejestrując strukturę file_operacje.
Inicjalizacja urządzenia platformy portu
Ta sekcja daje ponadview przepływu kodu dla inicjalizacji urządzenia portu wykonywanego przez intel-fpga-afu.ko. Podświetlono główne struktury danych i funkcje. Ta sekcja jest najlepsza, gdy viewkorzystając z dołączonego kodu źródłowego (afu.c).
Struktury danych urządzeń platformy portowej
struktura feature_ops {
int (*init)(struktura urządzenia_platformowego *pdev, struktura funkcji *cecha);
int (*uinit)(struktura urządzenia_platformowego *pdev, struktura funkcji *cecha);
długie (*ioctl)(struktura urządzenia_platformowego *pdev, struktura funkcji *cecha,
unsigned int cmd, unsigned long arg);
int (*test)(struktura urządzenia_platformowego *pdev, struktura funkcji *cecha);
};
funkcja struktury {
const char *nazwa;
int indeks_zasobu;
void __iomem *ioaddr;
struktura feature_ops *ops;
};
struktura feature_platform_data {
struktura węzła list_head;
blokada struktury mutex;
unsigned long dev_status;
struktura cdev cdev;
struktura platform_device *dev;
unsigned int disable_count;
void *prywatny;
liczba całkowita;
int (*config_port)(struct platforma_device *, u32, bool);
struktura platformy_device *(*fpga_for_each_port)(struktura platformy_device *,
void *, int (*match)(struct platforma_device *, void *));
cecha struktury cechy[0];
};
struktura fpga_afu_region {
indeks u32;
flagi u32;
rozmiar u64;
przesunięcie u64;
u64 fiz;
struktura węzła list_head;
};
struktura fpga_afu_dma_region {
u64 adres_użytkownika;
długość u64;
u64 iowa;
struktura strony **pages;
struktura rb_node węzeł;
bool w_użyciu;
};
struktura fpga_afu {
u64 przesunięcie_bieżące_regionu;
int liczba_regionów;
u8 liczba_umsgs;
struktura list_head regiony;
struktura rb_root dma_regions;
struktura feature_platform_data *pdata;
};
Przepływ inicjalizacji urządzenia platformy portu
Przepływ inicjalizacji portu
- afu_probe() afu_dev_init()
- Zainicjuj strukturę fpga_afu i zapisz ją w polu feature_platform_data.private.
- afu_probe() fpga_dev_feature_init() init_instancji_funkcji()
- Zapisz strukturę feature_ops w feature_platform_data.features dla każdej uzupełnionej funkcji.
- Wywołaj funkcję testową, jeśli taka istnieje, ze struktury.
- Wywołaj funkcję init ze struktury.
- afu_probe() fpga_register_dev_ops()
- Utwórz węzeł urządzenia znakowego portu, rejestrując strukturę file_operacje.
Certyfikaty IOCTL FME
IOCTL-e wywoływane przy otwartym file deskryptor dla /dev/intel-fpga-fme.j FPGA_GET_API_VERSION — zwraca bieżącą wersję jako liczbę całkowitą, zaczynając od 0.
FPGA_CHECK_EXTENSION — obecnie nieobsługiwane.
FPGA_FME_PORT_RELEASE — arg jest wskaźnikiem do:
struktura fpga_fme_port_release {
__u32 argsz; // w: sizeof(struct fpga_fme_port_release)
__u32 flagi; // w: musi być 0
__u32 port_id; // in: identyfikator portu (od 0) do wydania.
};
FPGA_FME_PORT_ASSIGN — arg jest wskaźnikiem do:
struktura fpga_fme_port_assign {
__u32 argsz; // w: sizeof(struct fpga_fme_port_assign)
__u32 flagi; // w: musi być 0
__u32 port_id; // in: identyfikator portu (od 0) do przypisania. (musi być
wcześniej wydane przez FPGA_FME_PORT_RELEASE)
};
FPGA_FME_PORT_PR — arg jest wskaźnikiem do:
struktura fpga_fme_port_pr {
__u32 argsz; // w: sizeof(struct fpga_fme_port_pr)
__u32 flagi; // w: musi być 0
__u32 port_id; // w: identyfikator portu (od 0)
__u32 buffer_size; // in: rozmiar bufora strumienia bitów w bajtach. Musi być 4-bajtowy
wyrównany.
__u64 buffer_address; // in: adres procesu bufora strumienia bitów
__u64 status; // out: status błędu (maska bitowa)
};
Port IOCTL
IOCTL-e wywoływane przy otwartym file deskryptor dla /dev/intel-fpga-port.k FPGA_GET_API_VERSION — zwraca bieżącą wersję jako liczbę całkowitą, zaczynając od 0. FPGA_CHECK_EXTENSION — obecnie nieobsługiwane.
FPGA_PORT_GET_INFO — arg jest wskaźnikiem do:
struktura fpga_port_info {
__u32 argsz; // w: sizeof(struct fpga_port_info)
__u32 flagi; // wyjście: zwraca 0
__u32 num_regions; // out: liczba regionów MMIO, 2 (1 dla AFU i 1 dla
(STP)
__u32 num_umsgs; // out: liczba UMsg obsługiwanych przez sprzęt
};
FPGA_PORT_GET_REGION_INFO — arg jest wskaźnikiem do:
struktura fpga_port_region_info {
__u32 argsz; // w: sizeof(struct fpga_port_region_info)
__u32 flagi; // wyjście: (maska bitowa) { FPGA_REGION_READ, FPGA_REGION_WRITE,
FPGA_REGION_MMAP }
__u32 indeks; // w: FPGA_PORT_INDEX_UAFU lub FPGA_PORT_INDEX_STP
__u32 padding; // in: musi być 0
__u64 size; // out: rozmiar regionu MMIO w bajtach
__u64 offset; // out: offset regionu MMIO od początku urządzenia fd
};
FPGA_PORT_DMA_MAP — arg jest wskaźnikiem do:
struktura fpga_port_dma_map {
__u32 argsz; // w: sizeof(struct fpga_port_dma_map)
__u32 flagi; // w: musi być 0 __u64 user_addr; // w: proces wirtualny
adres. Musi być wyrównany do strony.
__u64 length; // in: długość mapowania w bajtach. Musi być wielokrotnością strony
rozmiar.
__u64 iova; // out: wirtualny adres IO };
FPGA_PORT_DMA_UNMAP — arg jest wskaźnikiem do:
struktura fpga_port_dma_unmap {
__u32 argsz; // w: sizeof(struct fpga_port_dma_unmap)
__u32 flagi; // w: musi być 0
__u64 iova; // w: wirtualny adres IO zwrócony przez poprzedni
Mapa_portu_FPGA_DMA };
- FPGA_PORT_RESET — arg musi być NULL.
- FPGA_PORT_UMSG_ENABLE — arg musi być NULL.
- FPGA_PORT_UMSG_DISABLE — argumenty muszą być NULL.
FPGA_PORT_UMSG_SET_MODE — arg jest wskaźnikiem do:
struktura fpga_port_umsg_cfg {
__u32 argsz; // w: sizeof(struct fpga_port_umsg_cfg)
__u32 flagi; // w: musi być 0
__u32 hint_bitmap; // w: trybie podpowiedzi UMsg bitmap. Oznacza, które UMsg są
włączony.
};
FPGA_PORT_UMSG_SET_BASE_ADDR—
- Przed wykonaniem tego ioctl należy wyłączyć UMsg.
- Pole iova musi być buforem wystarczająco dużym dla wszystkich UMsg (num_umsgs * PAGE_SIZE).
- Bufor jest oznaczony jako „w użyciu” przez zarządzanie buforem sterownika.
- Jeśli iova ma wartość NULL, każdy poprzedni region nie jest oznaczony jako „w użyciu”.
- arg jest wskaźnikiem do:
struktura fpga_port_umsg_base_addr {- u32 argsz; // w: sizeof(struct fpga_port_umsg_base_addr)
- u32 flags; // w: musi być 0
- u64 iova; // w: wirtualny adres IO z FPGA_PORT_DMA_MAP. };
Notatka:
- Aby wyczyścić błędy portu, musisz zapisać dokładną maskę bitową bieżących błędów, np.ample, błędy cat > wyczyść
- UMsg jest obsługiwany wyłącznie poprzez Acceleration Stack dla procesorów Intel Xeon ze zintegrowanym układem FPGA.
system plików Files
Nagłówek FME sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/
system plików file | pole mmio | typ | dostęp |
numer_portu | fme_header.capability.liczba_portów | liczba dziesiętna | Tylko do odczytu |
rozmiar_pamięci_podręcznej | fme_header.capability.rozmiar_pamięci_podręcznej | liczba dziesiętna | Tylko do odczytu |
wersja | fme_header.capability.fabric_verid | liczba dziesiętna | Tylko do odczytu |
identyfikator_gniazda | fme_header.capability.socket_id | liczba dziesiętna | Tylko do odczytu |
identyfikator_strumienia_bitów | fme_header.id_strumienia_bitowego | szesnastkowy uint64_t | Tylko do odczytu |
metadane_strumienia_bitów | nagłówek_fme.bitstream_md | szesnastkowy uint64_t | Tylko do odczytu |
Systemy zarządzania termicznego FME files
intel-fpga-dev.i/intel-fpga-fme.j/thermal_mgmt/
system plików file | pole mmio | typ | dostęp |
próg1 | termiczny.próg.tmp_thshold1 | liczba dziesiętna | Użytkownik: Tylko do odczytu Root: Odczyt-zapis |
próg2 | termiczny.próg.tmp_thshold2 | liczba dziesiętna | Użytkownik: Tylko do odczytu Root: Odczyt-zapis |
próg_wyzwolenia | termiczny.próg.termiczny_wyzwolenie_thshold | liczba dziesiętna | Tylko do odczytu |
próg1_osiągnięty | termiczny.próg.thshold1_status | liczba dziesiętna | Tylko do odczytu |
próg2_osiągnięty | termiczny.próg.thshold2_status | liczba dziesiętna | Tylko do odczytu |
próg1_polityka | termiczny.próg.thshold_policy | liczba dziesiętna | Użytkownik: Tylko do odczytu Root: Odczyt-zapis |
temperatura | termiczny.rdsensor_fm1.fpga_temp | liczba dziesiętna | Tylko do odczytu |
System zarządzania energią FME files
intel-fpga-dev.i/intel-fpga-fme.j/power_mgmt/
system plików file | pole mmio | typ | dostęp |
strawiony | stan.mocy.moc_zużyta | szesnastkowy uint64_t | Tylko do odczytu |
próg1 | moc.próg.próg1 | szesnastkowy uint64_t | Użytkownik: Tylko do odczytu Root: Odczyt-zapis |
próg2 | moc.próg.próg2 | szesnastkowy uint64_t | Użytkownik: Tylko do odczytu Root: Odczyt-zapis |
status_progu1 | moc.próg.status_próg1 | dziesiętny bez znaku | Tylko do odczytu |
status_progu2 | moc.próg.status_próg2 | dziesiętny bez znaku | Tylko do odczytu |
rtl | power.status.fpga_latency_report | dziesiętny bez znaku | Tylko do odczytu |
Błąd globalny FME sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/błędy/
system plików file | pole mmio | typ | dostęp |
błędy pcie0 | błąd.pcie0_err | szesnastkowy uint64_t | Czytaj-pisz |
błędy pcie1 | błąd.pcie1_err | szesnastkowy uint64_t | Czytaj-pisz |
wstrzyknij_błąd | błąd.ras_error_inj | szesnastkowy uint64_t | Czytaj-pisz |
intel-fpga-dev.i/intel-fpga-fme.j/błędy/błędy-fme/
system plików file | pole mmio | typ | dostęp |
błędy | błąd.fme_err | szesnastkowy uint64_t | Tylko do odczytu |
pierwszy_błąd | gerror.fme_first_err.err_reg_status | szesnastkowy uint64_t | Tylko do odczytu |
następny_błąd | gerror.fme_next_err.err_reg_status | szesnastkowy uint64_t | Tylko do odczytu |
jasne | Czyści błędy, first_error, next_error | różne uint64_t | Tylko do zapisu |
Notatka:
Aby usunąć błędy FME, należy zapisać dokładną maskę bitową bieżących błędów, np.ampbłędy le cat > wyczyść.
Częściowa rekonfiguracja FME sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/pr/
system plików file | pole mmio | typ | dostęp |
identyfikator_interfejsu | pr.fme_pr_intfc_id0_h, pr.fme_pre_intfc_id0_l | szesnastkowy 16-bajtowy | Tylko do odczytu |
FME Global Performance sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/dperf/zegar
system plików file | pole mmio | typ | dostęp |
zegar | gperf.clk.afu_interf_clock | szesnastkowy uint64_t | Tylko do odczytu |
intel-fpga-dev.i/intel-fpga-fme.j/dperf/cache/ (Nie dotyczy stosu akceleracyjnego dla procesorów Intel Xeon z układami FPGA)
system plików file | pole mmio | typ | dostęp |
zamrażać | gperf.ch_ctl.freeze | liczba dziesiętna | Czytaj-pisz |
przeczytaj_trafienie | gperf.CACHE_RD_TRAFIENIE | szesnastkowy uint64_t | Tylko do odczytu |
odczyt_braku | gperf.CACHE_RD_Brak | szesnastkowy uint64_t | Tylko do odczytu |
napisz_uderzenie | gperf.CACHE_WR_HIT | szesnastkowy uint64_t | Tylko do odczytu |
zapis_chybienia | gperf.CACHE_WR_MISS | szesnastkowy uint64_t | Tylko do odczytu |
żądanie_wstrzymania | gperf.CACHE_HOLD_REQ | szesnastkowy uint64_t | Tylko do odczytu |
tx_req_stall | gperf.CACHE_TX_REQ_STALL | szesnastkowy uint64_t | Tylko do odczytu |
system plików file | pole mmio | typ | dostęp |
rx_req_stall | gperf.CACHE_RX_REQ_STALL | szesnastkowy uint64_t | Tylko do odczytu |
zawartość_portu_zapisu_danych | gperf.CACHE_DATA_WR_PORT_CONTEN | szesnastkowy uint64_t | Tylko do odczytu |
tag_zapisz_treść_portu | gperf.CACHE_TAG_WR_PORT_CONTEN | szesnastkowy uint64_t | Tylko do odczytu |
intel-fpga-dev.i/intel-fpga-fme.j/dperf/iommu/ (Nie dotyczy stosu akceleracyjnego dla procesorów Intel Xeon z układami FPGA)
system plików file | pole mmio | typ | dostęp |
zamrażać | gperf.vtd_ctl.freeze | liczba dziesiętna | Użytkownik: Tylko do odczytu Root: Odczyt-zapis |
intel-fpga-dev.i/intel-fpga-fme.j/dperf/iommu/afuk/ (Nie dotyczy stosu akceleracyjnego dla procesorów Intel Xeon z układami FPGA)
system plików file | pole mmio | typ | dostęp |
przeczytaj_transakcję | gperf.VTD_AFU0_MEM_RD_TRANS | szesnastkowy uint64_t | Tylko do odczytu |
napisz_transakcję | gperf.VTD_AFU0_MEM_WR_TRANS | szesnastkowy uint64_t | Tylko do odczytu |
tlb_odczytane_uderzenie | gperf.VTD_AFU0_TLB_RD_TRAFIENIE | szesnastkowy uint64_t | Tylko do odczytu |
tlb_zapisz_hit | gperf.VTD_AFU0_TLB_WR_HIT | szesnastkowy uint64_t | Tylko do odczytu |
intel-fpga-dev.i/intel-fpga-fme.j/dperf/fabric/
system plików file | pole mmio | typ | dostęp |
włączać | gperf.fab_ctl.(włączone) | liczba dziesiętna | Użytkownik: Tylko do odczytu Root: Odczyt-zapis |
zamrażać | gperf.fab_ctl.freeze | liczba dziesiętna | Użytkownik: Tylko do odczytu Root: Odczyt-zapis |
pcie0_odczyt | gperf.FAB_PCIE0_RD | szesnastkowy uint64_t | Tylko do odczytu |
pcie0_write | gperf.FAB_PCIE0_WR | szesnastkowy uint64_t | Tylko do odczytu |
pcie1_odczyt | gperf.FAB_PCIE1_RD | szesnastkowy uint64_t | Tylko do odczytu |
pcie1_write | gperf.FAB_PCIE1_WR | szesnastkowy uint64_t | Tylko do odczytu |
upi_odczyt | gperf.FAB_UPI_RD | szesnastkowy uint64_t | Tylko do odczytu |
upi_write | gperf.FAB_UPI_WR | szesnastkowy uint64_t | Tylko do odczytu |
intel-fpga-ev.i/intel-fpga/fme.j/dperf/fabric/portk/
system plików file | pole mmio | typ | dostęp |
pcie0_odczyt | gperf.FAB_PCIE0_RD | szesnastkowy uint64_t | Tylko do odczytu |
pcie0_write | gperf.FAB_PCIE0_WR | szesnastkowy uint64_t | Tylko do odczytu |
pcie1_odczyt | gperf.FAB_PCIE1_RD | szesnastkowy uint64_t | Tylko do odczytu |
pcie1_write | gperf.FAB_PCIE1_WR | szesnastkowy uint64_t | Tylko do odczytu |
upi_odczyt | gperf.FAB_UPI_RD | szesnastkowy uint64_t | Tylko do odczytu |
upi_write | gperf.FAB_UPI_WR | szesnastkowy uint64_t | Tylko do odczytu |
Nagłówek portu sysfs files
intel-fpga-dev.i/intel-fpga-port.k/
system plików file | pole mmio | typ | dostęp |
id | port_header.capability.port_number | liczba dziesiętna | Tylko do odczytu |
ltr | port_header.control.tolerancja_opóźnienia | liczba dziesiętna | Tylko do odczytu |
Nagłówek portu AFU sysfs files
intel-fpga-dev.i/intel-fpga-port.k/
system plików file | pole mmio | typ | dostęp |
afu_id | afu_header.guid | szesnastkowy 16-bajtowy | Tylko do odczytu |
Błąd portu sysfs files
intel-fpga-dev.i/intel-fpga-port.k/błędy/
system plików file | pole mmio | typ | dostęp |
błędy | perror.port_error | szesnastkowy uint64_t | Tylko do odczytu |
pierwszy_błąd | perror.port_first_error | szesnastkowy uint64_t | Tylko do odczytu |
first_malformed_req | perror.malreq | szesnastkowy 16-bajtowy | Tylko do odczytu |
jasne | perror.(wszystkie błędy) | różne uint64_t | Tylko do zapisu |
Notatka:
Aby wyczyścić błędy portu, należy zapisać dokładną maskę bitową bieżących błędów, np.ampbłędy le cat > wyczyść.
Historia rewizji
Wersja dokumentu | Zmiany |
2017.10.02 | Pierwsze wydanie. |
Przewodnik po architekturze sterownika urządzenia OPAE Intel FPGA Linux
Dokumenty / Zasoby
![]() |
Intel OPAE FPGA Linux Device Driver Architecture [plik PDF] Instrukcja użytkownika Architektura sterownika urządzenia FPGA systemu Linux firmy OPAE, OPAE FPGA, architektura sterownika urządzenia Linux, architektura sterownika, architektura |