logotipo intel

Arquitetura de driver de dispositivo Linux intel OPAE FPGA

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

Arquitetura de driver de dispositivo Linux OPAE Intel FPGA

O driver OPAE Intel FPGA fornece interfaces para aplicativos de espaço de usuário para configurar, enumerar, abrir e acessar aceleradores FPGA em plataformas equipadas com soluções Intel FPGA e permite funções de gerenciamento em nível de sistema, como reconfiguração de FPGA, gerenciamento de energia e virtualização.

Arquitetura de Hardware

Do ponto de vista do sistema operacional view, o hardware FPGA aparece como um dispositivo PCIe normal. A memória do dispositivo FPGA é organizada usando uma estrutura de dados predefinida (Device Feature List). Os recursos suportados pelo dispositivo FPGA são expostos por meio dessas estruturas de dados, conforme ilustrado abaixo na figura a seguir:

Dispositivo FPGA PCIe

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

O driver suporta PCIe SR-IOV para criar funções virtuais (VFs) que podem ser usadas para atribuir aceleradores individuais a máquinas virtuais.

Corporação Intel. Todos os direitos reservados. Intel, o logotipo da Intel e outras marcas da Intel são marcas comerciais da Intel Corporation ou de suas subsidiárias. A Intel garante o desempenho de seus produtos FPGA e semicondutores de acordo com as especificações atuais de acordo com a garantia padrão da Intel, mas reserva-se o direito de fazer alterações em quaisquer produtos e serviços a qualquer momento sem aviso prévio. A Intel não assume nenhuma responsabilidade decorrente do aplicativo ou uso de qualquer informação, produto ou serviço aqui descrito, exceto conforme expressamente acordado por escrito pela Intel. Os clientes da Intel são aconselhados a obter a versão mais recente das especificações do dispositivo antes de confiar em qualquer informação publicada e antes de fazer pedidos de produtos ou serviços.

Outros nomes e marcas podem ser reivindicados como propriedade de terceiros.

Dispositivo FPGA PCIe virtualizado

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

Mecanismo de gerenciamento de FPGA (FME)
O FPGA Management Engine realiza gerenciamento térmico e de energia, relatórios de erros, reconfiguração, relatórios de desempenho e outras funções de infraestrutura. Cada FPGA possui uma FME, que é sempre acessada através da Função Física (PF). Os aplicativos de espaço do usuário podem adquirir acesso exclusivo ao FME usando open() e liberá-lo usando close() como um usuário privilegiado (root).

Porta
Uma porta representa a interface entre a estrutura estática do FPGA (o “FPGA Interface Manager (FIM)”) e uma região parcialmente reconfigurável contendo uma função de acelerador (AF). A porta controla a comunicação do software para o acelerador e expõe recursos como redefinir e depurar. Um dispositivo PCIe pode ter várias portas, e cada porta pode ser exposta por meio de um VF, atribuindo-a usando o ioctl FPGA_FME_PORT_ASSIGN no dispositivo FME.

Unidade de função do acelerador (AF)

  • Uma unidade de função do acelerador (AF) é anexada a uma porta e expõe uma região 256K MMIO para ser usada para registros de controle específicos do acelerador.
  • Aplicativos de espaço de usuário podem adquirir acesso exclusivo a um AFU conectado a uma porta usando open() no dispositivo de porta e liberá-lo usando close().
  • Os aplicativos de espaço do usuário também podem regiões MMIO do acelerador mmap().

Reconfiguração Parcial
Como mencionado acima, os aceleradores podem ser reconfigurados por meio da reconfiguração parcial de uma função do acelerador (AF) file. A Accelerator Function (AF) deve ter sido gerada para o FIM exato e a região estática de destino (Porta) do FPGA; caso contrário, a operação de reconfiguração falhará e possivelmente causará instabilidade no sistema. Essa compatibilidade pode ser verificada comparando o ID da interface anotado no cabeçalho AF com o ID da interface exposto pelo FME por meio do sysfs. Essa verificação geralmente é feita pelo espaço do usuário antes de chamar o IOCTL de reconfiguração.

Observação:
Atualmente, qualquer programa de software que acesse o FPGA, incluindo aqueles executados em um host virtualizado, deve ser fechado antes de tentar uma reconfiguração parcial. As etapas seriam:

  1. Descarregue o driver do convidado
  2. Desconecte o VF do convidado
  3. Desativar SR-IOV
  4. Executar reconfiguração parcial
  5. Ativar SR-IOV
  6. Conecte o VF ao convidado
  7. Carregar o driver no convidado

Virtualização FPGA
Para habilitar o acesso a um acelerador a partir de aplicativos em execução em uma VM, a respectiva porta AFU precisa ser atribuída a um VF usando as seguintes etapas:

  1. O PF possui todas as portas AFU por padrão. Qualquer porta que precise ser reatribuída a um VF deve primeiro ser liberada do PF por meio do ioctl FPGA_FME_PORT_RELEASE no dispositivo FME.
  2. Uma vez que N portas são liberadas do PF, o comando abaixo pode ser usado para habilitar SRIOV e VFs. Cada VF possui apenas uma porta com AFU. echo N > PCI_DEVICE_PATH/sriov_numvfs
  3. Passe pelos VFs para VMs.
  4. O AFU sob VF é acessível a partir de aplicativos em VM (usando o mesmo driver dentro do VF).

Observação:
Um FME não pode ser atribuído a um VF, portanto PR e outras funções de gerenciamento estão disponíveis apenas por meio do PF.

Organização do Motorista

Driver de dispositivo do módulo PCIe

Organização do Motorista

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

Os dispositivos FPGA aparecem como dispositivos PCIe normais; assim, o driver do dispositivo FPGA PCIe (intel-FPGA-PCI.ko) é sempre carregado primeiro quando um FPGA PCIe PF ou VF é detectado. Esse driver desempenha um papel de infraestrutura na arquitetura do driver. Isto:

  • Cria um dispositivo de contêiner FPGA como pai dos dispositivos de recursos.
  • Percorre a lista de recursos do dispositivo, que é implementada na memória BAR do dispositivo PCIe, para descobrir os dispositivos de recursos e seus sub-recursos e criar dispositivos de plataforma para eles no dispositivo de contêiner.
  • Suporta SR-IOV.
  • Apresenta a infra-estrutura de dispositivos de recursos, que abstrai operações para sub-recursos e expõe funções comuns para drivers de dispositivos de recursos.

Funções do driver de dispositivo do módulo PCIe

  • Contém descoberta de PCIe, enumeração de dispositivos e descoberta de recursos.
  • Cria diretórios sysfs para o dispositivo pai, FPGA Management Engine (FME) e Port.
  • Cria as instâncias do driver de plataforma, fazendo com que o kernel do Linux carregue seus respectivos drivers de módulo de plataforma.

Driver de dispositivo do módulo da plataforma FME

  • Gerenciamento térmico e de energia, relatórios de erros, relatórios de desempenho e outras funções de infraestrutura. Você pode acessar essas funções por meio de interfaces sysfs expostas pelo driver FME.
  • Reconfiguração Parcial. O driver FME registra um FPGA Manager durante a inicialização do sub-recurso PR; uma vez que recebe um ioctl FPGA_FME_PORT_PR de você, ele invoca a função de interface comum do FPGA Manager para completar a reconfiguração parcial do fluxo de bits para a porta fornecida.
  • Gerenciamento de portas para virtualização. O driver FME apresenta dois ioctls, FPGA_FME_PORT_RELEASE, que libera a porta fornecida do PF; e FPGA_FME_PORT_ASSIGN, que atribui a porta de volta ao PF. Depois que a porta é liberada do PF, ela pode ser atribuída ao VF por meio das interfaces SR-IOV fornecidas pelo driver PCIe. Para obter mais informações, consulte “Virtualização de FPGA”.

Funções do driver de dispositivo do módulo da plataforma FME

  • Cria o nó de dispositivo de caractere FME.
  • Cria o FME sysfs filese implementa o FME sysfs file acessores.
  • Implementa os subdrivers de recursos privados do FME.
  • Subdrivers de recursos privados do FME:
    • Cabeçalho FME
    • Gestão Térmica
    • Gerenciamento de energia
    • Erro global
    • Reconfiguração Parcial
    • Desempenho Global

Driver de dispositivo do módulo de plataforma portuária
Semelhante ao driver FME, o driver da porta FPGA (e AFU) (intel-fpga-afu. ko) é testado assim que o dispositivo da plataforma da porta é criado. A principal função deste módulo é fornecer uma interface para aplicativos de espaço de usuário para acessar os aceleradores individuais, incluindo controle básico de redefinição na porta, exportação de região AFU MMIO, serviço de mapeamento de buffer DMA, notificação UMsg(1) e funções de depuração remota ( Veja acima).

O UMsg é compatível apenas com o Acceleration Stack para o processador Intel Xeon® com FPGA integrado.

Funções do driver de dispositivo do módulo de plataforma portuária

  • Cria o nó de dispositivo de caractere de porta.
  • Cria o sysfs da porta files e implementa o Port sysfs file acessores.
  • Implementa os subdrivers do recurso privado da porta.
  • Subdrivers de recurso privado de porta:
    • Cabeçalho da porta
    • AFU
    • Erro de porta
    • UMsg(2)
    • Toque de sinal

