web-dev-qa-db-fra.com

Qu'est-ce que le registre d'adresses de base (BAR) dans PCIe?

Après avoir parcouru certains documents de base, j'ai compris que le registre d'adresses de base est un espace d'adressage accessible par PCIe IP. PCIe IP peut soit transmettre des données dans le registre d'adresses de base, soit y écrire des données reçues.

Ai-je raison? Ou quelque chose vous manque?

15
tollin jose

Je pense que c'est une question très fondamentale et je suggère de lire:

Un registre d'adresses de base (BAR) est utilisé pour:
- spécifiez la quantité de mémoire qu'un périphérique veut être mappée dans la mémoire principale, et
- après l'énumération du périphérique, il contient l'adresse (de base), où le bloc de mémoire mappé commence.

Un appareil peut avoir jusqu'à six BARRES 32 bits ou combiner deux BARRES à une BARRE 64 bits.

10
Paebbels

Point de vue du noyau Linux

Un bon moyen d'apprendre quelque chose est d'interagir avec lui, alors utilisons le noyau Linux pour cela.

Voici un exemple PCI minimal sur un périphérique émulé QEMU: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/366b1c1af269f56d6a7e6464f2862ba2bc368062/kernel_module/pci.c

Les 64 premiers octets de la configuration PCI sont normalisés comme suit:

enter image description here

Image de LDD3.

On voit donc qu'il y a 6 BARRES. La page wiki montre alors le contenu de chaque BARRE:

enter image description here

La largeur de la région nécessite cependant une écriture magique: Comment la taille d'une BARRE PCI/PCIe est-elle déterminée?

Cette mémoire est configurée par le périphérique PCI et fournit des informations au noyau.

Chaque BAR correspond à une plage d'adresses qui sert de canal de communication distinct au périphérique PCI.

La longueur de chaque région est définie par le matériel et communiquée au logiciel via les registres de configuration.

Chaque région possède également d'autres propriétés définies par le matériel en plus de la longueur, notamment le type de mémoire:

  • IORESOURCE_IO: doit être accessible avec inX et outX
  • IORESOURCE_MEM: doit être accessible avec ioreadX et iowriteX

Plusieurs fonctions PCI du noyau Linux prennent le BAR comme paramètre pour identifier le canal de communication à utiliser, par exemple:

mmio = pci_iomap(pdev, BAR, pci_resource_len(pdev, BAR));
pci_resource_flags(dev, BAR);
pci_resource_start(pdev, BAR);
pci_resource_end(pdev, BAR);

En examinant le code source du périphérique QEMU, nous constatons que les périphériques QEMU enregistrent ces régions avec:

memory_region_init_io(&edu->mmio, OBJECT(edu), &edu_mmio_ops, edu,
                "edu-mmio", 1 << 20);
pci_register_bar(pdev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &edu->mmio);

et il est clair que les propriétés de la BAR sont définies par le matériel, par ex. le numéro BAR 0, a une mémoire de type PCI_BASE_ADDRESS_SPACE_MEMORY, et la zone de mémoire mesure 1 Mo de long 1 << 20.

Voir aussi: http://wiki.osdev.org/PCI#Base_Address_Registers bien sûr.