Intel OPAE FPGA Linux Device Driver Architecture
Arquitectura de controladores de dispositivo OPAE Intel FPGA Linux
O controlador OPAE Intel FPGA ofrece interfaces para aplicacións de espazo de usuario para configurar, enumerar, abrir e acceder aos aceleradores FPGA en plataformas equipadas con solucións Intel FPGA e permite funcións de xestión a nivel de sistema como a reconfiguración de FPGA, a xestión de enerxía e a virtualización.
Arquitectura de hardware
Desde o punto de vista do SO view, o hardware FPGA aparece como un dispositivo PCIe normal. A memoria do dispositivo FPGA organízase mediante unha estrutura de datos predefinida (Lista de características do dispositivo). As funcións admitidas polo dispositivo FPGA expóñense a través destas estruturas de datos, como se ilustra a continuación na seguinte figura:
Dispositivo FPGA PCIe
O controlador admite PCIe SR-IOV para crear funcións virtuais (VF) que se poden usar para asignar aceleradores individuais a máquinas virtuais.
Intel Corporation. Todos os dereitos reservados. Intel, o logotipo de Intel e outras marcas de Intel son marcas comerciais de Intel Corporation ou das súas subsidiarias. Intel garante o rendemento dos seus produtos FPGA e de semicondutores segundo as especificacións actuais de acordo coa garantía estándar de Intel, pero resérvase o dereito de facer cambios en calquera produto e servizo en calquera momento sen previo aviso. Intel non asume ningunha responsabilidade ou responsabilidade derivada da aplicación ou uso de calquera información, produto ou servizo descrito aquí, salvo que Intel o acorde expresamente por escrito. Recoméndase aos clientes de Intel que obteñan a versión máis recente das especificacións do dispositivo antes de confiar en calquera información publicada e antes de facer pedidos de produtos ou servizos.
Outros nomes e marcas pódense reclamar como propiedade doutros.
Dispositivo PCIe FPGA virtualizado
Motor de xestión FPGA (FME)
O motor de xestión FPGA realiza a xestión de enerxía e térmica, informes de erros, reconfiguración, informes de rendemento e outras funcións de infraestrutura. Cada FPGA ten un FME, ao que sempre se accede a través da Función Física (PF). As aplicacións de espazo de usuario poden adquirir acceso exclusivo ao FME usando open() e liberalo usando close() como usuario privilexiado (root).
Porto
Un porto representa a interface entre o tecido FPGA estático (o "Xestor de interfaces FPGA (FIM)") e unha rexión parcialmente reconfigurable que contén unha función de aceleración (AF). O porto controla a comunicación do software ao acelerador e expón funcións como o restablecemento e a depuración. Un dispositivo PCIe pode ter varios portos, e cada porto pode ser exposto a través dun VF asignándoo mediante o ioctl FPGA_FME_PORT_ASSIGN do dispositivo FME.
Unidade de función de acelerador (AF).
- Unha unidade de función de acelerador (AF) está unida a un porto e expón unha rexión MMIO de 256 XNUMX que se utilizará para rexistros de control específicos do acelerador.
- As aplicacións de espazo de usuario poden adquirir acceso exclusivo a unha AFU conectada a un porto usando open() no dispositivo de porto e liberalo usando close().
- As aplicacións de espazo de usuario tamén poden acelerar mmap() rexións MMIO.
Reconfiguración parcial
Como se mencionou anteriormente, os aceleradores pódense reconfigurar mediante a reconfiguración parcial dunha función de acelerador (AF) file. A función de aceleración (AF) debe ser xerada para a FIM exacta e a rexión estática (Porto) de destino do FPGA; se non, a operación de reconfiguración fallará e posiblemente causará inestabilidade do sistema. Esta compatibilidade pódese comprobar comparando o ID da interface indicado na cabeceira AF co ID da interface exposto polo FME a través de sysfs. Esta comprobación adoita facerse polo espazo do usuario antes de chamar ao IOCTL de reconfiguración.
Nota:
Actualmente, calquera programa de software que acceda á FPGA, incluídos os que se executan nun host virtualizado, debe pecharse antes de intentar unha reconfiguración parcial. Os pasos serían:
- Descarga o controlador do convidado
- Desconecta o VF do convidado
- Desactivar SR-IOV
- Realice unha reconfiguración parcial
- Activar SR-IOV
- Conecte o VF ao convidado
- Carga o condutor no convidado
Virtualización FPGA
Para habilitar o acceso a un acelerador desde aplicacións que se executan nunha máquina virtual, o porto da AFU respectivo debe asignarse a un VF mediante os seguintes pasos:
- O PF posúe todos os portos AFU por defecto. Calquera porto que teña que ser reasignado a un VF debe ser liberado primeiro do PF a través do ioctl FPGA_FME_PORT_RELEASE no dispositivo FME.
- Unha vez que se liberan N portos do PF, pódese usar o seguinte comando para activar SRIOV e VF. Cada VF posúe só un porto con AFU. echo N > PCI_DEVICE_PATH/sriov_numvfs
- Pasa a través dos VF ás máquinas virtuales.
- A AFU baixo VF é accesible desde aplicacións en VM (usando o mesmo controlador dentro do VF).
Nota:
Non se pode asignar un FME a un VF, polo que as relacións públicas e outras funcións de xestión só están dispoñibles a través do PF.
Organización de condutores
Controlador de dispositivo do módulo PCIe
Organización de condutores
Os dispositivos FPGA aparecen como dispositivos PCIe normais; así, o controlador de dispositivo FPGA PCIe (intel-FPGA-PCI.ko) sempre se carga primeiro unha vez que se detecta un FPGA PCIe PF ou VF. Este controlador xoga un papel de infraestrutura na arquitectura do controlador. É:
- Crea un dispositivo contenedor FPGA como pai dos dispositivos con funcións.
- Percorre a Lista de características do dispositivo, que se implementa na memoria BAR do dispositivo PCIe, para descubrir dispositivos con funcións e as súas subfuncións e crear dispositivos de plataforma para eles baixo o dispositivo contenedor.
- Soporta SR-IOV.
- Presenta a infraestrutura de dispositivos de funcións, que abstrae as operacións de subfuncións e expón funcións comúns aos controladores de dispositivos.
Funcións do controlador de dispositivo do módulo PCIe
- Contén descubrimento de PCIe, enumeración de dispositivos e descubrimento de funcións.
- Crea directorios sysfs para o dispositivo principal, o motor de xestión FPGA (FME) e o porto.
- Crea as instancias do controlador da plataforma, facendo que o núcleo de Linux cargue os seus respectivos controladores do módulo da plataforma.
Controlador de dispositivo do módulo de plataforma FME
- Xestión de enerxía e térmica, informes de erros, informes de rendemento e outras funcións de infraestrutura. Pode acceder a estas funcións mediante interfaces sysfs expostas polo controlador FME.
- Reconfiguración parcial. O controlador FME rexistra un Xestor FPGA durante a inicialización da subfunción PR; unha vez que recibe un ioctl FPGA_FME_PORT_PR de ti, invoca a función de interface común do FPGA Manager para completar a reconfiguración parcial do fluxo de bits para o porto indicado.
- Xestión de portos para virtualización. O controlador FME introduce dous ioctls, FPGA_FME_PORT_RELEASE, que libera o porto indicado de PF; e FPGA_FME_PORT_ASSIGN, que asigna o porto de novo a PF. Unha vez que se libera o porto do PF, pódese asignar ao VF a través das interfaces SR-IOV proporcionadas polo controlador PCIe. Para obter máis información, consulte "Virtualización FPGA".
Funcións do controlador de dispositivo do módulo da plataforma FME
- Crea o nodo do dispositivo de carácter FME.
- Crea os sysfs FME files e implementa o sysfs FME file accesorios.
- Implementa os subcontroladores de funcións privadas de FME.
- Subcontroladores de funcións privadas de FME:
- Cabeceira FME
- Xestión Térmica
- Xestión de enerxía
- Erro global
- Reconfiguración parcial
- Desempeño global
Controlador de dispositivo do módulo de plataforma portuaria
Do mesmo xeito que o controlador FME, o controlador de porto FPGA (e AFU) (intel-fpga-afu. ko) sondóase unha vez que se crea o dispositivo da plataforma de porto. A función principal deste módulo é proporcionar unha interface para que as aplicacións de espazo de usuario accedan aos aceleradores individuais, incluíndo o control básico de reinicio no porto, a exportación da rexión AFU MMIO, o servizo de mapeo de búfer DMA, a notificación UMsg(1) e as funcións de depuración remota ( ver arriba).
UMsg só se admite mediante Acceleration Stack para o procesador Intel Xeon® con FPGA integrado.
Funcións do controlador de dispositivo do módulo de plataforma de portos
- Crea o nodo do dispositivo de caracteres de porto.
- Crea o port sysfs files e implementa o port sysfs file accesorios.
- Implementa os subcontroladores de funcións privadas do porto.
- Subconductores das funcións privadas do porto:
- Cabeceira do porto
- AFU
- Erro de porto
- UMsg (2)
- Toque sinal
Aplicación de enumeración de dispositivos FPGA
Esta sección presenta como as aplicacións enumeran o dispositivo FPGA da xerarquía sysfs en /sys/class/fpga. No exampa continuación, dous dispositivos Intel FPGA están instalados no host. Cada dispositivo FPGA ten un FME e dous portos (AFU). Para cada dispositivo FPGA, créase un directorio de dispositivos en /sys/class/fpga:
/sys/class/fpga/intel-fpga-dev.0
/sys/class/fpga/intel-fpga-dev.1
Cada nodo ten un FME e dous portos (AFU) como dispositivos fillos:
/sys/class/fpga/intel-fpga-dev.0/intel-fpga-fme.0
/sys/class/fpga/intel-fpga-dev.0/intel-fpga-port.0
/sys/class/fpga/intel-fpga-dev.0/intel-fpga-port.1
/sys/class/fpga/intel-fpga-dev.1/intel-fpga-fme.1
/sys/class/fpga/intel-fpga-dev.1/intel-fpga-port.2
/sys/class/fpga/intel-fpga-dev.1/intel-fpga-port.3
En xeral, as interfaces FME/Port sysfs denomínanse do seguinte xeito:
/sys/class/fpga/intel-fpga-dev.i/intel-fpga-fme.j/
/sys/class/fpga/intel-fpga-dev.i/intel-fpga-port.k/
con I numerando consecutivamente todos os dispositivos contedores, j numerando consecutivamente os FME e k numerando consecutivamente todos os portos.
Os nodos do dispositivo utilizados para ioctl() e mmap() pódense facer referencia a través de:
/dev/intel-fpga-fme.j
/dev/intel-fpga-port.k
Enumeración de controladores PCIe
Esta sección dá unha voltaview do fluxo de código para a enumeración de dispositivos realizada por intel-fpga-pci.ko. Destacan as principais estruturas e funcións de datos. Esta sección é mellor seguir cando viewing o código fonte que se acompaña (pcie.c).
Estruturas de datos de enumeración
enumeración fpga_id_type {
PARENT_ID,
FME_ID,
PORT_ID,
FPGA_ID_MAX
};
idr de estrutura estático fpga_ids[FPGA_ID_MAX];
struct fpga_chardev_info {
const char *nome;
dev_t devt;
};
struct fpga_chardev_info fpga_chrdevs[] = {
{ .name = FPGA_FEATURE_DEV_FME },
{ .name = FPGA_FEATURE_DEV_PORT },
};
clase de estrutura estática *fpga_class;
estrutura estática 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,}
};
estrutura estática 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
};
estrutura cci_drvdata {
int dispositivo_id;
dispositivo de estrutura *fme_dev;
bloqueo struct mutex;
struct list_head port_dev_list;
int número_porto_liberado;
struct list_head rexións;
};
struct build_feature_devs_info {
struct pci_dev *pdev;
void __iomem *ioaddr;
void __iomem *ioend;
int barra_actual;
void __iomem *pfme_hdr;
dispositivo de estrutura *parent_dev;
struct platform_device *feature_dev;
};
Fluxo de enumeración
- ccidrv_init()
- Inicialice fpga_ids usando idr_init().
- Inicialice fpga_chrdevs[i].devt usando alloc_chrdev_region().
- Inicialice fpga_class usando class_create().
- controlador_pci_register(&cci_pci_driver);
- cci_pci_probe()
- Active o dispositivo PCI, solicite acceso ás súas rexións, configure o modo mestre PCI e configure DMA.
- cci_pci_create_feature_devs() build_info_alloc_and_init()
- Asigne unha estrutura build_feature_devs_info, inicialízaa.
.parent_dev establécese nun directorio sysfs principal (intel-fpga-dev.id) que contén os directorios FME e Port sysfs.
- Asigne unha estrutura build_feature_devs_info, inicialízaa.
- parse_feature_list()
- Percorre a Lista de funcións do dispositivo BAR0 para descubrir o FME, o porto e as súas funcións privadas.
- parse_feature() parse_feature_afus() parse_feature_fme()
- Cando se atopa un FME:
- build_info_create_dev()
- Asigne un dispositivo de plataforma para o FME, almacenando en build_feature_devs_info.feature_dev.
- feature_dev.id inicialízase co resultado de idr_alloc(fpga_ids[FME_ID],
- feature_dev.parent está configurado como build_feature_devs_info.parent_dev.
- Asigne unha matriz de recursos de estrutura en feature_dev.resource.
- Asigne unha estrutura feature_platform_data, inicialízaa e almacene un punteiro en feature_dev.dev.platform_data
- create_feature_instance() build_info_add_sub_feature()
- Inicializa feature_dev.resource[FME_FEATURE_ID_HEADER].
- feature_platform_data_add()
- Inicializa feature_platform_data.features[FME_FEATURE_ID_HEADER], todo menos .fops.
- parse_feature() parse_feature_afus() parse_feature_port()
- Cando se atopa un porto:
- build_info_create_dev()
- Asigne un dispositivo de plataforma para o porto, almacenando en build_feature_devs_info.feature_dev.
- feature_dev.id inicialízase co resultado de idr_alloc(fpga_ids[PORT_ID],
- feature_dev.parent está configurado como build_feature_devs_info.parent_dev.
- Asigne unha matriz de recursos de estrutura en feature_dev.resource.
- Asigne unha estrutura feature_platform_data, inicialízaa e almacene un punteiro en feature_dev.dev.platform_data
- build_info_commit_dev()
- Engade o struct feature_platform_data.node para o porto á lista de portos en struct cci_drvdata.port_dev_list
- create_feature_instance() build_info_add_sub_feature()
- Inicializa feature_dev.resource[PORT_FEATURE_ID_HEADER].
- feature_platform_data_add()
- Inicializa feature_platform_data.features[PORT_FEATURE_ID_HEADER], todo menos .fops.
- parse_feature() parse_feature_afus() parse_feature_port_uafu()
- Cando se atopa unha AFU:
- create_feature_instance() build_info_add_sub_feature()
- Inicializa feature_dev.resource[PORT_FEATURE_ID_UAFU].
- feature_platform_data_add()
- Inicializa feature_platform_data.features[PORT_FEATURE_ID_UAFU], todo menos .fops.
- parse_feature() parse_feature_private() parse_feature_fme_private()
- Cando se atopa unha función privada de FME:
- create_feature_instance() build_info_add_sub_feature()
- Inicializa feature_dev.resource[id].
- feature_platform_data_add()
- Inicializa feature_platform_data.features[id], todo menos .fops.
- parse_feature() parse_feature_private() parse_feature_port_private()
- Cando se atopa unha característica privada do porto: * create_feature_instance() build_info_add_sub_feature() * Inicializa feature_dev.resource[id]. * feature_platform_data_add() Inicializa feature_platform_data.features[id], todo menos .fops.
- parse_ports_from_fme()
- Se o controlador está cargado na función física (PF), entón:
- Execute o fluxo parse_feature_list() en cada porto descrito na cabeceira FME.
- Use a BAR mencionada en cada entrada de porto na cabeceira.
Inicialización do dispositivo da plataforma FME
Esta sección dá unha voltaview do fluxo de código para a inicialización do dispositivo FME realizada por intel-fpga-fme.ko. Destacan as principais estruturas e funcións de datos. Esta sección é mellor seguir cando viewing o código fonte que se acompaña (fme-main.c).
Estruturas de datos do dispositivo da plataforma FME
struct feature_ops {
int (*init)(struct platform_device *pdev, struct feature *característica);
int (*uinit)(struct platform_device *pdev, struct feature *característica);
long (*ioctl)(struct platform_device *pdev, struct feature *feature,
unsigned int cmd, unsigned long arg);
int (*test)(struct platform_device *pdev, struct feature *característica);
};
característica de estrutura {
const char *nome;
int índice_recurso;
void __iomem *ioaddr;
struct feature_ops *ops;
};
struct feature_platform_data {
struct list_head nodo;
bloqueo struct mutex;
estado de desenvolvemento longo sen asinar;
struct cdev cdev;
struct platform_device *dev;
unsigned int disable_count;
baleiro *privado;
int num;
int (*config_port)(struct platform_device *, u32, bool);
struct platform_device *(*fpga_for_each_port)(struct platform_device *,
void *, int (*coincidir)(struct platform_device *, void *)); estrutura
características das características[0];
};
struct perf_object {
int id;
const struct grupo_atributos **grupos_attr;
dispositivo de estrutura *fme_dev;
struct list_head nodo;
struct list_head fillos;
struct kobject kobj;
};
estrutura fpga_fme {
u8 port_id;
u64 pr_err;
dispositivo de estrutura *dev_err;
struct perf_object *perf_dev;
struct feature_platform_data *pdata;
};
Fluxo de inicialización do dispositivo da plataforma FME
Fluxo de inicialización FME
- fme_probe() fme_dev_init()
- Inicialice unha estrutura fpga_fme e gárdaa no campo feature_platform_data.private.
- fme_probe() fpga_dev_feature_init() feature_instance_init()
- Garda unha estrutura feature_ops no feature_platform_data.features para cada función poboada.
- Chame á función de proba, se a hai, desde a estrutura.
- Chame á función init desde a estrutura.
- fme_probe() fpga_register_dev_ops()
- Cree o nodo do dispositivo de carácter FME, rexistrando unha estrutura file_operacións.
Inicialización do dispositivo da plataforma portuaria
Esta sección dá unha voltaview do fluxo de código para a inicialización do dispositivo de porto realizado por intel-fpga-afu.ko. Destacan as principais estruturas e funcións de datos. Esta sección é mellor seguir cando viewing o código fonte que se acompaña (afu.c).
Estruturas de datos do dispositivo da plataforma portuaria
struct feature_ops {
int (*init)(struct platform_device *pdev, struct feature *característica);
int (*uinit)(struct platform_device *pdev, struct feature *característica);
long (*ioctl)(struct platform_device *pdev, struct feature *feature,
unsigned int cmd, unsigned long arg);
int (*test)(struct platform_device *pdev, struct feature *característica);
};
característica de estrutura {
const char *nome;
int índice_recurso;
void __iomem *ioaddr;
struct feature_ops *ops;
};
struct feature_platform_data {
struct list_head nodo;
bloqueo struct mutex;
estado de desenvolvemento longo sen asinar;
struct cdev cdev;
struct platform_device *dev;
unsigned int disable_count;
baleiro *privado;
int num;
int (*config_port)(struct platform_device *, u32, bool);
struct platform_device *(*fpga_for_each_port)(struct platform_device *,
void *, int (*coincidir)(struct platform_device *, void *));
características de estrutura[0];
};
estrutura fpga_afu_region {
índice u32;
bandeiras u32;
tamaño u64;
compensación u64;
u64 físico;
struct list_head nodo;
};
estrutura fpga_afu_dma_region {
u64 user_addr;
lonxitude u64;
u64 iova;
páxina de estrutura ** páxinas;
struct rb_node nodo;
bool in_use;
};
estrutura fpga_afu {
u64 region_cur_offset;
int num_regions;
u8 num_umsgs;
struct list_head rexións;
struct rb_root dma_regions;
struct feature_platform_data *pdata;
};
Fluxo de inicialización do dispositivo da plataforma portuaria
Fluxo de inicialización do porto
- afu_probe() afu_dev_init()
- Inicialice unha estrutura fpga_afu e gárdaa no campo feature_platform_data.private.
- afu_probe() fpga_dev_feature_init() feature_instance_init()
- Garda unha estrutura feature_ops no feature_platform_data.features para cada función poboada.
- Chame á función de proba, se a hai, desde a estrutura.
- Chame á función init desde a estrutura.
- afu_probe() fpga_register_dev_ops()
- Cree o nodo do dispositivo de carácter Port, rexistrando unha estrutura file_operacións.
IOCTL FME
IOCTL que se convocan nun aberto file descriptor para /dev/intel-fpga-fme.j FPGA_GET_API_VERSION: devolve a versión actual como un número enteiro, a partir de 0.
FPGA_CHECK_EXTENSION: non é compatible actualmente.
FPGA_FME_PORT_RELEASE: arg é un punteiro a:
struct fpga_fme_port_release {
__u32 argsz; // en: sizeof(struct fpga_fme_port_release)
__u32 bandeiras; // en: debe ser 0
__u32 port_id; // en: ID de porto (de 0) para liberar.
};
FPGA_FME_PORT_ASSIGN: arg é un punteiro a:
struct fpga_fme_port_assign {
__u32 argsz; // en: sizeof(struct fpga_fme_port_assign)
__u32 bandeiras; // en: debe ser 0
__u32 port_id; // en: ID de porto (de 0) para asignar. (debeu ser
publicado anteriormente por FPGA_FME_PORT_RELEASE)
};
FPGA_FME_PORT_PR: arg é un punteiro a:
estrutura fpga_fme_port_pr {
__u32 argsz; // en: sizeof(struct fpga_fme_port_pr)
__u32 bandeiras; // en: debe ser 0
__u32 port_id; // en: ID de porto (de 0)
__u32 buffer_size; // en: tamaño do búfer de fluxo de bits en bytes. Debe ser de 4 bytes
aliñados.
__u64 enderezo_búfer; // en: enderezo do proceso do búfer de fluxo de bits
__u64 estado; // fóra: estado de erro (máscara de bits)
};
IOCTL portuarios
IOCTL que se convocan nun aberto file descriptor para /dev/intel-fpga-port.k FPGA_GET_API_VERSION: devolve a versión actual como un número enteiro, a partir de 0. FPGA_CHECK_EXTENSION: non se admite actualmente.
FPGA_PORT_GET_INFO: arg é un punteiro a:
estrutura fpga_port_info {
__u32 argsz; // en: sizeof(struct fpga_port_info)
__u32 bandeiras; // fóra: devolve 0
__u32 num_regions; // saída: número de rexións MMIO, 2 (1 para AFU e 1 para
STP)
__u32 num_umsgs; // out: número de UMsg soportados polo hardware
};
FPGA_PORT_GET_REGION_INFO: arg é un punteiro a:
struct fpga_port_region_info {
__u32 argsz; // en: sizeof(struct fpga_port_region_info)
__u32 bandeiras; // saída: (máscara de bits) { FPGA_REGION_READ, FPGA_REGION_WRITE,
FPGA_REGION_MMAP }
índice __u32; // en: FPGA_PORT_INDEX_UAFU ou FPGA_PORT_INDEX_STP
__u32 recheo; // en: debe ser 0
__u64 tamaño; // out: tamaño da rexión MMIO en bytes
__u64 compensación; // fóra: compensación da rexión MMIO desde o inicio do dispositivo fd
};
FPGA_PORT_DMA_MAP: arg é un punteiro a:
struct fpga_port_dma_map {
__u32 argsz; // en: sizeof(struct fpga_port_dma_map)
__u32 bandeiras; // en: debe ser 0 __u64 user_addr; // en: proceso virtual
enderezo. Debe estar aliñado á páxina.
__u64 lonxitude; // en: lonxitude da asignación en bytes. Debe ser un múltiplo de páxina
tamaño.
__u64 iova; // saída: enderezo virtual IO };
FPGA_PORT_DMA_UNMAP: arg é un punteiro a:
struct fpga_port_dma_unmap {
__u32 argsz; // en: sizeof(struct fpga_port_dma_unmap)
__u32 bandeiras; // en: debe ser 0
__u64 iova; // en: enderezo virtual IO devolto por un anterior
FPGA_PORT_DMA_MAP };
- FPGA_PORT_RESET: arg debe ser NULL.
- FPGA_PORT_UMSG_ENABLE—arg debe ser NULL.
- FPGA_PORT_UMSG_DISABLE: os argumentos deben ser NULL.
FPGA_PORT_UMSG_SET_MODE: arg é un punteiro a:
estrutura fpga_port_umsg_cfg {
__u32 argsz; // en: sizeof(struct fpga_port_umsg_cfg)
__u32 bandeiras; // en: debe ser 0
__u32 suxestión_mapa de bits; // en: mapa de bits do modo suxestión UMsg. Indica cales son os UMsg
activado.
};
FPGA_PORT_UMSG_SET_BASE_ADDR—
- UMsg debe estar desactivado antes de emitir este ioctl.
- O campo iova debe ser para un búfer o suficientemente grande para todos os UMsg (num_umsgs * PAGE_SIZE).
- O búfer está marcado como "en uso" pola xestión do búfer do controlador.
- Se iova é NULL, calquera rexión anterior non está marcada como "en uso".
- arg é un punteiro a:
struct fpga_port_umsg_base_addr {- u32 argsz; // en: sizeof(struct fpga_port_umsg_base_addr)
- bandeiras u32; // en: debe ser 0
- u64 iova; // en: enderezo virtual IO de FPGA_PORT_DMA_MAP. };
Nota:
- Para borrar os erros de porto, ten que escribir a máscara de bits exacta dos erros actuais, por exemploample, cat erros > borrar
- UMsg só se admite mediante Acceleration Stack para o procesador Intel Xeon con FPGA integrado.
sysfs Files
Sistemas de cabeceira FME files
intel-fpga-dev.i/intel-fpga-fme.j/
sysfs file | campo mmio | tipo | acceso |
portos_num | fme_header.capability.num_ports | decimal int | Só lectura |
caché_tamaño | fme_header.capability.cache_size | decimal int | Só lectura |
versión | fme_header.capability.fabric_verid | decimal int | Só lectura |
id_socket | fme_header.capability.socket_id | decimal int | Só lectura |
bitstream_id | fme_header.bitstream_id | hexadecimal uint64_t | Só lectura |
metadatos_bitstream | fme_header.bitstream_md | hexadecimal uint64_t | Só lectura |
Sistemas de xestión térmica FME files
intel-fpga-dev.i/intel-fpga-fme.j/thermal_mgmt/
sysfs file | campo mmio | tipo | acceso |
limiar 1 | limiar.térmico.tmp_thshold1 | decimal int | Usuario: só lectura Raíz: lectura-escritura |
limiar 2 | limiar.térmico.tmp_thshold2 | decimal int | Usuario: só lectura Raíz: lectura-escritura |
viaxe_limiar | limiar.térmico.limiar.term_trip_threshold | decimal int | Só lectura |
limiar1_alcanzouse | limiar.térmico.thshold1_status | decimal int | Só lectura |
limiar2_alcanzouse | limiar.térmico.thshold2_status | decimal int | Só lectura |
limiar1_política | térmica. limiar.thshold_policy | decimal int | Usuario: só lectura Raíz: lectura-escritura |
temperatura | thermal.rdsensor_fm1.fpga_temp | decimal int | Só lectura |
Sistemas de xestión de enerxía FME files
intel-fpga-dev.i/intel-fpga-fme.j/power_mgmt/
sysfs file | campo mmio | tipo | acceso |
consumido | power.status.pwr_consumed | hexadecimal uint64_t | Só lectura |
limiar 1 | limiar.potencia.limiar1 | hexadecimal uint64_t | Usuario: só lectura Raíz: lectura-escritura |
limiar 2 | limiar.potencia.limiar2 | hexadecimal uint64_t | Usuario: só lectura Raíz: lectura-escritura |
estado_limiar1 | estado.limiar.potencia.limiar1 | decimal sen signo | Só lectura |
estado_limiar2 | estado.limiar.potencia.limiar2 | decimal sen signo | Só lectura |
rtl | power.status.fpga_latency_report | decimal sen signo | Só lectura |
Erro global FME sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/errors/
sysfs file | campo mmio | tipo | acceso |
pcie0_erros | gerror.pcie0_err | hexadecimal uint64_t | Ler-escribir |
pcie1_erros | gerror.pcie1_err | hexadecimal uint64_t | Ler-escribir |
erro_inxectar | gerror.ras_error_inj | hexadecimal uint64_t | Ler-escribir |
intel-fpga-dev.i/intel-fpga-fme.j/errors/fme-errors/
sysfs file | campo mmio | tipo | acceso |
erros | gerror.fme_err | hexadecimal uint64_t | Só lectura |
primeiro_erro | gerror.fme_first_err.err_reg_status | hexadecimal uint64_t | Só lectura |
seguinte_erro | gerror.fme_next_err.err_reg_status | hexadecimal uint64_t | Só lectura |
claro | Borra os erros, first_error, next_error | varios uint64_t | Só de escritura |
Nota:
Para borrar os erros de FME, debe escribir a máscara de bits exacta dos erros actuais, por exemploample cat erros > borrar.
Sysfs de reconfiguración parcial de FME files
intel-fpga-dev.i/intel-fpga-fme.j/pr/
sysfs file | campo mmio | tipo | acceso |
interface_id | pr.fme_pr_intfc_id0_h, pr.fme_pre_intfc_id0_l | hexadecimal de 16 bytes | Só lectura |
Sistemas FME Global Performance files
intel-fpga-dev.i/intel-fpga-fme.j/dperf/clock
sysfs file | campo mmio | tipo | acceso |
reloxo | gperf.clk.afu_interf_clock | hexadecimal uint64_t | Só lectura |
intel-fpga-dev.i/intel-fpga-fme.j/dperf/cache/ (no válido para Acceleration Stack para CPU Intel Xeon con FPGA)
sysfs file | campo mmio | tipo | acceso |
conxelar | gperf.ch_ctl.freeze | decimal int | Ler-escribir |
read_hit | gperf.CACHE_RD_HIT | hexadecimal uint64_t | Só lectura |
ler_perder | gperf.CACHE_RD_MISS | hexadecimal uint64_t | Só lectura |
escribir_golpear | gperf.CACHE_WR_HIT | hexadecimal uint64_t | Só lectura |
escribir_falta | gperf.CACHE_WR_MISS | hexadecimal uint64_t | Só lectura |
hold_request | gperf.CACHE_HOLD_REQ | hexadecimal uint64_t | Só lectura |
tx_req_stall | gperf.CACHE_TX_REQ_STALL | hexadecimal uint64_t | Só lectura |
sysfs file | campo mmio | tipo | acceso |
rx_req_stall | gperf.CACHE_RX_REQ_STALL | hexadecimal uint64_t | Só lectura |
data_write_port_contention | gperf.CACHE_DATA_WR_PORT_CONTEN | hexadecimal uint64_t | Só lectura |
tag_write_port_contention | gperf.CACHE_TAG_WR_PORT_CONTEN | hexadecimal uint64_t | Só lectura |
intel-fpga-dev.i/intel-fpga-fme.j/dperf/iommu/ (no válido para Acceleration Stack para CPU Intel Xeon con FPGA)
sysfs file | campo mmio | tipo | acceso |
conxelar | gperf.vtd_ctl.freeze | decimal int | Usuario: só lectura Raíz: lectura-escritura |
intel-fpga-dev.i/intel-fpga-fme.j/dperf/iommu/afuk/ (no válido para Acceleration Stack para CPU Intel Xeon con FPGA)
sysfs file | campo mmio | tipo | acceso |
lectura_transacción | gperf.VTD_AFU0_MEM_RD_TRANS | hexadecimal uint64_t | Só lectura |
transacción_escribir | gperf.VTD_AFU0_MEM_WR_TRANS | hexadecimal uint64_t | Só lectura |
tlb_read_hit | gperf.VTD_AFU0_TLB_RD_HIT | hexadecimal uint64_t | Só lectura |
tlb_write_hit | gperf.VTD_AFU0_TLB_WR_HIT | hexadecimal uint64_t | Só lectura |
intel-fpga-dev.i/intel-fpga-fme.j/dperf/fabric/
sysfs file | campo mmio | tipo | acceso |
habilitar | gperf.fab_ctl.(activado) | decimal int | Usuario: só lectura Raíz: lectura-escritura |
conxelar | gperf.fab_ctl.freeze | decimal int | Usuario: só lectura Raíz: lectura-escritura |
pcie0_read | gperf.FAB_PCIE0_RD | hexadecimal uint64_t | Só lectura |
pcie0_write | gperf.FAB_PCIE0_WR | hexadecimal uint64_t | Só lectura |
pcie1_read | gperf.FAB_PCIE1_RD | hexadecimal uint64_t | Só lectura |
pcie1_write | gperf.FAB_PCIE1_WR | hexadecimal uint64_t | Só lectura |
upi_read | gperf.FAB_UPI_RD | hexadecimal uint64_t | Só lectura |
upi_write | gperf.FAB_UPI_WR | hexadecimal uint64_t | Só lectura |
intel-fpga-ev.i/intel-fpga/fme.j/dperf/fabric/portk/
sysfs file | campo mmio | tipo | acceso |
pcie0_read | gperf.FAB_PCIE0_RD | hexadecimal uint64_t | Só lectura |
pcie0_write | gperf.FAB_PCIE0_WR | hexadecimal uint64_t | Só lectura |
pcie1_read | gperf.FAB_PCIE1_RD | hexadecimal uint64_t | Só lectura |
pcie1_write | gperf.FAB_PCIE1_WR | hexadecimal uint64_t | Só lectura |
upi_read | gperf.FAB_UPI_RD | hexadecimal uint64_t | Só lectura |
upi_write | gperf.FAB_UPI_WR | hexadecimal uint64_t | Só lectura |
Sysfs de cabeceira de porto files
intel-fpga-dev.i/intel-fpga-port.k/
sysfs file | campo mmio | tipo | acceso |
id | port_header.capability.port_number | decimal int | Só lectura |
ltr | port_header.control.latency_tolerance | decimal int | Só lectura |
Sysfs de cabeceira AFU de porto files
intel-fpga-dev.i/intel-fpga-port.k/
sysfs file | campo mmio | tipo | acceso |
afu_id | afu_header.guid | hexadecimal de 16 bytes | Só lectura |
Erro de porto sysfs files
intel-fpga-dev.i/intel-fpga-port.k/errors/
sysfs file | campo mmio | tipo | acceso |
erros | perror.port_error | hexadecimal uint64_t | Só lectura |
primeiro_erro | perror.port_first_error | hexadecimal uint64_t | Só lectura |
primeiro_requisito_malformado | perror.malreq | hexadecimal de 16 bytes | Só lectura |
claro | erro.(todos os erros) | varios uint64_t | Só de escritura |
Nota:
Para borrar os erros do porto, debes escribir a máscara de bits exacta dos erros actuais, por exemploample cat erros > borrar.
Historial de revisións
Versión do documento | Cambios |
2017.10.02 | Lanzamento inicial. |
OPAE Intel FPGA Linux Device Driver Architecture Guide
Documentos/Recursos
![]() |
Intel OPAE FPGA Linux Device Driver Architecture [pdfGuía do usuario OPAE FPGA Linux Device Driver Architecture, OPAE FPGA, Linux Device Driver Architecture, Driver Architecture, Architecture |