Enumeração de dispositivo FPGA de aplicativo
Esta seção apresenta como os aplicativos enumeram o dispositivo FPGA da hierarquia sysfs em /sys/class/fpga. no exampNo arquivo abaixo, dois dispositivos Intel FPGA estão instalados no host. Cada dispositivo FPGA possui um FME e duas portas (AFUs). Para cada dispositivo FPGA, um diretório de dispositivo é criado em /sys/class/fpga:

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

Cada nó possui um FME e duas portas (AFUs) como dispositivos filhos:
/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

Em geral, as interfaces FME/Port sysfs são nomeadas da seguinte forma:
/sys/class/fpga/intel-fpga-dev.i/intel-fpga-fme.j/
/sys/class/fpga/intel-fpga-dev.i/intel-fpga-port.k/

com I numerando consecutivamente todos os dispositivos de contêiner, j numerando consecutivamente os FMEs ek numerando consecutivamente todas as portas.

Os nós de dispositivo usados ​​para ioctl() e mmap() podem ser referenciados por meio de:
/dev/intel-fpga-fme.j
/dev/intel-fpga-port.k

Enumeração do Driver PCIe
Esta seção oferece uma visãoview do fluxo de código para enumeração de dispositivos realizada por intel-fpga-pci.ko. As principais estruturas e funções de dados são destacadas. Esta seção é melhor seguida quando viewing o código-fonte que acompanha (pcie.c).

Estruturas de dados de enumeração

enumeração fpga_id_type {
ID_PAI,
ID_FME,
PORTA_ID,
ID_MÁXIMO_FPGA
};
idr de estrutura estática fpga_ids[FPGA_ID_MAX];
estrutura fpga_chardev_info {
const char * name;
dev_t dev;
};
estrutura fpga_chardev_info fpga_chrdevs[] = {
{ .nome = FPGA_FEATURE_DEV_FME },
{ .nome=FPGA_FEATURE_DEV_PORT },
};
classe struct estática *fpga_class;
estrutura estática pci_device_id cci_pcie_id_tbl[] = {
{PCI_DEVICE(ID_DO_VENDEDOR_PCI_INTEL, ID_DO_DISPOSITIVO_PCIe_RCiEP0_MCP),},
{PCI_DEVICE(ID_DO_VENDEDOR_PCI_INTEL, ID_DO_DISPOSITIVO_PCIe_VF_MCP),},
{PCI_DEVICE(ID_DO_VENDEDOR_PCI_INTEL, ID_DO_DISPOSITIVO_PCIe_RCiEP0_SKX_P),},
{PCI_DEVICE(ID_DO_VENDEDOR_PCI_INTEL, ID_DO_DISPOSITIVO_PCIe_VF_SKX_P),},
{PCI_DEVICE(ID_DO_VENDEDOR_PCI_INTEL, ID_DO_DISPOSITIVO_PCIe_RCiEP0_DCP),},
{PCI_DEVICE(ID_DO_VENDEDOR_PCI_INTEL, ID_DO_DISPOSITIVO_PCIe_VF_DCP),},
{0,}
};
struct estático pci_driver cci_pci_driver = {
.nome = DRV_NAME,
.id_table = cci_pcie_id_tbl,
.probe = cci_pci_probe,
.remover = cci_pci_remove,
.sriov_configure = cci_pci_sriov_configure
};
estrutura cci_drvdata {
int dispositivo_id;
dispositivo de estrutura *fme_dev;
struct bloqueio mutex;
estrutura list_head port_dev_list;
int release_port_num;
struct list_head regiões;
};
estrutura build_feature_devs_info {
estrutura pci_dev *pdev;
vazio __iomem *ioaddr;
vazio __iomem *ioend;
int barra_atual;
vazio __iomem *pfme_hdr;
dispositivo de estrutura *parent_dev;
estrutura platform_device *feature_dev;
};

