PCI: Difference between revisions

1,739 bytes added ,  3 years ago
[unchecked revision][unchecked revision]
(too much bold text (IMHO), so make bit field names italic in their lists)
Line 1,082:
 
With time manufacturers started to use mainly INTA#, forgetting the existence of other pins. So you will likely have 18 devices on INTA# and 2 on INTB#. Motherboard manufacturers decided take the situation in control. So at boot the INTx# are remapped, so that you will have 5 devices for INTA#, 5 for INTB#, 5 for INTC#, and 5 for INTD# (in the best case). That's great! IRQs are balanced and IRQ sharing is reduced. The only problem is that you don't know what devices where mapped. If you read the ''Interrupt Pin'' you still get INTA#. You now need to parse the MP Tables or the [[ACPI]] ones to solve the mess. Good luck.
 
Alternatively, you could just use MSI or MSI-X, and skip all that nasty ACPI stuff.
 
== Message Signaled Interrupts ==
{{In Progress}}
Message Signaled Interrupts, or MSI, have been supported since PCI v2.2. However, support for them is ''mandatory'' in PCIe devices, so you can be sure that they're usable on modern hardware.
 
=== Enabling MSI ===
First, check that the device has a pointer to the capabilities list (Status register bit 4 set to 1).
Then, traverse the capabilities list. The low 8 bits of a capability register are the ID - 0x05 for MSI. The next 8 bits are the offset (in PCI configuration space) of the next capability.
 
The MSI capability is as folows:
{| {{wikitable}}
|-
! register !! offset !! bits 31-24 !! bits 23-16 !! bits 15-8 !! bits 7-0
|-
| cap+00
| cap+00
| colspan="2" | Message Control
| Next ptr || Capability ID = 05
|-
| cap+01
| cap+04
| colspan="4" | Message Address [Low]
|-
| cap+02
| cap+08
| colspan="4" | [Message Address High]
|-
| cap+02/03
| cap+08/0C
| colspan="2" | Reserved
| colspan="2" | Message Data
|-
| cap+04
| cap+10
| colspan="4" | Mask
|}
 
Here is the layout of the message control register:
 
{| {{wikitable}}
|-
! Bit 15-8 ! Bit 7 !! Bit 6-4 !! Bit 3-1 !! Bit 0
|-
| Reserved
| 64 bit
| Multiple Message Enable
| Multiple Message Capable
| Enable
|}
 
The message address/data is architecture specific. On x86(-64), it is as follows:
<source lang="c">
paddr_t arch_msi_address(uint64_t* data, size_t vector, uint32_t processor, uint8_t edgetrigger, uint8_t deassert)
{
*data = (vector & 0xFF) | (edgetrigger == 1 ? 0 : (1 << 15)) | (deassert == 1 ? 0 : (1 << 14));
return (0xFEE00000 | (processor << 12));
}
</source>
MSI interrupts seem to be invariably edge triggered high.
 
== Multifunction Devices ==
Anonymous user