Support to multi-threading and pthread interface (POSIX.1-2008) (#23)
[lunaix-os.git] / slides / c12-pci / pci-notes.txt
1                         PCI Local Bus Specification
2                              A Learning Note
3
4                                 Lunaixsky
5                                 2022-6-22
6
7
8 Convention:
9         A WORD is 16 bits, 2 bytes
10         DWORD -> Double WORD -> 4 bytes
11 +++++++++++++++++
12
13
14 PCI buses has a hierarchical structure, buses connected together with PCI-to-PCI bridge, in a tree-like manner
15
16                 CPU, Memory
17                     |
18                 Host Bridge
19                     |
20      ---+-----------+-------+-------            bus #0
21         |                   |
22        dev                 P2PB
23                             |
24                 ---+--------+---------+---      bus #1
25                    |                  |
26                  P2PB               P2PB
27                    |                  |
28   bus #j   --------+--------    ------+-------- bus #i
29
30 Where
31         P2PB: PCI-to-PCI Bridge
32
33 Note
34         Each P2PB can connect more than one subordinate buses.
35         The bus number that host bridge connected to is always 0.
36
37
38 Configuration space
39 -------
40
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.
45
46
47 C-Space command
48 -------
49
50   Type 0:
51         register num[7::2]
52         function num[10::8]
53         use to select the function and register on current bus
54                 (that direct connect to CPU)
55   Type 1:
56         dev num[15::11]
57         bus num[23::16]
58         use to select one of *32* device on local bus identified by bus num.
59
60   Type 0 is claimed by device on current bus
61   Type 1 is checked and forwarded by PCI-to-PCI bridge.
62
63
64
65 Software (OS) interaction with PCI:
66 =====
67  
68 CONFIG_ADDRESS ([OUT] 32 bits I/O port at 0xcf8)
69         Specify the:
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
75
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.
80
81 The host-to-pci bridge will transfer the CONFIG_ADDRESS into either type0 or type1 commands and start transcation.
82
83
84
85 C-space organization
86 ====
87
88 Each c-space has a header at start.
89
90 Three types of headers.
91
92 The first 16 bytes (0x00-0x0f) are same across headers.
93
94 Remaining bytes depends on header type.
95
96 The header following little-endian.
97
98 header type available at byte 0xe
99         
100         0x0: normal pci target
101         0x1: pci2pci bridge
102         0x2: cardbus bridge
103
104
105 PCI-Bus enumeration
106 -----
107
108 enumerating the device number, bus number, and read the vendor ID (byte 0x0)
109
110 for non-existing device, 0xffff will be reported at CONFIG_DATA
111
112
113 Device Command Register (0x04)
114 -----
115
116 see pp. 217, fig. 6-2
117
118
119 Device Status Register (0x6)
120 -----
121
122 see pp. 219, fig. 6-3
123
124
125 Interrupt Line
126 -----
127
128 the irq number on interrupt controller
129
130
131 Base Address Registers (BARS)
132 -----
133
134 Define the base address of device specific registers (ones apart from PCI specified).
135
136 Has following format:
137         MMIO [0]
138           :0 if the registers should be access by I/O port number
139           :1 if the registers are MMIO.
140
141 Thus, the BAR can be divided into two category according to bit 0
142
143 Memory Space (MMIO=1)
144         Type [2::1]
145           :00 base address is 32bits wide
146         Prefechable [3]
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.
151         Base address [31::4]
152           16 bytes aligned
153
154 I/O Space (MMIO=0)
155         Base address [31:2]
156
157
158
159 Message Signaled Interrupts (MSI)
160 ======
161
162 An alternative to traditional pin-asserted interrupt.
163
164 The device request service of kernel by writing a kernel-specified message (a DWORD) to a kernel-specified address (Physical, DWORD-aligned)
165
166 Each device that support MSI has MSI capability link-list within c-space
167
168 The structure of a typical MSI capability for 32bits is shown below:
169
170 31              15      7       0
171 +---------------+-------+-------+
172 |    MSG_CTRL   |  NEXT | CAPID |
173 |---------------+-------+-------|
174 |        Message Address        |
175 |---------------+---------------|
176 |    Reserved   |   MSG_DATA    |
177 |---------------+---------------|
178 |           Mask Bits           |
179 |-------------------------------|
180 |          Pending Bits         |
181 +-------------------------------+
182
183 Where
184     CAP_ID always 0x5
185     MSG_CTRL identify the characteristic of this capability
186         bit[8]
187            1 if this capability support per-vector mask
188            which meaning Mask Bits and Pending Bits field present.
189         bit[7]
190            1 if this capability is for 64bits. 
191            LunaixOS should make sure this bit is clear.
192         bit[6::4]
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
198         bit[3::1]
199            Requested messages. This tells the kernel how many of vectors
200            this device is requesting. Format is same as Enable Messsages.
201         bit[0]
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.
207    Mask Bits
208         bit x represent a mask on vector x (LSB is 0, MSB is 31)
209    Pending BIts
210         bit x represent a vector is in pending.
211
212
213 Executive Summary
214 -------
215
216 To initialize MSI:
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.
224
225
226 A note on using MSI on x86 arch
227 ------
228
229 In x86, the MSI is integrated with the APIC/IOAPIC ecosystem.
230
231 The message register and message data follows the x86 specific layout
232 (see Intel Manual Vol 3. section 10.11)
233
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.
235
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.
237
238
239
240