Fluxo de Enumeração

  • ccidrv_init()
    • Inicialize fpga_ids usando idr_init().
    • Inicialize fpga_chrdevs[i].devt usando alloc_chrdev_region().
    • Inicialize fpga_class usando class_create().
    • pci_register_driver(&cci_pci_driver);
  • cci_pci_probe()
    • Habilite o dispositivo PCI, solicite acesso a suas regiões, defina o modo mestre PCI e configure o DMA.
  • cci_pci_create_feature_devs() construir_info_alloc_and_init()
    • Aloque um struct build_feature_devs_info, inicialize-o.
      .parent_dev é definido como um diretório pai sysfs (intel-fpga-dev.id) que contém os diretórios FME e Port sysfs.
  • analisar_lista_de_recursos()
    • Percorra a lista de recursos do dispositivo BAR0 para descobrir o FME, a porta e seus recursos privados.
  • analisar_recurso() analisar_recurso_afus() analisar_recurso_fme()
    • Quando um FME é encontrado:
  • build_info_create_dev()
    • Aloque um dispositivo de plataforma para o FME, armazenando em build_feature_devs_info.feature_dev.
    • feature_dev.id é inicializado com o resultado de idr_alloc(fpga_ids[FME_ID],
    • feature_dev.parent é definido como build_feature_devs_info.parent_dev.
    • Aloque uma matriz de recursos struct em feature_dev.resource.
  • Aloque um struct feature_platform_data, inicialize-o e armazene um ponteiro em feature_dev.dev.platform_data
    • criar_instância_de_recurso() construir_info_adicionar_sub_recurso()
    • Inicialize feature_dev.resource[FME_FEATURE_ID_HEADER].
    • feature_plataforma_dados_adicionar()
    • Inicialize feature_platform_data.features[FME_FEATURE_ID_HEADER], tudo menos .fops.
  • analisar_recurso() analisar_recurso_afus() analisar_recurso_porta()
    • Quando uma porta é encontrada:
  • build_info_create_dev()
    • Aloque um dispositivo de plataforma para o Port, armazenando em build_feature_devs_info.feature_dev.
    • feature_dev.id é inicializado com o resultado de idr_alloc(fpga_ids[PORT_ID],
    • feature_dev.parent é definido como build_feature_devs_info.parent_dev.
    • Aloque uma matriz de recurso struct em feature_dev.resource.
    • Aloque um struct feature_platform_data, inicialize-o e armazene um ponteiro em feature_dev.dev.platform_data
  • build_info_commit_dev()
    • Adicione o struct feature_platform_data.node para a porta à lista de portas em struct cci_drvdata.port_dev_list
  • criar_instância_de_recurso() construir_info_adicionar_sub_recurso()
    • Inicialize feature_dev.resource[PORT_FEATURE_ID_HEADER].
  • feature_plataforma_dados_adicionar()
    • Inicialize feature_platform_data.features[PORT_FEATURE_ID_HEADER], tudo menos .fops.
  • parse_feature() parse_feature_afus() parse_feature_port_uafu()
    • Quando uma AFU é encontrada:
  • criar_instância_de_recurso() construir_info_adicionar_sub_recurso()
    • Inicialize feature_dev.resource[PORT_FEATURE_ID_UAFU].
  • feature_plataforma_dados_adicionar()
    • Inicialize feature_platform_data.features[PORT_FEATURE_ID_UAFU], tudo menos .fops.
  • analisar_recurso() analisar_recurso_privado() analisar_recurso_fme_privado()
    • Quando um recurso privado do FME é encontrado:
  • criar_instância_de_recurso() construir_info_adicionar_sub_recurso()
    • Inicialize feature_dev.resource[id].
  • feature_plataforma_dados_adicionar()
    • Inicialize feature_platform_data.features[id], tudo menos .fops.
  • analisar_recurso() analisar_recurso_privado() analisar_recurso_porta_privada()
  • Quando um recurso privado de porta é encontrado: * create_feature_instance() build_info_add_sub_feature() * Inicialize feature_dev.resource[id]. * feature_platform_data_add() Inicializar feature_platform_data.features[id], tudo menos .fops.
  • analisar_portas_de_fme()
    • Se o driver estiver carregado na Função Física (PF), então:
  • Execute o fluxo parse_feature_list() em cada porta descrita no cabeçalho FME.
  • Use a BAR mencionada em cada entrada de porta no cabeçalho.

Inicialização do Dispositivo da Plataforma FME
Esta seção oferece uma visãoview do fluxo de código para a inicialização do dispositivo FME realizada por intel-fpga-fme.ko. As principais estruturas e funções de dados são destacadas. Esta seção é melhor seguida quando viewing o código-fonte que acompanha (fme-main.c).

Estruturas de dados do dispositivo da plataforma FME

estrutura feature_ops {
int (*init)(struct platform_device *pdev, struct feature *feature);
int (*uinit)(struct platform_device *pdev, struct feature *feature);
longo (*ioctl)(struct platform_device *pdev, struct feature *feature,
cmd int não assinado, argumento longo não assinado);
int (*teste)(struct platform_device *pdev, struct feature *feature);
};
recurso de estrutura {
const char * name;
int índice_de_recursos;
vazio __iomem *ioaddr;
estrutura feature_ops *ops;
};
estrutura feature_platform_data {
struct list_head nó;
struct bloqueio mutex;
dev_status longo não assinado;
estrutura cdev cdev;
estrutura dispositivo_plataforma *dev;
unsigned int desativar_contagem;
vazio *privado;
número inteiro;
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 *)); estrutura
recurso recursos[0];
};
estrutura perf_object {
você mão;
const struct atributos_grupo **attr_groups;
dispositivo de estrutura *fme_dev;
struct list_head nó;
struct list_head filhos;
estrutura kobject kobj;
};
estrutura fpga_fme {
u8 porta_id;
u64 pr_err;
dispositivo de estrutura *dev_err;
estrutura perf_object *perf_dev;
estrutura feature_platform_data *pdata;
};

