PCI: Difference between revisions
Jump to navigation
Jump to search
[unchecked revision] | [unchecked revision] |
Content deleted Content added
m →External Links: Update some links |
m →Enabling MSI: Clean up section |
||
Line 1,108: | Line 1,108: | ||
=== Enabling MSI === |
=== Enabling MSI === |
||
First, check that the device has a pointer to the capabilities list ( |
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 - |
Then, traverse the capabilities list. The low 8 bits of a capability register are the ID - 0x5 for MSI. The next 8 bits are the offset (in [[#Configuration Space|PCI Configuration Space]]) of the next capability. |
||
The MSI capability is as |
The MSI capability is as follows: |
||
{| {{wikitable}} |
{| {{wikitable}} |
||
|- |
|- |
||
! |
! Register !! Offset !! Bits 31-24 !! Bits 23-16 !! Bits 15-8 !! Bits 7-0 |
||
|- |
|- |
||
| |
| Cap + 0x0 |
||
| |
| Cap + 0x0 |
||
| colspan="2" | Message Control |
| colspan="2" | Message Control |
||
| Next |
| Next pointer || Capability ID = 05 |
||
|- |
|- |
||
| |
| Cap + 0x1 |
||
| |
| Cap + 0x4 |
||
| colspan="4" | Message Address [Low] |
| colspan="4" | Message Address [Low] |
||
|- |
|- |
||
| |
| Cap + 0x2 |
||
| |
| Cap + 0x8 |
||
| colspan="4" | [Message Address High] |
| colspan="4" | [Message Address High] |
||
|- |
|- |
||
| |
| Cap + 0x2/0x3 |
||
| |
| Cap + 0x8/0xC |
||
| colspan="2" | Reserved |
| colspan="2" | Reserved |
||
| colspan="2" | Message Data |
| colspan="2" | Message Data |
||
|- |
|- |
||
| |
| Cap + 0x4 |
||
| |
| Cap + 0x10 |
||
| colspan="4" | [Mask] |
| colspan="4" | [Mask] |
||
|- |
|- |
||
| |
| Cap + 0x5 |
||
| |
| Cap + 0x14 |
||
| colspan="4" | [Pending] |
| colspan="4" | [Pending] |
||
|} |
|} |
||
Line 1,147: | Line 1,147: | ||
{| {{wikitable}} |
{| {{wikitable}} |
||
|- |
|- |
||
! |
! Bits 15-9 !! Bit 8 !! Bit 7 !! Bits 6-4 !! Bits 3-1 !! Bit 0 |
||
|- |
|- |
||
| Reserved |
| Reserved |
||
| Per-vector masking |
| Per-vector masking |
||
| 64 |
| 64-bit |
||
| Multiple Message Enable |
| Multiple Message Enable |
||
| Multiple Message Capable |
| Multiple Message Capable |
||
Line 1,159: | Line 1,159: | ||
The message address/data is architecture specific. On x86(-64), it is as follows: |
The message address/data is architecture specific. On x86(-64), it is as follows: |
||
<source lang="c"> |
<source lang="c"> |
||
uint64_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)); |
*data = (vector & 0xFF) | (edgetrigger == 1 ? 0 : (1 << 15)) | (deassert == 1 ? 0 : (1 << 14)); |
||
return (0xFEE00000 | (processor << 12)); |
return (0xFEE00000 | (processor << 12)); |
||
Line 1,191: | Line 1,190: | ||
'''Interrupt masking''' |
'''Interrupt masking''' |
||
If capable, you can mask individual messages by setting the corresponding bit (1<< |
If capable, you can mask individual messages by setting the corresponding bit (1 << n), in the mask register. |
||
If a message is pending, then the corresponding bit in the pending register is set. |
If a message is pending, then the corresponding bit in the pending register is set. |
||
Note that the PCI specification doesn't specify the location of these registers if the message address is 32 |
Note that the PCI specification doesn't specify the location of these registers if the message address is 32-bit. This is because a function that supports masking is required to implement 64-bit addressing! |
||
=== Enabling MSI-X === |
=== Enabling MSI-X === |