source: SVN/cambria/redboot/packages/io/pci/current/doc/pci.sgml @ 1

Last change on this file since 1 was 1, checked in by Tim Harvey, 2 years ago

restored latest version of files from server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 34.1 KB
Line 
1<!-- {{{ Banner                         -->
2
3<!-- =============================================================== -->
4<!--                                                                 -->
5<!--     pci.sgml                                                    -->
6<!--                                                                 -->
7<!--     eCos PCI support                                            -->
8<!--                                                                 -->
9<!-- =============================================================== -->
10<!-- ####COPYRIGHTBEGIN####                                          -->
11<!--                                                                 -->
12<!-- =============================================================== -->
13<!-- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004 Red Hat, Inc.  -->
14<!-- This material may be distributed only subject to the terms      -->
15<!-- and conditions set forth in the Open Publication License, v1.0  -->
16<!-- or later (the latest version is presently available at          -->
17<!-- http://www.opencontent.org/openpub/)                            -->
18<!-- Distribution of the work or derivative of the work in any       -->
19<!-- standard (paper) book form is prohibited unless prior           -->
20<!-- permission obtained from the copyright holder                   -->
21<!-- =============================================================== -->
22<!--                                                                 -->     
23<!-- ####COPYRIGHTEND####                                            -->
24<!-- =============================================================== -->
25<!-- #####DESCRIPTIONBEGIN####                                       -->
26<!--                                                                 -->
27<!-- ####DESCRIPTIONEND####                                          -->
28<!-- =============================================================== -->
29
30<!-- }}} -->
31
32<PART id="io-pci">
33<TITLE>PCI Library</TITLE>
34<CHAPTER id="ecos-pci-library">
35<TITLE>The eCos PCI Library</TITLE>
36<PARA>The PCI library is an optional part of eCos, and is only
37        applicable to some platforms.</PARA>
38<SECT1 id="pci-library">
39<TITLE>PCI Library</TITLE>
40<PARA>The eCos PCI library provides the following functionality:</PARA>
41<orderedlist>
42<listitem><para>Scan the PCI bus for specific devices or devices of a certain
43class.</para></listitem>
44<listitem><para>Read and change generic PCI information.</para></listitem>
45<listitem><para>Read and change device-specific PCI information.</para></listitem>
46<listitem><para>Allocate PCI memory and IO space to devices.</para></listitem>
47<listitem><para>Translate a device's PCI interrupts to equivalent HAL
48vectors.</para></listitem>
49</orderedlist>
50<PARA>Example code fragments are from the pci1 test (see <filename>io/pci/&lt;release&gt;/tests/pci1.c</filename>).</PARA>
51<PARA>All of the functions described below are declared in the header
52file <filename>&lt;cyg/io/pci.h&gt;</filename> which all
53clients of the PCI library should include.</PARA>
54<SECT2>
55<TITLE>PCI Overview</TITLE>
56<PARA>The PCI bus supports several address spaces: memory, IO, and configuration. All PCI
57devices must support mandatory configuration space registers. Some devices may also present
58IO mapped and/or memory mapped resources. Before devices on the bus can be used, they must
59be configured. Basically, configuration will assign PCI IO and/or memory address ranges to
60each device and then enable that device. All PCI devices have a unique address in
61configuration space. This address is comprised of a bus number, a device number, and a
62function number. Special devices called bridges are used to connect two PCI busses together.
63The PCI standard supports up to 255 busses with each bus having up to 32 devices and each
64device having up to 8 functions.
65</PARA>
66<PARA>The environment in which a platform operates will dictate if and how eCos should
67configure devices on the PCI bus. If the platform acts as a host on a single PCI bus,
68then devices may be configured individually from the relevant device driver. If the
69platform is not the primary host, such as a PCI card plugged into a PC, configuration
70of PCI devices may be left to the PC BIOS. If PCI-PCI bridges are involved, configuration
71of all devices is best done all at once early in the boot process. This is because all
72devices on the secondary side of a bridge must be evaluated for their IO and memory space
73requirements before the bridge can be configured.
74</PARA>
75</SECT2>
76<SECT2>
77<TITLE>Initializing the bus</TITLE>
78<PARA>The PCI bus needs to be initialized before it can be used.
79This only needs to be done once - some HALs may do it as part of
80the platform initialization procedure, other HALs may leave it to
81the application or device drivers to do it. The following function
82will do the initialization only once, so it's safe to call from
83multiple drivers:</PARA>
84<PROGRAMLISTING>void cyg_pci_init( void );</PROGRAMLISTING>
85</SECT2>
86<SECT2>
87<TITLE>Scanning for devices</TITLE>
88<PARA>After the bus has been initialized, it is possible to scan
89it for devices. This is done using the function:</PARA>
90<PROGRAMLISTING>cyg_bool cyg_pci_find_next(  cyg_pci_device_id cur_devid,
91                             cyg_pci_device_id *next_devid );
92</PROGRAMLISTING>
93<PARA>It will scan the bus for devices starting at <parameter>cur_devid
94</parameter>. If a device is found, its devid is stored in <parameter>
95next_devid</parameter> and the function returns <constant>true</constant>.
96</PARA>
97<PARA>The <filename>pci1</filename> test's outer loop looks like:</PARA>
98<PROGRAMLISTING>
99    cyg_pci_init();
100    if (cyg_pci_find_next(CYG_PCI_NULL_DEVID, &amp;devid)) {
101        do {
102             &lt;use devid&gt;
103        } while (cyg_pci_find_next(devid, &amp;devid));
104    }</PROGRAMLISTING>
105<PARA>What happens is that the bus gets initialized and a scan is
106started. <literal>CYG_PCI_NULL_DEVID</literal> causes <function>
107cyg_pci_find_next()</function> to restart its scan. If the bus does not
108contain any devices, the first call to <function>cyg_pci_find_next()</function>
109will return <constant>false</constant>.</PARA>
110<PARA>If the call returns <constant>true</constant>, a loop is entered where
111the found devid is used. After devid processing has completed, the next device
112on the bus is searched for; <function>cyg_pci_find_next()</function>
113continues its scan from the current devid. The loop terminates when
114no more devices are found on the bus.</PARA>
115<PARA>This is the generic way of scanning the bus, enumerating all
116the devices on the bus. But if the application is looking for a
117device of a given device class (e.g., a SCSI controller), or a specific
118vendor device, these functions simplify the task a bit:</PARA>
119<PROGRAMLISTING>
120cyg_bool cyg_pci_find_class(  cyg_uint32 dev_class,
121                              cyg_pci_device_id *devid );
122cyg_bool cyg_pci_find_device(  cyg_uint16 vendor, cyg_uint16 device,
123                               cyg_pci_device_id *devid );</PROGRAMLISTING>
124<PARA>They work just like <function>cyg_pci_find_next()</function>,
125but only return true when the dev_class or vendor/device
126qualifiers match those of a device on the bus. The devid serves
127as both an input and an output operand: the scan starts at the given
128device, and if a device is found devid is updated with the value
129for the found device.</PARA>
130<PARA>The <filename>&lt;cyg/io/pci_cfg.h&gt;</filename> header
131file (included by <filename>pci.h</filename>) contains definitions for PCI
132class, vendor and device codes which can be used as arguments to the find
133functions.
134The list of vendor and device codes is not complete: add new codes
135as necessary. If possible also register the codes at the PCI Code
136List (<ulink url="http://www.yourvote.com/pci">http://www.yourvote.com/pci)
137</ulink> which is where the eCos definitions are generated from.</PARA>
138</SECT2>
139<SECT2>
140<TITLE>Generic config information</TITLE>
141<PARA>When a valid device ID (devid) is found using one of the above
142functions, the associated device can be queried and controlled using
143the functions:</PARA>
144<PROGRAMLISTING>
145void cyg_pci_get_device_info (  cyg_pci_device_id devid,
146                                cyg_pci_device *dev_info );
147void cyg_pci_set_device_info (  cyg_pci_device_id devid,
148                                cyg_pci_device *dev_info );</PROGRAMLISTING>
149<PARA>The <structname>cyg_pci_device structure</structname> (defined in
150<filename>pci.h</filename>) primarily holds information as described by the PCI
151 specification <link linkend=pci-spec>[1]</link>.
152The <filename>pci1</filename> test prints out some of this information:</PARA>
153<PROGRAMLISTING>            // Get device info
154            cyg_pci_get_device_info(devid, &amp;dev_info);
155            diag_printf("\n Command   0x%04x, Status 0x%04x\n",
156                        dev_info.command, dev_info.status);</PROGRAMLISTING>
157<PARA>The command register can also be written to, controlling (among
158other things) whether the device responds to IO and memory access
159from the bus. </PARA>
160</SECT2>
161<SECT2>
162<TITLE>Specific config information</TITLE>
163<PARA>The above functions only allow access to generic PCI config
164registers. A device can have extra config registers not specified
165by the PCI specification. These can be accessed with these functions:</PARA>
166<PROGRAMLISTING>
167void cyg_pci_read_config_uint8(  cyg_pci_device_id devid,
168                                 cyg_uint8 offset, cyg_uint8 *val);
169void cyg_pci_read_config_uint16(  cyg_pci_device_id devid,
170                                  cyg_uint8 offset, cyg_uint16 *val);
171void cyg_pci_read_config_uint32(  cyg_pci_device_id devid,
172                                  cyg_uint8 offset, cyg_uint32 *val);
173void cyg_pci_write_config_uint8(  cyg_pci_device_id devid,
174                                  cyg_uint8 offset, cyg_uint8 val);
175void cyg_pci_write_config_uint16(  cyg_pci_device_id devid,
176                                   cyg_uint8 offset, cyg_uint16 val);
177void cyg_pci_write_config_uint32(  cyg_pci_device_id devid,
178                                   cyg_uint8 offset, cyg_uint32 val);
179</PROGRAMLISTING>
180<PARA>The write functions should only be used for device-specific
181config registers since using them on generic registers may invalidate
182the contents of a previously fetched cyg_pci_device
183structure.</PARA>
184</SECT2>
185<SECT2>
186<TITLE>Allocating memory</TITLE>
187<PARA>A PCI device ignores all IO and memory access from the PCI
188bus until it has been activated. Activation cannot happen until
189after device configuration. Configuration means telling the device
190where it should map its IO and memory resources. This is done with
191one of the following functions::</PARA>
192<PROGRAMLISTING>cyg_bool cyg_pci_configure_device( cyg_pci_device *dev_info );
193cyg_bool cyg_pci_configure_bus( cyg_uint8 bus, cyg_uint8 *next_bus );
194</PROGRAMLISTING>
195<PARA>The <function>cyg_pci_configure_device</function> handles all IO
196and memory regions that need configuration on non-bridge devices. On
197platforms with multiple busses connected by bridges, the <function>
198cyg_pci_configure_bus</function> function should be used. It will recursively
199configure all devices on the given <parameter>bus</parameter> and all
200subordinate busses. <function>cyg_pci_configure_bus</function> will
201use <function>cyg_pci_configure_device</function> to configure
202individual non-bridge devices.
203</PARA>
204<PARA> Each region is represented in the PCI device's config space by BARs
205(Base Address Registers) and is handled individually according to type
206using these functions:</PARA>
207<PROGRAMLISTING>cyg_bool cyg_pci_allocate_memory(  cyg_pci_device *dev_info,
208                                   cyg_uint32 bar,
209                                   CYG_PCI_ADDRESS64 *base );
210cyg_bool cyg_pci_allocate_io(  cyg_pci_device *dev_info,
211                               cyg_uint32 bar,
212                               CYG_PCI_ADDRESS32 *base );</PROGRAMLISTING>
213<PARA>The memory bases (in two distinct address spaces) are increased
214as memory regions are allocated to devices. Allocation will fail
215(the function returns false) if the base exceeds the limits of the
216address space (IO is 1MB, memory is 2^32 or 2^64 bytes).</PARA>
217<PARA>These functions can also be called directly by the application/driver
218if necessary, but this should not be necessary.</PARA>
219<PARA>The bases are initialized with default values provided by
220the HAL. It is possible for an application to override these using
221the following functions: </PARA>
222<PROGRAMLISTING>void cyg_pci_set_memory_base(  CYG_PCI_ADDRESS64 base );
223void cyg_pci_set_io_base( CYG_PCI_ADDRESS32 base );</PROGRAMLISTING>
224<PARA>When a device has been configured, the cyg_pci_device
225structure will contain the physical address in the CPU's
226address space where the device's memory regions can be
227accessed. </PARA>
228<PARA>This information is provided in <varname>base_map[]</varname> -
229there is a 32 bit word for each of the device's BARs. For
23032 bit PCI memory regions, each 32 bit word will be an actual pointer
231that can be used immediately by the driver: the memory space will normally
232be linearly addressable by the CPU.</PARA>
233<PARA>However, for 64 bit PCI memory regions, some (or all) of the
234region may be outside of the CPUs address space. In this case the
235driver will need to know how to access the region in segments. This
236functionality may be adopted by the eCos HAL if deemed useful in
237the future. The 2GB available on many systems should suffice though.</PARA>
238</SECT2>
239<SECT2 id="pci-interrupts">
240<TITLE>Interrupts</TITLE>
241<PARA>A device may generate interrupts. The HAL vector associated
242with a given device on the bus is platform specific. This function
243allows a driver to find the actual interrupt vector for a given
244device:</PARA>
245<PROGRAMLISTING>cyg_bool cyg_pci_translate_interrupt(  cyg_pci_device *dev_info,
246                                       CYG_ADDRWORD *vec );</PROGRAMLISTING>
247<PARA>If the function returns false, no interrupts will be generated
248by the device. If it returns true, the CYG_ADDRWORD pointed
249to by vec is updated with the HAL interrupt vector the device will
250be using. This is how the function is used in the <filename>pci1</filename>
251test:</PARA>
252<PROGRAMLISTING>            if (cyg_pci_translate_interrupt(&amp;dev_info, &amp;irq))
253                diag_printf(" Wired to HAL vector %d\n", irq);
254            else
255                diag_printf(" Does not generate interrupts.\n");</PROGRAMLISTING>
256<PARA>The application/drive should attach an interrupt
257handler to a device's interrupt before activating the device.</PARA>
258</SECT2>
259<SECT2>
260<TITLE>Activating a device</TITLE>
261<PARA>When the device has been allocated memory space it can be
262activated. This is not done by the library since a driver may have
263to initialize more state on the device before it can be safely activated.</PARA>
264<PARA>Activating the device is done by enabling flags in its command
265word. As an example, see the <filename>pci1</filename> test which can be
266configured to enable the devices it finds. This allows these to be accessed from
267GDB (if a breakpoint is set on <function>cyg_test_exit</function>):</PARA>
268<PROGRAMLISTING>#ifdef ENABLE_PCI_DEVICES
269      {
270          cyg_uint16 cmd;
271
272          // Don't use cyg_pci_set_device_info since it clears
273          // some of the fields we want to print out below.
274          cyg_pci_read_config_uint16(dev_info.devid,
275                                     CYG_PCI_CFG_COMMAND, &amp;cmd);
276          cmd |= CYG_PCI_CFG_COMMAND_IO|CYG_PCI_CFG_COMMAND_MEMORY;
277          cyg_pci_write_config_uint16(dev_info.devid,
278                                      CYG_PCI_CFG_COMMAND, cmd);
279      }
280      diag_printf(" **** Device IO and MEM access enabled\n");
281#endif</PROGRAMLISTING>
282<note><title>Note</title><PARA>The best way to activate a device is actually
283through <function>cyg_pci_set_device_info()</function>,
284but in this particular case the <structname>cyg_pci_device</structname>
285structure contents from before the activation is required for printout
286further down in the code.</PARA></note>
287</SECT2>
288<SECT2>
289<TITLE>Links</TITLE>
290<PARA>See these links for more information about PCI:</PARA>
291<orderedlist>
292<listitem><PARA><anchor id="pci-spec"><ulink url="http://www.pcisig.com/">
293http://www.pcisig.com/</ulink> - information on the PCI specifications
294</para></listitem>
295<listitem><para>
296<ulink url="http://www.yourvote.com/pci/">http://www.yourvote.com/pci/
297</ulink> - list of vendor and device IDs
298</para>
299</listitem>
300<listitem><para><ulink url="http://www.picmg.org/">http://www.picmg.org/
301</ulink> - PCI Industrial Computer Manufacturers Group</PARA>
302</listitem>
303</orderedlist>
304</SECT2>
305</SECT1>
306<SECT1 id="pci-library-reference">
307<TITLE>PCI Library reference</TITLE>
308<PARA>This document defines the PCI Support Library for eCos.</PARA>
309<PARA>The PCI support library provides a set of routines for accessing
310the PCI bus configuration space in a portable manner. This is provided
311by two APIs. The high level API is used by device drivers, or other
312code, to access the PCI configuration space portably. The low level
313API is used by the PCI library itself to access the hardware in
314a platform-specific manner, and may also be used by device drivers
315to access the PCI configuration space directly.</PARA>
316<PARA>Underlying the low-level API is HAL support for the basic
317configuration space operations. These should not generally be used
318by any code other than the PCI library, and are present in the HAL
319to allow low level initialization of the PCI bus and devices to
320take place if necessary.</PARA>
321<SECT2>
322<TITLE>PCI Library API</TITLE>
323<PARA>The PCI library provides the following routines and types
324for accessing the PCI configuration space.</PARA>
325<PARA>The API for the PCI library is found in the header file
326<filename class=headerfile>&lt;cyg/io/pci.h&gt;</filename>.</PARA>
327</SECT2>
328<SECT2>
329<TITLE>Definitions</TITLE>
330<PARA>The header file contains definitions for the common configuration
331structure offsets and specimen values for device, vendor and class
332code.</PARA>
333</SECT2>
334<SECT2>
335<TITLE>Types and data structures</TITLE>
336<PARA>The following types are defined:</PARA>
337<PROGRAMLISTING>typedef CYG_WORD32 cyg_pci_device_id;</PROGRAMLISTING>
338<PARA>This is comprised of the bus number, device number and functional
339unit numbers packed into a single word. The macro <function>CYG_PCI_DEV_MAKE_ID()
340</function>, in conjunction with the <function>CYG_PCI_DEV_MAKE_DEVFN()</function>
341macro, may be used to construct a device id from the bus, device and functional
342unit numbers. Similarly the macros <function>CYG_PCI_DEV_GET_BUS()</function>,
343<function>CYG_PCI_DEV_GET_DEVFN()</function>,
344<function>CYG_PCI_DEV_GET_DEV()</function>, and
345<function>CYG_PCI_DEV_GET_FN()</function> may be used to extract the
346constituent parts of a device id. It should not be necessary to use these
347macros under normal circumstances. The following code fragment demonstrates
348how these macros may be used:</PARA>
349<PROGRAMLISTING>
350  // Create a packed representation of device 1, function 0
351  cyg_uint8 devfn = CYG_PCI_DEV_MAKE_DEVFN(1,0);
352
353  // Create a packed devid for that device on bus 2
354  cyg_pci_device_id devid = CYG_PCI_DEV_MAKE_ID(2, devfn);
355
356  diag_printf("bus %d, dev %d, func %d\n",
357              CYG_PCI_DEV_GET_BUS(devid),
358              CYG_PCI_DEV_GET_DEV(CYG_PCI_DEV_GET_DEVFN(devid)),
359              CYG_PCI_DEV_GET_FN(CYG_PCI_DEV_GET_DEVFN(devid));
360</PROGRAMLISTING>
361<PROGRAMLISTING>typedef struct cyg_pci_device;</PROGRAMLISTING>
362<PARA>This structure is used to contain data read from a PCI device's
363configuration header by <function>cyg_pci_get_device_info()</function>.
364It is also used to record the resource allocations made to the device.</PARA>
365<PROGRAMLISTING>typedef CYG_WORD64 CYG_PCI_ADDRESS64;
366typedef CYG_WORD32 CYG_PCI_ADDRESS32;</PROGRAMLISTING>
367<PARA>Pointers in the PCI address space are 32 bit (IO space) or
36832/64 bit (memory space). In most platform and device configurations
369all of PCI memory will be linearly addressable using only 32 bit
370pointers as read from <varname>base_map[]</varname>.</PARA>
371<PARA>The 64 bit type is used to allow handling 64 bit devices in
372the future, should it be necessary, without changing the library's
373API.</PARA>
374</SECT2>
375<SECT2>
376<TITLE>Functions</TITLE>
377<PROGRAMLISTING>void cyg_pci_init(void);</PROGRAMLISTING>
378<PARA>Initialize the PCI library and establish contact with the
379hardware. This function is idempotent and can be called either by
380all drivers in the system, or just from an application initialization
381function.</PARA>
382<PROGRAMLISTING>cyg_bool cyg_pci_find_device( cyg_uint16 vendor,
383                              cyg_uint16 device,
384                              cyg_pci_device_id *devid );</PROGRAMLISTING>
385<PARA>Searches the PCI bus configuration space for a device with
386the given <parameter>vendor</parameter> and <parameter>device</parameter>
387ids. The search starts at the device pointed to by <parameter>devid</parameter>,
388or at the first slot if it contains <literal>CYG_PCI_NULL_DEVID</literal>.
389<parameter>*devid</parameter> will be updated with the ID of the next device
390found. Returns <constant>true</constant> if one is found and <constant>false
391</constant> if not.</PARA>
392<PROGRAMLISTING>cyg_bool cyg_pci_find_class( cyg_uint32 dev_class,
393                             cyg_pci_device_id *devid );</PROGRAMLISTING>
394<PARA>Searches the PCI bus configuration space for a device with
395the given <parameter>dev_class</parameter> class code.  The search starts at the
396device pointed to by <parameter>devid</parameter>, or at the first slot if it
397contains <literal>CYG_PCI_NULL_DEVID</literal>.</PARA>
398<PARA><parameter>*devid</parameter> will be updated with the ID of the next
399device found. Returns <constant>true</constant> if one is found and
400<constant>false</constant> if not.</PARA>
401<PROGRAMLISTING>cyg_bool cyg_pci_find_next( cyg_pci_device_id cur_devid,
402                            cyg_pci_device_id *next_devid );</PROGRAMLISTING>
403<PARA>Searches the PCI configuration space for the next valid device
404after <parameter>cur_devid</parameter>. If <parameter>cur_devid</parameter>
405is given the value <literal>CYG_PCI_NULL_DEVID</literal>, then the search starts
406at the first slot. It is permitted for <parameter>next_devid</parameter> to
407point to <parameter>cur_devid</parameter>.  Returns <constant>true</constant>
408if another device is found and <constant>false</constant> if not.</PARA>
409<PROGRAMLISTING>
410cyg_bool cyg_pci_find_matching( cyg_pci_match_func *matchp,
411                                void * match_callback_data,
412                                cyg_pci_device_id *devid );
413</PROGRAMLISTING>
414<PARA>Searches the PCI bus configuration space for a device whose properties
415match those required by the caller supplied <parameter>cyg_pci_match_func</parameter>.
416The search starts at the device pointed to by <parameter>devid</parameter>, or
417at the first slot if it contains <constant>CYG_PCI_NULL_DEVID</constant>. The
418<parameter>devid</parameter> will be updated with the ID of the next device found.
419This function returns <constant>true</constant> if a matching device is found
420and <constant>false</constant> if not.
421</PARA>
422<PARA>The match_func has a type declared as:</PARA>
423<PROGRAMLISTING>
424typedef cyg_bool (cyg_pci_match_func)( cyg_uint16 vendor,
425                                       cyg_uint16 device,
426                                       cyg_uint32 class,
427                                       void *     user_data);
428</PROGRAMLISTING>
429<PARA>The <parameter>vendor</parameter>, <parameter>device</parameter>, and
430<parameter>class</parameter> are from the device configuration space. The
431<parameter>user_data</parameter> is the callback data passed to <function>
432cyg_pci_find_matching</function>.
433</PARA>
434<PROGRAMLISTING>void cyg_pci_get_device_info ( cyg_pci_device_id devid,
435                               cyg_pci_device *dev_info );</PROGRAMLISTING>
436<PARA>This function gets the PCI configuration information for the
437device indicated in <parameter>devid</parameter>. The common fields of the
438<structname>cyg_pci_device</structname> structure, and the appropriate fields
439of the relevant header union member are filled in from the device's
440configuration space.
441If the device has not been enabled, then this function will also fetch
442the size and type information from the base address registers and
443place it in the <varname>base_size[]</varname> array.</PARA>
444<PROGRAMLISTING>void cyg_pci_set_device_info ( cyg_pci_device_id devid,
445                               cyg_pci_device *dev_info );</PROGRAMLISTING>
446<PARA>This function sets the PCI configuration information for the
447device indicated in <parameter>devid</parameter>. Only the configuration space
448registers that are writable are actually written. Once all the fields have
449been written, the device info will be read back into <parameter>*dev_info
450</parameter>, so that it reflects the true state of the hardware.</PARA>
451<PROGRAMLISTING>
452void cyg_pci_read_config_uint8(  cyg_pci_device_id devid,
453                                 cyg_uint8 offset, cyg_uint8 *val );
454void cyg_pci_read_config_uint16( cyg_pci_device_id devid,
455                                 cyg_uint8 offset, cyg_uint16 *val );
456void cyg_pci_read_config_uint32( cyg_pci_device_id devid,
457                                 cyg_uint8 offset, cyg_uint32 *val );
458</PROGRAMLISTING>
459<PARA>These functions read registers of the appropriate size from
460the configuration space of the given device. They should mainly
461be used to access registers that are device specific. General PCI
462registers are best accessed through <function>cyg_pci_get_device_info()
463</function>.</PARA>
464<PROGRAMLISTING>
465void cyg_pci_write_config_uint8(  cyg_pci_device_id devid,
466                                  cyg_uint8 offset, cyg_uint8 val );
467void cyg_pci_write_config_uint16( cyg_pci_device_id devid,
468                                  cyg_uint8 offset, cyg_uint16 val );
469void cyg_pci_write_config_uint32( cyg_pci_device_id devid,
470                                  cyg_uint8 offset, cyg_uint32 val );
471</PROGRAMLISTING>
472<PARA>These functions write registers of the appropriate size to
473the configuration space of the given device. They should mainly
474be used to access registers that are device specific. General PCI
475registers are best accessed through <function>cyg_pci_get_device_info()
476</function>. Writing the general registers this way may render the contents of
477a <structname>cyg_pci_device</structname> structure invalid.</PARA>
478</SECT2>
479<SECT2>
480<TITLE>Resource allocation</TITLE>
481<PARA>These routines allocate memory and I/O space to PCI devices.</PARA>
482<PROGRAMLISTING>cyg_bool cyg_pci_configure_device( cyg_pci_device *dev_info )</PROGRAMLISTING>
483<PARA>Allocate memory and IO space to all base address registers
484using the current memory and IO base addresses in the library. The
485allocated base addresses, translated into directly usable values,
486will be put into the matching <varname>base_map[]</varname> entries
487in <parameter>*dev_info</parameter>. If <parameter>*dev_info</parameter> does
488not contain valid <varname>base_size[]</varname> entries, then the result is
489<constant>false</constant>. This function will also call <function>
490cyg_pci_translate_interrupt()</function> to put the interrupt vector into the
491HAL vector entry.</PARA>
492<PROGRAMLISTING>cyg_bool cyg_pci_configure_bus( cyg_uint8 bus, cyg_uint8 *next_bus )
493</PROGRAMLISTING>
494<PARA>Allocate memory and IO space to all base address registers on all devices
495on the given bus and all subordinate busses. If a PCI-PCI bridge is found on
496<parameter>bus</parameter>, this function will call itself recursively in order
497to configure the bus on the other side of the bridge. Because of the nature of
498bridge devices, all devices on the secondary side of a bridge must be allocated
499memory and IO space before the memory and IO windows on the bridge device can be
500properly configured. The <parameter>next_bus</parameter> argument points to the
501bus number to assign to the next subordinate bus found. The number will be
502incremented as new busses are discovered. If successful, <constant>true</constant>
503is returned. Otherwise, <constant>false</constant> is returned.
504</PARA>
505<PROGRAMLISTING>
506cyg_bool cyg_pci_translate_interrupt( cyg_pci_device *dev_info,
507                                      CYG_ADDRWORD *vec );
508</PROGRAMLISTING>
509<PARA>Translate the device's PCI interrupt (INTA#-INTD#)
510to the associated HAL vector. This may also depend on which slot
511the device occupies. If the device may generate interrupts, the
512translated vector number will be stored in <parameter>vec</parameter> and the
513result is <constant>true</constant>. Otherwise the result is <constant>false
514</constant>.</PARA>
515<PROGRAMLISTING>
516cyg_bool cyg_pci_allocate_memory( cyg_pci_device *dev_info,
517                                  cyg_uint32 bar,
518                                  CYG_PCI_ADDRESS64 *base );
519cyg_bool cyg_pci_allocate_io( cyg_pci_device *dev_info,
520                              cyg_uint32 bar,
521                              CYG_PCI_ADDRESS32 *base );
522</PROGRAMLISTING>
523<PARA>These routines allocate memory or I/O space to the base address
524register indicated by <parameter>bar</parameter>. The base address in
525<parameter>*base</parameter> will be correctly aligned and the address of the
526next free location will be written back into it if the allocation succeeds. If
527the base address register is of the wrong type for this allocation, or
528<parameter>dev_info</parameter> does not contain valid <varname>base_size[]
529</varname> entries, the result is <constant>false</constant>. These functions
530allow a device driver to set up its own mappings if it wants. Most devices
531should probably use <function>cyg_pci_configure_device()</function>.</PARA>
532<PROGRAMLISTING>void cyg_pci_set_memory_base( CYG_PCI_ADDRESS64 base );
533void cyg_pci_set_io_base( CYG_PCI_ADDRESS32 base );</PROGRAMLISTING>
534<PARA>These routines set the base addresses for memory and I/O mappings
535to be used by the memory allocation routines. Normally these base
536addresses will be set to default values based on the platform. These
537routines allow these to be changed by application code if necessary.</PARA>
538</SECT2>
539<SECT2>
540<TITLE>PCI Library Hardware API</TITLE>
541<PARA>This API is used by the PCI library to access the PCI bus
542configuration space. Although it should not normally be necessary,
543this API may also be used by device driver or application code to
544perform PCI bus operations not supported by the PCI library.</PARA>
545<PROGRAMLISTING>void cyg_pcihw_init(void);</PROGRAMLISTING>
546<PARA>Initialize the PCI hardware so that the configuration space
547may be accessed.</PARA>
548<PROGRAMLISTING>
549void cyg_pcihw_read_config_uint8(  cyg_uint8 bus,
550               cyg_uint8 devfn, cyg_uint8 offset, cyg_uint8 *val);
551void cyg_pcihw_read_config_uint16( cyg_uint8 bus,
552               cyg_uint8 devfn, cyg_uint8 offset, cyg_uint16 *val);
553void cyg_pcihw_read_config_uint32( cyg_uint8 bus,
554               cyg_uint8 devfn, cyg_uint8 offset, cyg_uint32 *val);
555</PROGRAMLISTING>
556<PARA>These functions read a register of the appropriate size from
557the PCI configuration space at an address composed from the <parameter>bus
558</parameter>, <parameter>devfn</parameter> and <parameter>offset</parameter>
559arguments.</PARA>
560<PROGRAMLISTING>
561void cyg_pcihw_write_config_uint8(  cyg_uint8 bus,
562                cyg_uint8 devfn, cyg_uint8 offset, cyg_uint8 val);
563void cyg_pcihw_write_config_uint16( cyg_uint8 bus,
564                cyg_uint8 devfn, cyg_uint8 offset, cyg_uint16 val);
565void cyg_pcihw_write_config_uint32( cyg_uint8 bus,
566                cyg_uint8 devfn, cyg_uint8 offset, cyg_uint32 val);
567</PROGRAMLISTING>
568<PARA>These functions write a register of the appropriate size to
569the PCI configuration space at an address composed from the
570<parameter>bus</parameter>, <parameter>devfn</parameter> and
571<parameter>offset</parameter> arguments.</PARA>
572<PROGRAMLISTING>
573cyg_bool cyg_pcihw_translate_interrupt( cyg_uint8 bus,
574                                        cyg_uint8 devfn,
575                                        CYG_ADDRWORD *vec);
576</PROGRAMLISTING>
577<PARA>This function interrogates the device and determines which
578HAL interrupt vector it is connected to.</PARA>
579</SECT2>
580<SECT2>
581<TITLE>HAL PCI support</TITLE>
582<PARA>HAL support consists of a set of C macros that provide the
583implementation of the low level PCI API.</PARA>
584<PROGRAMLISTING>HAL_PCI_INIT()</PROGRAMLISTING>
585<PARA>Initialize the PCI bus.</PARA>
586<PROGRAMLISTING>HAL_PCI_READ_UINT8( bus, devfn, offset, val )
587HAL_PCI_READ_UINT16( bus, devfn, offset, val )
588HAL_PCI_READ_UINT32( bus, devfn, offset, val )</PROGRAMLISTING>
589<PARA>Read a value from the PCI configuration space of the appropriate
590size at an address composed from the <parameter>bus</parameter>, <parameter>
591devfn</parameter> and <parameter>offset</parameter>.</PARA>
592<PROGRAMLISTING>HAL_PCI_WRITE_UINT8( bus, devfn, offset, val )
593HAL_PCI_WRITE_UINT16( bus, devfn, offset, val )
594HAL_PCI_WRITE_UINT32( bus, devfn, offset, val )</PROGRAMLISTING>
595<PARA>Write a value to the PCI configuration space of the appropriate
596size at an address composed from the <parameter>bus</parameter>, <parameter>
597devfn</parameter> and <parameter>offset</parameter>.</PARA>
598<PROGRAMLISTING>HAL_PCI_TRANSLATE_INTERRUPT( bus, devfn, *vec, valid )</PROGRAMLISTING>
599<PARA>Translate the device's interrupt line into a HAL
600interrupt vector.</PARA>
601<PROGRAMLISTING>HAL_PCI_ALLOC_BASE_MEMORY
602HAL_PCI_ALLOC_BASE_IO</PROGRAMLISTING>
603<PARA>These macros define the default base addresses used to initialize
604the memory and I/O allocation pointers.</PARA>
605<PROGRAMLISTING>HAL_PCI_PHYSICAL_MEMORY_BASE
606HAL_PCI_PHYSICAL_IO_BASE</PROGRAMLISTING>
607<PARA>PCI memory and IO range do not always correspond directly
608to physical memory or IO addresses. Frequently the PCI address spaces
609are windowed into the processor's address range at some
610offset. These macros define offsets to be added to the PCI base
611addresses to translate PCI bus addresses into physical memory addresses
612that can be used to access the allocated memory or IO space.</PARA>
613<NOTE>
614<PARA>The chunk of PCI memory space directly addressable though
615the window by the CPU may be smaller than the amount of PCI memory
616actually provided. In that case drivers will have to access PCI
617memory space in segments. Doing this will be platform specific and
618is currently beyond the scope of the HAL.</PARA>
619</NOTE>
620<PROGRAMLISTING>HAL_PCI_IGNORE_DEVICE( bus, dev, fn )</PROGRAMLISTING
621<PARA>This macro, if defined, may be used to limit the devices which are
622found by the bus scanning functions. This is sometimes necessary for
623devices which need special handling. If this macro evaluates to <constant>true
624</constant>, the given device will not be found by <function>cyg_pci_find_next
625</function> or other bus scanning functions.
626</PARA>
627<PROGRAMLISTING>HAL_PCI_IGNORE_BAR( dev_info, bar_num )</PROGRAMLISTING
628<PARA>This macro, if defined, may be used to limit which BARs are discovered
629and configured. This is sometimes necessary for platforms with limited PCI
630windows. If this macro evaluates to <constant>true</constant>, the given BAR
631will not be discovered by <function>cyg_pci_get_device_info</function> and
632therefore not configured by <function>cyg_pci_configure_device</function>.
633</PARA>
634</SECT2>
635</SECT1>
636</CHAPTER>
637</PART>
Note: See TracBrowser for help on using the repository browser.