Fluxo de inicialização do dispositivo da plataforma FME

Fluxo de Inicialização FMEintel-OPAE-FPGA-Linux-Device-Driver-Arquitetura-fig- (4)

  • fme_probe() fme_dev_init()
    • Inicialize um struct fpga_fme e armazene-o no campo feature_platform_data.private.
  • fme_probe() fpga_dev_feature_init() recurso_instance_init()
    • Salve um struct feature_ops no feature_platform_data.features para cada recurso preenchido.
    • Chame a função de teste, se houver, da estrutura.
    • Chame a função init da estrutura.
  • fme_probe() fpga_register_dev_ops()
    • Crie o nó de dispositivo de caractere FME, registrando uma estrutura file_operações.

Inicialização do Dispositivo da Plataforma Portuária
Esta seção oferece uma visãoview do fluxo de código para a inicialização do dispositivo de porta realizada por intel-fpga-afu.ko. As principais estruturas e funções de dados são destacadas. Esta seção é melhor seguida quando viewing o código-fonte que acompanha (afu.c).

Estruturas de dados do dispositivo da plataforma portuária

estrutura feature_ops {
int (*init)(struct platform_device *pdev, struct feature *feature);
int (*uinit)(struct platform_device *pdev, struct feature *feature);
longo (*ioctl)(struct platform_device *pdev, struct feature *feature,
cmd int não assinado, argumento longo não assinado);
int (*teste)(struct platform_device *pdev, struct feature *feature);
};
recurso de estrutura {
const char * name;
int índice_de_recursos;
vazio __iomem *ioaddr;
estrutura feature_ops *ops;
};
estrutura feature_platform_data {
struct list_head nó;
struct bloqueio mutex;
dev_status longo não assinado;
estrutura cdev cdev;
estrutura dispositivo_plataforma *dev;
unsigned int desativar_contagem;
vazio *privado;
número inteiro;
int (*config_port)(struct platform_device *, u32, bool);
struct platform_device *(*fpga_for_each_port)(struct platform_device *,
void *, int (*correspondência)(struct platform_device *, void *));
recursos de recurso de estrutura[0];
};
estrutura fpga_afu_region {
índice u32;
bandeiras u32;
tamanho u64;
deslocamento u64;
u64 fis;
struct list_head nó;
};
estrutura fpga_afu_dma_region {
u64 endereço_usuário;
comprimento u64;
u64iova;
página de estrutura **páginas;
struct rb_node nó;
bool em_uso;
};
estrutura fpga_afu {
u64 região_cur_offset;
int num_regiões;
u8 num_umsgs;
struct list_head regiões;
estrutura rb_root dma_regions;
estrutura feature_platform_data *pdata;
};

Fluxo de inicialização do dispositivo da plataforma portuária

Fluxo de inicialização da portaintel-OPAE-FPGA-Linux-Device-Driver-Arquitetura-fig- (5)

  • afu_probe() afu_dev_init()
    • Inicialize um struct fpga_afu e armazene-o no campo feature_platform_data.private.
  • afu_probe() fpga_dev_feature_init() recurso_instance_init()
    • Salve um struct feature_ops no feature_platform_data.features para cada recurso preenchido.
    • Chame a função de teste, se houver, da estrutura.
    • Chame a função init da estrutura.
  • afu_probe() fpga_register_dev_ops()
    • Crie o nó de dispositivo de caractere de porta, registrando uma estrutura file_operações.

IOCTLs FME
IOCTLs que são chamados em um servidor aberto file descritor para /dev/intel-fpga-fme.j FPGA_GET_API_VERSION — retorna a versão atual como um número inteiro, começando em 0.

FPGA_CHECK_EXTENSION—não suportado atualmente.

FPGA_FME_PORT_RELEASE—arg é um ponteiro para um:

estrutura fpga_fme_port_release {
__u32 argsz; // em: sizeof(struct fpga_fme_port_release)
__sinalizadores u32; // in: deve ser 0
__u32 port_id; // in: ID da porta (de 0) para liberação.
};

FPGA_FME_PORT_ASSIGN—arg é um ponteiro para um:

