linux configure fpga pci-e

¿Cómo se puede obligar al kernel de Linux a enumerar el bus PCI-e?



configure fpga (3)

Kernel de linux 2.6

Tengo un fpga que se carga a través de GPIO conectado a una placa de desarrollo que ejecuta Linux. El fpga transmitirá y recibirá datos a través del bus pci-express. Sin embargo, esto se enumera en el arranque y, como tal, no se descubre ningún enlace (porque el fpga no se carga en el arranque).

¿Cómo puedo forzar la re-enumeración del bus pci-e en linux? ¿Hay un comando simple o tendré que hacer cambios en el kernel? Necesito la capacidad para hotplug dispositivos pcie.



Después de encender su computadora, el BIOS enumera el bus PCI e intenta cumplir con todas las solicitudes de IO (MMIO) de espacio de IO y memoria asignada. Establece estos BAR''s inicialmente, y cuando el sistema operativo se carga, el sistema operativo puede cambiar estos BAR''s según lo considere conveniente, mientras que el controlador de bus PCI enumera el bus nuevamente. Incluso es posible que el superusuario del sistema ejecute el comando setpci para cambiar estos BAR después de que el BIOS ya haya intentado configurarlos y el sistema operativo se haya cargado (puede causar fallas en los controladores y varias otras cosas malas si se hace incorrectamente).

He tenido que hacer esto en los casos en que la BIOS no asignó ningún recurso a la tarjeta en cuestión, ya que la región solicitada requería una dirección de 64 bits y la BIOS solo funcionaba con asignaciones de direcciones de 32 bits. Pude ingresar después del hecho y cambiar estas direcciones (originalmente asignadas por el BIOS) a cualquier dirección que considerara adecuada, insertar el módulo del kernel y mi controlador asignaría y utilizaría estas direcciones recién asignadas para la tarjeta sin sabiendo la diferencia

El problema que existe con las tarjetas PCI-Express de conexión en caliente es que la alimentación a la ranura, en sí misma, no se puede activar / desactivar sin los controladores específicos de conexión en caliente que deben existir en la placa base / placa posterior. No tener estos controladores de conexión en caliente para apagar la ranura de la ranura puede ocasionar cortocircuitos entre las pequeñas clavijas cuando la tarjeta se inserta físicamente y / o se retira si todavía hay energía. Sin embargo, los eventos de conexión en caliente pueden iniciarse por cualquiera de los extremos (el host o el dispositivo de punto final). Este no parece ser el caso, sin embargo, si su FPGA ya tiene un enlace establecido con el complejo raíz, una posible solución a su problema sería generar interrupciones de conexión en caliente para provocar una reexploración del bus en el sistema operativo.

Sin embargo, existe un problema importante: si su tarjeta no obtiene realmente un enlace al complejo raíz, no podrá generar ningún evento de conexión en caliente; lo que parece ser el caso. Después de iniciar, el FPGA debe alternar la línea PRESENTE en el bus PCIe para indicar al sistema operativo que hay una tarjeta lista para ser enumerada. Una vez detectado, el sistema operativo debe intentar establecer un enlace a la tarjeta y asignar regiones de memoria al dispositivo. Después de que el sistema operativo enumere la tarjeta, podrá cargar controladores contra ella y verla en lspci . Usted indicó que está usando el kernel 2.6, que tiene soporte para la conexión dinámica y la asignación dinámica de recursos, por lo que este método debería funcionar siempre que su FPGA admita la capacidad de alternar la línea PRESENTE PCIe.


Me pregunto en qué plataforma se encuentra: una solución alternativa (también conocida como pirateo) para esto que funciona en sistemas x86 es hacer que el BIOS básicamente configure de forma estática un dispositivo PCI en cualquier bus, dispositivo, función en la que FPGA normalmente aterrice, entonces el sistema operativo enumere el dispositivo y reserve el espacio PCI para él (aunque el dispositivo no esté realmente allí). Luego, en el controlador de su dispositivo, tendrá que hacer algunas cosas adicionales como configurar los BAR y las líneas int manualmente después de que se haya programado el fpga. Por supuesto, esto requiere modificar el BIOS, que si está trabajando con un proveedor de BIOS puede contratarlos para hacer este cambio por usted, si no está trabajando con un proveedor de BIOS, entonces será mucho más difícil ... También tenga en cuenta que estaba trabajando en VxWorks en x86, y tuvimos un AMI que creó un BIOS personalizado para nuestros tableros ...

Si no tiene un BIOS, entonces considere programarlo en el gestor de arranque, ya tiene la capacidad de leer desde el disco, y agregar las capacidades de GPIO probablemente no sea demasiado difícil (asumiendo que está usando jtag y GPIOs?), En ¿De acuerdo con el cargador de arranque que use, es posible que ya pueda hacer GPIO?

Los problemas con la modificación del kernel para hacer esto es que tiene que encontrar el punto ideal para leer el archivo de bits, antes de la enumeración de PCI ... Si, por ejemplo, los controladores de dispositivos de disco se inicializan después de PCI, entonces obviamente debe cambios radicales en el kernel solo para leer el archivo de bits antes de la enumeración de PCI, lo que podría causar otros problemas molestos ...

Otra opción que quizás ya haya descubierto, y que en realidad solo está bien para el tiempo de desarrollo: encienda el sistema, programe la placa fpga, luego reinicie (sin ciclo de energía, por ejemplo: reinicio de sudo ahora), el FPGA debería mantener su configuración, y Linux debe enumerarlo ...