📄 pci.sgml
字号:
CYG_PCI_ADDRESS32 *base );</PROGRAMLISTING>
<PARA>The memory bases (in two distinct address spaces) are increased
as memory regions are allocated to devices. Allocation will fail
(the function returns false) if the base exceeds the limits of the
address space (IO is 1MB, memory is 2^32 or 2^64 bytes).</PARA>
<PARA>These functions can also be called directly by the application/driver
if necessary, but this should not be necessary.</PARA>
<PARA>The bases are initialized with default values provided by
the HAL. It is possible for an application to override these using
the following functions: </PARA>
<PROGRAMLISTING>void cyg_pci_set_memory_base( CYG_PCI_ADDRESS64 base );
void cyg_pci_set_io_base( CYG_PCI_ADDRESS32 base );</PROGRAMLISTING>
<PARA>When a device has been configured, the cyg_pci_device
structure will contain the physical address in the CPU's
address space where the device's memory regions can be
accessed. </PARA>
<PARA>This information is provided in <varname>base_map[]</varname> -
there is a 32 bit word for each of the device's BARs. For
32 bit PCI memory regions, each 32 bit word will be an actual pointer
that can be used immediately by the driver: the memory space will normally
be linearly addressable by the CPU.</PARA>
<PARA>However, for 64 bit PCI memory regions, some (or all) of the
region may be outside of the CPUs address space. In this case the
driver will need to know how to access the region in segments. This
functionality may be adopted by the eCos HAL if deemed useful in
the future. The 2GB available on many systems should suffice though.</PARA>
</SECT2>
<SECT2 id="pci-interrupts">
<TITLE>Interrupts</TITLE>
<PARA>A device may generate interrupts. The HAL vector associated
with a given device on the bus is platform specific. This function
allows a driver to find the actual interrupt vector for a given
device:</PARA>
<PROGRAMLISTING>cyg_bool cyg_pci_translate_interrupt( cyg_pci_device *dev_info,
CYG_ADDRWORD *vec );</PROGRAMLISTING>
<PARA>If the function returns false, no interrupts will be generated
by the device. If it returns true, the CYG_ADDRWORD pointed
to by vec is updated with the HAL interrupt vector the device will
be using. This is how the function is used in the <filename>pci1</filename>
test:</PARA>
<PROGRAMLISTING> if (cyg_pci_translate_interrupt(&dev_info, &irq))
diag_printf(" Wired to HAL vector %d\n", irq);
else
diag_printf(" Does not generate interrupts.\n");</PROGRAMLISTING>
<PARA>The application/drive should attach an interrupt
handler to a device's interrupt before activating the device.</PARA>
</SECT2>
<SECT2>
<TITLE>Activating a device</TITLE>
<PARA>When the device has been allocated memory space it can be
activated. This is not done by the library since a driver may have
to initialize more state on the device before it can be safely activated.</PARA>
<PARA>Activating the device is done by enabling flags in its command
word. As an example, see the <filename>pci1</filename> test which can be
configured to enable the devices it finds. This allows these to be accessed from
GDB (if a breakpoint is set on <function>cyg_test_exit</function>):</PARA>
<PROGRAMLISTING>#ifdef ENABLE_PCI_DEVICES
{
cyg_uint16 cmd;
// Don't use cyg_pci_set_device_info since it clears
// some of the fields we want to print out below.
cyg_pci_read_config_uint16(dev_info.devid,
CYG_PCI_CFG_COMMAND, &cmd);
cmd |= CYG_PCI_CFG_COMMAND_IO|CYG_PCI_CFG_COMMAND_MEMORY;
cyg_pci_write_config_uint16(dev_info.devid,
CYG_PCI_CFG_COMMAND, cmd);
}
diag_printf(" **** Device IO and MEM access enabled\n");
#endif</PROGRAMLISTING>
<note><title>Note</title><PARA>The best way to activate a device is actually
through <function>cyg_pci_set_device_info()</function>,
but in this particular case the <structname>cyg_pci_device</structname>
structure contents from before the activation is required for printout
further down in the code.</PARA></note>
</SECT2>
<SECT2>
<TITLE>Links</TITLE>
<PARA>See these links for more information about PCI:</PARA>
<orderedlist>
<listitem><PARA><anchor id="pci-spec"><ulink url="http://www.pcisig.com/">
http://www.pcisig.com/</ulink> - information on the PCI specifications
</para></listitem>
<listitem><para>
<ulink url="http://www.yourvote.com/pci/">http://www.yourvote.com/pci/
</ulink> - list of vendor and device IDs
</para>
</listitem>
<listitem><para><ulink url="http://www.picmg.org/">http://www.picmg.org/
</ulink> - PCI Industrial Computer Manufacturers Group</PARA>
</listitem>
</orderedlist>
</SECT2>
</SECT1>
<SECT1 id="pci-library-reference">
<TITLE>PCI Library reference</TITLE>
<PARA>This document defines the PCI Support Library for eCos.</PARA>
<PARA>The PCI support library provides a set of routines for accessing
the PCI bus configuration space in a portable manner. This is provided
by two APIs. The high level API is used by device drivers, or other
code, to access the PCI configuration space portably. The low level
API is used by the PCI library itself to access the hardware in
a platform-specific manner, and may also be used by device drivers
to access the PCI configuration space directly.</PARA>
<PARA>Underlying the low-level API is HAL support for the basic
configuration space operations. These should not generally be used
by any code other than the PCI library, and are present in the HAL
to allow low level initialization of the PCI bus and devices to
take place if necessary.</PARA>
<SECT2>
<TITLE>PCI Library API</TITLE>
<PARA>The PCI library provides the following routines and types
for accessing the PCI configuration space.</PARA>
<PARA>The API for the PCI library is found in the header file
<filename class=headerfile><cyg/io/pci.h></filename>.</PARA>
</SECT2>
<SECT2>
<TITLE>Definitions</TITLE>
<PARA>The header file contains definitions for the common configuration
structure offsets and specimen values for device, vendor and class
code.</PARA>
</SECT2>
<SECT2>
<TITLE>Types and data structures</TITLE>
<PARA>The following types are defined:</PARA>
<PROGRAMLISTING>typedef CYG_WORD32 cyg_pci_device_id;</PROGRAMLISTING>
<PARA>This is comprised of the bus number, device number and functional
unit numbers packed into a single word. The macro <function>CYG_PCI_DEV_MAKE_ID()
</function>, in conjunction with the <function>CYG_PCI_DEV_MAKE_DEVFN()</function>
macro, may be used to construct a device id from the bus, device and functional
unit numbers. Similarly the macros <function>CYG_PCI_DEV_GET_BUS()</function>,
<function>CYG_PCI_DEV_GET_DEVFN()</function>,
<function>CYG_PCI_DEV_GET_DEV()</function>, and
<function>CYG_PCI_DEV_GET_FN()</function> may be used to extract the
constituent parts of a device id. It should not be necessary to use these
macros under normal circumstances. The following code fragment demonstrates
how these macros may be used:</PARA>
<PROGRAMLISTING>
// Create a packed representation of device 1, function 0
cyg_uint8 devfn = CYG_PCI_DEV_MAKE_DEVFN(1,0);
// Create a packed devid for that device on bus 2
cyg_pci_device_id devid = CYG_PCI_DEV_MAKE_ID(2, devfn);
diag_printf("bus %d, dev %d, func %d\n",
CYG_PCI_DEV_GET_BUS(devid),
CYG_PCI_DEV_GET_DEV(CYG_PCI_DEV_GET_DEVFN(devid)),
CYG_PCI_DEV_GET_FN(CYG_PCI_DEV_GET_DEVFN(devid));
</PROGRAMLISTING>
<PROGRAMLISTING>typedef struct cyg_pci_device;</PROGRAMLISTING>
<PARA>This structure is used to contain data read from a PCI device's
configuration header by <function>cyg_pci_get_device_info()</function>.
It is also used to record the resource allocations made to the device.</PARA>
<PROGRAMLISTING>typedef CYG_WORD64 CYG_PCI_ADDRESS64;
typedef CYG_WORD32 CYG_PCI_ADDRESS32;</PROGRAMLISTING>
<PARA>Pointers in the PCI address space are 32 bit (IO space) or
32/64 bit (memory space). In most platform and device configurations
all of PCI memory will be linearly addressable using only 32 bit
pointers as read from <varname>base_map[]</varname>.</PARA>
<PARA>The 64 bit type is used to allow handling 64 bit devices in
the future, should it be necessary, without changing the library's
API.</PARA>
</SECT2>
<SECT2>
<TITLE>Functions</TITLE>
<PROGRAMLISTING>void cyg_pci_init(void);</PROGRAMLISTING>
<PARA>Initialize the PCI library and establish contact with the
hardware. This function is idempotent and can be called either by
all drivers in the system, or just from an application initialization
function.</PARA>
<PROGRAMLISTING>cyg_bool cyg_pci_find_device( cyg_uint16 vendor,
cyg_uint16 device,
cyg_pci_device_id *devid );</PROGRAMLISTING>
<PARA>Searches the PCI bus configuration space for a device with
the given <parameter>vendor</parameter> and <parameter>device</parameter>
ids. The search starts at the device pointed to by <parameter>devid</parameter>,
or at the first slot if it contains <literal>CYG_PCI_NULL_DEVID</literal>.
<parameter>*devid</parameter> will be updated with the ID of the next device
found. Returns <constant>true</constant> if one is found and <constant>false
</constant> if not.</PARA>
<PROGRAMLISTING>cyg_bool cyg_pci_find_class( cyg_uint32 dev_class,
cyg_pci_device_id *devid );</PROGRAMLISTING>
<PARA>Searches the PCI bus configuration space for a device with
the given <parameter>dev_class</parameter> class code. The search starts at the
device pointed to by <parameter>devid</parameter>, or at the first slot if it
contains <literal>CYG_PCI_NULL_DEVID</literal>.</PARA>
<PARA><parameter>*devid</parameter> will be updated with the ID of the next
device found. Returns <constant>true</constant> if one is found and
<constant>false</constant> if not.</PARA>
<PROGRAMLISTING>cyg_bool cyg_pci_find_next( cyg_pci_device_id cur_devid,
cyg_pci_device_id *next_devid );</PROGRAMLISTING>
<PARA>Searches the PCI configuration space for the next valid device
after <parameter>cur_devid</parameter>. If <parameter>cur_devid</parameter>
is given the value <literal>CYG_PCI_NULL_DEVID</literal>, then the search starts
at the first slot. It is permitted for <parameter>next_devid</parameter> to
point to <parameter>cur_devid</parameter>. Returns <constant>true</constant>
if another device is found and <constant>false</constant> if not.</PARA>
<PROGRAMLISTING>
cyg_bool cyg_pci_find_matching( cyg_pci_match_func *matchp,
void * match_callback_data,
cyg_pci_device_id *devid );
</PROGRAMLISTING>
<PARA>Searches the PCI bus configuration space for a device whose properties
match those required by the caller supplied <parameter>cyg_pci_match_func</parameter>.
The search starts at the device pointed to by <parameter>devid</parameter>, or
at the first slot if it contains <constant>CYG_PCI_NULL_DEVID</constant>. The
<parameter>devid</parameter> will be updated with the ID of the next device found.
This function returns <constant>true</constant> if a matching device is found
and <constant>false</constant> if not.
</PARA>
<PARA>The match_func has a type declared as:</PARA>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -