⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ecos-pci-library.html

📁 ecos 文档
💻 HTML
📖 第 1 页 / 共 2 页
字号:
            diag_printf("\n Command   0x%04x, Status 0x%04x\n",
                        dev_info.command, dev_info.status);</PRE
></TD
></TR
></TABLE
><P
>The command register can also be written to, controlling (among
other things) whether the device responds to IO and memory access
from the bus. </P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN12736">Specific config information</H2
><P
>The above functions only allow access to generic PCI config
registers. A device can have extra config registers not specified
by the PCI specification. These can be accessed with these functions:</P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>void cyg_pci_read_config_uint8(  cyg_pci_device_id devid,
                                 cyg_uint8 offset, cyg_uint8 *val);
void cyg_pci_read_config_uint16(  cyg_pci_device_id devid,
                                  cyg_uint8 offset, cyg_uint16 *val);
void cyg_pci_read_config_uint32(  cyg_pci_device_id devid,
                                  cyg_uint8 offset, cyg_uint32 *val);
void cyg_pci_write_config_uint8(  cyg_pci_device_id devid,
                                  cyg_uint8 offset, cyg_uint8 val);
void cyg_pci_write_config_uint16(  cyg_pci_device_id devid,
                                   cyg_uint8 offset, cyg_uint16 val);
void cyg_pci_write_config_uint32(  cyg_pci_device_id devid,
                                   cyg_uint8 offset, cyg_uint32 val);</PRE
></TD
></TR
></TABLE
><P
>The write functions should only be used for device-specific
config registers since using them on generic registers may invalidate
the contents of a previously fetched cyg_pci_device
structure.</P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN12741">Allocating memory</H2
><P
>A PCI device ignores all IO and memory access from the PCI
bus until it has been activated. Activation cannot happen until
after device configuration. Configuration means telling the device
where it should map its IO and memory resources. This is done with
one of the following functions::</P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>cyg_bool cyg_pci_configure_device( cyg_pci_device *dev_info );
cyg_bool cyg_pci_configure_bus( cyg_uint8 bus, cyg_uint8 *next_bus );</PRE
></TD
></TR
></TABLE
><P
>The <TT
CLASS="FUNCTION"
>cyg_pci_configure_device</TT
> handles all IO
and memory regions that need configuration on non-bridge devices. On
platforms with multiple busses connected by bridges, the <TT
CLASS="FUNCTION"
>cyg_pci_configure_bus</TT
> function should be used. It will recursively
configure all devices on the given <TT
CLASS="PARAMETER"
><I
>bus</I
></TT
> and all
subordinate busses. <TT
CLASS="FUNCTION"
>cyg_pci_configure_bus</TT
> will
use <TT
CLASS="FUNCTION"
>cyg_pci_configure_device</TT
> to configure
individual non-bridge devices.</P
><P
> Each region is represented in the PCI device's config space by BARs
(Base Address Registers) and is handled individually according to type
using these functions:</P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>cyg_bool cyg_pci_allocate_memory(  cyg_pci_device *dev_info,
                                   cyg_uint32 bar, 
                                   CYG_PCI_ADDRESS64 *base );
cyg_bool cyg_pci_allocate_io(  cyg_pci_device *dev_info,
                               cyg_uint32 bar, 
                               CYG_PCI_ADDRESS32 *base );</PRE
></TD
></TR
></TABLE
><P
>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).</P
><P
>These functions can also be called directly by the application/driver
if necessary, but this should not be necessary.</P
><P
>The bases are initialized with default values provided by
the HAL. It is possible for an application to override these using
the following functions: </P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>void cyg_pci_set_memory_base(  CYG_PCI_ADDRESS64 base );
void cyg_pci_set_io_base( CYG_PCI_ADDRESS32 base );</PRE
></TD
></TR
></TABLE
><P
>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. </P
><P
>This information is provided in <TT
CLASS="VARNAME"
>base_map[]</TT
> -
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.</P
><P
>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.</P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="PCI-INTERRUPTS">Interrupts</H2
><P
>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:</P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>cyg_bool cyg_pci_translate_interrupt(  cyg_pci_device *dev_info,
                                       CYG_ADDRWORD *vec );</PRE
></TD
></TR
></TABLE
><P
>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 <TT
CLASS="FILENAME"
>pci1</TT
>
test:</P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>            if (cyg_pci_translate_interrupt(&amp;dev_info, &amp;irq))
                diag_printf(" Wired to HAL vector %d\n", irq);
            else
                diag_printf(" Does not generate interrupts.\n");</PRE
></TD
></TR
></TABLE
><P
>The application/drive should attach an interrupt
handler to a device's interrupt before activating the device.</P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN12769">Activating a device</H2
><P
>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.</P
><P
>Activating the device is done by enabling flags in its command
word. As an example, see the <TT
CLASS="FILENAME"
>pci1</TT
> 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 <TT
CLASS="FUNCTION"
>cyg_test_exit</TT
>):</P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="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, &amp;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</PRE
></TD
></TR
></TABLE
><DIV
CLASS="NOTE"
><BLOCKQUOTE
CLASS="NOTE"
><P
><B
>Note: </B
>The best way to activate a device is actually
through <TT
CLASS="FUNCTION"
>cyg_pci_set_device_info()</TT
>,
but in this particular case the <SPAN
CLASS="STRUCTNAME"
>cyg_pci_device</SPAN
>
structure contents from before the activation is required for printout
further down in the code.</P
></BLOCKQUOTE
></DIV
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN12781">Links</H2
><P
>See these links for more information about PCI:</P
><P
></P
><OL
TYPE="1"
><LI
><P
><A
NAME="PCI-SPEC"
></A
><A
HREF="http://www.pcisig.com/"
TARGET="_top"
>http://www.pcisig.com/</A
> - information on the PCI specifications</P
></LI
><LI
><P
><A
HREF="http://www.yourvote.com/pci/"
TARGET="_top"
>http://www.yourvote.com/pci/</A
> - list of vendor and device IDs</P
></LI
><LI
><P
><A
HREF="http://www.picmg.org/"
TARGET="_top"
>http://www.picmg.org/</A
> - PCI Industrial Computer Manufacturers Group</P
></LI
></OL
></DIV
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="io-pci.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="ecos-ref.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="pci-library-reference.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>PCI Library</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="io-pci.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>PCI Library reference</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -