source: rtems-docs/c_user/pci_library.rst @ 9aafb39

4.115
Last change on this file since 9aafb39 was 489740f, checked in by Chris Johns <chrisj@…>, on 05/20/16 at 02:47:09

Set SPDX License Identifier in each source file.

  • Property mode set to 100644
File size: 18.0 KB
Line 
1.. comment SPDX-License-Identifier: CC-BY-SA-4.0
2
3.. COMMENT: COPYRIGHT (c) 1988-2008.
4.. COMMENT: On-Line Applications Research Corporation (OAR).
5.. COMMENT: All rights reserved.
6
7PCI Library
8###########
9
10.. index:: libpci
11
12Introduction
13============
14
15The Peripheral Component Interconnect (PCI) bus is a very common computer bus
16architecture that is found in almost every PC today. The PCI bus is normally
17located at the motherboard where some PCI devices are soldered directly onto
18the PCB and expansion slots allows the user to add custom devices easily. There
19is a wide range of PCI hardware available implementing all sorts of interfaces
20and functions.
21
22This section describes the PCI Library available in RTEMS used to access the
23PCI bus in a portable way across computer architectures supported by RTEMS.
24
25The PCI Library aims to be compatible with PCI 2.3 with a couple of
26limitations, for example there is no support for hot-plugging, 64-bit memory
27space and cardbus bridges.
28
29In order to support different architectures and with small foot-print embedded
30systems in mind the PCI Library offers four different configuration options
31listed below. It is selected during compile time by defining the appropriate
32macros in confdefs.h. It is also possible to enable PCI_LIB_NONE (No
33Configuration) which can be used for debuging PCI access functions.
34
35- Auto Configuration (Plug & Play)
36
37- Read Configuration (read BIOS or boot loader configuration)
38
39- Static Configuration (write user defined configuration)
40
41- Peripheral Configuration (no access to cfg-space)
42
43Background
44==========
45
46The PCI bus is constructed in a way where on-board devices and devices in
47expansion slots can be automatically found (probed) and configured using Plug &
48Play completely implemented in software. The bus is set up once during boot
49up. The Plug & Play information can be read and written from PCI configuration
50space. A PCI device is identified in configuration space by a unique bus, slot
51and function number. Each PCI slot can have up to 8 functions and interface to
52another PCI sub-bus by implementing a PCI-to-PCI bridge according to the PCI
53Bridge Architecture specification.
54
55Using the unique \[bus:slot:func] any device can be configured regardless of
56how PCI is currently set up as long as all PCI buses are enumerated
57correctly. The enumeration is done during probing, all bridges are given a bus
58number in order for the bridges to respond to accesses from both
59directions. The PCI library can assign address ranges to which a PCI device
60should respond using Plug & Play technique or a static user defined
61configuration. After the configuration has been performed the PCI device
62drivers can find devices by the read-only PCI Class type, Vendor ID and Device
63ID information found in configuration space for each device.
64
65In some systems there is a boot loader or BIOS which have already configured
66all PCI devices, but on embedded targets it is quite common that there is no
67BIOS or boot loader, thus RTEMS must configure the PCI bus. Only the PCI host
68may do configuration space access, the host driver or BSP is responsible to
69translate the \[bus:slot:func] into a valid PCI configuration space access.
70
71If the target is not a host, but a peripheral, configuration space can not be
72accessed, the peripheral is set up by the host during start up. In complex
73embedded PCI systems the peripheral may need to access other PCI boards than
74the host. In such systems a custom (static) configuration of both the host and
75peripheral may be a convenient solution.
76
77The PCI bus defines four interrupt signals INTA#..INTD#. The interrupt signals
78must be mapped into a system interrupt/vector, it is up to the BSP or host
79driver to know the mapping, however the BIOS or boot loader may use the 8-bit
80read/write "Interrupt Line" register to pass the knowledge along to the OS.
81
82The PCI standard defines and recommends that the backplane route the interupt
83lines in a systematic way, however in standard there is no such requirement.
84The PCI Auto Configuration Library implements the recommended way of routing
85which is very common but it is also supported to some extent to override the
86interrupt routing from the BSP or Host Bridge driver using the configuration
87structure.
88
89Software Components
90-------------------
91
92The PCI library is located in cpukit/libpci, it consists of different parts:
93
94- PCI Host bridge driver interface
95
96- Configuration routines
97
98- Access (Configuration, I/O and Memory space) routines
99
100- Interrupt routines (implemented by BSP)
101
102- Print routines
103
104- Static/peripheral configuration creation
105
106- PCI shell command
107
108PCI Configuration
109-----------------
110
111During start up the PCI bus must be configured in order for host and
112peripherals to access one another using Memory or I/O accesses and that
113interrupts are properly handled. Three different spaces are defined and mapped
114separately:
115
116# I/O space (IO)
117
118# non-prefetchable Memory space (MEMIO)
119
120# prefetchable Memory space (MEM)
121
122Regions of the same type (I/O or Memory) may not overlap which is guaranteed by
123the software. MEM regions may be mapped into MEMIO regions, but MEMIO regions
124can not be mapped into MEM, for that could lead to prefetching of
125registers. The interrupt pin which a board is driving can be read out from PCI
126configuration space, however it is up to software to know how interrupt signals
127are routed between PCI-to-PCI bridges and how PCI INT[A..D]# pins are mapped to
128system IRQ. In systems where previous software (boot loader or BIOS) has
129already set up this the configuration is overwritten or simply read out.
130
131In order to support different configuration methods the following configuration
132libraries are selectable by the user:
133
134- Auto Configuration (run Plug & Play software)
135
136- Read Configuration (relies on a boot loader or BIOS)
137
138- Static Configuration (write user defined setup, no Plug & Play)
139
140- Peripheral Configuration (user defined setup, no access to
141  configuration space)
142
143A host driver can be made to support all three configuration methods, or any
144combination. It may be defined by the BSP which approach is used.
145
146The configuration software is called from the PCI driver
147(``pci_config_init()``).
148
149Regardless of configuration method a PCI device tree is created in RAM during
150initialization, the tree can be accessed to find devices and resources without
151accessing configuration space later on. The user is responsible to create the
152device tree at compile time when using the static/peripheral method.
153
154RTEMS Configuration selection
155~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
156
157The active configuration method can be selected at compile time in the same way
158as other project parameters by including rtems/confdefs.h and setting
159
160- ``CONFIGURE_INIT``
161
162- ``RTEMS_PCI_CONFIG_LIB``
163
164- ``CONFIGURE_PCI_LIB`` = PCI_LIB_(AUTO,STATIC,READ,PERIPHERAL)
165
166See the RTEMS configuration section how to setup the PCI library.
167
168Auto Configuration
169~~~~~~~~~~~~~~~~~~
170
171The auto configuration software enumerates PCI buses and initializes all PCI
172devices found using Plug & Play. The auto configuration software requires that
173a configuration setup has been registered by the driver or BSP in order to
174setup the I/O and Memory regions at the correct address ranges. PCI interrupt
175pins can optionally be routed over PCI-to-PCI bridges and mapped to a system
176interrupt number. BAR resources are sorted by size and required alignment,
177unused "dead" space may be created when PCI bridges are present due to the PCI
178bridge window size does not equal the alignment. To cope with that resources
179are reordered to fit smaller BARs into the dead space to minimize the PCI space
180required. If a BAR or ROM register can not be allocated a PCI address region
181(due to too few resources available) the register will be given the value of
182pci_invalid_address which defaults to 0.
183
184The auto configuration routines support:
185
186- PCI 2.3
187
188- Little and big endian PCI bus
189
190- one I/O 16 or 32-bit range (IO)
191
192- memory space (MEMIO)
193
194- prefetchable memory space (MEM), if not present MEM will be mapped into MEMIO
195
196- multiple PCI buses - PCI-to-PCI bridges
197
198- standard BARs, PCI-to-PCI bridge BARs, ROM BARs
199
200- Interrupt routing over bridges
201
202- Interrupt pin to system interrupt mapping
203
204Not supported:
205
206- hot-pluggable devices
207
208- Cardbus bridges
209
210- 64-bit memory space
211
212- 16-bit and 32-bit I/O address ranges at the same time
213
214In PCI 2.3 there may exist I/O BARs that must be located at the low 64kBytes
215address range, in order to support this the host driver or BSP must make sure
216that I/O addresses region is within this region.
217
218Read Configuration
219~~~~~~~~~~~~~~~~~~
220
221When a BIOS or boot loader already has setup the PCI bus the configuration can
222be read directly from the PCI resource registers and buses are already
223enumerated, this is a much simpler approach than configuring PCI ourselves. The
224PCI device tree is automatically created based on the current configuration and
225devices present. After initialization is done there is no difference between
226the auto or read configuration approaches.
227
228Static Configuration
229~~~~~~~~~~~~~~~~~~~~
230
231To support custom configurations and small-footprint PCI systems, the user may
232provide the PCI device tree which contains the current configuration. The PCI
233buses are enumerated and all resources are written to PCI devices during
234initialization. When this approach is selected PCI boards must be located at
235the same slots every time and devices can not be removed or added, Plug & Play
236is not performed. Boards of the same type may of course be exchanged.
237
238The user can create a configuration by calling pci_cfg_print() on a running
239system that has had PCI setup by the auto or read configuration routines, it
240can be called from the PCI shell command. The user must provide the PCI device
241tree named pci_hb.
242
243Peripheral Configuration
244~~~~~~~~~~~~~~~~~~~~~~~~
245
246On systems where a peripheral PCI device needs to access other PCI devices than
247the host the peripheral configuration approach may be handy. Most PCI devices
248answers on the PCI host's requests and start DMA accesses into the Hosts
249memory, however in some complex systems PCI devices may want to access other
250devices on the same bus or at another PCI bus.
251
252A PCI peripheral is not allowed to do PCI configuration cycles, which means
253that it must either rely on the host to give it the addresses it needs, or that
254the addresses are predefined.
255
256This configuration approach is very similar to the static option, however the
257configuration is never written to PCI bus, instead it is only used for drivers
258to find PCI devices and resources using the same PCI API as for the host
259
260PCI Access
261----------
262
263The PCI access routines are low-level routines provided for drivers,
264configuration software, etc. in order to access different regions in a way not
265dependent upon the host driver, BSP or platform.
266
267- PCI configuration space
268
269- PCI I/O space
270
271- Registers over PCI memory space
272
273- Translate PCI address into CPU accessible address and vice versa
274
275By using the access routines drivers can be made portable over different
276architectures. The access routines take the architecture endianness into
277consideration and let the host driver or BSP implement I/O space and
278configuration space access.
279
280Some non-standard hardware may also define the PCI bus big-endian, for example
281the LEON2 AT697 PCI host bridge and some LEON3 systems may be configured that
282way. It is up to the BSP to set the appropriate PCI endianness on compile time
283(``BSP_PCI_BIG_ENDIAN``) in order for inline macros to be correctly defined.
284Another possibility is to use the function pointers defined by the access layer
285to implement drivers that support "run-time endianness detection".
286
287Configuration space
288~~~~~~~~~~~~~~~~~~~
289
290Configuration space is accessed using the routines listed below. The pci_dev_t
291type is used to specify a specific PCI bus, device and function. It is up to
292the host driver or BSP to create a valid access to the requested PCI
293slot. Requests made to slots that are not supported by hardware should result
294in ``PCISTS_MSTABRT`` and/or data must be ignored (writes) or ``0xFFFFFFFF`` is
295always returned (reads).
296
297.. code-block:: c
298
299    /* Configuration Space Access Read Routines */
300    extern int pci_cfg_r8(pci_dev_t dev, int ofs, uint8_t *data);
301    extern int pci_cfg_r16(pci_dev_t dev, int ofs, uint16_t *data);
302    extern int pci_cfg_r32(pci_dev_t dev, int ofs, uint32_t *data);
303
304    /* Configuration Space Access Write Routines */
305    extern int pci_cfg_w8(pci_dev_t dev, int ofs, uint8_t data);
306    extern int pci_cfg_w16(pci_dev_t dev, int ofs, uint16_t data);
307    extern int pci_cfg_w32(pci_dev_t dev, int ofs, uint32_t data);
308
309I/O space
310~~~~~~~~~
311
312The BSP or driver provide special routines in order to access I/O space. Some
313architectures have a special instruction accessing I/O space, others have it
314mapped into a "PCI I/O window" in the standard address space accessed by the
315CPU. The window size may vary and must be taken into consideration by the host
316driver. The below routines must be used to access I/O space. The address given
317to the functions is not the PCI I/O addresses, the caller must have translated
318PCI I/O addresses (available in the PCI BARs) into a BSP or host driver custom
319address, see `Access functions`_ for how addresses are translated.
320
321.. code-block:: c
322
323    /* Read a register over PCI I/O Space */
324    extern uint8_t pci_io_r8(uint32_t adr);
325    extern uint16_t pci_io_r16(uint32_t adr);
326    extern uint32_t pci_io_r32(uint32_t adr);
327
328    /* Write a register over PCI I/O Space */
329    extern void pci_io_w8(uint32_t adr, uint8_t data);
330    extern void pci_io_w16(uint32_t adr, uint16_t data);
331    extern void pci_io_w32(uint32_t adr, uint32_t data);
332
333Registers over Memory space
334~~~~~~~~~~~~~~~~~~~~~~~~~~~
335
336PCI host bridge hardware normally swap data accesses into the endianness of the
337host architecture in order to lower the load of the CPU, peripherals can do DMA
338without swapping. However, the host controller can not separate a standard
339memory access from a memory access to a register, registers may be mapped into
340memory space. This leads to register content being swapped, which must be
341swapped back. The below routines makes it possible to access registers over PCI
342memory space in a portable way on different architectures, the BSP or
343architecture must provide necessary functions in order to implement this.
344
345.. code-block:: c
346
347    static inline uint16_t pci_ld_le16(volatile uint16_t *addr);
348    static inline void pci_st_le16(volatile uint16_t *addr, uint16_t val);
349    static inline uint32_t pci_ld_le32(volatile uint32_t *addr);
350    static inline void pci_st_le32(volatile uint32_t *addr, uint32_t val);
351    static inline uint16_t pci_ld_be16(volatile uint16_t *addr);
352    static inline void pci_st_be16(volatile uint16_t *addr, uint16_t val);
353    static inline uint32_t pci_ld_be32(volatile uint32_t *addr);
354    static inline void pci_st_be32(volatile uint32_t *addr, uint32_t val);
355
356In order to support non-standard big-endian PCI bus the above ``pci_*``
357functions is required, ``pci_ld_le16 != ld_le16`` on big endian PCI buses.
358
359Access functions
360~~~~~~~~~~~~~~~~
361
362The PCI Access Library can provide device drivers with function pointers
363executing the above Configuration, I/O and Memory space accesses. The functions
364have the same arguments and return values as the above functions.
365
366The pci_access_func() function defined below can be used to get a function
367pointer of a specific access type.
368
369.. code-block:: c
370
371    /* Get Read/Write function for accessing a register over PCI Memory Space
372     * (non-inline functions).
373     *
374     * Arguments
375     *  wr             0(Read), 1(Write)
376     *  size           1(Byte), 2(Word), 4(Double Word)
377     *  func           Where function pointer will be stored
378     *  endian         PCI_LITTLE_ENDIAN or PCI_BIG_ENDIAN
379     *  type           1(I/O), 3(REG over MEM), 4(CFG)
380     *
381     * Return
382     *  0              Found function
383     *  others         No such function defined by host driver or BSP
384    */
385    int pci_access_func(int wr, int size, void **func, int endian, int type);
386
387PCI device drivers may be written to support run-time detection of endianess,
388this is mosly for debugging or for development systems. When the product is
389finally deployed macros switch to using the inline functions instead which have
390been configured for the correct endianness.
391
392PCI address translation
393~~~~~~~~~~~~~~~~~~~~~~~
394
395When PCI addresses, both I/O and memory space, is not mapped 1:1 address
396translation before access is needed. If drivers read the PCI resources directly
397using configuration space routines or in the device tree, the addresses given
398are PCI addresses. The below functions can be used to translate PCI addresses
399into CPU accessible addresses or vice versa, translation may be different for
400different PCI spaces/regions.
401
402.. code-block:: c
403
404    /* Translate PCI address into CPU accessible address */
405    static inline int pci_pci2cpu(uint32_t *address, int type);
406
407    /* Translate CPU accessible address into PCI address (for DMA) */
408    static inline int pci_cpu2pci(uint32_t *address, int type);
409
410PCI Interrupt
411-------------
412
413The PCI specification defines four different interrupt lines INTA#..INTD#, the
414interrupts are low level sensitive which make it possible to support multiple
415interrupt sources on the same interrupt line. Since the lines are level
416sensitive the interrupt sources must be acknowledged before clearing the
417interrupt contoller, or the interrupt controller must be masked. The BSP must
418provide a routine for clearing/acknowledging the interrupt controller, it is up
419to the interrupt service routine to acknowledge the interrupt source.
420
421The PCI Library relies on the BSP for implementing shared interrupt handling
422through the BSP_PCI_shared_interrupt_* functions/macros, they must be defined
423when including bsp.h.
424
425PCI device drivers may use the pci_interrupt_* routines in order to call the
426BSP specific functions in a platform independent way. The PCI interrupt
427interface has been made similar to the RTEMS IRQ extension so that a BSP can
428use the standard RTEMS interrupt functions directly.
429
430PCI Shell command
431-----------------
432
433The RTEMS shell has a PCI command 'pci' which makes it possible to read/write
434configuration space, print the current PCI configuration and print out a
435configuration C-file for the static or peripheral library.
Note: See TracBrowser for help on using the repository browser.