1 PCI Local Bus Specification
9 A WORD is 16 bits, 2 bytes
10 DWORD -> Double WORD -> 4 bytes
14 PCI buses has a hierarchical structure, buses connected together with PCI-to-PCI bridge, in a tree-like manner
20 ---+-----------+-------+------- bus #0
24 ---+--------+---------+--- bus #1
28 bus #j --------+-------- ------+-------- bus #i
31 P2PB: PCI-to-PCI Bridge
34 Each P2PB can connect more than one subordinate buses.
35 The bus number that host bridge connected to is always 0.
41 Each device has multiple registers and functions
42 Configuration space is a 256 bytes memory region in target device
43 contains config info for the device,
44 it is comprising a set of read/write registers.
53 use to select the function and register on current bus
54 (that direct connect to CPU)
58 use to select one of *32* device on local bus identified by bus num.
60 Type 0 is claimed by device on current bus
61 Type 1 is checked and forwarded by PCI-to-PCI bridge.
65 Software (OS) interaction with PCI:
68 CONFIG_ADDRESS ([OUT] 32 bits I/O port at 0xcf8)
70 register num[7::2] (0~63, corresponding to each DWORD)
71 function num[10::8] (0~7)
72 dev num[15::11] (0~31)
73 bus num[23::16] (0~255)
74 enable bit[31] - set to start transcation
76 CONFIG_DATA ([IN/OUT] 32 bits I/O port at 0xcfc)
77 Reference the register specified by CONFIG_ADDRESS
78 any read result available here
79 any data should be write into register must be put here.
81 The host-to-pci bridge will transfer the CONFIG_ADDRESS into either type0 or type1 commands and start transcation.
88 Each c-space has a header at start.
90 Three types of headers.
92 The first 16 bytes (0x00-0x0f) are same across headers.
94 Remaining bytes depends on header type.
96 The header following little-endian.
98 header type available at byte 0xe
100 0x0: normal pci target
108 enumerating the device number, bus number, and read the vendor ID (byte 0x0)
110 for non-existing device, 0xffff will be reported at CONFIG_DATA
113 Device Command Register (0x04)
116 see pp. 217, fig. 6-2
119 Device Status Register (0x6)
122 see pp. 219, fig. 6-3
128 the irq number on interrupt controller
131 Base Address Registers (BARS)
134 Define the base address of device specific registers (ones apart from PCI specified).
136 Has following format:
138 :0 if the registers should be access by I/O port number
139 :1 if the registers are MMIO.
141 Thus, the BAR can be divided into two category according to bit 0
143 Memory Space (MMIO=1)
145 :00 base address is 32bits wide
147 If set, then any read in these register will not cause state change
148 and thus can be prefech and cached by CPU.
149 So one can mark such page containing this base address as cachable
150 to maximize the performance.
159 Message Signaled Interrupts (MSI)
162 An alternative to traditional pin-asserted interrupt.
164 The device request service of kernel by writing a kernel-specified message (a DWORD) to a kernel-specified address (Physical, DWORD-aligned)
166 Each device that support MSI has MSI capability link-list within c-space
168 The structure of a typical MSI capability for 32bits is shown below:
171 +---------------+-------+-------+
172 | MSG_CTRL | NEXT | CAPID |
173 |---------------+-------+-------|
175 |---------------+---------------|
176 | Reserved | MSG_DATA |
177 |---------------+---------------|
179 |-------------------------------|
181 +-------------------------------+
185 MSG_CTRL identify the characteristic of this capability
187 1 if this capability support per-vector mask
188 which meaning Mask Bits and Pending Bits field present.
190 1 if this capability is for 64bits.
191 LunaixOS should make sure this bit is clear.
193 Enable messages. This is used for multiple message support.
194 A device may request more than one messages (vectors).
195 The number of allocated message is aligned at power of 2.
196 i.e., if bit[6::4] represent value x, the number is 2^x
197 Max support of 32 vectors
199 Requested messages. This tells the kernel how many of vectors
200 this device is requesting. Format is same as Enable Messsages.
202 1 if MSI enable. default 0
203 Message Data: A 16-bits data
204 Note that the lower x bits are modifiable by device itself for
205 identifying the vector that cause this data to be signaled.
206 Where x is the value represented by bit[6::4] of MSG_CTRL.
208 bit x represent a mask on vector x (LSB is 0, MSB is 31)
210 bit x represent a vector is in pending.
217 1. Locate the MSI capability by traversing down the capability
218 list, looking for CAP_ID of 0x5
219 2. Read the MSG_CTRL[3::1] to determine the vectors requested by
220 device and allocate it (full or subset of it)
221 3. Check the masking capable (MSG_CTRL[8]) and use it optionally
222 4. Allocate a DWORD-aligned address for siganlling message.
223 5. Set the MSG_CTRL[0] for enabling MSI capability.
226 A note on using MSI on x86 arch
229 In x86, the MSI is integrated with the APIC/IOAPIC ecosystem.
231 The message register and message data follows the x86 specific layout
232 (see Intel Manual Vol 3. section 10.11)
234 When an MSI is signalled, the message data is written to the message address, which will be intercepted by IOAPIC and the message data as well as address are getting parsed, and deliver to the processor(s) by IOAPIC.
236 This makes sense if you take a look at the layout, you will found that is really similar to the redirection entry of IRQ in IOAPIC.