estrutura fpga_fme_port_assign {
__u32 argsz; // em: sizeof(struct fpga_fme_port_assign)
__sinalizadores u32; // in: deve ser 0
__u32 port_id; // in: ID da porta (de 0) para atribuir. (deve ter sido
lançado anteriormente por FPGA_FME_PORT_RELEASE)
};

FPGA_FME_PORT_PR—arg é um ponteiro para um:

estrutura fpga_fme_port_pr {
__u32 argsz; // em: sizeof(struct fpga_fme_port_pr)
__sinalizadores u32; // in: deve ser 0
__u32 port_id; // em: ID da porta (de 0)
__u32 buffer_size; // in: tamanho do buffer bitstream em bytes. Deve ter 4 bytes
alinhado.
__u64 buffer_address; // in: endereço do processo do buffer bitstream
__u64 status; // out: status de erro (bitmask)
};

IOCTLs de porta
IOCTLs que são chamados em um servidor aberto file descritor para /dev/intel-fpga-port.k FPGA_GET_API_VERSION—retorna a versão atual como um número inteiro, começando em 0. FPGA_CHECK_EXTENSION—não suportado atualmente.

FPGA_PORT_GET_INFO—arg é um ponteiro para um:

estrutura fpga_port_info {
__u32 argsz; // em: sizeof(struct fpga_port_info)
__sinalizadores u32; // fora: retorna 0
__u32 num_regions; // out: número de regiões MMIO, 2 (1 para AFU e 1 para
STP)
__u32 num_umsgs; // out: número de UMsg's suportados pelo hardware
};

FPGA_PORT_GET_REGION_INFO—arg é um ponteiro para um:

estrutura fpga_port_region_info {
__u32 argsz; // em: sizeof(struct fpga_port_region_info)
__sinalizadores u32; // out: (bitmask) { FPGA_REGION_READ, FPGA_REGION_WRITE,
} FPGA_REGION_MMAP }
__u32 índice; // em: FPGA_PORT_INDEX_UAFU ou FPGA_PORT_INDEX_STP
preenchimento __u32; // in: deve ser 0
__tamanho u64; // out: tamanho da região MMIO em bytes
__u64 offset; // out: deslocamento da região MMIO desde o início do dispositivo fd
};

