El espacio de configuración PCI es la forma subyacente en que PCI convencional , PCI-X y PCI Express realizan la configuración automática de las tarjetas insertadas en su bus.
Los dispositivos PCI tienen un conjunto de registros denominados espacio de configuración y PCI Express introduce un espacio de configuración ampliado para los dispositivos. Los registros del espacio de configuración se asignan a las ubicaciones de la memoria. Los controladores de dispositivos y el software de diagnóstico deben tener acceso al espacio de configuración, y los sistemas operativos suelen utilizar API para permitir el acceso al espacio de configuración del dispositivo. Cuando el sistema operativo no tiene métodos de acceso definidos o API para solicitudes de espacio de configuración asignado a la memoria, el controlador o el software de diagnóstico tienen la responsabilidad de acceder al espacio de configuración de una manera que sea compatible con las reglas de acceso subyacentes del sistema operativo. En todos los sistemas, se recomienda que los controladores de dispositivos utilicen las API proporcionadas por el sistema operativo para acceder al espacio de configuración del dispositivo.
Una de las principales mejoras que tuvo el bus local PCI sobre otras arquitecturas de E/S fue su mecanismo de configuración. Además de los espacios normales de puertos de E/S y mapeados en memoria, cada función de dispositivo en el bus tiene un espacio de configuración , que tiene 256 bytes de longitud, al que se puede acceder conociendo los números de bus PCI de ocho bits , dispositivo de cinco bits y función de tres bits para el dispositivo (comúnmente denominados BDF o B/D/F , como abreviatura de bus/dispositivo/función ). Esto permite hasta 256 buses, cada uno con hasta 32 dispositivos, cada uno de los cuales admite ocho funciones. Una sola tarjeta de expansión PCI puede responder como un dispositivo y debe implementar al menos la función número cero. Los primeros 64 bytes del espacio de configuración están estandarizados; el resto está disponible para fines definidos por el proveedor. Algunas computadoras de alta gama admiten más de un dominio PCI (o segmento PCI); cada dominio PCI admite hasta 256 buses.
Para permitir que más partes del espacio de configuración se estandaricen sin entrar en conflicto con los usos existentes, puede haber una lista de capacidades definidas dentro de los 192 bytes restantes del espacio de configuración PCI. Cada capacidad tiene un byte que describe de qué capacidad se trata y un byte que apunta a la siguiente capacidad. La cantidad de bytes adicionales depende del identificador de capacidad. Si se están utilizando capacidades, se establece un bit en el registro de estado y se proporciona un puntero a la primera de una lista enlazada de capacidades en el registro de puntero Cap. definido en los registros estandarizados.
PCI-X 2.0 y PCI Express introdujeron un espacio de configuración extendido, de hasta 4096 bytes. La única parte estandarizada del espacio de configuración extendido son los primeros cuatro bytes en 0x100, que son el comienzo de una lista de capacidades extendidas. Las capacidades extendidas son muy similares a las capacidades normales, excepto que pueden hacer referencia a cualquier byte en el espacio de configuración extendido (usando 12 bits en lugar de ocho), tienen un número de versión de cuatro bits y un ID de capacidad de 16 bits. Los ID de capacidad extendida se superponen con los ID de capacidad normales, pero no hay posibilidad de confusión ya que están en listas separadas.
Los registros de ID de dispositivo (DID) e ID de proveedor (VID) identifican el dispositivo (como un IC ) y se denominan comúnmente ID de PCI . El ID de proveedor de 16 bits lo asigna el PCI-SIG . Luego, el proveedor asigna el ID de dispositivo de 16 bits. Hay un proyecto inactivo para recopilar todos los ID de proveedor y dispositivo conocidos. (Consulte los enlaces externos a continuación).
El registro de estado se utiliza para informar qué funciones son compatibles y si se han producido determinados tipos de errores. El registro de comando contiene una máscara de bits de funciones que se pueden habilitar y deshabilitar individualmente. Los valores del registro de tipo de encabezado determinan los diferentes diseños de los 48 bytes restantes (64-16) del encabezado, según la función del dispositivo. Es decir, encabezados de tipo 1 para el complejo raíz, conmutadores y puentes. Luego, tipo 0 para los puntos finales. El registro de tamaño de línea de caché debe programarse antes de que se le indique al dispositivo que puede usar la transacción de escritura e invalidación de memoria. Normalmente, esto debería coincidir con el tamaño de línea de caché de la CPU , pero la configuración correcta depende del sistema. Este registro no se aplica a PCI Express.
El ID de subsistema (SSID) y el ID de proveedor del subsistema (SVID) diferencian un modelo específico (como una tarjeta complementaria). Mientras que el ID de proveedor es el del fabricante del chipset , el ID de proveedor del subsistema es el del fabricante de la tarjeta. El ID de subsistema lo asigna el proveedor del subsistema, mientras que el ID de dispositivo lo asigna el fabricante del chipset. Por ejemplo, en el caso de las tarjetas de red inalámbricas , el fabricante del chip puede ser Intel , Broadcom o Atheros , y el fabricante de la tarjeta puede ser Netgear o Hewlett-Packard . Generalmente, la combinación de ID de proveedor e ID de dispositivo designa qué controlador debe cargar el host para manejar el dispositivo, ya que todas las tarjetas con la misma combinación VID:DID pueden ser manejadas por el mismo controlador. La combinación de ID de proveedor del subsistema e ID de subsistema identifica la tarjeta, que es el tipo de información que el controlador puede usar para aplicar un cambio menor específico de la tarjeta en su funcionamiento.
Para direccionar un dispositivo PCI, debe habilitarse mediante su mapeo en el espacio de direcciones del puerto de E/S del sistema o en el espacio de direcciones mapeado en memoria . El firmware del sistema (por ejemplo, BIOS ) o el sistema operativo programan los registros de dirección base (comúnmente llamados BAR) para informar al dispositivo sobre su configuración de recursos escribiendo comandos de configuración en el controlador PCI. Debido a que todos los dispositivos PCI están en un estado inactivo al reiniciar el sistema, no tendrán direcciones asignadas mediante las cuales el sistema operativo o los controladores de dispositivos puedan comunicarse con ellos. El BIOS o el sistema operativo direccionan geográficamente los dispositivos PCI (por ejemplo, la primera ranura PCI, la segunda ranura PCI, la tercera ranura PCI o los dispositivos PCI integrados, etc., en la placa base ) a través del controlador PCI utilizando las señales IDSEL (selección de dispositivo de inicialización) por ranura o por dispositivo.
Cuando se enciende la computadora, el BIOS o el sistema operativo deben enumerar los buses PCI y los dispositivos . La enumeración de buses se realiza intentando acceder a los registros del espacio de configuración PCI para cada bus, dispositivo y función. Tenga en cuenta que el número de dispositivo, diferente de VID y DID, es simplemente el número secuencial de un dispositivo en ese bus. Además, después de detectar un nuevo puente, se define un nuevo número de bus y la enumeración de dispositivos se reinicia en el dispositivo número cero.
Si no se recibe respuesta de la función n.° 0 del dispositivo, el maestro del bus realiza una interrupción y devuelve un valor con todos los bits activados ( FFFFFFFF en hexadecimal), que es un valor VID/DID no válido, por lo que el BIOS o el sistema operativo pueden saber que la combinación especificada de bus/número de dispositivo/función (B/D/F) no está presente. Por lo tanto, cuando una lectura de un ID de función de cero para un bus/dispositivo determinado hace que el maestro (iniciador) cancele, se debe presumir que no existe ningún dispositivo en funcionamiento en ese bus porque se requieren dispositivos para implementar la función número cero. En este caso, las lecturas de los números de funciones restantes (1 a 7) no son necesarias ya que tampoco existirán.
Cuando se realiza una lectura de una combinación B/D/F específica para el registro de identificación del proveedor, el firmware del sistema o el sistema operativo sabe que existe; escribe todos los unos en sus BAR y lee de nuevo el tamaño de memoria solicitado del dispositivo en forma codificada. El diseño implica que todos los tamaños de espacio de direcciones son una potencia de dos y están alineados de forma natural. [1]
En este punto, el BIOS o el sistema operativo programará las direcciones asignadas a la memoria y las direcciones del puerto de E/S en los registros de configuración BAR del dispositivo. Estas direcciones siguen siendo válidas mientras el sistema permanezca encendido. Al apagar, estas configuraciones se pierden y el procedimiento se repite la próxima vez que se vuelve a encender el sistema. El BIOS o el sistema operativo también programará algunos otros registros del espacio de configuración PCI para cada dispositivo PCI, por ejemplo, solicitud de interrupción . Dado que todo este proceso está completamente automatizado, el usuario se ahorra la tarea de configurar manualmente cualquier hardware recién agregado cambiando los interruptores DIP en las propias tarjetas. Este descubrimiento automático de dispositivos y asignación de espacio de direcciones es la forma en que se implementa el plug and play .
Si se encuentra un puente PCI a PCI, el sistema debe asignar al bus PCI secundario que se encuentra más allá del puente un número de bus distinto de cero y, a continuación, enumerar los dispositivos en ese bus secundario. Si se encuentran más puentes PCI, la detección continúa de forma recursiva hasta que se hayan escaneado todas las combinaciones posibles de dominio/bus/dispositivo.
Cada función de dispositivo PCI sin puente puede implementar hasta 6 BAR, cada uno de los cuales puede responder a diferentes direcciones en el puerto de E/S y el espacio de direcciones mapeado en memoria. Cada BAR describe una región [2] [1] que tiene un tamaño de entre 16 bytes y 2 gigabytes, ubicada por debajo del límite de espacio de direcciones de 4 gigabytes. Si una plataforma admite la opción "Por encima de 4G" en el firmware del sistema, se pueden usar BAR de 64 bits. BAR redimensionable (también conocido como Re-Size BAR , AMD Smart Access Memory (SAM), [3] o ASRock Clever Access Memory (CAM)) [4] es una capacidad que un dispositivo PCIe puede usar para negociar un tamaño de BAR más grande. [5] Clásicamente, los BAR estaban limitados a un tamaño de 256 MB, pero las tarjetas gráficas modernas tienen framebuffers mucho más grandes que eso. [3] Este desajuste provocó ineficiencias cuando la CPU accedió al framebuffer. [3] BAR redimensionable permite que una CPU acceda a todo el framebuffer a la vez, mejorando así el rendimiento. [3]
Un dispositivo PCI también puede tener una ROM opcional .
Al realizar un acceso al espacio de configuración , un dispositivo PCI no decodifica la dirección para determinar si debe responder, sino que observa la señal de selección de dispositivo de inicialización (IDSEL). Existe un método de activación exclusivo para todo el sistema para cada señal IDSEL. El dispositivo PCI debe decodificar solo los 11 bits de orden más bajo de las señales de dirección/datos del espacio de direcciones (AD[10] a AD[0]) y puede ignorar la decodificación de las 21 señales A/D de orden superior (AD[31] a AD[11]) porque una implementación de acceso al espacio de configuración tiene el pin IDSEL de cada ranura conectado a una línea de dirección/datos de orden superior diferente, AD[11] a AD[31]. La señal IDSEL es un pin diferente para cada dispositivo/adaptador/ranura PCI.
Para configurar la tarjeta en la ranura n , el puente de bus PCI realiza un ciclo de acceso al espacio de configuración con el registro del dispositivo PCI que se va a direccionar en las líneas AD[7:2] (AD[1:0] siempre son cero ya que los registros son palabras dobles (32 bits)), y el número de función PCI especificado en los bits AD[10:8], con todos los bits de orden superior ceros excepto AD[ n +11] siendo utilizados como la señal IDSEL en una ranura/dispositivo determinado.
Para reducir la carga eléctrica en el bus AD[] crítico para el tiempo (y por lo tanto sensible a la carga eléctrica), la señal IDSEL en el conector de ranura PCI se conecta generalmente a su pin AD[ n +11] asignado a través de una resistencia. Esto hace que la señal IDSEL de PCI alcance su condición activa más lentamente que otras señales de bus PCI (debido a la constante de tiempo RC tanto de la resistencia como de la capacitancia de entrada del pin IDSEL). Por lo tanto, los accesos al espacio de configuración se realizan más lentamente para dar tiempo a que la señal IDSEL alcance un nivel válido.
El escaneo en el bus se realiza en la plataforma Intel accediendo a dos puertos estandarizados definidos. Estos puertos son el puerto de E/S de dirección de espacio de configuración ( 0xCF8 ) y el puerto de E/S de datos de espacio de configuración ( 0xCFC ). El valor escrito en el puerto de E/S de dirección de espacio de configuración se crea combinando los valores B/D/F y el valor de la dirección de registros en una palabra de 32 bits.
Las lecturas y escrituras de configuración se pueden iniciar desde la CPU de dos maneras: un método heredado a través de las direcciones de E/S 0xCF8 y 0xCFC , y otro llamado configuración mapeada en memoria. [6]
El método heredado estaba presente en el PCI original y se denomina Mecanismo de acceso a la configuración (CAM). Permite acceder indirectamente a 256 bytes del espacio de direcciones de un dispositivo a través de dos registros de 32 bits denominados PCI CONFIG_ADDRESS y PCI CONFIG_DATA. Estos registros se encuentran en las direcciones 0xCF8 y 0xCFC en el espacio de direcciones de E/S x86. [7] Por ejemplo, un controlador de software (firmware, kernel del sistema operativo o controlador del kernel) puede utilizar estos registros para configurar un dispositivo PCI escribiendo la dirección del registro del dispositivo en CONFIG_ADDRESS y colocando los datos que se supone que deben escribirse en el dispositivo en CONFIG_DATA. Dado que este proceso requiere una escritura en un registro para poder escribir el registro del dispositivo, se lo denomina "indirección".
El formato de CONFIG_ADDRESS es el siguiente:
0x80000000 | bus << 16 | dispositivo << 11 | función << 8 | desplazamiento
Como se explicó anteriormente, el direccionamiento de un dispositivo a través de Bus, Dispositivo y Función (BDF) también se conoce como "direccionamiento geográfico de un dispositivo". Consulte arch/x86/pci/early.c
el código del núcleo de Linux para ver un ejemplo de código que utiliza direccionamiento geográfico. [8]
Cuando se utiliza un espacio de configuración extendido en algunas CPU AMD, los bits adicionales 11:8 del desplazamiento se escriben en los bits 27:24 del registro CONFIG_ADDRESS: [9] [10]
0x80000000 | ( desplazamiento y 0xf00 ) << 16 | bus << 16 | dispositivo << 11 | función << 8 | ( desplazamiento y 0xff )
El segundo método fue creado para PCI Express. Se llama Mecanismo de acceso a la configuración mejorada (ECAM). Amplía el espacio de configuración del dispositivo a 4 KB, con los 256 bytes inferiores superpuestos al espacio de configuración original (heredado) en PCI. La sección del espacio direccionable se "robó" para que los accesos desde la CPU no vayan a la memoria sino que lleguen a un dispositivo determinado en la estructura PCI Express. Durante la inicialización del sistema, el BIOS determina la dirección base para esta región de dirección "robada" y la comunica al complejo raíz y al sistema operativo.
Cada dispositivo tiene su propio espacio de 4 KB y la información de cada dispositivo es accesible a través de una matriz simple, dev[bus][device][function]
de modo que se "roban" 256 MB de espacio físico contiguo para este uso (256 buses × 32 dispositivos × 8 funciones × 4 KB = 256 MB). La dirección física base de esta matriz no se especifica. Por ejemplo, en los sistemas x86 modernos, las tablas ACPI contienen la información necesaria. [11]