Noyau Linux 2.6
J'ai un fpga qui est chargé sur GPIO connecté à une carte de développement exécutant linux. Le fpga transmettra et recevra des données via le bus pci-express. Cependant, cela est énuméré au démarrage et en tant que tel, aucun lien n'est découvert (car le fpga n'est pas chargé au démarrage).
Comment puis-je forcer la ré-énumération du bus PCI-E sous Linux? Existe-t-il une commande simple ou vais-je devoir apporter des modifications au noyau? J'ai besoin de pouvoir brancher à chaud des périphériques PCIE.
Je me demande sur quelle plate-forme vous vous trouvez: un contournement (ou hack) pour cela qui fonctionne sur les systèmes x86 est que le BIOS configure essentiellement statiquement un périphérique PCI sur n'importe quel bus, périphérique, fonction sur laquelle le FPGA atterrit normalement, puis le système d'exploitation énumérer le périphérique et lui réserver l'espace PCI (même si le périphérique n'est pas vraiment là). Ensuite, dans votre pilote de périphérique, vous devrez faire des choses supplémentaires comme configurer les BARRES et les lignes int manuellement après la programmation du fpga. Bien sûr, cela nécessite de modifier le BIOS, qui si vous travaillez avec un fournisseur de BIOS, vous pouvez les contracter pour effectuer cette modification pour vous, si vous ne travaillez pas avec un fournisseur de BIOS, cela sera beaucoup plus difficile ... Gardez également à l'esprit que je travaillais sur VxWorks sur x86, et nous avions une AMI faire un BIOS personnalisé pour nos cartes ...
Si vous n'avez pas de BIOS, alors envisagez de le programmer dans le chargeur de démarrage, vous avez déjà la possibilité de lire à partir du disque, et l'ajout de capacités GPIO n'est probablement pas trop difficile (en supposant que vous utilisez jtag et GPIO?), Dans En fait, selon le chargeur de démarrage que vous utilisez, il pourrait déjà être capable de faire GPIO?
Les problèmes avec la modification du noyau pour ce faire est que vous devez trouver le bon endroit où vous pouvez lire le fichier bit, avant l'énumération PCI ... Si, par exemple, les pilotes de périphérique de disque sont initialisés après PCI, alors vous devez évidemment faire quelques des changements radicaux dans le noyau juste pour lire le fichier bit avant l'énumération PCI, ce qui pourrait causer d'autres problèmes ennuyeux ...
Une autre option que vous avez peut-être déjà découverte et qui n'est vraiment acceptable que pour le temps de développement: allumez le système, programmez la carte fpga, puis faites une réinitialisation (sans cycle d'alimentation, par exemple: Sudo reboot now), le FPGA devrait garder sa configuration, et linux devrait l'énumérer ...
En tant que root, essayez la commande suivante:
echo "1" > /sys/bus/pci/rescan
Voir ce lien pour plus d'informations: http://www.kernel.org/doc/Documentation/ABI/testing/sysfs-bus-pci
Après avoir allumé votre ordinateur, le BIOS énumère le bus PCI et tente de répondre à toutes les demandes IO espace et mémoire mappés IO (MMIO)). Il configure ces Les BAR sont initialement, et lorsque le système d'exploitation se charge, ces BAR peuvent être modifiés par le système d'exploitation comme bon lui semble tandis que le pilote de bus PCI énumère à nouveau le bus. Il est même possible pour le superutilisateur du système d'exécuter la commande setpci
pour modifier ces BARS après que le BIOS a déjà tenté de les configurer et que le système d'exploitation a été chargé (peut entraîner l'échec des pilotes et plusieurs autres mauvaises choses s'il n'est pas fait correctement).
J'ai dû le faire dans les cas où la carte en question n'a pas été affectée de ressources par le BIOS car la région demandée nécessite une adresse 64 bits et le BIOS ne fonctionnait qu'avec des attributions d'adresses 32 bits. J'ai pu aller après-coup et changer ces adresses (initialement attribuées par le BIOS) à toutes les adresses que je jugeais appropriées, insérer le module du noyau, et mon pilote mapperait et utiliserait ces adresses nouvellement attribuées pour la carte sans connaître la différence.
Le problème qui existe avec le branchement à chaud des cartes PCI-Express est que l'alimentation de l'emplacement, lui-même, ne peut pas être activée/désactivée sans contrôleurs de branchement à chaud spécifiques qui doivent exister sur la carte mère/le fond de panier. Le fait de ne pas avoir ces contrôleurs de connexion à chaud pour éteindre le logement peut entraîner des courts-circuits entre les minuscules broches lorsque la carte est physiquement insérée et/ou retirée si l'alimentation est toujours présente. Cependant, les événements de connexion à chaud peuvent être déclenchés par l'une ou l'autre extrémité (l'hôte o le périphérique d'extrémité). Cela ne semble pas être le cas, mais si votre FPGA a déjà un lien établi avec le complexe racine, une solution possible à votre problème serait de générer des interruptions de branchement à chaud pour provoquer une nouvelle analyse du bus dans le système d'exploitation.
Il existe cependant un problème majeur - si votre carte n'obtient pas réellement de lien vers le complexe racine, elle ne pourra pas générer d'événements de connexion à chaud; ce qui semble être le cas. Après le démarrage, le FPGA doit basculer la ligne PRÉSENTE sur le bus PCIe pour indiquer au système d'exploitation qu'une carte est prête à être énumérée. Une fois détecté, le système d'exploitation devrait tenter d'établir un lien avec la carte et attribuer des régions de mémoire à l'appareil. Une fois que le système d'exploitation a énuméré la carte, vous pourrez charger des pilotes et la voir dans lspci
. Vous avez déclaré que vous utilisez le noyau 2.6, qui prend en charge le branchement à chaud et l'allocation dynamique des ressources, de sorte que cette méthode devrait fonctionner aussi longtemps que votre FPGA prend également en charge la possibilité de basculer la ligne PRESENT PCIe.