Il y a trois types d'adresses : les adresses mémoire centrale, les adresses d'E/S et les adresses de configuration. Pour le bus PCI, les adresses de configuration constituent un espace d'adressage séparé, exactement comme le sont les adresses d'E/S. Sauf dans le cas des adresses de configuration ISA, qu'une adresse sur le bus d'adresses (ou sur le bus partagé adresses-données dans le cas du PCI) soit ou non une adresse mémoire, une adresse d'E/S ou une adresse de configuration dépend uniquement des tensions sur d'autres fils (pistes) du bus.
En ce qui concerne le bus ISA, il n'y a pas, techniquement, d'espace d'adressage de configuration, mais il existe, pour le CPU, une méthode spéciale d'accès aux registres de configuration sur les cartes PnP. Trois adresses d'E/S sont réservées à cet usage. Ces 3 adresses ne sont pas différentes pour chaque carte, mais sont partagées par toutes les cartes.
Les trois adresses sont appelées port de lecture, port d'écriture et port d'adresse. Ces ports ont la taille d'un octet. Chaque carte PnP possède un certain nombre de registres car ces trois adresses seules ne sont pas suffisantes pour une simple carte. Pour communiquer avec une carte, le numéro de la carte (handle) est envoyé à toutes les cartes sur le port d'écriture. Une seule carte reconnaît son numéro et se met à l'écoute. Alors l'adresse du registre concerné est envoyée sur le port adresse (de toutes les cartes, mais une seule est à l'écoute). Ensuite, on fait une écriture sur le port d'écriture ou une lecture sur le port de lecture.
Le port d'écriture est toujours à l'adresse A79 et le port d'adresse est toujours 279. Le port de lecture n'est pas déterminé et est initialisé par le logiciel de configuration à une adresse qui est supposée ne pas être en conflit avec une autre carte ISA. S'il y a conflit, il modifiera l'adresse. Pour toutes les cartes PnP, cette adresses est "programmée". Donc, si vous utilisez disons, isapnp, pour initialiser ou tester des données de configuration, vous aurez besoin de connaître l'adresse du port de lecture.
Le terme "adresse" est quelquefois utilisé dans ce document pour parler d'une série d'adresses contiguës. Comme les adresses sont données en octets, une simple adresses contient uniquement un octet mais les adresses E/S (et mémoire centrale) ont besoin de plus que cela. Donc un espace de, disons, 8 octets est souvent utilisé pour les adresses d'E/S alors que le nombre d'adresses en mémoire centrale allouées à un périphérique est beaucoup plus grand. Pour un port série (périphérique d'E/S), il suffit de donner l'adresse de départ du périphérique (par exemple 3F8) puisqu'il est bien connu que le champ d'adresses de ce type de périphérique est seulement de 8 octets. Cette adresse de départ est connue sous le nom "d'adresse de base".
En ce qui concerne l'ISA, pour accéder à la fois aux "espaces" d'adresses E/S et mémoire (centrale) on utilise le même bus d'adresses (les fils utilisés pour les adresses sont partagés). Comment le périphérique reconnaît-il si une adresse qui apparaît sur le bus d'adresses est une adresse mémoire ou une adresse E/S ? Eh bien, il y a quatre lignes spécialisées du bus qui véhiculent cette information et un peu plus. Si l'un de ces quatre fils est alimenté, cela indique que le CPU veut lire une adresse E/S, et la mémoire centrale ne tient pas compte de l'adresse présente sur les fils d'adresses du bus. Les trois autres fils sont utilisés à des fins identiques. En résumé : il existe des lignes de lecture et d'écriture pour les adresses mémoire centrale et pour celles d'E/S (4 fils en tout).
Pour le bus PCI, l'idée de base est identique et on utilise également 4 fils, mais c'est réalisé de façon légèrement différente. Au lieu d'avoir uniquement l'un des quatre fils alimenté, on code un nombre binaire sur ces fils (16 possibilités différentes). On peut donc véhiculer plus d'informations. Quatre de ces 16 valeurs sont utilisées pour les espaces mémoire et E/S comme dans le paragraphe ci-dessus. En plus, on trouve l'espace des adresses de configuration qui utilise deux valeurs supplémentaires. Les dix possibilités restantes sont réservées pour d'autres utilisations.
Pour le bus ISA, il existe un système implanté sur chaque carte PnP pour vérifier que d'autres cartes n'utilisent pas la même adresse. Si deux cartes ou plus utilisent les mêmes adresses d'E/S, aucune des cartes ne fonctionnera correctement. Un bon logiciel PnP devrait affecter les ressources du bus pour éviter de tels conflits, mais, même dans ce cas, une carte ancienne pourrait se cacher quelque part avec la même adresse.
Le test consiste, pour la carte, à donner, sur le bus, comme numéros de test ses propres registres d'E/S. Le logiciel PnP les lit et vérifie qu'il lit les mêmes numéros. Si tel n'est pas le cas, quelque chose ne va pas (comme, par exemple, une autre carte à la même adresse). Il répète alors le test avec un autre numéro de test. Puisqu'en réalité il teste le champ des adresses d'E/S assigné à cette carte, on l'appelle " test des champs d'adresses". On devrait plutôt l'appeler "test des conflits d'adresses". S'il y a un conflit d'adresses, on obtient un message d'erreur qu'il faut résoudre par ses propres moyens.
Traditionnellement, la plupart des périphériques d'E/S utilisaient les E/S mémoire pour communiquer avec le CPU. Par exemple, le port série fonctionne de cette façon. Le pilote de périphérique, qui tourne sur le CPU lit et écrit les données de/vers l'espace des adresses d'E/S et la mémoire centrale. Une méthode plus rapide consisterait à faire mettre les données directement en mémoire centrale par le périphérique. Une manière de le réaliser est d'utiliser l'accès direct mémoire ( Canaux DMA). Une autre méthode consiste à affecter un espace de la mémoire centrale au périphérique. Comme cela, le périphérique lit et écrit directement en mémoire centrale sans avoir à se préoccuper de l'accès direct mémoire (DMA). De tels périphériques possèdent normalement des adresses d'E/S et des adresses mémoire.
Le système d'interruption véhicule un paquet d'informations, mais seulement de façon indirecte. Le signal d'interruption (une tension sur un fil) indique simplement à un circuit appelé contrôleur d'interruptions qu'un certain périphérique a besoin que l'on s'occupe de lui. Le contrôleur d'interruption le signale alors au CPU. Le CPU va chercher le pilote de ce périphérique et en exécute une partie que l'on désigne sous le nom de "routine de service de l'interruption" (ou "routine de gestion de l'interruption"). Cette "routine" essaie de voir ce qui s'est passé et se charge de traiter la question comme, par exemple, de transférer des octets du (ou vers le) périphérique. Ce programme (cette routine) peut facilement analyser ce qui s'est passé puisqu'il connaît les adresses des registres (à condition que les numéros d'interruption (IRQ) et que les adresses d'E/S aient été correctement renseignées). Ces registres contiennent les informations concernant l'état du périphérique. Le logiciel lit le contenu de ces registres et, en examinant ce contenu, voit ce qui s'est passé et entreprend l'action appropriée.
Donc, chaque pilote de périphérique a besoin de savoir quel est le numéro d'interruption (IRQ) qui le concerne. Sur le bus PCI (et pour les ports série sur un bus ISA depuis la version du noyau 2.2) il est possible que deux périphériques ou plus se partagent le même IRQ (numéro d'interruption). Cela est rendu possible en faisant exécuter par le CPU toutes les routines de service d'interruption de tous les périphériques qui utilisent cette interruption. La première chose que réalise une telle routine de service consiste à tester si l'interruption concerne son périphérique. Si tel n'est pas le cas (fausse alarme), elle se termine et le traitement continue avec la routine de service suivante etc.
Les interruptions PCI sont différentes, mais comme elles correspondent normalement aux IRQ, elles se comportent à peu près de la même façon. Le fait que les interruptions PCI puissent être partagées constitue une différence majeure. Par exemple l'IRQ5 peut être partagée entre deux périphériques PCI. Cette possibilité de partage est automatique : il n'est pas nécessaire de disposer d'un matériel ou d'un logiciel spécial. On a entendu parler de situations où un tel partage ne fonctionne pas, mais la cause réside certainement dans le logiciel du pilote de périphérique. Tous les pilotes de périphérique PCI sont supposés fonctionner avec partage des interruptions. Il faut cependant noter que le partage d'une même interruption entre un bus ISA et PCI n'est pas possible. Mais un partage illégal d'interruption fonctionnera à condition que les périphériques en conflit ne soient pas utilisés en même temps. "En même temps" signifie ici qu'un programme en cours d'exécution "ouvre" le périphérique dans le programme C.
Vous pouvez avoir besoin de connaître quelques-uns des détails du système d'interruption PCI de façon à pouvoir paramétrer la mémoire CMOS du BIOS ou pour positionner les cavaliers sur de vieilles cartes PCI. Le bus PCI possède quatre lignes d'interruptions de INTA# à INTD# (A, B, C et D). Pour un système à 7 connecteurs, d'après les spécifications, on aurait la possibilité de disposer de 7 x 4 = 28 lignes d'interruptions différentes. Mais ces spécifications ne permettent qu'un nombre inférieur de lignes d'interruption. Ce n'est pas trop contraignant puisque l'on peut partager les interruptions. Beaucoup de bus PCI ne paraissent disposer que de 4 lignes d'interruption. Appelons ces lignes (fils ou pistes) W, X, Y et Z. Supposons que l'on désigne l'interruption B de l'emplacement numéro 3 comme étant l'interruption 3B. Alors, on peut utiliser le fil W pour partager les interruptions 1A, 2B, 3C, 4D, 5A, 6B, 7C. On le réalise physiquement en connectant le fil W aux fils 1A, 2B etc... De même, le fil X pourrait être connecté aux fils 1B, 2C, 3D, 4A, 5B, 6C, 7D. Au démarrage, le BIOS fait correspondre X, W, Y, Z aux interruptions. Ensuite il écrit dans un registre physique de chaque périphérique quelle interruption lui a été affectée de sorte que le périphérique (et tout ce qui interroge le périphérique) sache quelle IRQ il utilise.
Les fils X, W, Y et Z mentionnés ci-dessus sont désignés dans les spécifications PCI par les noms INTA#, INTB#, INTC# et INTD#. Cette dénomination officielle PCI porte à confusion puisque, maintenant, INTA# a deux significations selon que l'on parle du connecteur ou du bus PCI. Par exemple, si 3C correspond à X alors on dira que l'INTC# du connecteur 3 est reliée à l'INTA# (X) du bus PCI. C'est une notation confuse.
Il y a également une autre obligation. Un connecteur PCI doit utiliser les premières lettres d'interruption en premier. Donc, s'il n'y a qu'un connecteur à utiliser une interruption, ce doit être L'INTA#. S'il utilise 2 interruptions ce doivent être INTA# et INTB# etc. Jusqu'à 8 périphériques peuvent être connectés à une carte à un emplacement donné, mais ils ne peuvent disposer que de 4 interruptions PCI. Cela ne pose pas de problème puisque les interruptions peuvent être partagées et donc, chacun des 8 périphériques (s'ils sont présents) pourra disposer d'une interruption. La lettre d'interruption PCI d'un périphérique est souvent fixe et câblée dans le périphérique.
Le BIOS affecte les IRQ(demandes d'interruptions) de façon à éviter les conflits avec les IRQ qu'il connaît sur le bus ISA. Quelquefois, dans le menu CMOS, on peut affecter des IRQ aux cartes PCI (mais ce n'est pas aussi facile à faire que ce qui a été expliqué ci-dessus). Il existe une situation dans laquelle Windows met à zéro tous les numéros d'interruption dans les cartes PCI après que l'affectation des numéros d'interruption a été effectué. Alors, quelqu'un qui utilise Windows et qui lance Linux à partir de Windows verra Linux ne trouver que des IRQ incorrectement paramétrées à zéro.
Vous pourriez penser que l'utilisation par le PCI des IRQ (bus ISA) peut être lent etc. Pas vraiment. Le(s) circuit(s) contrôleur(s) d'interruptions ISA possède(nt) un fil d'interruption directement relié au CPU afin que celui-ci puisse réagir immédiatement. Alors que les signaux sur les bus d'adresse et de données ISA doivent cheminer à travers le bus PCI pour atteindre le CPU, les signaux d'interruption IRQ lui parviennent pratiquement directement.
C'est uniquement valable pour le bus ISA. L'isolation est une méthode complexe d'assignation d'un identificateur temporaire (id number = numéro d'identification ou Card Select Number (CSN) = numéro de sélection de carte) à chaque périphérique PnP sur le bus. Puisqu'il existe des moyens plus efficaces (mais plus complexes) pour le faire, certains pourront affirmer que c'est une méthode simpliste. On n'utilise qu'une seule adresse d'écriture pour toutes les écritures sur tous les périphériques PnP connectés. Cette adresse est utilisée pour envoyer (assigner) un identificateur unique à chaque périphérique PnP. L'attribution de cet identificateur impose qu'un seul périphérique soit à l'écoute lorsque cet identificateur est envoyé (écrit) à cette adresse commune. Tous les périphériques PnP ont un numéro de série unique qu'ils utilisent dans le processus d'isolation. La réalisation de l'isolation ressemble à un jeu. Elle est réalisée en utilisant l'équivalent d'un bus à un seul fil reliant tous les périphériques PnP et du programme d'isolation.
Lors de la première manche de ce "jeu", tous les périphériques PnP sont à l'écoute sur ce fil et envoient simultanément une séquence de bits sur le fil. Les valeurs permises sont soit des 1 (tension positive) soit des "0 ouverts" sans tension (circuit ouvert ou troisième état). Chaque périphérique PnP commence à envoyer séquentiellement son numéro de série, bit par bit, en commençant par le bit de poids fort, sur le fil. Si l'un des périphériques envoie un 1 sur le fil, un 1 sera reçu par tous les autres. Si tous les périphériques envoient un "0 ouvert", on n'entendra rien sur le fil. L'objectif est d'éliminer (à la fin de cette première manche) tout le monde sauf le périphérique ayant le numéro de série le plus élevé. Par "éliminer", on entend cesser d'écouter plus avant l'adresse d'écriture que tous les périphériques encore dans la course continuent d'écouter. On appelle également cela "se retirer". (Il faut noter que tous les numéros de série sont de même longueur).
En premier lieu, ne prenons en considération que le bit de poids le plus élevé du numéro de série mis sur le fil par tous les périphériques n'ayant pas encore d'identificateur. Si l'un des périphériques PnP envoie un 0 (0 ouvert) mais reçoit un 1, cela signifie qu'un autre périphérique PnP possède un numéro de série supérieur au sien. Donc, il se retire provisoirement du jeu et n'écoute plus ce qui se passe sur la ligne jusqu'à la fin de cette manche (quand un identificateur est attribué au gagnant : celui qui a le numéro de série le plus élevé). Alors, les périphériques encore de la partie possèdent tous le bit de poids fort (un 1), donc, nous pouvons supprimer ce bit et prendre en compte uniquement le "numéro de série tronqué" résultant pour continuer à participer à cette manche. Retournez au début de ce paragraphe et répétez le processus jusqu'à ce que le numéro de série complet ait été traité pour chacun des périphériques (voir ci-dessous comment est traité le cas où il n'y a que des 0).
Il est donc clair que le numéro de série le plus élevé ne sera pas éliminé de la partie. Mais qu'en est-il si les chiffres de tête (du numéro de série éventuellement tronqué) sont tous des 0 ?. Dans ce cas un "0 ouvert" est envoyé sur la ligne et tous les participants restent en lice. S'ils ont tous des zéros en tête, alors les 0 sont éliminés exactement comme les 1 au paragraphe ci-dessus. La partie continue et les chiffres suivants (du numéro de série) sont envoyés.
À la fin de la manche (lorsque le bit de poids faible du numéro de série du concurrent restant a été émis), seul le périphérique PnP ayant le numéro de série le plus élevé est présent. On lui donne alors un identificateur et il quitte la partie définitivement. Ensuite, tous les éliminés de la dernière manche (ceux qui n'ont pas encore obtenu d'identificateur) reviennent dans le jeu et une nouvelle manche commence avec un concurrent de moins. Finalement, tous les périphériques PnP se verront attribuer un identificateur. Il est facile de prouver que cet algorithme fonctionne.
Une fois que tous les identificateurs ont été attribués,ils sont utilisés pour s'adresser à chacun des périphériques PnP pour les configurer et lire leur configuration. On notera que ces identificateurs ne sont utilisés que pour la configuration PnP et ne sont pas utilisés pour les communications normales avec le périphérique PnP. Au démarrage de l'ordinateur, tous les identificateurs sont perdus et, donc, un BIOS PnP refait normalement ce processus d'isolation à chaque fois que vous remettez votre PC en service.
FIN DU Plug-and-Play-HOWTO