# IO-APIC

IO-APIC est l'acronyme de I/O Advanced Programmable Interrupt Controller, qui est un contrôleur programmable d'interruptions.
C'est une architecture Intel pour gérer les interruptions dans les ordinateurs multiprocesseurs.
Elle est mise en œuvre par la puce Intel 82093AA et se trouve sur toutes les cartes Intel SMP.
C'est une des nombreuses tentatives pour résoudre les problèmes d'IRQ. Il ne faut pas la confondre avec l'ACPI (Advanced Configuration and Power Interface).
Dans la vue du niveau du système, il y a deux parties d'APIC. Une d'entre elles est dans le processeur, et nommée "Local APIC", alors que l'autre fait partie du système des Entrées/Sorties avec le nom de "IOAPIC". Elles sont connectées par un bus APIC dédié. Le Local APIC gère toutes les interruptions locales pour le processeur local. En plus, il est capable d'accepter et de générer des interruptions interprocesseurs sur le bus APIC. L'unité IOAPIC contient une table de redirections. Elle redirige les interruptions d'un APIC local vers un autre par l'intermédiaire du bus. Le mécanisme APIC rend possible la gestion des interruptions dans un environnement multiprocesseur, alors que l'ancien mécanisme PIC ne peut le faire.
Ce peut être une cause de défaillance du système, car certaines versions de certains systèmes d'exploitation ne le gèrent pas correctement. Si c'est le cas, la désactivation du IO-APIC peut régler le problème. Pour Linux, il faut essayer le paramètre noyau "noapic" ; pour FreeBSD, la variable d'environnement noyau "hint.apic.0.disabled"
Dans Linux, les problèmes avec IO-APIC sont une des nombreuses causes de messages d'erreur concernant "spurious 8259A interrupt: IRQ7.". Il est aussi possible que l'IO-APIC cause des lenteurs lors des copies entre médias différents (disque dur à clef USB par exemple) ou des problèmes avec les interfaces réseau basées sur le pilote via-rhine, causant un dépassement de délai de transmission. Les noyaux monoprocesseurs avec l'APIC activée peut provoquer la génération d'interruptions spécieuses.

## Détails de mise en œuvre

Chaque processeur contient un Local APIC et il peut y avoir plusieurs I/O APIC répartis dans le reste du système (dans le chipset ou bien dans des bridges PCI-PCIe par exemple). Le bus interconnectant ces différents APIC est un bus "logique", dans le sens qu'il ne s'agit pas de "nouveaux fils dédiés" (pour le PCI, il y a toujours le fil d'interruption classique, et pour le PCIe, les interruptions peuvent voyager sous forme de message, les MSI).
Chaque I/O APIC (qui possède 24 entrées) peut se voir attribuer par le BIOS une "base" qui définit quels numéros d'interruption il va générer : ainsi, un I/O APIC qui a comme base 0 générera les interruptions 0+0=0 à 0+23=23, alors qu'un I/O APIC qui a comme base 24 générera les interruptions 24+0=24 à 24+23=47, et ainsi de suite...
Si le système est bien conçu (ce qui n'est pas forcément le cas de toutes les cartes mères), alors chaque périphérique peut se voir attribuer un numéro d'interruption unique qu'il n'aura pas à partager avec d'autres périphériques.
Bien que les systèmes d'exploitation modernes (Windows XP ou Linux) soient capables de gérer le partage d'interruptions, ce mécanisme est intéressant pour la conception de systèmes temps réel ou l'on veut éviter d'interroger inutilement un périphérique pour savoir si c'est lui qui vient de générer l'interruption : si les interruptions ne sont pas partagées, lorsque l'on reçoit un numéro d'interruption donné, on sait en effet immédiatement quel périphérique a signalé cette interruption, ce qui réduit la latence et augmente le déterminisme de son traitement.