FPGA_PORT_DMA_MAP—arg é um ponteiro para um:
estrutura fpga_port_dma_map {
__u32 argsz; // em: sizeof(struct fpga_port_dma_map)
__sinalizadores u32; // in: deve ser 0 __u64 user_addr; // em: processo virtual
endereço. Deve estar alinhado à página.
__u64 comprimento; // in: comprimento do mapeamento em bytes. Deve ser um múltiplo da página
tamanho.
__u64 iova; // out: endereço virtual IO };

FPGA_PORT_DMA_UNMAP—arg é um ponteiro para um:
estrutura fpga_port_dma_unmap {
__u32 argsz; // em: sizeof(struct fpga_port_dma_unmap)
__sinalizadores u32; // in: deve ser 0
__u64 iova; // in: endereço virtual IO retornado por um anterior
MAPA_DMA_DA_PORTA_FPGA };

  • FPGA_PORT_RESET—arg deve ser NULL.
  • FPGA_PORT_UMSG_ENABLE—arg deve ser NULL.
  • FPGA_PORT_UMSG_DISABLE—args deve ser NULL.

FPGA_PORT_UMSG_SET_MODE—arg é um ponteiro para um:

estrutura fpga_port_umsg_cfg {
__u32 argsz; // em: sizeof(struct fpga_port_umsg_cfg)
__sinalizadores u32; // in: deve ser 0
__u32 dica_bitmap; // em: bitmap do modo de dica UMsg. Significa quais UMsg's são
habilitado.
};

FPGA_PORTA_UMSG_SET_BASE_ADDR—

  • UMsg deve ser desabilitado antes de emitir este ioctl.
  • O campo iova deve ser para um buffer grande o suficiente para todos os UMsg's (num_umsgs * PAGE_SIZE).
    • O buffer é marcado como “em uso” pelo gerenciamento de buffer do driver.
    • Se iova for NULL, qualquer região anterior será desmarcada como “em uso”.
  • arg é um ponteiro para a:
    estrutura fpga_port_umsg_base_addr {
    • u32 argsz; // em: sizeof(struct fpga_port_umsg_base_addr)
    • bandeiras u32; // in: deve ser 0
    • u64 iova; // em: endereço virtual IO de FPGA_PORT_DMA_MAP. };

Observação:

  • Para limpar os erros de porta, você deve escrever a máscara de bits exata dos erros atuais, por exemploample, erros de gato > limpar
  • O UMsg só é compatível com o Acceleration Stack para o processador Intel Xeon com FPGA integrado.

sysfs Files

Cabeçalho FME sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/

sysfs file campo mmio tipo acesso
portas_num fme_header.capability.num_portas inteiro decimal Somente leitura
tamanho_do_cache fme_header.capacidade.tamanho_do_cache inteiro decimal Somente leitura
versão fme_header.capacidade.fabric_verid inteiro decimal Somente leitura
soquete_id fme_header.capacidade.id_socket inteiro decimal Somente leitura
ID do fluxo de bits fme_header.bitstream_id hexadecimal uint64_t Somente leitura
metadados_de_fluxo_de_bits fme_header.bitstream_md hexadecimal uint64_t Somente leitura

Sistemas de gerenciamento térmico FME files
intel-fpga-dev.i/intel-fpga-fme.j/thermal_mgmt/

sysfs file campo mmio tipo acesso
limiar1 térmico.limiar.tmp_thshold1 inteiro decimal Usuário: somente leitura Raiz: leitura/gravação
limiar2 térmico.limiar.tmp_thshold2 inteiro decimal Usuário: somente leitura Raiz: leitura/gravação
viagem_limite térmico.limiar.therm_trip_thshold inteiro decimal Somente leitura
limite1_alcançado térmico.limiar.thshold1_status inteiro decimal Somente leitura
limite2_alcançado térmico.limiar.thshold2_status inteiro decimal Somente leitura
limite1_politica térmico. threshold.thshold_policy inteiro decimal Usuário: somente leitura Raiz: leitura/gravação
temperatura térmica.rdsensor_fm1.fpga_temp inteiro decimal Somente leitura

Sistemas de gerenciamento de energia FME files
intel-fpga-dev.i/intel-fpga-fme.j/power_mgmt/

sysfs file campo mmio tipo acesso
consumido energia.status.pwr_consumido hexadecimal uint64_t Somente leitura
limiar1 potência.limiar.limite1 hexadecimal uint64_t Usuário: somente leitura Raiz: leitura/gravação
limiar2 potência.limiar.limite2 hexadecimal uint64_t Usuário: somente leitura Raiz: leitura/gravação
limite1_status poder.limite.limite1_status decimal sem sinal Somente leitura
limite2_status poder.limite.limite2_status decimal sem sinal Somente leitura
rtl poder.status.relatório_de_latência_fpga decimal sem sinal Somente leitura

FME Erro Global sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/errors/

sysfs file campo mmio tipo acesso
pcie0_erros gerror.pcie0_err hexadecimal uint64_t Ler escrever
pcie1_erros gerror.pcie1_err hexadecimal uint64_t Ler escrever
erro_de_injeção gerror.ras_error_inj hexadecimal uint64_t Ler escrever

intel-fpga-dev.i/intel-fpga-fme.j/erros/erros-do-fme/

sysfs file campo mmio tipo acesso
erros gerror.fme_err hexadecimal uint64_t Somente leitura
primeiro_erro gerror.fme_primeiro_erro.err_reg_status hexadecimal uint64_t Somente leitura
próximo_erro gerror.fme_next_err.err_reg_status hexadecimal uint64_t Somente leitura
claro Limpa erros, first_error, next_error vários uint64_t Somente gravação

Observação:
Para limpar os erros FME, você deve escrever o bitmask exato dos erros atuais, por exemploample cat errors > limpar.

FME Reconfiguração Parcial sysfs files
intel-fpga-dev.i/intel-fpga-fme.j/pr/

sysfs file campo mmio tipo acesso
id_da_interface pr.fme_pr_intfc_id0_h, pr.fme_pre_intfc_id0_l hexadecimal de 16 bytes Somente leitura

Sistemas de Desempenho Global FME files
intel-fpga-dev.i/intel-fpga-fme.j/dperf/clock

sysfs file campo mmio tipo acesso
relógio gperf.clk.afu_interf_clock hexadecimal uint64_t Somente leitura

intel-fpga-dev.i/intel-fpga-fme.j/dperf/cache/ (Não válido para pilha de aceleração para CPU Intel Xeon com FPGAs)

sysfs file campo mmio tipo acesso
congelar gperf.ch_ctl.freeze inteiro decimal Ler escrever
leitura_hit gperf.CACHE_RD_HIT hexadecimal uint64_t Somente leitura
leitura_miss gperf.CACHE_RD_MISS hexadecimal uint64_t Somente leitura
escrever_hit gperf.CACHE_WR_HIT hexadecimal uint64_t Somente leitura
escrever_miss gperf.CACHE_WR_MISS hexadecimal uint64_t Somente leitura
solicitação_de_espera gperf.CACHE_HOLD_REQ hexadecimal uint64_t Somente leitura
tx_req_stall gperf.CACHE_TX_REQ_STALL hexadecimal uint64_t Somente leitura
sysfs file campo mmio tipo acesso
rx_req_stall gperf.CACHE_RX_REQ_STALL hexadecimal uint64_t Somente leitura
contenção_de_porta_de_gravação_de_dados gperf.CACHE_DATA_WR_PORT_CONTEN hexadecimal uint64_t Somente leitura
tag_escrever_contenção_de_porta gperf.CACHE_TAG_WR_PORT_CONTEÚDO hexadecimal uint64_t Somente leitura

intel-fpga-dev.i/intel-fpga-fme.j/dperf/iommu/ (Não válido para pilha de aceleração para CPU Intel Xeon com FPGAs)

sysfs file campo mmio tipo acesso
congelar gperf.vtd_ctl.congelar inteiro decimal Usuário: somente leitura Raiz: leitura/gravação

intel-fpga-dev.i/intel-fpga-fme.j/dperf/iommu/afuk/ (Não válido para pilha de aceleração para CPU Intel Xeon com FPGAs)

sysfs file campo mmio tipo acesso
leitura_transação gperf.VTD_AFU0_MEM_RD_TRANS hexadecimal uint64_t Somente leitura
gravação_transação gperf.VTD_AFU0_MEM_WR_TRANS hexadecimal uint64_t Somente leitura
tlb_leitura_acertada gperf.VTD_AFU0_TLB_RD_HIT hexadecimal uint64_t Somente leitura
tlb_escrever_acerto gperf.VTD_AFU0_TLB_WR_HIT hexadecimal uint64_t Somente leitura

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

sysfs file campo mmio tipo acesso
habilitar gperf.fab_ctl.(ativado) inteiro decimal Usuário: somente leitura Raiz: leitura/gravação
congelar gperf.fab_ctl.freeze inteiro decimal Usuário: somente leitura Raiz: leitura/gravação
pcie0_leitura gperf.FAB_PCIE0_RD hexadecimal uint64_t Somente leitura
pcie0_escrever gperf.FAB_PCIE0_WR hexadecimal uint64_t Somente leitura
pcie1_leitura gperf.FAB_PCIE1_RD hexadecimal uint64_t Somente leitura
pcie1_escrever gperf.FAB_PCIE1_WR hexadecimal uint64_t Somente leitura
upi_leitura gperf.FAB_UPI_RD hexadecimal uint64_t Somente leitura
upi_escrever gperf.FAB_UPI_WR hexadecimal uint64_t Somente leitura

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

sysfs file campo mmio tipo acesso
pcie0_leitura gperf.FAB_PCIE0_RD hexadecimal uint64_t Somente leitura
pcie0_escrever gperf.FAB_PCIE0_WR hexadecimal uint64_t Somente leitura
pcie1_leitura gperf.FAB_PCIE1_RD hexadecimal uint64_t Somente leitura
pcie1_escrever gperf.FAB_PCIE1_WR hexadecimal uint64_t Somente leitura
upi_leitura gperf.FAB_UPI_RD hexadecimal uint64_t Somente leitura
upi_escrever gperf.FAB_UPI_WR hexadecimal uint64_t Somente leitura

Cabeçalho da porta sysfs files
intel-fpga-dev.i/intel-fpga-port.k/

sysfs file campo mmio tipo acesso
id port_header.capacidade.número_porta inteiro decimal Somente leitura
litros port_header.control.latency_tolerance inteiro decimal Somente leitura

Cabeçalho AFU da porta sysfs files
intel-fpga-dev.i/intel-fpga-port.k/

sysfs file campo mmio tipo acesso
afu_id afu_header.guid hexadecimal de 16 bytes Somente leitura

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

sysfs file campo mmio tipo acesso
erros perror.porta_erro hexadecimal uint64_t Somente leitura
primeiro_erro perror.porta_primeiro_erro hexadecimal uint64_t Somente leitura
primeiro_malformado_req erro.malreq hexadecimal de 16 bytes Somente leitura
claro perror.(todos os erros) vários uint64_t Somente gravação

Observação:
Para limpar os erros de porta, você deve escrever o bitmask exato dos erros atuais, por exemploample cat errors > limpar.

Histórico de revisão

Versão do documento Mudanças
2017.10.02 Lançamento inicial.

Guia de arquitetura de driver de dispositivo Linux OPAE Intel FPGA

Documentos / Recursos

Arquitetura de driver de dispositivo Linux intel OPAE FPGA [pdf] Guia do Usuário
Arquitetura de driver de dispositivo Linux OPAE FPGA, OPAE FPGA, arquitetura de driver de dispositivo Linux, arquitetura de driver, arquitetura

Referências

Deixe um comentário

Seu endereço de e-mail não será publicado. Os campos obrigatórios estão marcados *