8259 PIC: Difference between revisions

1,093 bytes added ,  16 years ago
rewrote sections, added tables.
[unchecked revision][unchecked revision]
m (changed category to 'interrupts')
(rewrote sections, added tables.)
Line 1:
{{In Progress}}
 
The PIC stands for "''Programmable Interrupt Controller"'' and(PIC) is one of THEthe most important chips inmaking up the PCx86 architecture. Without it, the x86 architecture would not be an interrupt driven architecture. The function of the chipset (made up mostly of a set of 8259As) is to manage hardware interrupts and send them to the appropriate system [[Interrupts|interrupt]]. This allows the system to respond to devices needs without loss of time (from polling the device, for instance).
 
It is important to note that [[APIC]] has replaced PIC in more modern systems, especially those with multiple cores/processors.
== What does the PIC do ==
 
== What does the PIC do ?==
There needs to be a way for peripherals and other devices external of the CPU to tell the system that an event has happened or needs to happen. Examples of this: hard disk IO, modem/serial ports, keyboard.
The PIC controls the CPU's interrupt mechanism, by accepting several interrupt requests and feeding them to the processor in order. For instance, when a keyboard registers a keyhit, it sends a pulse along it's interrupt line ([[IRQ]] 1) to the PIC chip, which then translates the IRQ into a system interrupt, and sends a message to interrupt the CPU from whatever it is doing. Part of the kernel's job is to either handle these IRQs and perform the necessary procedures (poll the keyboard for the scancode) or alert a userspace program to the interrupt (send a message to the keyboard driver).
 
The PIC controls the CPU's interrupt mechanism, by accepting several interrupt requests and feeding them to the processor in order.
 
Without the PIC interface, you would have to poll all the devices in the system to see if they want to do anything (signal an event), but with the PIC, your system can run along nicely until such time that a device wants to signal an event, which means you don't waste time going to the devices, you let the devices come to you when they are ready.
 
===The IBM/PC PIC Architecture===
In the beginning, the age of the IBM XT, we had only 1 PIC chip giving us 8 hardware interrupt lines, but the 8259A PIC chip has a neat ability, it can cascade!
{{Stub}}
In the beginning (IBM PC and XT), only a single PIC chip was used, which provided 8 IRQs to the system. These were traditionally mapped by the BIOS to interrupts 8 to 15 (0x08 to 0x0F).
 
===The IBM/AT PIC Architecture===
CascadingThe meansIBM youAT canextended daisythe chainPC PICarchitecture chipsby togetheradding a second PIC chip. This iswas whatpossible happeneddue withto the introduction8259A's ofability theto IBMcascade ATinterrupts, wethat hadis, ahave secondthem PICflow chipthrough cascadedone ontochip theand first,into givinganother. This usgives a total of 15 hardware lines..interrupts. Why 15 and not 16? That's because when you cascade chips, the PIC needs to use one of the intinterrupt lines to signal to the other chip.
 
Thus, in an AT, IRQ line 2 is used to signal the second chip... But to confuse things more, IRQ 9 is redirected to IRQ 2. So when you get an IRQ 9, the signal is redirected to IRQ 2. This two-chip architecture is still used and available in modern systems, and hasn't changed (except for the advent of above-mentioned APIC chips).
 
== How does the PIC chip work ?==
Each of the two PICs in modern systems have 8 inputs. When any of the inputs is raised, the PIC sets a bit internally telling one of the inputs needs servicing. It then checks whether that channel is masked or not, and whether theresthere's an interrupt already pending.
If the channel is unmasked and theresthere's no interrupt pending, the PIC will raise the interrupt line. On the slave, this feeds IRQ 2 to the master, and the master is connected to the processor interrupt line.
 
When the processor accepts the interrupt, the master checks which of the two PICs is responsible for answering, then either supplies the interrupt number to the processor, or asks the slave to do so. The PIC that answers looks up the "vector offset" variable stored internally and adds the input line to form the requested interrupt number. After that the processor will look up the interrupt address and act accordingly (see [[Interrupts]] for more details).
Each of the two PICs in modern systems have 8 inputs. When any of the inputs is raised, the PIC sets a bit internally telling one of the inputs needs servicing. It then checks whether that channel is masked or not, and whether theres an interrupt already pending.
If the channel is unmasked and theres no interrupt pending, the PIC will raise the interrupt line. On the slave, this feeds IRQ 2 to the master, and the master is connected to the processor interrupt line.
 
== Programming with the PIC chips Chips==
When the processor accepts the interrupt, the master checks which of the two PICs is responsible for answering, then either supplies the interrupt number to the processor, or asks the slave to do so. The PIC that answers looks up the "vector offset" variable stored internally and adds the input line to form the requested interrupt number. After that the processor will look up the interrupt address and act accordingly.
* eachEach PIC vector offset must be divisible by 8, as the 8259A uses the lower 3 bits for the interrupt number of a particular interrupt (0..7).
* theThe only way to change the vector offsets used by the PIC is to re-initialize it, which explains why the code is "so long" and plenty of things that have apparently no reasons to be here.
* ifIf you plan to return to real mode from protected mode (for any purpose), you really must restore the PIC to its former configuration.
 
===Real Code Mode===
The default (BIOS-defined) vector offsets are 8 for Master PIC and 0x70 for Slave PIC:
{| {{wikitable}}
|-
! Chip
! Interrupt numbers (IRQ)
! Vector offset
! Interrupt Numbers
|-
| Master PIC
| 0 to 7
| 0x08
| 0x08 to 0x0F
|-
| Slave PIC
| 8 to 15
| 0x70
| 0x70 to 0x77
|}
These default BIOS values suit real mode programming quite well; they do not conflict with any CPU exceptions like they do in protected mode.
 
===Protected Mode===
* Master: IRQ 0..7 -> INT 8..0xF (vector offset = 0x08)
In protected mode, the IRQs 0 to 7 conflict with the CPU exception which are reserved by Intel up until 0x1F. Consequently it is difficult to tell the difference between an IRQ or an software error. It's is thus recommended to change the PIC's offsets (also known as remapping the PIC) so that IRQs use non-reserved vectors. A common choice is to move them to the beginning of the available range (IRQs 0..0xF -> INT 0x20..0x2F). For that, we need to set Masterthe master PIC's offset to 0x20 and Slavethe slave's to 0x28. For code examples, see below.
* Slave: IRQ 8..15 -> INT 0x70..0x77 (vector offset = 0x70)
 
However, these default values don't suit the needs of ProtectedMode programming: there's a collision between IRQs 0..7 (mapped to INT 8..0xF) and processor exceptions (INT 0..0x1F are reserved). Consequently you wouldn't be able to tell the difference between an IRQ or an software error.
 
It's thus recommended to change the PIC's offsets (also known as remapping the PIC) so that IRQs use non-reserved vectors. A common choice is to move them to the beginning of the available range (IRQs 0..0xF -> INT 0x20..0x2F). For that, we need to set Master's offset to 0x20 and Slave's to 0x28.
 
This can be done by calling remap_pics(0x20, 0x28); (see sample code below).
 
Note however that,
 
* each PIC vector offset must be divisible by 8, as the 8259A uses the lower 3 bits for the interrupt number of a particular interrupt (0..7).
* the only way to change the vector offsets used by the PIC is to re-initialize it, which explains why the code is "so long" and plenty of things that have apparently no reasons to be here.
* if you plan to return to real mode (for any purpose), you really must restore the PIC to its former configuration.
 
== Programming the PIC chips ==
 
==Code Examples==
Each chip (master and slave) has a command port and a data port (given in the table below). When no command is issued, the data port allows us to access the interrupt mask of the PIC.
 
Line 61 ⟶ 72:
|}
 
===End of Interrupt===
A common command for the PIC is the end of interrupt command (code 0x20), but there's also the "initialize" command (code 0x11), which makes the PIC wait for 3 extra "initialization words" on the data port. Those data bytes gives the PIC
A common command for the PIC is the end of interrupt command (code 0x20).
 
===Initialisation===
A common command for the PIC is the end of interrupt command (code 0x20), but there's also the "initialize" command (code 0x11), which makes the PIC wait for 3 extra "initialization words" on the data port. Those data bytes gives the PIC
* its vector offset (ICW2),
* tell it how it is wired to master/slaves (ICW3)
* gives additional infos about the environment (ICW4)
 
=== Code ===
 
<pre>
Anonymous user