LIBPCI: added PCI layer to cpukit/libpci

This commit is contained in:
Daniel Hellstrom
2011-11-28 10:11:10 +01:00
parent e51eb80e88
commit a31845f7f9
46 changed files with 5328 additions and 3 deletions

View File

@@ -9,6 +9,7 @@ SUBDIRS += dev
SUBDIRS += libcrypt
SUBDIRS += libcsupport libblock libfs
SUBDIRS += libnetworking librpc
SUBDIRS += libpci
SUBDIRS += libi2c
SUBDIRS += libmisc
SUBDIRS += libmd
@@ -95,7 +96,9 @@ endif
include_rtems_HEADERS += include/rtems/bspIo.h
include_rtems_HEADERS += include/rtems/userenv.h
include_rtems_HEADERS += include/rtems/fs.h
if !LIBPCI
include_rtems_HEADERS += include/rtems/pci.h
endif
include_rtems_HEADERS += include/rtems/concat.h
include_rtems_HEADERS += include/rtems/status-checks.h

View File

@@ -410,6 +410,17 @@ esac
AM_CONDITIONAL(SHA,[test x"$HAVE_SHA" = x"yes"])
AC_MSG_RESULT([$HAVE_SHA])
# Filter libpci to only build for architectures that have support for it
AC_MSG_CHECKING([whether CPU supports libpci])
case $RTEMS_CPU in
sparc)
HAVE_LIBPCI=yes ;;
*)
HAVE_LIBPCI=no ;;
esac
AM_CONDITIONAL(LIBPCI,[test x"$HAVE_LIBPCI" = x"yes"])
AC_MSG_RESULT([$HAVE_LIBPCI])
RTEMS_AMPOLISH3
# Explicitly list all Makefiles here
@@ -448,6 +459,7 @@ libgnat/Makefile
libcrypt/Makefile
libcsupport/Makefile
libnetworking/Makefile
libpci/Makefile
librpc/Makefile
libmisc/Makefile
libi2c/Makefile

46
cpukit/libpci/CHANGES Normal file
View File

@@ -0,0 +1,46 @@
2011-03-03, Daniel Hellstrom <daniel@gaisler.com>
Added support for ROM BARs at devices and PCI-PCI bridges.
2011-02-11, Daniel Hellstrom <daniel@gaisler.com>
Split Library into different parts, this enables PCI initialization to be done
outside of the PCI Host driver and smaller systems that don't want
Configuration Space to be setup.
- Access Library (Configuration, Memory and I/O Space read/write routines)
- Configuration Libarary
A. Auto Config
B. Static Config (not implemented yet)
- Interrupt Library (shared interrupt support rely on BSP)
This file created.
2011-02-11, Daniel Hellstrom <daniel@gaisler.com>
Changed library to use 16-bit identifiers (pci_dev_t), instead to 3 integers
(BUS,SLOT,FUNC), this reduces the footprint.
2010-09-29, Kristoffer Glembo <kristoffer@gaisler.com>
Fixed I/O BAR size calculation of bridges. Reading/Writing to 0x1C instead of
faulty 0x1E.
2010-06-10, Daniel Hellstrom <daniel@gaisler.com>
Fix in pci_res_insert(), where the above mentioned optimization failed due to
bad compare statement. Optimization only affects systems with multiple PCI
buses.
2010-04-19, Daniel Hellstrom <daniel@gaisler.com>
Optimized resource allocation when bridges are present: the resources lists
are sorted by boundary instead of size and a reorder aligorithm introduced
that move resources into unused areas if possible.
2010-04-19, Daniel Hellstrom <daniel@gaisler.com>
Fixed autoconf issue when bridges are present
2010-02-03, Daniel Hellstrom <daniel@gaisler.com>
Fixed initialization problem when first device is a bridge.
2010-02-03, Daniel Hellstrom <daniel@gaisler.com>
PCI Library rewritten from scratch. Support multiple buses/bridges, print
current PCI configuration space setup, BAR assigment sort implementation
speeded up drastically (bootup time noticable shorter), interrupt assignment
implemented, PCI Host driver extracted from library, support for I/O areas.
.... not updated ... lots of more changes

46
cpukit/libpci/Makefile.am Normal file
View File

@@ -0,0 +1,46 @@
##
## $Id: Makefile.am
##
include $(top_srcdir)/automake/compile.am
include $(top_srcdir)/automake/multilib.am
if LIBPCI
EXTRA_DIST=
## PCI Library
include_HEADERS = pci.h
include_pcidir = $(includedir)/pci
include_pci_HEADERS = pci/access.h pci/cfg.h \
pci/cfg_auto.h pci/cfg_static.h \
pci/cfg_peripheral.h pci/cfg_read.h \
pci/ids.h pci/ids_extra.h pci/irq.h
noinst_LIBRARIES = libpci.a
libpci_a_SOURCES = pci_access.c
libpci_a_SOURCES += pci_access_func.c
libpci_a_SOURCES += pci_access_io.c
libpci_a_SOURCES += pci_access_mem.c
libpci_a_SOURCES += pci_access_mem_be.c
libpci_a_SOURCES += pci_access_mem_le.c
libpci_a_SOURCES += pci_cfg.c
libpci_a_SOURCES += pci_cfg_auto.c
libpci_a_SOURCES += pci_cfg_print_code.c
libpci_a_SOURCES += pci_cfg_read.c
libpci_a_SOURCES += pci_cfg_static.c
libpci_a_SOURCES += pci_cfg_peripheral.c
libpci_a_SOURCES += pci_find.c
libpci_a_SOURCES += pci_find_dev.c
libpci_a_SOURCES += pci_for_each.c
libpci_a_SOURCES += pci_for_each_dev.c
libpci_a_SOURCES += pci_for_each_child.c
libpci_a_SOURCES += pci_get_dev.c
libpci_a_SOURCES += pci_irq.c
libpci_a_SOURCES += pci_print.c
endif
include $(srcdir)/preinstall.am
include $(top_srcdir)/automake/local.am

4
cpukit/libpci/README Normal file
View File

@@ -0,0 +1,4 @@
PCI Library
LIBPCI is documented in the ../../doc directory, see ../../doc/README how
to build documentation.

375
cpukit/libpci/pci.h Normal file
View File

@@ -0,0 +1,375 @@
/*
*
* PCI defines and function prototypes
* Copyright 1994, Drew Eckhardt
* Copyright 1997, 1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
*
* New PCI library written from scratch. Defines in this file was reused.
* auto-generated pci_ids.h also reused.
* Copyright 2009, Cobham Gaisler AB
*
* For more information, please consult the following manuals (look at
* http://www.pcisig.com/ for how to get them):
*
* PCI BIOS Specification
* PCI Local Bus Specification
* PCI to PCI Bridge Specification
* PCI System Design Guide
*/
#ifndef __PCI_H__
#define __PCI_H__
#include <pci/ids.h>
/*
* Under PCI, each device has 256 bytes of configuration address space,
* of which the first 64 bytes are standardized as follows:
*/
#define PCI_VENDOR_ID 0x00 /* 16 bits */
#define PCI_DEVICE_ID 0x02 /* 16 bits */
#define PCI_COMMAND 0x04 /* 16 bits */
#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */
#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */
#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */
#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
#define PCI_STATUS 0x06 /* 16 bits */
#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */
#define PCI_STATUS_UDF 0x40 /* Support User Definable Features */
#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */
#define PCI_STATUS_PARITY 0x100 /* Detected parity error */
#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */
#define PCI_STATUS_DEVSEL_FAST 0x000
#define PCI_STATUS_DEVSEL_MEDIUM 0x200
#define PCI_STATUS_DEVSEL_SLOW 0x400
#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8
revision */
#define PCI_REVISION_ID 0x08 /* Revision ID */
#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
#define PCI_CLASS_DEVICE 0x0a /* Device class */
#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
#define PCI_HEADER_TYPE 0x0e /* 8 bits */
#define PCI_HEADER_TYPE_NORMAL 0
#define PCI_HEADER_TYPE_BRIDGE 1
#define PCI_HEADER_TYPE_CARDBUS 2
#define PCI_BIST 0x0f /* 8 bits */
#define PCI_BIST_CODE_MASK 0x0f /* Return result */
#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */
#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */
/*
* Base addresses specify locations in memory or I/O space.
* Decoded size can be determined by writing a value of
* 0xffffffff to the register, and reading it back. Only
* 1 bits are decoded.
*/
#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits [htype 0,1 only] */
#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits [htype 0 only] */
#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */
#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */
#define PCI_BASE_ADDRESS_SPACE_IO 0x01
#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */
#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M */
#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL)
/* bit 1 is reserved if address_space = 1 */
/* Header type 0 (normal devices) */
#define PCI_CARDBUS_CIS 0x28
#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
#define PCI_SUBSYSTEM_ID 0x2e
#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */
#define PCI_ROM_ADDRESS_ENABLE 0x01
#define PCI_ROM_ADDRESS_MASK (~0x7ffUL)
/* 0x34 Capabilities Pointer (PCI 2.3) */
#define PCI_CAP_PTR 0x34 /* 8 bits */
/* 0x35-0x3b are reserved */
#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
#define PCI_MIN_GNT 0x3e /* 8 bits */
#define PCI_MAX_LAT 0x3f /* 8 bits */
/* Header type 1 (PCI-to-PCI bridges) */
#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */
#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */
#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */
#define PCI_IO_LIMIT 0x1d
#define PCI_IO_RANGE_TYPE_MASK 0x0f /* I/O bridging type */
#define PCI_IO_RANGE_TYPE_16 0x00
#define PCI_IO_RANGE_TYPE_32 0x01
#define PCI_IO_RANGE_MASK (~0x0f)
#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */
#define PCI_MEMORY_BASE 0x20 /* Memory range behind */
#define PCI_MEMORY_LIMIT 0x22
#define PCI_MEMORY_RANGE_TYPE_MASK 0x0f
#define PCI_MEMORY_RANGE_MASK (~0x0f)
#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */
#define PCI_PREF_MEMORY_LIMIT 0x26
#define PCI_PREF_RANGE_TYPE_MASK 0x0f
#define PCI_PREF_RANGE_TYPE_32 0x00
#define PCI_PREF_RANGE_TYPE_64 0x01
#define PCI_PREF_RANGE_MASK (~0x0f)
#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */
#define PCI_PREF_LIMIT_UPPER32 0x2c
#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */
#define PCI_IO_LIMIT_UPPER16 0x32
/* 0x34-0x3b is reserved */
#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */
/* 0x3c-0x3d are same as for htype 0 */
#define PCI_BRIDGE_CONTROL 0x3e
#define PCI_BRIDGE_CTL_PARITY 0x01 /* Enable parity detection on secondary interface */
#define PCI_BRIDGE_CTL_SERR 0x02 /* The same for SERR forwarding */
#define PCI_BRIDGE_CTL_NO_ISA 0x04 /* Disable bridging of ISA ports */
#define PCI_BRIDGE_CTL_VGA 0x08 /* Forward VGA addresses */
#define PCI_BRIDGE_CTL_MASTER_ABORT 0x20 /* Report master aborts */
#define PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */
#define PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface */
/* Header type 2 (CardBus bridges) */
/* 0x14-0x15 reserved */
#define PCI_CB_SEC_STATUS 0x16 /* Secondary status */
#define PCI_CB_PRIMARY_BUS 0x18 /* PCI bus number */
#define PCI_CB_CARD_BUS 0x19 /* CardBus bus number */
#define PCI_CB_SUBORDINATE_BUS 0x1a /* Subordinate bus number */
#define PCI_CB_LATENCY_TIMER 0x1b /* CardBus latency timer */
#define PCI_CB_MEMORY_BASE_0 0x1c
#define PCI_CB_MEMORY_LIMIT_0 0x20
#define PCI_CB_MEMORY_BASE_1 0x24
#define PCI_CB_MEMORY_LIMIT_1 0x28
#define PCI_CB_IO_BASE_0 0x2c
#define PCI_CB_IO_BASE_0_HI 0x2e
#define PCI_CB_IO_LIMIT_0 0x30
#define PCI_CB_IO_LIMIT_0_HI 0x32
#define PCI_CB_IO_BASE_1 0x34
#define PCI_CB_IO_BASE_1_HI 0x36
#define PCI_CB_IO_LIMIT_1 0x38
#define PCI_CB_IO_LIMIT_1_HI 0x3a
#define PCI_CB_IO_RANGE_MASK (~0x03)
/* 0x3c-0x3d are same as for htype 0 */
#define PCI_CB_BRIDGE_CONTROL 0x3e
#define PCI_CB_BRIDGE_CTL_PARITY 0x01 /* Similar to standard bridge control register */
#define PCI_CB_BRIDGE_CTL_SERR 0x02
#define PCI_CB_BRIDGE_CTL_ISA 0x04
#define PCI_CB_BRIDGE_CTL_VGA 0x08
#define PCI_CB_BRIDGE_CTL_MASTER_ABORT 0x20
#define PCI_CB_BRIDGE_CTL_CB_RESET 0x40 /* CardBus reset */
#define PCI_CB_BRIDGE_CTL_16BIT_INT 0x80 /* Enable interrupt for 16-bit cards */
#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 /* Prefetch enable for both memory regions */
#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
#define PCI_CB_BRIDGE_CTL_POST_WRITES 0x400
#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40
#define PCI_CB_SUBSYSTEM_ID 0x42
#define PCI_CB_LEGACY_MODE_BASE 0x44 /* 16-bit PC Card legacy mode base address (ExCa) */
/* 0x48-0x7f reserved */
/* Device classes and subclasses */
#define PCI_CLASS_NOT_DEFINED 0x0000
#define PCI_CLASS_NOT_DEFINED_VGA 0x0001
#define PCI_BASE_CLASS_STORAGE 0x01
#define PCI_CLASS_STORAGE_SCSI 0x0100
#define PCI_CLASS_STORAGE_IDE 0x0101
#define PCI_CLASS_STORAGE_FLOPPY 0x0102
#define PCI_CLASS_STORAGE_IPI 0x0103
#define PCI_CLASS_STORAGE_RAID 0x0104
#define PCI_CLASS_STORAGE_OTHER 0x0180
#define PCI_BASE_CLASS_NETWORK 0x02
#define PCI_CLASS_NETWORK_ETHERNET 0x0200
#define PCI_CLASS_NETWORK_TOKEN_RING 0x0201
#define PCI_CLASS_NETWORK_FDDI 0x0202
#define PCI_CLASS_NETWORK_ATM 0x0203
#define PCI_CLASS_NETWORK_OTHER 0x0280
#define PCI_BASE_CLASS_DISPLAY 0x03
#define PCI_CLASS_DISPLAY_VGA 0x0300
#define PCI_CLASS_DISPLAY_XGA 0x0301
#define PCI_CLASS_DISPLAY_OTHER 0x0380
#define PCI_BASE_CLASS_MULTIMEDIA 0x04
#define PCI_CLASS_MULTIMEDIA_VIDEO 0x0400
#define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401
#define PCI_CLASS_MULTIMEDIA_OTHER 0x0480
#define PCI_BASE_CLASS_MEMORY 0x05
#define PCI_CLASS_MEMORY_RAM 0x0500
#define PCI_CLASS_MEMORY_FLASH 0x0501
#define PCI_CLASS_MEMORY_OTHER 0x0580
#define PCI_BASE_CLASS_BRIDGE 0x06
#define PCI_CLASS_BRIDGE_HOST 0x0600
#define PCI_CLASS_BRIDGE_ISA 0x0601
#define PCI_CLASS_BRIDGE_EISA 0x0602
#define PCI_CLASS_BRIDGE_MC 0x0603
#define PCI_CLASS_BRIDGE_PCI 0x0604
#define PCI_CLASS_BRIDGE_PCMCIA 0x0605
#define PCI_CLASS_BRIDGE_NUBUS 0x0606
#define PCI_CLASS_BRIDGE_CARDBUS 0x0607
#define PCI_CLASS_BRIDGE_OTHER 0x0680
#define PCI_BASE_CLASS_COMMUNICATION 0x07
#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700
#define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701
#define PCI_CLASS_COMMUNICATION_OTHER 0x0780
#define PCI_BASE_CLASS_SYSTEM 0x08
#define PCI_CLASS_SYSTEM_PIC 0x0800
#define PCI_CLASS_SYSTEM_DMA 0x0801
#define PCI_CLASS_SYSTEM_TIMER 0x0802
#define PCI_CLASS_SYSTEM_RTC 0x0803
#define PCI_CLASS_SYSTEM_OTHER 0x0880
#define PCI_BASE_CLASS_INPUT 0x09
#define PCI_CLASS_INPUT_KEYBOARD 0x0900
#define PCI_CLASS_INPUT_PEN 0x0901
#define PCI_CLASS_INPUT_MOUSE 0x0902
#define PCI_CLASS_INPUT_OTHER 0x0980
#define PCI_BASE_CLASS_DOCKING 0x0a
#define PCI_CLASS_DOCKING_GENERIC 0x0a00
#define PCI_CLASS_DOCKING_OTHER 0x0a01
#define PCI_BASE_CLASS_PROCESSOR 0x0b
#define PCI_CLASS_PROCESSOR_386 0x0b00
#define PCI_CLASS_PROCESSOR_486 0x0b01
#define PCI_CLASS_PROCESSOR_PENTIUM 0x0b02
#define PCI_CLASS_PROCESSOR_ALPHA 0x0b10
#define PCI_CLASS_PROCESSOR_POWERPC 0x0b20
#define PCI_CLASS_PROCESSOR_CO 0x0b40
#define PCI_BASE_CLASS_SERIAL 0x0c
#define PCI_CLASS_SERIAL_FIREWIRE 0x0c00
#define PCI_CLASS_SERIAL_ACCESS 0x0c01
#define PCI_CLASS_SERIAL_SSA 0x0c02
#define PCI_CLASS_SERIAL_USB 0x0c03
#define PCI_CLASS_SERIAL_FIBER 0x0c04
#define PCI_CLASS_OTHERS 0xff
#define PCI_INVALID_VENDORDEVICEID 0xffffffff
#define PCI_MULTI_FUNCTION 0x80
#define PCI_MAX_DEVICES 32
#define PCI_MAX_FUNCTIONS 8
#include <pci/access.h>
#ifdef __cplusplus
extern "C" {
#endif
/* The PCI Library have the following build time configuration options. It is
* up to the BSP header file (bsp.h) to set options properly.
*
* BSP_PCI_BIG_ENDIAN - Access inline routines will be for a big-endian PCI
* bus, if not defined the routines will assume that
* PCI is as the standard defines: little-endian.
*
* Note that drivers may be run-time configurable,
* meaning that they may adopt to either big-endian or
* little-endian PCI bus, the host driver or BSP may
* detect endianness during run-time.
*/
/* Error return values */
enum {
PCISTS_ERR = -1, /* Undefined Error */
PCISTS_OK = 0,
PCISTS_EINVAL = 1, /* Bad input arguments */
PCISTS_MSTABRT = 2, /* CFG space access error (can be ignored) */
};
/* PCI System type can be used to determine system for drivers. Normally
* the system is Host, but the peripheral configuration library also supports
* being PCI peripheral not allowed to access configuration space.
*
* The active configuration Library set this variable.
*/
enum {
PCI_SYSTEM_NONE = 0,
PCI_SYSTEM_HOST = 1,
PCI_SYSTEM_PERIPHERAL = 2,
};
extern int pci_system_type;
/* PCI Bus Endianness. The PCI specification is little endian, however on some
* embedded systems (AT697-LEON2 for example) the PCI bus is defined as big
* endian (non-standard) in order to avoid byte-twisting.
*/
enum {
PCI_LITTLE_ENDIAN = 0,
PCI_BIG_ENDIAN = 1,
};
extern int pci_endian;
/* Return the number of PCI busses in the system */
extern int pci_bus_count(void);
/* Scan the PCI bus and print the PCI device/functions/bridges and their
* current resources and size to the system console.
*/
extern void pci_print(void);
/* Print current configuration of a single PCI device by reading PCI
* configuration space
*/
extern void pci_print_dev(pci_dev_t dev);
extern void pci_print_device(int bus, int slot, int function);
/*** PCI Configuration Space direct access routines ***/
/* Function iterates over all PCI buses/devices/functions and calls
* func(PCIDEV,arg) for each present device. The iteration is stopped if
* func() returns non-zero result the same result is returned. As long
* as func() returns zero the function will keep on iterating, when all
* devices has been processed the function return zero.
*
* The function iterates over all devices/functions on all buses by accessing
* configuration space directly (PCI RAM data structures not used). This
* function is valid to call after PCI buses have been enumrated.
*/
extern int pci_for_each(int (*func)(pci_dev_t, void*), void *arg);
/* Get PCI Configuration space BUS|SLOT|FUNC for a device matching PCI
* Vendor, Device and instance number 'index'.
*
* Return Values
* -1 pci_find_dev did not find a device matching the criterion.
* 0 device was found, *pdev was updated with the device's BUS|SLOT|FUNC
*/
extern int pci_find(uint16_t ven, uint16_t dev, int index, pci_dev_t *pdev);
#ifdef __cplusplus
}
#endif
#endif /* __PCI_H__ */

351
cpukit/libpci/pci/access.h Normal file
View File

@@ -0,0 +1,351 @@
/* Routines to access PCI memory/configuration space and other PCI related
* functions the PCI Library provides.
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#ifndef __PCI_ACCESS_H__
#define __PCI_ACCESS_H__
#include <stdint.h>
#include <libcpu/byteorder.h>
#include <pci.h>
/* Let BSP configure load/store from PCI */
#include <bsp.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Identification of a PCI configuration space device (16-bit) */
typedef uint16_t pci_dev_t;
/* Create a PCI Configuration Space ID */
#define PCI_DEV(bus, slot, func) (((bus)<<8) | ((slot)<<3) | (func))
/* Get Bus of a PCI Configuration Space ID */
#define PCI_DEV_BUS(dev) (((dev) >> 8) & 0xff)
/* Get Slot/Device of a PCI Configuration Space ID */
#define PCI_DEV_SLOT(dev) (((dev) >> 3) & 0x1f)
/* Get Function of a PCI Configuration Space ID */
#define PCI_DEV_FUNC(dev) ((dev) & 0x7)
/* Get Device and Function of a PCI Configuration Space ID */
#define PCI_DEV_DEVFUNC(dev) ((dev) & 0xff)
/* Expand Device into argument lists */
#define PCI_DEV_EXPAND(dev) PCI_DEV_BUS((dev)), PCI_DEV_SLOT((dev)), PCI_DEV_FUNC((dev))
/* Configuration Space Read/Write Operations */
struct pci_cfg_ops {
/* Configuration Space Access and Setup Routines */
int (*read8)(pci_dev_t dev, int ofs, uint8_t *data);
int (*read16)(pci_dev_t dev, int ofs, uint16_t *data);
int (*read32)(pci_dev_t dev, int ofs, uint32_t *data);
int (*write8)(pci_dev_t dev, int ofs, uint8_t data);
int (*write16)(pci_dev_t dev, int ofs, uint16_t data);
int (*write32)(pci_dev_t dev, int ofs, uint32_t data);
};
/* Read a register over PCI I/O Space, and swap it if necessary (due to
* PCI endianness)
*/
struct pci_io_ops {
uint8_t (*read8)(uint8_t *adr);
uint16_t(*read16)(uint16_t *adr);
uint32_t (*read32)(uint32_t *adr);
void (*write8)(uint8_t *adr, uint8_t data);
void (*write16)(uint16_t *adr, uint16_t data);
void (*write32)(uint32_t *adr, uint32_t data);
};
/* Read a register over PCI Memory Space (non-prefetchable memory), and
* swap it if necessary (due to PCI endianness)
*/
struct pci_memreg_ops {
uint8_t (*ld8)(uint8_t *adr);
void (*st8)(uint8_t *adr, uint8_t data);
uint16_t(*ld_le16)(uint16_t *adr);
void (*st_le16)(uint16_t *adr, uint16_t data);
uint16_t(*ld_be16)(uint16_t *adr);
void (*st_be16)(uint16_t *adr, uint16_t data);
uint32_t (*ld_le32)(uint32_t *adr);
void (*st_le32)(uint32_t *adr, uint32_t data);
uint32_t (*ld_be32)(uint32_t *adr);
void (*st_be32)(uint32_t *adr, uint32_t data);
};
typedef uint8_t (*pci_ld8_t)(uint8_t *adr);
typedef void (*pci_st8_t)(uint8_t *adr, uint8_t data);
typedef uint16_t(pci_ld16_t)(uint16_t *adr);
typedef void (*pci_st16_t)(uint16_t *adr, uint16_t data);
typedef uint32_t (*pci_ld32_t)(uint32_t *adr);
typedef void (*pci_st32_t)(uint32_t *adr, uint32_t data);
struct pci_access_drv {
/* Configuration */
struct pci_cfg_ops cfg;
/* I/O Access operations */
struct pci_io_ops io;
/* Registers over Memory Access operations. Note that these funcs
* are only for code that need to be compatible with both Big-Endian
* and Little-Endian PCI bus or for some other reason need function
* pointers to access functions. Normally drivers use the inline
* functions for Registers-over-Memory access to avoid extra function
* call.
*/
struct pci_memreg_ops *memreg;
/* Translate from PCI address to CPU address (dir=0). Translate
* CPU address to PCI address (dir!=0). The address will can be
* used to perform I/O access or memory access by CPU or PCI DMA
* peripheral.
*
* address In/Out. CPU address or PCI address.
* type Access type. 1=I/O, 2=MEMIO, 3=MEM
* dir Translate direction. 0=PCI-to-CPU, 0!=CPU-to-PCI,
*
* Return Value
* 0 = Success
* -1 = Requested Address not mapped into other address space
* i.e. not accessible
*/
int (*translate)(uint32_t *address, int type, int dir);
};
/* Access Routines valid after a PCI-Access-Driver has registered */
extern struct pci_access_drv pci_access_ops;
/* Register PCI Access Driver */
extern int pci_access_drv_register(struct pci_access_drv *drv);
/* Set/unset bits in command and status register of a PCI device */
extern void pci_modify_cmdsts(pci_dev_t dev, uint32_t mask, uint32_t val);
/* Enable Memory in command register */
static inline void pci_mem_enable(pci_dev_t dev)
{
pci_modify_cmdsts(dev, PCI_COMMAND_MEMORY, PCI_COMMAND_MEMORY);
}
static inline void pci_mem_disable(pci_dev_t dev)
{
pci_modify_cmdsts(dev, PCI_COMMAND_MEMORY, 0);
}
static inline void pci_io_enable(pci_dev_t dev)
{
pci_modify_cmdsts(dev, PCI_COMMAND_IO, PCI_COMMAND_IO);
}
static inline void pci_io_disable(pci_dev_t dev)
{
pci_modify_cmdsts(dev, PCI_COMMAND_IO, 0);
}
static inline void pci_master_enable(pci_dev_t dev)
{
pci_modify_cmdsts(dev, PCI_COMMAND_MASTER, PCI_COMMAND_MASTER);
}
static inline void pci_master_disable(pci_dev_t dev)
{
pci_modify_cmdsts(dev, PCI_COMMAND_MASTER, 0);
}
/* Configuration Space Access Read Routines */
extern int pci_cfg_r8(pci_dev_t dev, int ofs, uint8_t *data);
extern int pci_cfg_r16(pci_dev_t dev, int ofs, uint16_t *data);
extern int pci_cfg_r32(pci_dev_t dev, int ofs, uint32_t *data);
/* Configuration Space Access Write Routines */
extern int pci_cfg_w8(pci_dev_t dev, int ofs, uint8_t data);
extern int pci_cfg_w16(pci_dev_t dev, int ofs, uint16_t data);
extern int pci_cfg_w32(pci_dev_t dev, int ofs, uint32_t data);
/* Read a register over PCI I/O Space */
extern uint8_t pci_io_r8(uint32_t adr);
extern uint16_t pci_io_r16(uint32_t adr);
extern uint32_t pci_io_r32(uint32_t adr);
/* Write a register over PCI I/O Space */
extern void pci_io_w8(uint32_t adr, uint8_t data);
extern void pci_io_w16(uint32_t adr, uint16_t data);
extern void pci_io_w32(uint32_t adr, uint32_t data);
/* Translate PCI address into CPU accessible address */
static inline int pci_pci2cpu(uint32_t *address, int type)
{
return pci_access_ops.translate(address, type, 0);
}
/* Translate CPU accessible address into PCI address (for DMA) */
static inline int pci_cpu2pci(uint32_t *address, int type)
{
return pci_access_ops.translate(address, type, 1);
}
/*** Read/Write a register over PCI Memory Space ***/
static inline uint8_t pci_ld8(volatile uint8_t *addr)
{
return *addr;
}
static inline void pci_st8(volatile uint8_t *addr, uint8_t val)
{
*addr = val;
}
#ifdef BSP_PCI_BIG_ENDIAN
/* BSP has decided Big Endian PCI Bus (non-standard) */
static inline uint16_t pci_ld_le16(volatile uint16_t *addr)
{
return ld_be16(addr);
}
static inline void pci_st_le16(volatile uint16_t *addr, uint16_t val)
{
st_be16(addr, val);
}
static inline uint32_t pci_ld_le32(volatile uint32_t *addr)
{
return ld_be32(addr);
}
static inline void pci_st_le32(volatile uint32_t *addr, uint32_t val)
{
st_be32(addr, val);
}
static inline uint16_t pci_ld_be16(volatile uint16_t *addr)
{
return ld_le16(addr);
}
static inline void pci_st_be16(volatile uint16_t *addr, uint16_t val)
{
st_le16(addr, val);
}
static inline uint32_t pci_ld_be32(volatile uint32_t *addr)
{
return ld_le32(addr);
}
static inline void pci_st_be32(volatile uint32_t *addr, uint32_t val)
{
st_le32(addr, val);
}
#else
/* Little Endian PCI Bus */
static inline uint16_t pci_ld_le16(volatile uint16_t *addr)
{
return ld_le16(addr);
}
static inline void pci_st_le16(volatile uint16_t *addr, uint16_t val)
{
st_le16(addr, val);
}
static inline uint32_t pci_ld_le32(volatile uint32_t *addr)
{
return ld_le32(addr);
}
static inline void pci_st_le32(volatile uint32_t *addr, uint32_t val)
{
st_le32(addr, val);
}
static inline uint16_t pci_ld_be16(volatile uint16_t *addr)
{
return ld_be16(addr);
}
static inline void pci_st_be16(volatile uint16_t *addr, uint16_t val)
{
st_be16(addr, val);
}
static inline uint32_t pci_ld_be32(volatile uint32_t *addr)
{
return ld_be32(addr);
}
static inline void pci_st_be32(volatile uint32_t *addr, uint32_t val)
{
st_be32(addr, val);
}
#endif
/* Registers-over-Memory Space access routines. The routines are not inlined
* so it is possible during run-time to select which function implemention
* to use. The use of these functions are not recommended since it will have a
* performance penalty.
*
* 8-bit accesses are the same for Little and Big endian PCI buses.
*/
uint8_t pci_mem_ld8(uint8_t *adr);
void pci_mem_st8(uint8_t *adr, uint8_t data);
/* Registers-over-Memory Space - Generic Big endian PCI bus definitions */
uint16_t pci_mem_be_ld_le16(uint16_t *adr);
uint16_t pci_mem_be_ld_be16(uint16_t *adr);
uint32_t pci_mem_be_ld_le32(uint32_t *adr);
uint32_t pci_mem_be_ld_be32(uint32_t *adr);
void pci_mem_be_st_le16(uint16_t *adr, uint16_t data);
void pci_mem_be_st_be16(uint16_t *adr, uint16_t data);
void pci_mem_be_st_le32(uint32_t *adr, uint32_t data);
void pci_mem_be_st_be32(uint32_t *adr, uint32_t data);
/* Registers-over-Memory Space - Generic Little endian PCI bus definitions */
uint16_t pci_mem_le_ld_le16(uint16_t *adr);
uint16_t pci_mem_le_ld_be16(uint16_t *adr);
uint32_t pci_mem_le_ld_le32(uint32_t *adr);
uint32_t pci_mem_le_ld_be32(uint32_t *adr);
void pci_mem_le_st_le16(uint16_t *adr, uint16_t data);
void pci_mem_le_st_be16(uint16_t *adr, uint16_t data);
void pci_mem_le_st_le32(uint32_t *adr, uint32_t data);
void pci_mem_le_st_be32(uint32_t *adr, uint32_t data);
/* Get Read/Write function for accessing a register over PCI Memory Space
* (non-inline functions).
*
* Arguments
* wr 0(Read), 1(Write)
* size 1(Byte), 2(Word), 4(Double Word)
* func Where function pointer will be stored
* endian PCI_LITTLE_ENDIAN or PCI_BIG_ENDIAN
* type 1(I/O), 3(REG over MEM), 4(CFG)
*
* Return
* 0 Found function
* others No such function defined by host driver or BSP
*/
extern int pci_access_func(int wr, int size, void **func, int endian, int type);
/* Predefined functions for Host drivers or BSPs that define the
* register-over-memory space functions operations.
*/
extern struct pci_memreg_ops pci_mem_le_ops; /* For Little-Endian PCI bus */
extern struct pci_memreg_ops pci_mem_be_ops; /* For Big-Endian PCI bus */
#ifdef __cplusplus
}
#endif
#endif /* !__PCI_ACCESS_H__ */

244
cpukit/libpci/pci/cfg.h Normal file
View File

@@ -0,0 +1,244 @@
/* PCI Configuration Library, two versions of the library exists:
* - auto configuration (default)
* - static configuration (user defined config)
* both versions are defined here.
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#ifndef __PCI_CFG_H__
#define __PCI_CFG_H__
#include <pci.h>
/* PCI Configuration library */
/* Return the number of PCI buses in system */
extern int pci_bus_count(void);
/* PCI Address assigned to BARs which failed to fit into the PCI Window or
* is disabled by any other cause.
*/
extern uint32_t pci_invalid_address;
/* PCI Configuration Library of the system */
enum {
PCI_CONFIG_LIB_NONE = 0,
PCI_CONFIG_LIB_AUTO = 1,
PCI_CONFIG_LIB_STATIC = 2,
PCI_CONFIG_LIB_READ = 3,
PCI_CONFIG_LIB_PERIPHERAL = 4,
};
extern const int pci_config_lib_type;
/* Configuration library function pointers, these are set in <rtems/confdefs.h>
* by project configuration or by the BSP. The configuration will pull in the
* PCI Library needed and the PCI initialization functions will call these
* functions on initialization from the host driver.
*/
extern int (*pci_config_lib_init)(void);
extern void (*pci_config_lib_register)(void *config);
/* Configure PCI devices and bridges, and setup the RAM data structures
* describing the PCI devices currently present in the system.
*
* Returns 0 on success, -1 on failure.
*/
extern int pci_config_init(void);
/* Register a config-library specific configuration used by the libarary in
* pci_config_init().
*/
extern void pci_config_register(void *config);
/* Print current PCI configuration (C-code) to terminal, can be used in
* static and peripheral PCI configuration library. The configuration is
* taken from the current configuration library setup.
*/
extern void pci_cfg_print(void);
struct pci_bus; /* Bridge Device and secondary bus information */
struct pci_dev; /* Device/function */
struct pci_res; /* Resource: BAR, ROM or Bridge Window */
/* The Host Bridge and all subdevices (the PCI RAM data structure) */
extern struct pci_bus pci_hb;
/* Iterate over all PCI devices on a bus (see search options) and call func(),
* iteration is stopped if a non-zero value is returned by func().
*
* The function iterates over the PCI RAM data structure, it is not
* available until after all devices have been found and pci_hb is populated,
* typically after pci_config_init() is called.
*
* search options: 0 (no child buses), 1 (depth first, recursive)
*
* Return Values
* 0 All PCI devices were processed, func() returned 0 on every call
* X func() returned non-zero X value, the search was stopped
*/
#define SEARCH_DEPTH 1
extern int pci_for_each_child(
struct pci_bus *bus,
int (*func)(struct pci_dev *, void *arg),
void *arg,
int search);
/* Depth first search of all PCI devices in PCI RAM data structure and call
* func(dev, arg), iteration is stopped if a non-zero value is returned by
* func().
*
* The function iterates over the PCI RAM data structure, it is not
* available until after all devices have been found and pci_hb is populated,
* typically after pci_config_init() is called.
*
* Return Values
* 0 All PCI devices were processed, func() returned 0 on every call
* X func() returned non-zero X value, the search was stopped
*/
extern int pci_for_each_dev(
int (*func)(struct pci_dev *, void *arg),
void *arg);
/* Get PCI device from RAM device tree for a device matching PCI Vendor, Device
* and instance number 'index'.
*
* Return Values
* -1 pci_find_dev did not find a device matching the criterion.
* 0 device was found, *ppdev was updated with the PCI device address
*/
extern int pci_find_dev(uint16_t ven, uint16_t dev, int index,
struct pci_dev **ppdev);
/* Get PCI device from RAM device tree by BUS|SLOT|FUNC.
*
* Return Values
* -1 pci_get_dev did not find a device matching the criterion
* 0 device was found, *ppdev was updated with the PCI device address
*/
extern int pci_get_dev(pci_dev_t pcidev, struct pci_dev **ppdev);
/* Resource flags */
#define PCI_RES_IO 1
#define PCI_RES_MEMIO 2
#define PCI_RES_MEM_PREFETCH 1
#define PCI_RES_MEM (PCI_RES_MEMIO | PCI_RES_MEM_PREFETCH)
#define PCI_RES_TYPE_MASK 0x3
#define PCI_RES_IO32 0x08
#define PCI_RES_FAIL 0x10 /* Alloc Failed */
/* BAR Resouces entry */
struct pci_res {
struct pci_res *next;
uint32_t size;
uint32_t boundary;
unsigned char flags; /* I/O, MEM or MEMIO */
unsigned char bar;
/* Assigned Resource (PCI address), zero if not assigned */
uint32_t start;
uint32_t end;
};
/* Get Device from resource pointer */
#define RES2DEV(res) ((struct pci_dev *) \
((void *)res - (res->bar * (sizeof(struct pci_res)))))
/* Device flags */
#define PCI_DEV_BRIDGE 0x01 /* Device is a Bridge (struct pci_bus) */
#define PCI_DEV_RES_FAIL 0x02 /* Resource alloction for device BARs failed */
/* Bus Flags */
#define PCI_BUS_IO 0x01 /* 16-bit I/O address decoding */
#define PCI_BUS_MEMIO 0x02 /* Bus support non-prefetchable mem (always) */
#define PCI_BUS_MEM 0x04 /* Bus support prefetchable memory space */
#define PCI_BUS_IO32 0x08 /* 32-bit I/O address decoding */
#define BRIDGE_RES_COUNT 2 /* Number of BAR resources a bridge can have */
#define BUS_RES_START BRIDGE_RES_COUNT
/* Bus Resources Array */
enum {
BUS_RES_IO = 0,
BUS_RES_MEMIO = 1,
BUS_RES_MEM = 2,
};
/* Device Resource array index meaning */
enum {
/* A Device has up to 6 BARs and an optional ROM BAR */
DEV_RES_BAR1 = 0,
DEV_RES_BAR2 = 1,
DEV_RES_BAR3 = 2,
DEV_RES_BAR4 = 3,
DEV_RES_BAR5 = 4,
DEV_RES_BAR6 = 5,
DEV_RES_ROM = 6,
/* Bridges have 2 BARs (BAR1 and BAR2) and 3 Windows to secondary bus
* and an optional ROM BAR
*/
BRIDGE_RES_BAR1 = 0,
BRIDGE_RES_BAR2 = 1,
BRIDGE_RES_IO = 2,
BRIDGE_RES_MEMIO = 3,
BRIDGE_RES_MEM = 4,
BRIDGE_RES_UNUSED1 = 5,
BRIDGE_RES_ROM = 6,
};
/* Maximum Number of Resources of a device */
#define DEV_RES_CNT (DEV_RES_ROM + 1)
/* PCI Device (Bus|Slot|Function) description */
struct pci_dev {
struct pci_res resources[DEV_RES_CNT]; /* must be topmost field */
struct pci_dev *next;
struct pci_bus *bus;
pci_dev_t busdevfun;
uint8_t flags;
uint8_t sysirq;
uint16_t vendor;
uint16_t device;
uint16_t subvendor;
uint16_t subdevice;
uint32_t classrev;
/* static configuration settings */
uint16_t command;
};
/* PCI Bus description */
struct pci_bus {
struct pci_dev dev; /* PCI Bridge */
struct pci_dev *devs; /* Devices on child (secondary) Bus */
unsigned int flags;
/* Bridge Information */
int num; /* Bus number (0=Root-PCI-bus) */
int pri; /* Primary Bus Number */
int sord; /* Subordinate Buses (Child bus count) */
#if defined(PCI_CFG_AUTO_LIB)
/* Resources of devices on bus. USED INTERNALLY IN AUTO-CFG LIBRARY.
*
* BUS_RES_IO = 0: I/O resources
* BUS_RES_MEMIO = 1: Prefetchable memory resources
* BUS_RES_MEM = 2: Non-Prefetchable memory resources
*/
struct pci_res *busres[3];
#endif
};
#include <pci/cfg_auto.h>
#include <pci/cfg_static.h>
#include <pci/cfg_read.h>
#include <pci/cfg_peripheral.h>
#endif

View File

@@ -0,0 +1,59 @@
/* PCI Auto Configuration Library
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#ifndef __PCI_CFG_AUTO_H__
#define __PCI_CFG_AUTO_H__
#define CFGOPT_NOSETUP_IRQ 0x1 /* Skip IRQ setup */
/* PCI Memory Layout setup, used by the auto-config library in order to
* determine the addresses of PCI BARs and Buses.
*
* All addresses are in PCI address space, the actual address the CPU access
* may be different, and taken care of elsewhere.
*/
struct pci_auto_setup {
int options;
/* PCI prefetchable Memory space (OPTIONAL) */
uint32_t mem_start;
uint32_t mem_size; /* 0 = Use MEMIO space for prefetchable mem BARs */
/* PCI non-prefetchable Memory */
uint32_t memio_start;
uint32_t memio_size;
/* PCI I/O space (OPTIONAL) */
uint32_t io_start;
uint32_t io_size; /* 0 = No I/O space */
/* Get System IRQ connected to a PCI line of a PCI device on bus0.
* The return IRQ value zero equals no IRQ (IRQ disabled).
*/
uint8_t (*irq_map)(pci_dev_t dev, int irq_pin);
/* IRQ Bridge routing. Returns the interrupt pin (0..3 = A..D) that
* a device is connected to on parent bus.
*/
int (*irq_route)(pci_dev_t dev, int irq_pin);
};
/* Do PCI initialization: Enumrate buses, scan buses for devices, assign
* I/O MEM and MEMIO resources, assign IRQ and so on.
*/
extern int pci_config_auto(void);
/* Register a configuration for the auto library (struct pci_auto_setup *) */
extern void pci_config_auto_register(void *config);
/* PCI memory map */
extern struct pci_auto_setup pci_auto_cfg;
#endif

View File

@@ -0,0 +1,20 @@
/* PCI Peripheral Configuration Library
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#ifndef __PCI_CFG_PERIPHERAL_H__
#define __PCI_CFG_PERIPHERAL_H__
/* The user must provide a PCI configuration using the "struct pci_bus pci_hb"
* structure. Nothing else than setting pci_system_type and pci_bus_cnt is done
* by the peripheral library.
*/
extern int pci_config_peripheral(void);
#endif

View File

@@ -0,0 +1,22 @@
/* PCI Read Configuration Library. Read current config that bootloader/BIOS
* has setup.
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#ifndef __PCI_CFG_READ_H__
#define __PCI_CFG_READ_H__
/* Build PCI device tree in "struct pci_bus pci_hb" according to current setup
* in hardware. Devices/buses are created by reading the resource assignments
* that the BIOS/bootloader has already setup for us.
*/
extern int pci_config_read(void);
#endif

View File

@@ -0,0 +1,22 @@
/* Static PCI Auto Configuration Library
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#ifndef __PCI_CFG_STATIC_H__
#define __PCI_CFG_STATIC_H__
/* This function initializes all buses and device accorind to a user defined
* "static" configuration. The configuration can manually created with C
* data structures. Or it can be automatically created on a running target
* using the pci_cfg_print() routine after the AUTO or READ Configuration
* Library has setup the PCI bus
*/
extern int pci_config_static(void);
#endif

802
cpukit/libpci/pci/ids.h Normal file
View File

@@ -0,0 +1,802 @@
/* PCI Identifiers - auto generated */
#ifndef __PCI_IDS_H__
#define __PCI_IDS_H__
/* Include non-public PCI ids (not auto generated) */
#include <pci/ids_extra.h>
/* Not a valid ID, used to match any device ID */
#define PCI_ID_ANY 0xffff
/*
* Vendor and card ID's: sort these numerically according to vendor
* (and according to card ID within vendor). Send all updates to
* <linux-pcisupport@cck.uni-kl.de>.
*/
#define PCI_VENDOR_ID_COMPAQ 0x0e11
#define PCI_DEVICE_ID_COMPAQ_1280 0x3033
#define PCI_DEVICE_ID_COMPAQ_TRIFLEX 0x4000
#define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae10
#define PCI_DEVICE_ID_COMPAQ_NETEL100 0xae32
#define PCI_DEVICE_ID_COMPAQ_NETEL10 0xae34
#define PCI_DEVICE_ID_COMPAQ_NETFLEX3I 0xae35
#define PCI_DEVICE_ID_COMPAQ_NETEL100D 0xae40
#define PCI_DEVICE_ID_COMPAQ_NETEL100PI 0xae43
#define PCI_DEVICE_ID_COMPAQ_NETEL100I 0xb011
#define PCI_DEVICE_ID_COMPAQ_THUNDER 0xf130
#define PCI_DEVICE_ID_COMPAQ_NETFLEX3B 0xf150
#define PCI_VENDOR_ID_NCR 0x1000
#define PCI_DEVICE_ID_NCR_53C810 0x0001
#define PCI_DEVICE_ID_NCR_53C820 0x0002
#define PCI_DEVICE_ID_NCR_53C825 0x0003
#define PCI_DEVICE_ID_NCR_53C815 0x0004
#define PCI_DEVICE_ID_NCR_53C860 0x0006
#define PCI_DEVICE_ID_NCR_53C896 0x000b
#define PCI_DEVICE_ID_NCR_53C895 0x000c
#define PCI_DEVICE_ID_NCR_53C885 0x000d
#define PCI_DEVICE_ID_NCR_53C875 0x000f
#define PCI_DEVICE_ID_NCR_53C875J 0x008f
#define PCI_VENDOR_ID_ATI 0x1002
#define PCI_DEVICE_ID_ATI_68800 0x4158
#define PCI_DEVICE_ID_ATI_215CT222 0x4354
#define PCI_DEVICE_ID_ATI_210888CX 0x4358
#define PCI_DEVICE_ID_ATI_215GB 0x4742
#define PCI_DEVICE_ID_ATI_215GD 0x4744
#define PCI_DEVICE_ID_ATI_215GI 0x4749
#define PCI_DEVICE_ID_ATI_215GP 0x4750
#define PCI_DEVICE_ID_ATI_215GQ 0x4751
#define PCI_DEVICE_ID_ATI_215GT 0x4754
#define PCI_DEVICE_ID_ATI_215GTB 0x4755
#define PCI_DEVICE_ID_ATI_210888GX 0x4758
#define PCI_DEVICE_ID_ATI_215LG 0x4c47
#define PCI_DEVICE_ID_ATI_264LT 0x4c54
#define PCI_DEVICE_ID_ATI_264VT 0x5654
#define PCI_VENDOR_ID_VLSI 0x1004
#define PCI_DEVICE_ID_VLSI_82C592 0x0005
#define PCI_DEVICE_ID_VLSI_82C593 0x0006
#define PCI_DEVICE_ID_VLSI_82C594 0x0007
#define PCI_DEVICE_ID_VLSI_82C597 0x0009
#define PCI_DEVICE_ID_VLSI_82C541 0x000c
#define PCI_DEVICE_ID_VLSI_82C543 0x000d
#define PCI_DEVICE_ID_VLSI_82C532 0x0101
#define PCI_DEVICE_ID_VLSI_82C534 0x0102
#define PCI_DEVICE_ID_VLSI_82C535 0x0104
#define PCI_DEVICE_ID_VLSI_82C147 0x0105
#define PCI_DEVICE_ID_VLSI_VAS96011 0x0702
#define PCI_VENDOR_ID_ADL 0x1005
#define PCI_DEVICE_ID_ADL_2301 0x2301
#define PCI_VENDOR_ID_NS 0x100b
#define PCI_DEVICE_ID_NS_87415 0x0002
#define PCI_DEVICE_ID_NS_87410 0xd001
#define PCI_VENDOR_ID_TSENG 0x100c
#define PCI_DEVICE_ID_TSENG_W32P_2 0x3202
#define PCI_DEVICE_ID_TSENG_W32P_b 0x3205
#define PCI_DEVICE_ID_TSENG_W32P_c 0x3206
#define PCI_DEVICE_ID_TSENG_W32P_d 0x3207
#define PCI_DEVICE_ID_TSENG_ET6000 0x3208
#define PCI_VENDOR_ID_WEITEK 0x100e
#define PCI_DEVICE_ID_WEITEK_P9000 0x9001
#define PCI_DEVICE_ID_WEITEK_P9100 0x9100
#define PCI_VENDOR_ID_DEC 0x1011
#define PCI_DEVICE_ID_DEC_BRD 0x0001
#define PCI_DEVICE_ID_DEC_TULIP 0x0002
#define PCI_DEVICE_ID_DEC_TGA 0x0004
#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009
#define PCI_DEVICE_ID_DEC_TGA2 0x000D
#define PCI_DEVICE_ID_DEC_FDDI 0x000F
#define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014
#define PCI_DEVICE_ID_DEC_21142 0x0019
#define PCI_DEVICE_ID_DEC_21052 0x0021
#define PCI_DEVICE_ID_DEC_21150 0x0022
#define PCI_DEVICE_ID_DEC_21152 0x0024
#define PCI_VENDOR_ID_CIRRUS 0x1013
#define PCI_DEVICE_ID_CIRRUS_7548 0x0038
#define PCI_DEVICE_ID_CIRRUS_5430 0x00a0
#define PCI_DEVICE_ID_CIRRUS_5434_4 0x00a4
#define PCI_DEVICE_ID_CIRRUS_5434_8 0x00a8
#define PCI_DEVICE_ID_CIRRUS_5436 0x00ac
#define PCI_DEVICE_ID_CIRRUS_5446 0x00b8
#define PCI_DEVICE_ID_CIRRUS_5480 0x00bc
#define PCI_DEVICE_ID_CIRRUS_5464 0x00d4
#define PCI_DEVICE_ID_CIRRUS_5465 0x00d6
#define PCI_DEVICE_ID_CIRRUS_6729 0x1100
#define PCI_DEVICE_ID_CIRRUS_6832 0x1110
#define PCI_DEVICE_ID_CIRRUS_7542 0x1200
#define PCI_DEVICE_ID_CIRRUS_7543 0x1202
#define PCI_DEVICE_ID_CIRRUS_7541 0x1204
#define PCI_VENDOR_ID_IBM 0x1014
#define PCI_DEVICE_ID_IBM_FIRE_CORAL 0x000a
#define PCI_DEVICE_ID_IBM_TR 0x0018
#define PCI_DEVICE_ID_IBM_82G2675 0x001d
#define PCI_DEVICE_ID_IBM_MCA 0x0020
#define PCI_DEVICE_ID_IBM_82351 0x0022
#define PCI_DEVICE_ID_IBM_SERVERAID 0x002e
#define PCI_DEVICE_ID_IBM_TR_WAKE 0x003e
#define PCI_DEVICE_ID_IBM_MPIC 0x0046
#define PCI_DEVICE_ID_IBM_3780IDSP 0x007d
#define PCI_DEVICE_ID_IBM_MPIC_2 0xffff
#define PCI_VENDOR_ID_WD 0x101c
#define PCI_DEVICE_ID_WD_7197 0x3296
#define PCI_VENDOR_ID_AMD 0x1022
#define PCI_DEVICE_ID_AMD_LANCE 0x2000
#define PCI_DEVICE_ID_AMD_SCSI 0x2020
#define PCI_VENDOR_ID_TRIDENT 0x1023
#define PCI_DEVICE_ID_TRIDENT_9397 0x9397
#define PCI_DEVICE_ID_TRIDENT_9420 0x9420
#define PCI_DEVICE_ID_TRIDENT_9440 0x9440
#define PCI_DEVICE_ID_TRIDENT_9660 0x9660
#define PCI_DEVICE_ID_TRIDENT_9750 0x9750
#define PCI_VENDOR_ID_AI 0x1025
#define PCI_DEVICE_ID_AI_M1435 0x1435
#define PCI_VENDOR_ID_MATROX 0x102B
#define PCI_DEVICE_ID_MATROX_MGA_2 0x0518
#define PCI_DEVICE_ID_MATROX_MIL 0x0519
#define PCI_DEVICE_ID_MATROX_MYS 0x051A
#define PCI_DEVICE_ID_MATROX_MIL_2 0x051b
#define PCI_DEVICE_ID_MATROX_MIL_2_AGP 0x051f
#define PCI_DEVICE_ID_MATROX_MGA_IMP 0x0d10
#define PCI_VENDOR_ID_CT 0x102c
#define PCI_DEVICE_ID_CT_65545 0x00d8
#define PCI_DEVICE_ID_CT_65548 0x00dc
#define PCI_DEVICE_ID_CT_65550 0x00e0
#define PCI_DEVICE_ID_CT_65554 0x00e4
#define PCI_DEVICE_ID_CT_65555 0x00e5
#define PCI_VENDOR_ID_MIRO 0x1031
#define PCI_DEVICE_ID_MIRO_36050 0x5601
#define PCI_VENDOR_ID_NEC 0x1033
#define PCI_DEVICE_ID_NEC_PCX2 0x0046
#define PCI_VENDOR_ID_FD 0x1036
#define PCI_DEVICE_ID_FD_36C70 0x0000
#define PCI_VENDOR_ID_SI 0x1039
#define PCI_DEVICE_ID_SI_5591_AGP 0x0001
#define PCI_DEVICE_ID_SI_6202 0x0002
#define PCI_DEVICE_ID_SI_503 0x0008
#define PCI_DEVICE_ID_SI_ACPI 0x0009
#define PCI_DEVICE_ID_SI_5597_VGA 0x0200
#define PCI_DEVICE_ID_SI_6205 0x0205
#define PCI_DEVICE_ID_SI_501 0x0406
#define PCI_DEVICE_ID_SI_496 0x0496
#define PCI_DEVICE_ID_SI_601 0x0601
#define PCI_DEVICE_ID_SI_5107 0x5107
#define PCI_DEVICE_ID_SI_5511 0x5511
#define PCI_DEVICE_ID_SI_5513 0x5513
#define PCI_DEVICE_ID_SI_5571 0x5571
#define PCI_DEVICE_ID_SI_5591 0x5591
#define PCI_DEVICE_ID_SI_5597 0x5597
#define PCI_DEVICE_ID_SI_7001 0x7001
#define PCI_VENDOR_ID_HP 0x103c
#define PCI_DEVICE_ID_HP_J2585A 0x1030
#define PCI_DEVICE_ID_HP_J2585B 0x1031
#define PCI_VENDOR_ID_PCTECH 0x1042
#define PCI_DEVICE_ID_PCTECH_RZ1000 0x1000
#define PCI_DEVICE_ID_PCTECH_RZ1001 0x1001
#define PCI_DEVICE_ID_PCTECH_SAMURAI_0 0x3000
#define PCI_DEVICE_ID_PCTECH_SAMURAI_1 0x3010
#define PCI_DEVICE_ID_PCTECH_SAMURAI_IDE 0x3020
#define PCI_VENDOR_ID_DPT 0x1044
#define PCI_DEVICE_ID_DPT 0xa400
#define PCI_VENDOR_ID_OPTI 0x1045
#define PCI_DEVICE_ID_OPTI_92C178 0xc178
#define PCI_DEVICE_ID_OPTI_82C557 0xc557
#define PCI_DEVICE_ID_OPTI_82C558 0xc558
#define PCI_DEVICE_ID_OPTI_82C621 0xc621
#define PCI_DEVICE_ID_OPTI_82C700 0xc700
#define PCI_DEVICE_ID_OPTI_82C701 0xc701
#define PCI_DEVICE_ID_OPTI_82C814 0xc814
#define PCI_DEVICE_ID_OPTI_82C822 0xc822
#define PCI_DEVICE_ID_OPTI_82C825 0xd568
#define PCI_VENDOR_ID_SGS 0x104a
#define PCI_DEVICE_ID_SGS_2000 0x0008
#define PCI_DEVICE_ID_SGS_1764 0x0009
#define PCI_VENDOR_ID_BUSLOGIC 0x104B
#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140
#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER 0x1040
#define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT 0x8130
#define PCI_VENDOR_ID_TI 0x104c
#define PCI_DEVICE_ID_TI_TVP4010 0x3d04
#define PCI_DEVICE_ID_TI_TVP4020 0x3d07
#define PCI_DEVICE_ID_TI_PCI1130 0xac12
#define PCI_DEVICE_ID_TI_PCI1031 0xac13
#define PCI_DEVICE_ID_TI_PCI1131 0xac15
#define PCI_DEVICE_ID_TI_PCI1250 0xac16
#define PCI_DEVICE_ID_TI_PCI1220 0xac17
#define PCI_VENDOR_ID_OAK 0x104e
#define PCI_DEVICE_ID_OAK_OTI107 0x0107
/* Winbond have two vendor IDs! See 0x10ad as well */
#define PCI_VENDOR_ID_WINBOND2 0x1050
#define PCI_DEVICE_ID_WINBOND2_89C940 0x0940
#define PCI_VENDOR_ID_MOTOROLA 0x1057
#define PCI_DEVICE_ID_MOTOROLA_MPC105 0x0001
#define PCI_DEVICE_ID_MOTOROLA_MPC106 0x0002
#define PCI_DEVICE_ID_MOTOROLA_RAVEN 0x4801
#define PCI_VENDOR_ID_PROMISE 0x105a
#define PCI_DEVICE_ID_PROMISE_20246 0x4d33
#define PCI_DEVICE_ID_PROMISE_5300 0x5300
#define PCI_VENDOR_ID_N9 0x105d
#define PCI_DEVICE_ID_N9_I128 0x2309
#define PCI_DEVICE_ID_N9_I128_2 0x2339
#define PCI_DEVICE_ID_N9_I128_T2R 0x493d
#define PCI_VENDOR_ID_UMC 0x1060
#define PCI_DEVICE_ID_UMC_UM8673F 0x0101
#define PCI_DEVICE_ID_UMC_UM8891A 0x0891
#define PCI_DEVICE_ID_UMC_UM8886BF 0x673a
#define PCI_DEVICE_ID_UMC_UM8886A 0x886a
#define PCI_DEVICE_ID_UMC_UM8881F 0x8881
#define PCI_DEVICE_ID_UMC_UM8886F 0x8886
#define PCI_DEVICE_ID_UMC_UM9017F 0x9017
#define PCI_DEVICE_ID_UMC_UM8886N 0xe886
#define PCI_DEVICE_ID_UMC_UM8891N 0xe891
#define PCI_VENDOR_ID_X 0x1061
#define PCI_DEVICE_ID_X_AGX016 0x0001
#define PCI_VENDOR_ID_PICOP 0x1066
#define PCI_DEVICE_ID_PICOP_PT86C52X 0x0001
#define PCI_DEVICE_ID_PICOP_PT80C524 0x8002
#define PCI_VENDOR_ID_APPLE 0x106b
#define PCI_DEVICE_ID_APPLE_BANDIT 0x0001
#define PCI_DEVICE_ID_APPLE_GC 0x0002
#define PCI_DEVICE_ID_APPLE_HYDRA 0x000e
#define PCI_VENDOR_ID_NEXGEN 0x1074
#define PCI_DEVICE_ID_NEXGEN_82C501 0x4e78
#define PCI_VENDOR_ID_QLOGIC 0x1077
#define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020
#define PCI_DEVICE_ID_QLOGIC_ISP1022 0x1022
#define PCI_VENDOR_ID_CYRIX 0x1078
#define PCI_DEVICE_ID_CYRIX_5510 0x0000
#define PCI_DEVICE_ID_CYRIX_PCI_MASTER 0x0001
#define PCI_DEVICE_ID_CYRIX_5520 0x0002
#define PCI_DEVICE_ID_CYRIX_5530_LEGACY 0x0100
#define PCI_DEVICE_ID_CYRIX_5530_SMI 0x0101
#define PCI_DEVICE_ID_CYRIX_5530_IDE 0x0102
#define PCI_DEVICE_ID_CYRIX_5530_AUDIO 0x0103
#define PCI_DEVICE_ID_CYRIX_5530_VIDEO 0x0104
#define PCI_VENDOR_ID_LEADTEK 0x107d
#define PCI_DEVICE_ID_LEADTEK_805 0x0000
#define PCI_VENDOR_ID_CONTAQ 0x1080
#define PCI_DEVICE_ID_CONTAQ_82C599 0x0600
#define PCI_DEVICE_ID_CONTAQ_82C693 0xc693
#define PCI_VENDOR_ID_FOREX 0x1083
#define PCI_VENDOR_ID_OLICOM 0x108d
#define PCI_DEVICE_ID_OLICOM_OC3136 0x0001
#define PCI_DEVICE_ID_OLICOM_OC2315 0x0011
#define PCI_DEVICE_ID_OLICOM_OC2325 0x0012
#define PCI_DEVICE_ID_OLICOM_OC2183 0x0013
#define PCI_DEVICE_ID_OLICOM_OC2326 0x0014
#define PCI_DEVICE_ID_OLICOM_OC6151 0x0021
#define PCI_VENDOR_ID_SUN 0x108e
#define PCI_DEVICE_ID_SUN_EBUS 0x1000
#define PCI_DEVICE_ID_SUN_HAPPYMEAL 0x1001
#define PCI_DEVICE_ID_SUN_SIMBA 0x5000
#define PCI_DEVICE_ID_SUN_PBM 0x8000
#define PCI_DEVICE_ID_SUN_SABRE 0xa000
#define PCI_VENDOR_ID_CMD 0x1095
#define PCI_DEVICE_ID_CMD_640 0x0640
#define PCI_DEVICE_ID_CMD_643 0x0643
#define PCI_DEVICE_ID_CMD_646 0x0646
#define PCI_DEVICE_ID_CMD_647 0x0647
#define PCI_DEVICE_ID_CMD_670 0x0670
#define PCI_VENDOR_ID_VISION 0x1098
#define PCI_DEVICE_ID_VISION_QD8500 0x0001
#define PCI_DEVICE_ID_VISION_QD8580 0x0002
#define PCI_VENDOR_ID_BROOKTREE 0x109e
#define PCI_DEVICE_ID_BROOKTREE_848 0x0350
#define PCI_DEVICE_ID_BROOKTREE_849A 0x0351
#define PCI_DEVICE_ID_BROOKTREE_8474 0x8474
#define PCI_VENDOR_ID_SIERRA 0x10a8
#define PCI_DEVICE_ID_SIERRA_STB 0x0000
#define PCI_VENDOR_ID_ACC 0x10aa
#define PCI_DEVICE_ID_ACC_2056 0x0000
#define PCI_VENDOR_ID_WINBOND 0x10ad
#define PCI_DEVICE_ID_WINBOND_83769 0x0001
#define PCI_DEVICE_ID_WINBOND_82C105 0x0105
#define PCI_DEVICE_ID_WINBOND_83C553 0x0565
#define PCI_VENDOR_ID_DATABOOK 0x10b3
#define PCI_DEVICE_ID_DATABOOK_87144 0xb106
#define PCI_VENDOR_ID_PLX 0x10b5
#define PCI_DEVICE_ID_PLX_9050 0x9050
#define PCI_DEVICE_ID_PLX_9060 0x9060
#define PCI_DEVICE_ID_PLX_9060ES 0x906E
#define PCI_DEVICE_ID_PLX_9060SD 0x906D
#define PCI_DEVICE_ID_PLX_9080 0x9080
#define PCI_VENDOR_ID_MADGE 0x10b6
#define PCI_DEVICE_ID_MADGE_MK2 0x0002
#define PCI_DEVICE_ID_MADGE_C155S 0x1001
#define PCI_VENDOR_ID_3COM 0x10b7
#define PCI_DEVICE_ID_3COM_3C339 0x3390
#define PCI_DEVICE_ID_3COM_3C590 0x5900
#define PCI_DEVICE_ID_3COM_3C595TX 0x5950
#define PCI_DEVICE_ID_3COM_3C595T4 0x5951
#define PCI_DEVICE_ID_3COM_3C595MII 0x5952
#define PCI_DEVICE_ID_3COM_3C900TPO 0x9000
#define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001
#define PCI_DEVICE_ID_3COM_3C905TX 0x9050
#define PCI_DEVICE_ID_3COM_3C905T4 0x9051
#define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055
#define PCI_VENDOR_ID_SMC 0x10b8
#define PCI_DEVICE_ID_SMC_EPIC100 0x0005
#define PCI_VENDOR_ID_AL 0x10b9
#define PCI_DEVICE_ID_AL_M1445 0x1445
#define PCI_DEVICE_ID_AL_M1449 0x1449
#define PCI_DEVICE_ID_AL_M1451 0x1451
#define PCI_DEVICE_ID_AL_M1461 0x1461
#define PCI_DEVICE_ID_AL_M1489 0x1489
#define PCI_DEVICE_ID_AL_M1511 0x1511
#define PCI_DEVICE_ID_AL_M1513 0x1513
#define PCI_DEVICE_ID_AL_M1521 0x1521
#define PCI_DEVICE_ID_AL_M1523 0x1523
#define PCI_DEVICE_ID_AL_M1531 0x1531
#define PCI_DEVICE_ID_AL_M1533 0x1533
#define PCI_DEVICE_ID_AL_M3307 0x3307
#define PCI_DEVICE_ID_AL_M4803 0x5215
#define PCI_DEVICE_ID_AL_M5219 0x5219
#define PCI_DEVICE_ID_AL_M5229 0x5229
#define PCI_DEVICE_ID_AL_M5237 0x5237
#define PCI_DEVICE_ID_AL_M7101 0x7101
#define PCI_VENDOR_ID_MITSUBISHI 0x10ba
#define PCI_VENDOR_ID_SURECOM 0x10bd
#define PCI_DEVICE_ID_SURECOM_NE34 0x0e34
#define PCI_VENDOR_ID_NEOMAGIC 0x10c8
#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2070 0x0001
#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128V 0x0002
#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZV 0x0003
#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2160 0x0004
#define PCI_VENDOR_ID_ASP 0x10cd
#define PCI_DEVICE_ID_ASP_ABP940 0x1200
#define PCI_DEVICE_ID_ASP_ABP940U 0x1300
#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
#define PCI_VENDOR_ID_MACRONIX 0x10d9
#define PCI_DEVICE_ID_MACRONIX_MX98713 0x0512
#define PCI_DEVICE_ID_MACRONIX_MX987x5 0x0531
#define PCI_VENDOR_ID_CERN 0x10dc
#define PCI_DEVICE_ID_CERN_SPSB_PMC 0x0001
#define PCI_DEVICE_ID_CERN_SPSB_PCI 0x0002
#define PCI_DEVICE_ID_CERN_HIPPI_DST 0x0021
#define PCI_DEVICE_ID_CERN_HIPPI_SRC 0x0022
#define PCI_VENDOR_ID_NVIDIA 0x10de
#define PCI_VENDOR_ID_IMS 0x10e0
#define PCI_DEVICE_ID_IMS_8849 0x8849
#define PCI_VENDOR_ID_TEKRAM2 0x10e1
#define PCI_DEVICE_ID_TEKRAM2_690c 0x690c
#define PCI_VENDOR_ID_TUNDRA 0x10e3
#define PCI_DEVICE_ID_TUNDRA_CA91C042 0x0000
#define PCI_VENDOR_ID_AMCC 0x10e8
#define PCI_DEVICE_ID_AMCC_MYRINET 0x8043
#define PCI_DEVICE_ID_AMCC_PARASTATION 0x8062
#define PCI_DEVICE_ID_AMCC_S5933 0x807d
#define PCI_DEVICE_ID_AMCC_S5933_HEPC3 0x809c
#define PCI_VENDOR_ID_INTERG 0x10ea
#define PCI_DEVICE_ID_INTERG_1680 0x1680
#define PCI_DEVICE_ID_INTERG_1682 0x1682
#define PCI_VENDOR_ID_REALTEK 0x10ec
#define PCI_DEVICE_ID_REALTEK_8029 0x8029
#define PCI_DEVICE_ID_REALTEK_8129 0x8129
#define PCI_DEVICE_ID_REALTEK_8139 0x8139
#define PCI_VENDOR_ID_TRUEVISION 0x10fa
#define PCI_DEVICE_ID_TRUEVISION_T1000 0x000c
#define PCI_VENDOR_ID_INIT 0x1101
#define PCI_DEVICE_ID_INIT_320P 0x9100
#define PCI_DEVICE_ID_INIT_360P 0x9500
#define PCI_VENDOR_ID_TTI 0x1103
#define PCI_DEVICE_ID_TTI_HPT343 0x0003
#define PCI_VENDOR_ID_VIA 0x1106
#define PCI_DEVICE_ID_VIA_82C505 0x0505
#define PCI_DEVICE_ID_VIA_82C561 0x0561
#define PCI_DEVICE_ID_VIA_82C586_1 0x0571
#define PCI_DEVICE_ID_VIA_82C576 0x0576
#define PCI_DEVICE_ID_VIA_82C585 0x0585
#define PCI_DEVICE_ID_VIA_82C586_0 0x0586
#define PCI_DEVICE_ID_VIA_82C595 0x0595
#define PCI_DEVICE_ID_VIA_82C597_0 0x0597
#define PCI_DEVICE_ID_VIA_82C926 0x0926
#define PCI_DEVICE_ID_VIA_82C416 0x1571
#define PCI_DEVICE_ID_VIA_82C595_97 0x1595
#define PCI_DEVICE_ID_VIA_82C586_2 0x3038
#define PCI_DEVICE_ID_VIA_82C586_3 0x3040
#define PCI_DEVICE_ID_VIA_86C100A 0x6100
#define PCI_DEVICE_ID_VIA_82C597_1 0x8597
#define PCI_VENDOR_ID_VORTEX 0x1119
#define PCI_DEVICE_ID_VORTEX_GDT60x0 0x0000
#define PCI_DEVICE_ID_VORTEX_GDT6000B 0x0001
#define PCI_DEVICE_ID_VORTEX_GDT6x10 0x0002
#define PCI_DEVICE_ID_VORTEX_GDT6x20 0x0003
#define PCI_DEVICE_ID_VORTEX_GDT6530 0x0004
#define PCI_DEVICE_ID_VORTEX_GDT6550 0x0005
#define PCI_DEVICE_ID_VORTEX_GDT6x17 0x0006
#define PCI_DEVICE_ID_VORTEX_GDT6x27 0x0007
#define PCI_DEVICE_ID_VORTEX_GDT6537 0x0008
#define PCI_DEVICE_ID_VORTEX_GDT6557 0x0009
#define PCI_DEVICE_ID_VORTEX_GDT6x15 0x000a
#define PCI_DEVICE_ID_VORTEX_GDT6x25 0x000b
#define PCI_DEVICE_ID_VORTEX_GDT6535 0x000c
#define PCI_DEVICE_ID_VORTEX_GDT6555 0x000d
#define PCI_DEVICE_ID_VORTEX_GDT6x17RP 0x0100
#define PCI_DEVICE_ID_VORTEX_GDT6x27RP 0x0101
#define PCI_DEVICE_ID_VORTEX_GDT6537RP 0x0102
#define PCI_DEVICE_ID_VORTEX_GDT6557RP 0x0103
#define PCI_DEVICE_ID_VORTEX_GDT6x11RP 0x0104
#define PCI_DEVICE_ID_VORTEX_GDT6x21RP 0x0105
#define PCI_DEVICE_ID_VORTEX_GDT6x17RP1 0x0110
#define PCI_DEVICE_ID_VORTEX_GDT6x27RP1 0x0111
#define PCI_DEVICE_ID_VORTEX_GDT6537RP1 0x0112
#define PCI_DEVICE_ID_VORTEX_GDT6557RP1 0x0113
#define PCI_DEVICE_ID_VORTEX_GDT6x11RP1 0x0114
#define PCI_DEVICE_ID_VORTEX_GDT6x21RP1 0x0115
#define PCI_DEVICE_ID_VORTEX_GDT6x17RP2 0x0120
#define PCI_DEVICE_ID_VORTEX_GDT6x27RP2 0x0121
#define PCI_DEVICE_ID_VORTEX_GDT6537RP2 0x0122
#define PCI_DEVICE_ID_VORTEX_GDT6557RP2 0x0123
#define PCI_DEVICE_ID_VORTEX_GDT6x11RP2 0x0124
#define PCI_DEVICE_ID_VORTEX_GDT6x21RP2 0x0125
#define PCI_VENDOR_ID_EF 0x111a
#define PCI_DEVICE_ID_EF_ATM_FPGA 0x0000
#define PCI_DEVICE_ID_EF_ATM_ASIC 0x0002
#define PCI_VENDOR_ID_FORE 0x1127
#define PCI_DEVICE_ID_FORE_PCA200PC 0x0210
#define PCI_DEVICE_ID_FORE_PCA200E 0x0300
#define PCI_VENDOR_ID_IMAGINGTECH 0x112f
#define PCI_DEVICE_ID_IMAGINGTECH_ICPCI 0x0000
#define PCI_VENDOR_ID_PHILIPS 0x1131
#define PCI_DEVICE_ID_PHILIPS_SAA7145 0x7145
#define PCI_DEVICE_ID_PHILIPS_SAA7146 0x7146
#define PCI_VENDOR_ID_CYCLONE 0x113c
#define PCI_DEVICE_ID_CYCLONE_SDK 0x0001
#define PCI_VENDOR_ID_ALLIANCE 0x1142
#define PCI_DEVICE_ID_ALLIANCE_PROMOTIO 0x3210
#define PCI_DEVICE_ID_ALLIANCE_PROVIDEO 0x6422
#define PCI_DEVICE_ID_ALLIANCE_AT24 0x6424
#define PCI_DEVICE_ID_ALLIANCE_AT3D 0x643d
#define PCI_VENDOR_ID_SK 0x1148
#define PCI_DEVICE_ID_SK_FP 0x4000
#define PCI_DEVICE_ID_SK_TR 0x4200
#define PCI_DEVICE_ID_SK_GE 0x4300
#define PCI_VENDOR_ID_VMIC 0x114a
#define PCI_DEVICE_ID_VMIC_VME 0x7587
#define PCI_VENDOR_ID_DIGI 0x114f
#define PCI_DEVICE_ID_DIGI_EPC 0x0002
#define PCI_DEVICE_ID_DIGI_RIGHTSWITCH 0x0003
#define PCI_DEVICE_ID_DIGI_XEM 0x0004
#define PCI_DEVICE_ID_DIGI_XR 0x0005
#define PCI_DEVICE_ID_DIGI_CX 0x0006
#define PCI_DEVICE_ID_DIGI_XRJ 0x0009
#define PCI_DEVICE_ID_DIGI_EPCJ 0x000a
#define PCI_DEVICE_ID_DIGI_XR_920 0x0027
#define PCI_VENDOR_ID_MUTECH 0x1159
#define PCI_DEVICE_ID_MUTECH_MV1000 0x0001
#define PCI_VENDOR_ID_RENDITION 0x1163
#define PCI_DEVICE_ID_RENDITION_VERITE 0x0001
#define PCI_DEVICE_ID_RENDITION_VERITE2100 0x2000
#define PCI_VENDOR_ID_TOSHIBA 0x1179
#define PCI_DEVICE_ID_TOSHIBA_601 0x0601
#define PCI_DEVICE_ID_TOSHIBA_TOPIC95 0x060a
#define PCI_DEVICE_ID_TOSHIBA_TOPIC97 0x060f
#define PCI_VENDOR_ID_RICOH 0x1180
#define PCI_DEVICE_ID_RICOH_RL5C465 0x0465
#define PCI_DEVICE_ID_RICOH_RL5C466 0x0466
#define PCI_DEVICE_ID_RICOH_RL5C475 0x0475
#define PCI_DEVICE_ID_RICOH_RL5C478 0x0478
#define PCI_VENDOR_ID_ARTOP 0x1191
#define PCI_DEVICE_ID_ARTOP_ATP8400 0x0004
#define PCI_DEVICE_ID_ARTOP_ATP850UF 0x0005
#define PCI_VENDOR_ID_ZEITNET 0x1193
#define PCI_DEVICE_ID_ZEITNET_1221 0x0001
#define PCI_DEVICE_ID_ZEITNET_1225 0x0002
#define PCI_VENDOR_ID_OMEGA 0x119b
#define PCI_DEVICE_ID_OMEGA_82C092G 0x1221
#define PCI_VENDOR_ID_LITEON 0x11ad
#define PCI_DEVICE_ID_LITEON_LNE100TX 0x0002
#define PCI_VENDOR_ID_NP 0x11bc
#define PCI_DEVICE_ID_NP_PCI_FDDI 0x0001
#define PCI_VENDOR_ID_ATT 0x11c1
#define PCI_DEVICE_ID_ATT_L56XMF 0x0440
#define PCI_VENDOR_ID_SPECIALIX 0x11cb
#define PCI_DEVICE_ID_SPECIALIX_IO8 0x2000
#define PCI_DEVICE_ID_SPECIALIX_XIO 0x4000
#define PCI_DEVICE_ID_SPECIALIX_RIO 0x8000
#define PCI_VENDOR_ID_AURAVISION 0x11d1
#define PCI_DEVICE_ID_AURAVISION_VXP524 0x01f7
#define PCI_VENDOR_ID_IKON 0x11d5
#define PCI_DEVICE_ID_IKON_10115 0x0115
#define PCI_DEVICE_ID_IKON_10117 0x0117
#define PCI_VENDOR_ID_ZORAN 0x11de
#define PCI_DEVICE_ID_ZORAN_36057 0x6057
#define PCI_DEVICE_ID_ZORAN_36120 0x6120
#define PCI_VENDOR_ID_KINETIC 0x11f4
#define PCI_DEVICE_ID_KINETIC_2915 0x2915
#define PCI_VENDOR_ID_COMPEX 0x11f6
#define PCI_DEVICE_ID_COMPEX_ENET100VG4 0x0112
#define PCI_DEVICE_ID_COMPEX_RL2000 0x1401
#define PCI_VENDOR_ID_RP 0x11fe
#define PCI_DEVICE_ID_RP32INTF 0x0001
#define PCI_DEVICE_ID_RP8INTF 0x0002
#define PCI_DEVICE_ID_RP16INTF 0x0003
#define PCI_DEVICE_ID_RP4QUAD 0x0004
#define PCI_DEVICE_ID_RP8OCTA 0x0005
#define PCI_DEVICE_ID_RP8J 0x0006
#define PCI_DEVICE_ID_RPP4 0x000A
#define PCI_DEVICE_ID_RPP8 0x000B
#define PCI_DEVICE_ID_RP8M 0x000C
#define PCI_VENDOR_ID_CYCLADES 0x120e
#define PCI_DEVICE_ID_CYCLOM_Y_Lo 0x0100
#define PCI_DEVICE_ID_CYCLOM_Y_Hi 0x0101
#define PCI_DEVICE_ID_CYCLOM_Z_Lo 0x0200
#define PCI_DEVICE_ID_CYCLOM_Z_Hi 0x0201
#define PCI_VENDOR_ID_ESSENTIAL 0x120f
#define PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER 0x0001
#define PCI_VENDOR_ID_O2 0x1217
#define PCI_DEVICE_ID_O2_6729 0x6729
#define PCI_DEVICE_ID_O2_6730 0x673a
#define PCI_DEVICE_ID_O2_6832 0x6832
#define PCI_DEVICE_ID_O2_6836 0x6836
#define PCI_VENDOR_ID_3DFX 0x121a
#define PCI_DEVICE_ID_3DFX_VOODOO 0x0001
#define PCI_DEVICE_ID_3DFX_VOODOO2 0x0002
#define PCI_VENDOR_ID_SIGMADES 0x1236
#define PCI_DEVICE_ID_SIGMADES_6425 0x6401
#define PCI_VENDOR_ID_CCUBE 0x123f
#define PCI_VENDOR_ID_DIPIX 0x1246
#define PCI_VENDOR_ID_STALLION 0x124d
#define PCI_DEVICE_ID_STALLION_ECHPCI832 0x0000
#define PCI_DEVICE_ID_STALLION_ECHPCI864 0x0002
#define PCI_DEVICE_ID_STALLION_EIOPCI 0x0003
#define PCI_VENDOR_ID_OPTIBASE 0x1255
#define PCI_DEVICE_ID_OPTIBASE_FORGE 0x1110
#define PCI_DEVICE_ID_OPTIBASE_FUSION 0x1210
#define PCI_DEVICE_ID_OPTIBASE_VPLEX 0x2110
#define PCI_DEVICE_ID_OPTIBASE_VPLEXCC 0x2120
#define PCI_DEVICE_ID_OPTIBASE_VQUEST 0x2130
#define PCI_VENDOR_ID_SATSAGEM 0x1267
#define PCI_DEVICE_ID_SATSAGEM_PCR2101 0x5352
#define PCI_DEVICE_ID_SATSAGEM_TELSATTURBO 0x5a4b
#define PCI_VENDOR_ID_HUGHES 0x1273
#define PCI_DEVICE_ID_HUGHES_DIRECPC 0x0002
#define PCI_VENDOR_ID_ENSONIQ 0x1274
#define PCI_DEVICE_ID_ENSONIQ_AUDIOPCI 0x5000
#define PCI_VENDOR_ID_ALTEON 0x12ae
#define PCI_DEVICE_ID_ALTEON_ACENIC 0x0001
#define PCI_VENDOR_ID_PICTUREL 0x12c5
#define PCI_DEVICE_ID_PICTUREL_PCIVST 0x0081
#define PCI_VENDOR_ID_NVIDIA_SGS 0x12d2
#define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018
#define PCI_VENDOR_ID_CBOARDS 0x1307
#define PCI_DEVICE_ID_CBOARDS_DAS1602_16 0x0001
#define PCI_VENDOR_ID_SYMPHONY 0x1c1c
#define PCI_DEVICE_ID_SYMPHONY_101 0x0001
#define PCI_VENDOR_ID_TEKRAM 0x1de1
#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
#define PCI_VENDOR_ID_3DLABS 0x3d3d
#define PCI_DEVICE_ID_3DLABS_300SX 0x0001
#define PCI_DEVICE_ID_3DLABS_500TX 0x0002
#define PCI_DEVICE_ID_3DLABS_DELTA 0x0003
#define PCI_DEVICE_ID_3DLABS_PERMEDIA 0x0004
#define PCI_DEVICE_ID_3DLABS_MX 0x0006
#define PCI_VENDOR_ID_AVANCE 0x4005
#define PCI_DEVICE_ID_AVANCE_ALG2064 0x2064
#define PCI_DEVICE_ID_AVANCE_2302 0x2302
#define PCI_VENDOR_ID_NETVIN 0x4a14
#define PCI_DEVICE_ID_NETVIN_NV5000SC 0x5000
#define PCI_VENDOR_ID_S3 0x5333
#define PCI_DEVICE_ID_S3_PLATO_PXS 0x0551
#define PCI_DEVICE_ID_S3_ViRGE 0x5631
#define PCI_DEVICE_ID_S3_TRIO 0x8811
#define PCI_DEVICE_ID_S3_AURORA64VP 0x8812
#define PCI_DEVICE_ID_S3_TRIO64UVP 0x8814
#define PCI_DEVICE_ID_S3_ViRGE_VX 0x883d
#define PCI_DEVICE_ID_S3_868 0x8880
#define PCI_DEVICE_ID_S3_928 0x88b0
#define PCI_DEVICE_ID_S3_864_1 0x88c0
#define PCI_DEVICE_ID_S3_864_2 0x88c1
#define PCI_DEVICE_ID_S3_964_1 0x88d0
#define PCI_DEVICE_ID_S3_964_2 0x88d1
#define PCI_DEVICE_ID_S3_968 0x88f0
#define PCI_DEVICE_ID_S3_TRIO64V2 0x8901
#define PCI_DEVICE_ID_S3_PLATO_PXG 0x8902
#define PCI_DEVICE_ID_S3_ViRGE_DXGX 0x8a01
#define PCI_DEVICE_ID_S3_ViRGE_GX2 0x8a10
#define PCI_DEVICE_ID_S3_ViRGE_MX 0x8c01
#define PCI_DEVICE_ID_S3_ViRGE_MXP 0x8c02
#define PCI_DEVICE_ID_S3_ViRGE_MXPMV 0x8c03
#define PCI_DEVICE_ID_S3_SONICVIBES 0xca00
#define PCI_VENDOR_ID_INTEL 0x8086
#define PCI_DEVICE_ID_INTEL_82375 0x0482
#define PCI_DEVICE_ID_INTEL_82424 0x0483
#define PCI_DEVICE_ID_INTEL_82378 0x0484
#define PCI_DEVICE_ID_INTEL_82430 0x0486
#define PCI_DEVICE_ID_INTEL_82434 0x04a3
#define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221
#define PCI_DEVICE_ID_INTEL_82092AA_1 0x1222
#define PCI_DEVICE_ID_INTEL_7116 0x1223
#define PCI_DEVICE_ID_INTEL_82596 0x1226
#define PCI_DEVICE_ID_INTEL_82865 0x1227
#define PCI_DEVICE_ID_INTEL_82557 0x1229
#define PCI_DEVICE_ID_INTEL_82437 0x122d
#define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e
#define PCI_DEVICE_ID_INTEL_82371FB_1 0x1230
#define PCI_DEVICE_ID_INTEL_82371MX 0x1234
#define PCI_DEVICE_ID_INTEL_82437MX 0x1235
#define PCI_DEVICE_ID_INTEL_82441 0x1237
#define PCI_DEVICE_ID_INTEL_82380FB 0x124b
#define PCI_DEVICE_ID_INTEL_82439 0x1250
#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000
#define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010
#define PCI_DEVICE_ID_INTEL_82371SB_2 0x7020
#define PCI_DEVICE_ID_INTEL_82437VX 0x7030
#define PCI_DEVICE_ID_INTEL_82439TX 0x7100
#define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110
#define PCI_DEVICE_ID_INTEL_82371AB 0x7111
#define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112
#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
#define PCI_DEVICE_ID_INTEL_82443LX_0 0x7180
#define PCI_DEVICE_ID_INTEL_82443LX_1 0x7181
#define PCI_DEVICE_ID_INTEL_82443BX_0 0x7190
#define PCI_DEVICE_ID_INTEL_82443BX_1 0x7191
#define PCI_DEVICE_ID_INTEL_82443BX_2 0x7192
#define PCI_DEVICE_ID_INTEL_P6 0x84c4
#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5
#define PCI_VENDOR_ID_KTI 0x8e2e
#define PCI_DEVICE_ID_KTI_ET32P2 0x3000
#define PCI_VENDOR_ID_ADAPTEC 0x9004
#define PCI_DEVICE_ID_ADAPTEC_7810 0x1078
#define PCI_DEVICE_ID_ADAPTEC_7850 0x5078
#define PCI_DEVICE_ID_ADAPTEC_7855 0x5578
#define PCI_DEVICE_ID_ADAPTEC_5800 0x5800
#define PCI_DEVICE_ID_ADAPTEC_1480A 0x6075
#define PCI_DEVICE_ID_ADAPTEC_7860 0x6078
#define PCI_DEVICE_ID_ADAPTEC_7861 0x6178
#define PCI_DEVICE_ID_ADAPTEC_7870 0x7078
#define PCI_DEVICE_ID_ADAPTEC_7871 0x7178
#define PCI_DEVICE_ID_ADAPTEC_7872 0x7278
#define PCI_DEVICE_ID_ADAPTEC_7873 0x7378
#define PCI_DEVICE_ID_ADAPTEC_7874 0x7478
#define PCI_DEVICE_ID_ADAPTEC_7895 0x7895
#define PCI_DEVICE_ID_ADAPTEC_7880 0x8078
#define PCI_DEVICE_ID_ADAPTEC_7881 0x8178
#define PCI_DEVICE_ID_ADAPTEC_7882 0x8278
#define PCI_DEVICE_ID_ADAPTEC_7883 0x8378
#define PCI_DEVICE_ID_ADAPTEC_7884 0x8478
#define PCI_DEVICE_ID_ADAPTEC_1030 0x8b78
#define PCI_VENDOR_ID_ADAPTEC2 0x9005
#define PCI_DEVICE_ID_ADAPTEC2_2940U2 0x0010
#define PCI_DEVICE_ID_ADAPTEC2_7890 0x001f
#define PCI_DEVICE_ID_ADAPTEC2_3940U2 0x0050
#define PCI_DEVICE_ID_ADAPTEC2_7896 0x005f
#define PCI_VENDOR_ID_ATRONICS 0x907f
#define PCI_DEVICE_ID_ATRONICS_2015 0x2015
#define PCI_VENDOR_ID_HOLTEK 0x9412
#define PCI_DEVICE_ID_HOLTEK_6565 0x6565
#define PCI_VENDOR_ID_TIGERJET 0xe159
#define PCI_DEVICE_ID_TIGERJET_300 0x0001
#define PCI_VENDOR_ID_ARK 0xedd8
#define PCI_DEVICE_ID_ARK_STING 0xa091
#define PCI_DEVICE_ID_ARK_STINGARK 0xa099
#define PCI_DEVICE_ID_ARK_2000MT 0xa0a1
#endif /* !__PCI_IDS_H__ */

View File

@@ -0,0 +1,19 @@
/* RTEMS local PCI data base */
/* Only included from pci_ids.h */
#ifndef __PCI_IDS_H__
#error pci/ids_extra.h should only be included from pci/ids.h
#endif
/* Gaisler PCI IDs */
#define PCIID_VENDOR_GAISLER 0x1AC8
#define PCIID_VENDOR_GAISLER_OLD 0x16E3
/* Gaisler PCI Devices */
#define PCIID_DEVICE_GR_RASTA_IO 0x0010 /* GR-RASTA-IO */
#define PCIID_DEVICE_GR_RASTA_IO_OLD 0x0210 /* old GR-RASTA-IO ID*/
#define PCIID_DEVICE_GR_RASTA_TMTC 0x0011 /* GR-RASTA-TMTC */
#define PCIID_DEVICE_GR_RASTA_ADCDAC 0x0014 /* GR-RASTA-ADCDAC */
#define PCIID_DEVICE_GR_701 0x0701 /* GR-701 */
#define PCIID_DEVICE_GR_TMTC_1553 0x0198 /* GR-TMTC-1553 */
#define PCIID_DEVICE_GR_RASTA_SPW_RTR 0x0062 /* GR-RASTA-SPW-ROUTER */

105
cpukit/libpci/pci/irq.h Normal file
View File

@@ -0,0 +1,105 @@
/* PCI IRQ Library
*
* IRQ handling does not have so much with PCI to do, this library depends
* on the BSP to implement shared interrupts.
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#ifndef __PCI_IRQ_H__
#define __PCI_IRQ_H__
#include <bsp.h>
/* PCI Handler (ISR) called when IRQ is generated by any of the PCI devices
* connected to the same PCI IRQ Pin. This is been defined the same way as
* rtems_interrupt_handler in order for BSPs to "direct-map" the register
* and unregister functions rtems_interrupt_handler_install/remove
*/
typedef void (*pci_isr)(void *arg);
/* Get assigned system IRQ to a PCI Device. If no IRQ 0 is returned */
extern int pci_dev_irq(pci_dev_t dev);
/* Register shared PCI IRQ handler, but does not enable it. The system interrupt
* number is read from the PCI board's PCI configuration space header iline
* field. The iline field is initialized by the PCI subsystem during start up,
* the ipin field is translated into a system IRQ and written to iline. The
* board's driver should use the iline field as the irq argument to this
* function.
*
* Arguments
* irq System IRQ number, normally taken from the PCI configuration area
* isr Function pointer to the ISR
* arg Second argument to function isr
*/
static inline int pci_interrupt_register(int irq, const char *info,
pci_isr isr, void *arg)
{
return BSP_PCI_shared_interrupt_register(irq, info, isr, arg);
}
/* Unregister previously registered shared PCI IRQ handler
*
* Arguments
* irq System IRQ number, normally taken from the PCI configuration area
* isr Function pointer to the ISR
* arg Second argument to function isr
*/
static inline int pci_interrupt_unregister(int irq, pci_isr isr, void *arg)
{
return BSP_PCI_shared_interrupt_unregister(irq, isr, arg);
}
/* Enable shared PCI IRQ handler. This function will unmask the interrupt
* controller and mark this interrupt handler ready to handle interrupts. Note
* that since it is a shared interrupt handler service the interrupt may
* already be enabled, however no calls to this specific handler is made
* until it is enabled.
*
* Arguments
* irq System IRQ number, normally taken from the PCI configuration area
* isr Function pointer to the ISR
* arg Second argument to function isr
*/
static inline void pci_interrupt_unmask(int irq)
{
BSP_PCI_shared_interrupt_unmask(irq);
}
/* Disable shared PCI IRQ handler. This function will mask the interrupt
* controller and mark this interrupt handler not ready to receive interrupts.
* Note that since it is a shared interrupt handler service the interrupt may
* still be enabled, however no calls to this specific handler is made
* while it is disabled.
*
* Arguments
* irq System IRQ number, normally taken from the PCI configuration area
* isr Function pointer to the ISR
* arg Second argument to function isr
*/
static inline void pci_interrupt_mask(int irq)
{
BSP_PCI_shared_interrupt_mask(irq);
}
/* Acknowledge the interrupt controller by writing to the interrupt controller.
* Note that since it is a shared interrupt handler service, clearing the
* interrupt source may affect other ISRs registered to this IRQ.
*
* Arguments
* irq System IRQ number, normally taken from the PCI configuration area
* isr Function pointer to the ISR
* arg Second argument to function isr
*/
static inline void pci_interrupt_clear(int irq)
{
BSP_PCI_shared_interrupt_clear(irq);
}
#endif /* !__PCI_IRQ_H__ */

View File

@@ -0,0 +1,74 @@
/* PCI Access Library
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <pci.h>
#include <pci/access.h>
/* Access Routines valid after a PCI-Access-Driver has registered */
struct pci_access_drv pci_access_ops = {
.cfg = {.read8 = 0},
};
/* Read a 8-bit register over configuration space */
int pci_cfg_r8(pci_dev_t dev, int ofs, uint8_t *data)
{
return pci_access_ops.cfg.read8(dev, ofs, data);
}
/* Read a 16-bit register over configuration space */
int pci_cfg_r16(pci_dev_t dev, int ofs, uint16_t *data)
{
return pci_access_ops.cfg.read16(dev, ofs, data);
}
/* Read a 32-bit register over configuration space */
int pci_cfg_r32(pci_dev_t dev, int ofs, uint32_t *data)
{
return pci_access_ops.cfg.read32(dev, ofs, data);
}
/* Write a 8-bit register over configuration space */
int pci_cfg_w8(pci_dev_t dev, int ofs, uint8_t data)
{
return pci_access_ops.cfg.write8(dev, ofs, data);
}
/* Write a 16-bit register over configuration space */
int pci_cfg_w16(pci_dev_t dev, int ofs, uint16_t data)
{
return pci_access_ops.cfg.write16(dev, ofs, data);
}
/* Write a 32-bit register over configuration space */
int pci_cfg_w32(pci_dev_t dev, int ofs, uint32_t data)
{
return pci_access_ops.cfg.write32(dev, ofs, data);
}
void pci_modify_cmdsts(pci_dev_t dev, uint32_t mask, uint32_t val)
{
uint32_t data;
pci_cfg_r32(dev, PCI_COMMAND, &data);
data &= ~mask;
data |= val;
pci_cfg_w32(dev, PCI_COMMAND, data);
}
/* Register a driver for handling access to PCI */
int pci_access_drv_register(struct pci_access_drv *drv)
{
if (pci_access_ops.cfg.read8)
return -1; /* Already registered a driver.. */
pci_access_ops = *drv;
return 0;
}

View File

@@ -0,0 +1,73 @@
/* PCI Access Library
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <pci.h>
/* Get PCI I/O or Configuration space access function */
static int pci_ioc_func(int wr, int size, void **func, void **ops)
{
int ofs;
ofs = 0;
if (wr)
ofs += 3;
if (size == 4)
size = 3;
ofs += (size & 0x3) - 1;
if (ops[ofs] == NULL)
return -1;
if (func)
*func = ops[ofs];
return 0;
}
/* Get Registers-over-Memory Space access function */
static int pci_memreg_func(int wr, int size, void **func, int endian)
{
void **ops;
int ofs = 0;
ops = (void **)pci_access_ops.memreg;
if (!ops)
return -1;
if (size == 2)
ofs += 2;
else if (size == 4)
ofs += 6;
if (size != 1 && endian == PCI_BIG_ENDIAN)
ofs += 2;
if (wr)
ofs += 1;
if (ops[ofs] == NULL)
return -1;
if (func)
*func = ops[ofs];
return 0;
}
/* Get function pointer from Host/BSP driver definitions */
int pci_access_func(int wr, int size, void **func, int endian, int type)
{
switch (type) {
default:
case 2: /* Memory Space - not implemented */
return -1;
case 1: /* I/O space */
return pci_ioc_func(wr, size, func, (void**)&pci_access_ops.cfg);
case 3: /* Registers over Memory space */
return pci_memreg_func(wr, size, func, endian);
case 4: /* Configuration space */
return pci_ioc_func(wr, size, func, (void**)&pci_access_ops.io);
}
}

View File

@@ -0,0 +1,48 @@
/* PCI Access Library
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <pci.h>
#include <pci/access.h>
/* Read a 8-bit register over PCI I/O Space */
uint8_t pci_io_r8(uint32_t adr)
{
return pci_access_ops.io.read8((uint8_t *)adr);
}
/* Read a 16-bit I/O Register */
uint16_t pci_io_r16(uint32_t adr)
{
return pci_access_ops.io.read16((uint16_t *)adr);
}
/* Read a 32-bit I/O Register */
uint32_t pci_io_r32(uint32_t adr)
{
return pci_access_ops.io.read32((uint32_t *)adr);
}
/* Write a 8-bit I/O Register */
void pci_io_w8(uint32_t adr, uint8_t data)
{
pci_access_ops.io.write8((uint8_t *)adr, data);
}
/* Write a 16-bit I/O Register */
void pci_io_w16(uint32_t adr, uint16_t data)
{
pci_access_ops.io.write16((uint16_t *)adr, data);
}
/* Write a 32-bit I/O Register */
void pci_io_w32(uint32_t adr, uint32_t data)
{
pci_access_ops.io.write32((uint32_t *)adr, data);
}

View File

@@ -0,0 +1,22 @@
/* PCI Access Library
* Registers-over-Memory Space - Generic Big/Little endian PCI bus definitions
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <pci.h>
uint8_t pci_mem_ld8(uint8_t *adr)
{
return *adr;
}
void pci_mem_st8(uint8_t *adr, uint8_t data)
{
*adr = data;
}

View File

@@ -0,0 +1,67 @@
/* PCI Access Library
* Registers-over-Memory Space - Generic Big endian PCI bus definitions
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <pci.h>
uint16_t pci_mem_be_ld_le16(uint16_t *adr)
{
return ld_be16(adr);
}
uint16_t pci_mem_be_ld_be16(uint16_t *adr)
{
return ld_le16(adr);
}
uint32_t pci_mem_be_ld_le32(uint32_t *adr)
{
return ld_be32(adr);
}
uint32_t pci_mem_be_ld_be32(uint32_t *adr)
{
return ld_le32(adr);
}
void pci_mem_be_st_le16(uint16_t *adr, uint16_t data)
{
st_be16(adr, data);
}
void pci_mem_be_st_be16(uint16_t *adr, uint16_t data)
{
st_le16(adr, data);
}
void pci_mem_be_st_le32(uint32_t *adr, uint32_t data)
{
st_be32(adr, data);
}
void pci_mem_be_st_be32(uint32_t *adr, uint32_t data)
{
st_le32(adr, data);
}
struct pci_memreg_ops pci_mem_be_ops = {
.ld8 = pci_mem_ld8,
.st8 = pci_mem_st8,
.ld_le16 = pci_mem_be_ld_le16,
.st_le16 = pci_mem_be_st_le16,
.ld_be16 = pci_mem_be_ld_be16,
.st_be16 = pci_mem_be_st_be16,
.ld_le32 = pci_mem_be_ld_le32,
.st_le32 = pci_mem_be_st_le32,
.ld_be32 = pci_mem_be_ld_be32,
.st_be32 = pci_mem_be_st_be32,
};

View File

@@ -0,0 +1,66 @@
/* PCI Access Library
* Registers-over-Memory Space - Generic Little endian PCI bus definitions
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <pci.h>
uint16_t pci_mem_le_ld_le16(uint16_t *adr)
{
return ld_le16(adr);
}
uint16_t pci_mem_le_ld_be16(uint16_t *adr)
{
return ld_be16(adr);
}
uint32_t pci_mem_le_ld_le32(uint32_t *adr)
{
return ld_le32(adr);
}
uint32_t pci_mem_le_ld_be32(uint32_t *adr)
{
return ld_be32(adr);
}
void pci_mem_le_st_le16(uint16_t *adr, uint16_t data)
{
st_le16(adr, data);
}
void pci_mem_le_st_be16(uint16_t *adr, uint16_t data)
{
st_be16(adr, data);
}
void pci_mem_le_st_le32(uint32_t *adr, uint32_t data)
{
st_le32(adr, data);
}
void pci_mem_le_st_be32(uint32_t *adr, uint32_t data)
{
st_be32(adr, data);
}
struct pci_memreg_ops pci_mem_le_ops = {
.ld8 = pci_mem_ld8,
.st8 = pci_mem_st8,
.ld_le16 = pci_mem_le_ld_le16,
.st_le16 = pci_mem_le_st_le16,
.ld_be16 = pci_mem_le_ld_be16,
.st_be16 = pci_mem_le_st_be16,
.ld_le32 = pci_mem_le_ld_le32,
.st_le32 = pci_mem_le_st_le32,
.ld_be32 = pci_mem_le_ld_be32,
.st_be32 = pci_mem_le_st_be32,
};

55
cpukit/libpci/pci_cfg.c Normal file
View File

@@ -0,0 +1,55 @@
/* PCI Configuration Library
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <pci/cfg.h>
/* Number of buses. This is set from respective library */
int pci_bus_cnt = 0;
/* PCI Address assigned to BARs which failed to fit into the PCI Window or
* is disabled by any other cause.
*/
uint32_t pci_invalid_address = 0;
/* PCI System type. Configuration Library setup this */
int pci_system_type = PCI_SYSTEM_NONE;
/* PCI Endianness.
*
* Host driver or BSP must override this be writing here if bus is defined
* as non-standard big-endian.
*/
int pci_endian = PCI_LITTLE_ENDIAN;
/* Configure PCI devices and bridges, and setup the RAM data structures
* describing the PCI devices currently present in the system
*/
int pci_config_init(void)
{
if (pci_config_lib_init)
return pci_config_lib_init();
else
return 0;
}
void pci_config_register(void *config)
{
if (pci_config_lib_register)
pci_config_lib_register(config);
}
/* Return the number of PCI busses available in the system, note that
* there are always one bus (bus0) after the PCI library has been
* initialized and a driver has been registered.
*/
int pci_bus_count(void)
{
return pci_bus_cnt;
}

1014
cpukit/libpci/pci_cfg_auto.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
/* PCI (Peripheral) Configuration Library
*
* COPYRIGHT (c) 2011.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
/*
*
* The Host Bridge bus must be declared by user. It contain the static
* configuration used to setup the devices/functions.
*/
/* Configure headers */
#define PCI_CFG_PERIPHERAL_LIB
#include <pci/cfg.h>
/* Number of buses */
extern int pci_bus_cnt;
/* Assume that user has defined static setup array in pci_hb */
int pci_config_peripheral(void)
{
pci_bus_cnt = pci_hb.sord + 1;
pci_system_type = PCI_SYSTEM_PERIPHERAL;
return 0;
}

View File

@@ -0,0 +1,172 @@
/* PCI (Static) Configuration Library. PCI Configuration C code console
* printout routines that can be used to build a static PCI configuration.
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <rtems.h>
#include <stdio.h>
#include <pci/cfg.h>
int pci_cfg_print_bus(struct pci_bus *bus);
static void get_bus_name(struct pci_bus *bus, char *buf)
{
if (bus->num == 0)
strcpy(buf, "pci_hb");
else
sprintf(buf, "bus%d", bus->num);
}
static void get_device_name(struct pci_dev *dev, char *buf)
{
char busname[64];
if (dev->flags & PCI_DEV_BRIDGE) {
get_bus_name((struct pci_bus *)dev, busname);
sprintf(buf, "%s.dev", busname);
} else {
sprintf(buf, "dev_%x_%x_%x", PCI_DEV_EXPAND(dev->busdevfun));
}
}
static void pci_cfg_print_resources(struct pci_res *resources, char *prefix)
{
struct pci_res *res;
int i;
for (i = 0; i < DEV_RES_CNT; i++) {
res = &resources[i];
if (((res->flags & PCI_RES_TYPE_MASK) == 0) ||
((res->flags & PCI_RES_FAIL) == PCI_RES_FAIL)) {
printf("%sPCIRES_EMPTY,\n", prefix);
continue;
}
printf("%s{\n", prefix);
printf("%s\t.next = NULL,\n", prefix);
printf("%s\t.size = 0x%08lx,\n", prefix, res->size);
printf("%s\t.boundary = 0x%08lx,\n", prefix, res->boundary);
printf("%s\t.flags = 0x%x,\n", prefix, res->flags);
printf("%s\t.bar = %d,\n", prefix, i);
printf("%s\t.start = 0x%08lx,\n", prefix, res->start);
printf("%s\t.end = 0x%08lx,\n", prefix, res->end);
printf("%s},\n", prefix);
}
}
static void pci_cfg_print_device(struct pci_dev *dev, char *prefix)
{
char name[32];
char buf[8];
printf("%s.resources = {\n", prefix);
strcpy(buf, prefix);
strcat(buf, "\t");
pci_cfg_print_resources(dev->resources, buf);
printf("%s},\n", prefix);
if (dev->next == NULL) {
printf("%s.next = NULL,\n", prefix);
} else {
get_device_name(dev->next, name);
printf("%s.next = &%s,\n", prefix, name);
}
if (!dev->bus) { /* Host Bridge? */
printf("%s.bus = NULL,\n", prefix);
} else {
get_bus_name(dev->bus, name);
printf("%s.bus = &%s,\n", prefix, name);
}
printf("%s.busdevfun = 0x%04x,\n", prefix, dev->busdevfun);
printf("%s.flags = 0x%x,\n", prefix, dev->flags);
printf("%s.sysirq = %d,\n", prefix, dev->sysirq);
printf("%s.vendor = 0x%04x,\n", prefix, dev->vendor);
printf("%s.device = 0x%04x,\n", prefix, dev->device);
printf("%s.subvendor = 0x%04x,\n", prefix, dev->subvendor);
printf("%s.subdevice = 0x%04x,\n", prefix, dev->subdevice);
printf("%s.classrev = 0x%08lx,\n", prefix, dev->classrev);
printf("%s.command = 0,\n", prefix);
}
static int pci_cfg_print_dev(struct pci_dev *dev, void *unused)
{
if (dev->flags & PCI_DEV_BRIDGE) {
pci_cfg_print_bus((struct pci_bus *)dev);
} else {
printf("\n\n/* PCI DEV at [%x:%x:%x] */\n",
PCI_DEV_EXPAND(dev->busdevfun));
printf("static struct pci_dev dev_%x_%x_%x = {\n",
PCI_DEV_EXPAND(dev->busdevfun));
pci_cfg_print_device(dev, "\t");
printf("};\n");
}
return 0;
}
int pci_cfg_print_bus(struct pci_bus *bus)
{
char name[32];
/* Print Bus */
printf("\n\n/* PCI BUS %d - Bridge at [%x:%x:%x] */\n\n",
bus->num, PCI_DEV_EXPAND(bus->dev.busdevfun));
get_bus_name(bus, name);
printf("%sstruct pci_bus %s = {\n",
bus->num == 0 ? "" : "static ", name);
printf("\t.dev = {\n");
pci_cfg_print_device(&bus->dev, "\t\t");
printf("\t},\n");
if (bus->devs == NULL) {
printf("\t.devs = NULL,\n");
} else {
get_device_name(bus->devs, name);
printf("\t.devs = &%s,\n", name);
}
printf("\t.flags = 0x%x,\n", bus->flags);
printf("\t.num = %d,\n", bus->num);
printf("\t.pri = %d,\n", bus->pri);
printf("\t.sord = %d,\n", bus->sord);
printf("};\n");
/* Print all child devices */
pci_for_each_child(bus, pci_cfg_print_dev, NULL, 0);
return 0;
}
static int pci_cfg_print_forw_dev(struct pci_dev *dev, void *unused)
{
if ((dev->flags & PCI_DEV_BRIDGE) == 0) {
printf("static struct pci_dev dev_%x_%x_%x;\n",
PCI_DEV_EXPAND(dev->busdevfun));
}
return 0;
}
void pci_cfg_print(void)
{
int i;
printf("\n\n/*** PCI Configuration ***/\n\n");
printf("#include <stdlib.h>\n");
printf("#define PCI_CFG_STATIC_LIB\n");
printf("#include <pci/cfg.h>\n\n");
printf("#define PCIRES_EMPTY {0}\n\n");
/* Forward declaration for all devices / buses */
printf("/* FORWARD BUS DECLARATIONS */\n");
for (i = 0; i < pci_bus_count(); i++) {
if (i == 0)
printf("struct pci_bus pci_hb;\n");
else
printf("static struct pci_bus bus%d;\n", i);
}
printf("\n/* FORWARD DEVICE DECLARATIONS */\n");
pci_for_each_dev(pci_cfg_print_forw_dev, NULL);
pci_cfg_print_bus(&pci_hb);
}

View File

@@ -0,0 +1,357 @@
/* Read current PCI configuration that bootloader or BIOS has already setup
* and initialize the PCI structures.
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <rtems.h>
#include <stdlib.h>
#include <rtems/bspIo.h>
#include <pci/cfg.h>
#include <pci/access.h>
/* PCI Library
* (For debugging it might be good to use other functions or the driver's
* directly)
*/
#define PCI_CFG_R8(dev, args...) pci_cfg_r8(dev, args)
#define PCI_CFG_R16(dev, args...) pci_cfg_r16(dev, args)
#define PCI_CFG_R32(dev, args...) pci_cfg_r32(dev, args)
#define PCI_CFG_W8(dev, args...) pci_cfg_w8(dev, args)
#define PCI_CFG_W16(dev, args...) pci_cfg_w16(dev, args)
#define PCI_CFG_W32(dev, args...) pci_cfg_w32(dev, args)
#ifdef DEBUG
#define DBG(args...) printk(args)
#else
#define DBG(args...)
#endif
/* Number of buses */
extern int pci_bus_cnt;
/* The Host Bridge bus is initialized here */
extern struct pci_bus pci_hb;
static struct pci_dev *pci_dev_create(int isbus)
{
void *ptr;
int size;
if (isbus)
size = sizeof(struct pci_bus);
else
size = sizeof(struct pci_dev);
ptr = malloc(size);
if (!ptr)
rtems_fatal_error_occurred(RTEMS_NO_MEMORY);
memset(ptr, 0, size);
return ptr;
}
/* Check if address is accessible from host */
static int pci_read_addressable(struct pci_dev *dev, struct pci_res *res)
{
struct pci_bus *bus = dev->bus;
int type = res->flags & PCI_RES_TYPE_MASK;
struct pci_res *range0, *range1;
if (type == PCI_BUS_IO && (bus->flags & PCI_BUS_IO) == 0)
return 0;
/* Assume that host bridge can access all */
if (bus->pri == 0)
return 1;
range1 = NULL;
switch (type) {
case PCI_RES_IO:
range0 = &bus->dev.resources[BRIDGE_RES_IO];
break;
case PCI_RES_MEM:
range1 = &bus->dev.resources[BRIDGE_RES_MEM];
default:
case PCI_RES_MEMIO:
range0 = &bus->dev.resources[BRIDGE_RES_MEMIO];
break;
}
if ((res->start >= range0->start) && (res->end <= range0->end)) {
return pci_read_addressable(&bus->dev, range0);
} else if (range1 && (res->start >= range1->start) &&
(res->end <= range1->end)) {
return pci_read_addressable(&bus->dev, range1);
}
return 0;
}
static void pci_read_bar(struct pci_dev *dev, int bar)
{
uint32_t orig, size, mask;
struct pci_res *res = &dev->resources[bar];
pci_dev_t pcidev = dev->busdevfun;
int ofs;
#ifdef DEBUG
char *str;
#define DBG_SET_STR(str, val) str = (val)
#else
#define DBG_SET_STR(str, val)
#endif
DBG("Bus: %x, Slot: %x, function: %x, bar%d\n",
PCI_DEV_EXPAND(pcidev), bar);
res->bar = bar;
if (bar == DEV_RES_ROM) {
if (dev->flags & PCI_DEV_BRIDGE)
ofs = PCI_ROM_ADDRESS1;
else
ofs = PCI_ROM_ADDRESS;
} else {
ofs = PCI_BASE_ADDRESS_0 + (bar << 2);
}
PCI_CFG_R32(pcidev, ofs, &orig);
PCI_CFG_W32(pcidev, ofs, 0xffffffff);
PCI_CFG_R32(pcidev, ofs, &size);
PCI_CFG_W32(pcidev, ofs, orig);
if (size == 0 || size == 0xffffffff)
return;
if (bar == DEV_RES_ROM) {
mask = PCI_ROM_ADDRESS_MASK;
DBG_SET_STR(str, "ROM");
if (dev->bus->flags & PCI_BUS_MEM)
res->flags = PCI_RES_MEM;
else
res->flags = PCI_RES_MEMIO;
} else if (((size & 0x1) == 0) && (size & 0x6)) {
/* unsupported Memory type */
return;
} else {
mask = ~0xf;
if (size & 0x1) {
/* I/O */
mask = ~0x3;
res->flags = PCI_RES_IO;
DBG_SET_STR(str, "I/O");
if (size & 0xffff0000)
res->flags |= PCI_RES_IO32;
/* Limit size of I/O space to 256 byte */
size |= 0xffffff00;
if ((dev->bus->flags & PCI_BUS_IO) == 0) {
res->flags |= PCI_RES_FAIL;
dev->flags |= PCI_DEV_RES_FAIL;
}
} else {
/* Memory */
if (size & 0x8) {
/* Prefetchable */
res->flags = PCI_RES_MEM;
DBG_SET_STR(str, "MEM");
} else {
res->flags = PCI_RES_MEMIO;
DBG_SET_STR(str, "MEMIO");
}
}
}
res->start = orig & mask;
size &= mask;
res->size = ~size + 1;
res->boundary = res->size;
res->end = res->start + res->size;
DBG("Bus: %x, Slot: %x, function: %x, %s bar%d size: %x\n",
PCI_DEV_EXPAND(pcidev), str, bar, res->size);
/* Check if BAR is addressable by host */
if (pci_read_addressable(dev, res) == 0) {
/* No matching bridge window contains this BAR */
res->flags |= PCI_RES_FAIL;
dev->flags |= PCI_DEV_RES_FAIL;
}
}
static void pci_read_devs(struct pci_bus *bus)
{
uint32_t id, tmp;
uint16_t tmp16;
uint8_t header;
int slot, func, fail, i, maxbars, max_sord;
struct pci_dev *dev, **listptr;
struct pci_bus *bridge;
pci_dev_t pcidev;
struct pci_res *res;
DBG("Scanning bus %d\n", bus->num);
max_sord = bus->num;
listptr = &bus->devs;
for (slot = 0; slot < PCI_MAX_DEVICES; slot++) {
/* Slot address */
pcidev = PCI_DEV(bus->num, slot, 0);
for (func = 0; func < PCI_MAX_FUNCTIONS; func++, pcidev++) {
fail = PCI_CFG_R32(pcidev, PCI_VENDOR_ID, &id);
if (fail || id == 0xffffffff || id == 0) {
/*
* This slot is empty
*/
if (func == 0)
break;
else
continue;
}
DBG("Found PCIDEV 0x%x at (bus %x, slot %x, func %x)\n",
id, bus, slot, func);
PCI_CFG_R32(pcidev, PCI_CLASS_REVISION, &tmp);
tmp >>= 16;
dev = pci_dev_create(tmp == PCI_CLASS_BRIDGE_PCI);
*listptr = dev;
listptr = &dev->next;
dev->busdevfun = pcidev;
dev->bus = bus;
PCI_CFG_R16(pcidev, PCI_VENDOR_ID, &dev->vendor);
PCI_CFG_R16(pcidev, PCI_DEVICE_ID, &dev->device);
PCI_CFG_R32(pcidev, PCI_CLASS_REVISION, &dev->classrev);
if (tmp == PCI_CLASS_BRIDGE_PCI) {
DBG("Found PCI-PCI Bridge 0x%x at "
"(bus %x, slot %x, func %x)\n",
id, bus, slot, func);
dev->flags = PCI_DEV_BRIDGE;
bridge = (struct pci_bus *)dev;
PCI_CFG_R32(pcidev, PCI_PRIMARY_BUS, &tmp);
bridge->pri = tmp & 0xff;
bridge->num = (tmp >> 8) & 0xff;
bridge->sord = (tmp >> 16) & 0xff;
if (bridge->sord > max_sord)
max_sord = bridge->sord;
DBG(" Primary %x, Secondary %x, "
"Subordinate %x\n",
bridge->pri, bridge->num, bridge->sord);
/*** Probe Bridge Spaces ***/
/* MEMIO Window - always implemented */
bridge->flags = PCI_BUS_MEMIO;
res = &bridge->dev.resources[BRIDGE_RES_MEMIO];
res->flags = PCI_RES_MEMIO;
res->bar = BRIDGE_RES_MEMIO;
PCI_CFG_R32(pcidev, 0x20, &tmp);
res->start = (tmp & 0xfff0) << 16;
res->end = 1 + ((tmp & 0xfff00000) | 0xfffff);
if (res->end <= res->start) {
/* Window disabled */
res->end = res->start = 0;
}
res->size = res->end - res->start;
/* I/O Window - optional */
res = &bridge->dev.resources[BRIDGE_RES_IO];
res->bar = BRIDGE_RES_IO;
PCI_CFG_R32(pcidev, 0x30, &tmp);
PCI_CFG_R16(pcidev, 0x1c, &tmp16);
if (tmp != 0 || tmp16 != 0) {
bridge->flags |= PCI_BUS_IO;
res->flags = PCI_RES_IO;
if (tmp16 & 0x1) {
bridge->flags |= PCI_BUS_IO32;
res->flags |= PCI_RES_IO32;
}
res->start = (tmp & 0xffff) << 16 |
(tmp16 & 0xf0) << 8;
res->end = 1 + ((tmp & 0xffff0000) |
(tmp16 & 0xf000) |
0xfff);
if (res->end <= res->start) {
/* Window disabled */
res->end = res->start = 0;
}
res->size = res->end - res->start;
}
/* MEM Window - optional */
res = &bridge->dev.resources[BRIDGE_RES_MEM];
res->bar = BRIDGE_RES_MEM;
PCI_CFG_R32(pcidev, 0x24, &tmp);
if (tmp != 0) {
bridge->flags |= PCI_BUS_MEM;
res->flags = PCI_RES_MEM;
res->start = (tmp & 0xfff0) << 16;
res->end = 1 + ((tmp & 0xfff00000) |
0xfffff);
if (res->end <= res->start) {
/* Window disabled */
res->end = res->start = 0;
}
res->size = res->end - res->start;
}
/* Scan Secondary Bus */
pci_read_devs(bridge);
/* Only 2 BARs for Bridges */
maxbars = 2;
} else {
/* Devices have subsytem device and vendor ID */
PCI_CFG_R16(pcidev, PCI_SUBSYSTEM_VENDOR_ID,
&dev->subvendor);
PCI_CFG_R16(pcidev, PCI_SUBSYSTEM_ID,
&dev->subdevice);
/* Normal PCI Device has max 6 BARs */
maxbars = 6;
}
/* Probe BARs */
for (i = 0; i < maxbars; i++)
pci_read_bar(dev, i);
pci_read_bar(dev, DEV_RES_ROM);
/* Get System Interrupt/Vector for device.
* 0 means no-IRQ
*/
PCI_CFG_R8(pcidev, PCI_INTERRUPT_LINE, &dev->sysirq);
/* Stop if not a multi-function device */
if (func == 0) {
pci_cfg_r8(pcidev, PCI_HEADER_TYPE, &header);
if ((header & PCI_MULTI_FUNCTION) == 0)
break;
}
}
}
if (bus->num == 0)
bus->sord = max_sord;
}
int pci_config_read(void)
{
pci_system_type = PCI_SYSTEM_HOST;
/* Find all devices and buses */
pci_hb.flags = PCI_BUS_IO|PCI_BUS_MEMIO|PCI_BUS_MEM;
pci_hb.dev.flags = PCI_DEV_BRIDGE;
pci_read_devs(&pci_hb);
pci_bus_cnt = pci_hb.sord + 1;
if (pci_hb.devs == NULL)
return 0;
return 0;
}

View File

@@ -0,0 +1,157 @@
/* PCI (Static) Configuration Library
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
/*
* The Host Bridge bus must be declared by user. It contains the static
* configuration used to setup the devices/functions.
*/
/* Configure headers */
#define PCI_CFG_STATIC_LIB
#include <stdlib.h>
#include <pci.h>
#include <pci/access.h>
#include <pci/cfg.h>
#define PCI_CFG_R8(dev, args...) pci_cfg_r8(dev, args)
#define PCI_CFG_R16(dev, args...) pci_cfg_r16(dev, args)
#define PCI_CFG_R32(dev, args...) pci_cfg_r32(dev, args)
#define PCI_CFG_W8(dev, args...) pci_cfg_w8(dev, args)
#define PCI_CFG_W16(dev, args...) pci_cfg_w16(dev, args)
#define PCI_CFG_W32(dev, args...) pci_cfg_w32(dev, args)
/* Number of buses */
extern int pci_bus_cnt;
/* Enumrate one bus if device is a bridge, and all it's subordinate buses */
static int pci_init_dev(struct pci_dev *dev, void *unused)
{
uint32_t tmp;
uint16_t tmp16, cmd;
struct pci_bus *bridge;
int maxbars, i, romofs;
pci_dev_t pcidev = dev->busdevfun;
struct pci_res *res;
/* Init Device */
/* Set command to reset values, it disables bus
* mastering and address responses.
*/
PCI_CFG_W16(pcidev, PCI_COMMAND, 0);
/* Clear any already set status bits */
PCI_CFG_W16(pcidev, PCI_STATUS, 0xf900);
/* Set latency timer to 64 */
PCI_CFG_W8(pcidev, PCI_LATENCY_TIMER, 64);
/* Set System IRQ of PIN */
PCI_CFG_W8(pcidev, PCI_INTERRUPT_LINE, dev->sysirq);
cmd = dev->command;
if ((dev->flags & PCI_DEV_BRIDGE) == 0) {
/* Disable Cardbus CIS Pointer */
PCI_CFG_W32(pcidev, PCI_CARDBUS_CIS, 0);
romofs = PCI_ROM_ADDRESS;
maxbars = 6;
} else {
/* Init Bridge */
/* Configure bridge (no support for 64-bit) */
PCI_CFG_W32(pcidev, PCI_PREF_BASE_UPPER32, 0);
PCI_CFG_W32(pcidev, PCI_PREF_LIMIT_UPPER32, 0);
bridge = (struct pci_bus *)dev;
tmp = (64 << 24) | (bridge->sord << 16) |
(bridge->num << 8) | bridge->pri;
PCI_CFG_W32(pcidev, PCI_PRIMARY_BUS, tmp);
/*** Setup I/O Bridge Window ***/
res = &dev->resources[BRIDGE_RES_IO];
if (res->size > 0) {
tmp16 = ((res->end-1) & 0x0000f000) |
((res->start & 0x0000f000) >> 8);
tmp = ((res->end-1) & 0xffff0000) | (res->start >> 16);
cmd |= PCI_COMMAND_IO;
} else {
tmp16 = 0x00ff;
tmp = 0;
}
/* I/O Limit and Base */
PCI_CFG_W16(pcidev, PCI_IO_BASE, tmp16);
PCI_CFG_W32(pcidev, PCI_IO_BASE_UPPER16, tmp);
/*** Setup MEMIO Bridge Window ***/
res = &dev->resources[BRIDGE_RES_MEMIO];
if (res->size > 0) {
tmp = ((res->end-1) & 0xffff0000) |
(res->start >> 16);
cmd |= PCI_COMMAND_MEMORY;
} else {
tmp = 0x0000ffff;
}
/* MEMIO Limit and Base */
PCI_CFG_W32(pcidev, PCI_MEMORY_BASE, tmp);
/*** Setup MEM Bridge Window ***/
res = &dev->resources[BRIDGE_RES_MEM];
if (res->size > 0) {
tmp = ((res->end-1) & 0xffff0000) |
(res->start >> 16);
cmd |= PCI_COMMAND_MEMORY;
} else {
tmp = 0x0000ffff;
}
/* MEM Limit and Base */
PCI_CFG_W32(pcidev, PCI_PREF_MEMORY_BASE, tmp);
/* 64-bit space not supported */
PCI_CFG_W32(pcidev, PCI_PREF_BASE_UPPER32, 0);
PCI_CFG_W32(pcidev, PCI_PREF_LIMIT_UPPER32, 0);
cmd |= PCI_COMMAND_MASTER;
romofs = PCI_ROM_ADDRESS1;
maxbars = 2;
}
/* Init BARs */
for (i = 0; i < maxbars; i++) {
res = &dev->resources[i];
if (res->flags & PCI_RES_TYPE_MASK) {
PCI_CFG_W32(pcidev, PCI_BASE_ADDRESS_0 + 4*i,
res->start);
if ((res->flags & PCI_RES_TYPE_MASK) == PCI_RES_IO)
cmd |= PCI_COMMAND_IO;
else
cmd |= PCI_COMMAND_MEMORY;
}
}
res = &dev->resources[DEV_RES_ROM];
if (res->flags & PCI_RES_TYPE_MASK) {
PCI_CFG_W32(pcidev, romofs, res->start|PCI_ROM_ADDRESS_ENABLE);
cmd |= PCI_COMMAND_MEMORY;
}
PCI_CFG_W16(pcidev, PCI_COMMAND, cmd);
return 0;
}
/* Assume that user has defined static setup array in pci_hb */
int pci_config_static(void)
{
pci_bus_cnt = pci_hb.sord + 1;
pci_system_type = PCI_SYSTEM_HOST;
/* Init all PCI devices according to depth-first search algorithm */
return pci_for_each_dev(pci_init_dev, NULL);
}

52
cpukit/libpci/pci_find.c Normal file
View File

@@ -0,0 +1,52 @@
/* PCI Help function, Find a PCI device by VENDOR/DEVICE ID
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <pci.h>
#include <pci/access.h>
struct compare_info {
int index;
uint16_t vendor;
uint16_t device;
};
static int compare_dev_id(pci_dev_t pcidev, void *arg)
{
struct compare_info *info = arg;
uint16_t vid, did;
pci_cfg_r16(pcidev, PCI_VENDOR_ID, &vid);
pci_cfg_r16(pcidev, PCI_DEVICE_ID, &did);
if ((vid != info->vendor) || (did != info->device))
return 0;
if (info->index-- == 0)
return pcidev;
else
return 0;
}
/* Find a Device in PCI configuration space */
int pci_find(uint16_t ven, uint16_t dev, int index, pci_dev_t *pdev)
{
struct compare_info info;
int result;
info.index = index;
info.vendor = ven;
info.device = dev;
result = pci_for_each(compare_dev_id, &info);
if (pdev)
*pdev = (pci_dev_t)result;
if (result == 0)
return -1;
else
return 0;
}

View File

@@ -0,0 +1,49 @@
/* PCI Help function, Find a PCI device by VENDOR/DEVICE ID
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <pci.h>
#include <pci/cfg.h>
struct compare_info {
int index;
uint16_t vendor;
uint16_t device;
};
static int compare_dev_id(struct pci_dev *dev, void *arg)
{
struct compare_info *info = arg;
if ((dev->vendor != info->vendor) || (dev->device != info->device))
return 0;
if (info->index-- == 0)
return (int)dev;
else
return 0;
}
/* Find a Device in PCI device tree located in RAM */
int pci_find_dev(uint16_t ven, uint16_t dev, int index, struct pci_dev **ppdev)
{
struct compare_info info;
int result;
info.index = index;
info.vendor = ven;
info.device = dev;
result = pci_for_each_dev(compare_dev_id, &info);
if (ppdev)
*ppdev = (struct pci_dev *)result;
if (result == 0)
return -1;
else
return 0;
}

View File

@@ -0,0 +1,62 @@
/* PCI Help Function, iterate over all PCI devices. Find devices by cfg access.
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <pci.h>
#include <pci/access.h>
/*#define DEBUG*/
#ifdef DEBUG
#include <rtems/bspIo.h>
#define DBG(args...) printk(args)
#else
#define DBG(args...)
#endif
int pci_for_each(int (*func)(pci_dev_t, void*), void *arg)
{
uint32_t id;
uint8_t hd;
int bus, dev, fun, result, fail;
int maxbus = pci_bus_count();
pci_dev_t pcidev;
for (bus = 0; bus < maxbus ; bus++) {
for (dev = 0; dev < PCI_MAX_DEVICES; dev++) {
pcidev = PCI_DEV(bus, dev, 0);
for (fun = 0; fun < PCI_MAX_FUNCTIONS; fun++, pcidev++) {
fail = pci_cfg_r32(pcidev, PCI_VENDOR_ID, &id);
if (fail || (0xffffffff == id) || (0 == id)) {
if (fun == 0)
break;
else
continue;
}
DBG("pcibus_for_each: found 0x%08lx at"
" %d/%d/%d\n", id, bus, dev, fun);
result = func(pcidev, arg);
if (result != 0)
return result; /* Stopped */
/* Stop if not a multi-function device */
if (fun == 0) {
pci_cfg_r8(pcidev, PCI_HEADER_TYPE,
&hd);
if ((hd & PCI_MULTI_FUNCTION) == 0)
break;
}
}
}
}
return 0; /* scanned all */
}

View File

@@ -0,0 +1,41 @@
/* PCI Help function, iterate all PCI device children of PCI bus.
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <pci/cfg.h>
/* Iterate over all PCI devices on a bus (not child buses) and call func(),
* iteration is stopped if a non-zero value is returned by func().
*
* search options: 0 (no child buses), 1 (depth first), 2 (breadth first)
*/
int pci_for_each_child(
struct pci_bus *bus,
int (*func)(struct pci_dev *, void *arg),
void *arg,
int search)
{
struct pci_dev *dev = bus->devs;
int ret;
while (dev) {
ret = func(dev, arg);
if (ret)
return ret;
if (search == SEARCH_DEPTH && (dev->flags & PCI_DEV_BRIDGE)) {
ret = pci_for_each_child((struct pci_bus *)dev,
func, arg, search);
if (ret)
return ret;
}
dev = dev->next;
}
return 0;
}

View File

@@ -0,0 +1,18 @@
/* PCI Help function, iterate all PCI devices.
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <pci/cfg.h>
int pci_for_each_dev(
int (*func)(struct pci_dev *, void *arg),
void *arg)
{
return pci_for_each_child(&pci_hb, func, arg, SEARCH_DEPTH);
}

View File

@@ -0,0 +1,36 @@
/* PCI Help function, Find a PCI device by BUS|SLOT|FUNCTION
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <pci.h>
#include <pci/cfg.h>
static int compare_dev_pcidev(struct pci_dev *dev, void *arg)
{
pci_dev_t pcidev = (unsigned)arg;
if (dev->busdevfun == pcidev)
return (int)dev;
else
return 0;
}
/* Get a Device in PCI device tree located in RAM by PCI BUS|SLOT|FUNCTION */
int pci_get_dev(pci_dev_t pcidev, struct pci_dev **ppdev)
{
int result;
result = pci_for_each_dev(compare_dev_pcidev, (void *)(unsigned)pcidev);
if (ppdev)
*ppdev = (struct pci_dev *)result;
if (result == 0)
return -1;
else
return 0;
}

20
cpukit/libpci/pci_irq.c Normal file
View File

@@ -0,0 +1,20 @@
/* PCI IRQ Library
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <pci.h>
#include <pci/access.h>
#include <pci/irq.h>
int pci_dev_irq(pci_dev_t dev)
{
uint8_t irq_line;
pci_cfg_r8(dev, PCI_INTERRUPT_LINE, &irq_line);
return irq_line;
}

190
cpukit/libpci/pci_print.c Normal file
View File

@@ -0,0 +1,190 @@
/* PCI Print Current Configuration To Terminal
*
* COPYRIGHT (c) 2010.
* Cobham Gaisler AB.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <stdio.h>
#include <pci.h>
#include <pci/access.h>
/* PCI Access Library shortcuts */
#define PCI_CFG_R8(dev, args...) pci_cfg_r8(dev, args)
#define PCI_CFG_R16(dev, args...) pci_cfg_r16(dev, args)
#define PCI_CFG_R32(dev, args...) pci_cfg_r32(dev, args)
#define PCI_CFG_W8(dev, args...) pci_cfg_w8(dev, args)
#define PCI_CFG_W16(dev, args...) pci_cfg_w16(dev, args)
#define PCI_CFG_W32(dev, args...) pci_cfg_w32(dev, args)
void pci_print_dev(pci_dev_t dev)
{
int maxbars, pos, romadrs;
uint32_t tmp, tmp2, id;
uint16_t irq;
uint8_t irq_pin;
char *str, *str2;
uint32_t base, limit;
maxbars = 6;
romadrs = 0x30;
str = "";
PCI_CFG_R32(dev, PCI_CLASS_REVISION, &tmp);
tmp >>= 16;
if (tmp == PCI_CLASS_BRIDGE_PCI) {
maxbars = 2;
romadrs = 0x38;
str = "(BRIDGE)";
}
PCI_CFG_R32(dev, PCI_VENDOR_ID, &id);
printf("\nBus %x Slot %x function: %x [0x%x] %s\n",
PCI_DEV_EXPAND(dev), dev, str);
printf("\tVendor id: 0x%lx, device id: 0x%lx\n",
id & 0xffff, id >> 16);
if (maxbars == 2) {
PCI_CFG_R32(dev, PCI_PRIMARY_BUS, &tmp);
printf("\tPrimary: %lx Secondary: %lx Subordinate: %lx\n",
tmp & 0xff, (tmp >> 8) & 0xff, (tmp >> 16) & 0xff);
}
PCI_CFG_R16(dev, PCI_INTERRUPT_LINE, &irq);
irq_pin = irq >> 8;
if ((irq_pin > 0) && (irq_pin < 5))
printf("\tIRQ INT%c# LINE: %d\n",
(irq_pin - 1) + 'A', (irq & 0xff));
/* Print standard BARs */
for (pos = 0; pos < maxbars; pos++) {
PCI_CFG_R32(dev, PCI_BASE_ADDRESS_0 + pos*4, &tmp);
PCI_CFG_W32(dev, PCI_BASE_ADDRESS_0 + pos*4, 0xffffffff);
PCI_CFG_R32(dev, PCI_BASE_ADDRESS_0 + pos*4, &tmp2);
PCI_CFG_W32(dev, PCI_BASE_ADDRESS_0 + pos*4, tmp);
if (tmp2 != 0 && tmp2 != 0xffffffff && ((tmp2 & 0x1) ||
((tmp2 & 0x6) == 0))) {
uint32_t mask = ~0xf;
if ((tmp2 & 0x1) == 1) {
/* I/O Bar */
mask = ~3;
tmp2 = tmp2 | 0xffffff00;
}
tmp2 &= mask;
tmp2 = ~tmp2+1; /* Size of BAR */
if (tmp2 < 0x1000) {
str = "B";
} else if (tmp2 < 0x100000) {
str = "kB";
tmp2 = tmp2 / 1024;
} else {
str = "MB";
tmp2 = tmp2 / (1024*1024);
}
printf("\tBAR %d: %lx [%lu%s]\n", pos, tmp, tmp2, str);
}
}
/* Print ROM BARs */
PCI_CFG_R32(dev, romadrs, &tmp);
PCI_CFG_W32(dev, romadrs, 0xffffffff);
PCI_CFG_R32(dev, romadrs, &tmp2);
PCI_CFG_W32(dev, romadrs, tmp);
if (tmp2 & 1) {
/* ROM BAR available */
tmp2 &= PCI_ROM_ADDRESS_MASK;
tmp2 = (~tmp2 + 1); /* Size of BAR */
if (tmp2 < 0x1000) {
str = "B";
} else if (tmp2 < 0x100000) {
str = "kB";
tmp2 = tmp2 / 1024;
} else {
str = "MB";
tmp2 = tmp2 / (1024*1024);
}
str2 = tmp & 1 ? "ENABLED" : "DISABLED";
printf("\tROM: %08lx [%lu%s] (%s)\n",
tmp, tmp2, str, str2);
}
/* Print Bridge addresses */
if (maxbars == 2) {
tmp = 0;
PCI_CFG_R32(dev, 0x1C, &tmp);
if (tmp != 0) {
base = (tmp & 0x00f0) << 8;
limit = (tmp & 0xf000) | 0xfff;
PCI_CFG_R32(dev, 0x30, &tmp);
base |= (tmp & 0xffff) << 16;
limit |= (tmp & 0xffff0000);
str = "ENABLED";
if (limit < base)
str = "DISABLED";
printf("\tI/O: BASE: 0x%08lx, LIMIT: 0x%08lx (%s)\n",
base, limit, str);
}
PCI_CFG_R32(dev, 0x20, &tmp);
if (tmp != 0) {
base = (tmp & 0xfff0) << 16;
limit = (tmp & 0xfff00000) | 0xfffff;
str = "ENABLED";
if (limit < base)
str = "DISABLED";
printf("\tMEMIO: BASE: 0x%08lx, LIMIT: 0x%08lx (%s)\n",
base, limit, str);
}
PCI_CFG_R32(dev, 0x24, &tmp);
if (tmp != 0) {
base = (tmp & 0xfff0) << 16;
limit = (tmp & 0xfff00000) | 0xfffff;
str = "ENABLED";
if (limit < base)
str = "DISABLED";
printf("\tMEM: BASE: 0x%08lx, LIMIT: 0x%08lx (%s)\n",
base, limit, str);
}
}
printf("\n");
}
void pci_print_device(int bus, int slot, int function)
{
pci_print_dev(PCI_DEV(bus, slot, function));
}
void pci_print(void)
{
int fail, bus, slot, func;
pci_dev_t dev;
uint8_t header;
uint32_t id;
printf("\nPCI devices found and configured:\n");
for (bus = 0; bus < pci_bus_count(); bus++) {
for (slot = 0; slot < PCI_MAX_DEVICES; slot++) {
for (func=0; func < PCI_MAX_FUNCTIONS; func++) {
dev = PCI_DEV(bus, slot, func);
fail = PCI_CFG_R32(dev, PCI_VENDOR_ID, &id);
if (!fail && id != PCI_INVALID_VENDORDEVICEID && id != 0) {
pci_print_dev(dev);
/* Stop if not a multi-function device */
if (func == 0) {
PCI_CFG_R8(dev, PCI_HEADER_TYPE, &header);
if ((header & PCI_MULTI_FUNCTION) == 0)
break;
}
} else if (func == 0)
break;
}
}
}
printf("\n");
}

View File

@@ -0,0 +1,66 @@
## Automatically generated by ampolish3 - Do not edit
if AMPOLISH3
$(srcdir)/preinstall.am: Makefile.am
$(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
endif
PREINSTALL_DIRS =
DISTCLEANFILES = $(PREINSTALL_DIRS)
all-am: $(PREINSTALL_FILES)
PREINSTALL_FILES =
CLEANFILES = $(PREINSTALL_FILES)
$(PROJECT_INCLUDE)/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)
@: > $(PROJECT_INCLUDE)/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
if LIBPCI
$(PROJECT_INCLUDE)/pci.h: pci.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/pci.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/pci.h
$(PROJECT_INCLUDE)/pci/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)/pci
@: > $(PROJECT_INCLUDE)/pci/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/pci/$(dirstamp)
$(PROJECT_INCLUDE)/pci/access.h: pci/access.h $(PROJECT_INCLUDE)/pci/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/pci/access.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/pci/access.h
$(PROJECT_INCLUDE)/pci/cfg.h: pci/cfg.h $(PROJECT_INCLUDE)/pci/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/pci/cfg.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/pci/cfg.h
$(PROJECT_INCLUDE)/pci/cfg_auto.h: pci/cfg_auto.h $(PROJECT_INCLUDE)/pci/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/pci/cfg_auto.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/pci/cfg_auto.h
$(PROJECT_INCLUDE)/pci/cfg_static.h: pci/cfg_static.h $(PROJECT_INCLUDE)/pci/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/pci/cfg_static.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/pci/cfg_static.h
$(PROJECT_INCLUDE)/pci/cfg_peripheral.h: pci/cfg_peripheral.h $(PROJECT_INCLUDE)/pci/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/pci/cfg_peripheral.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/pci/cfg_peripheral.h
$(PROJECT_INCLUDE)/pci/cfg_read.h: pci/cfg_read.h $(PROJECT_INCLUDE)/pci/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/pci/cfg_read.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/pci/cfg_read.h
$(PROJECT_INCLUDE)/pci/ids.h: pci/ids.h $(PROJECT_INCLUDE)/pci/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/pci/ids.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/pci/ids.h
$(PROJECT_INCLUDE)/pci/ids_extra.h: pci/ids_extra.h $(PROJECT_INCLUDE)/pci/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/pci/ids_extra.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/pci/ids_extra.h
$(PROJECT_INCLUDE)/pci/irq.h: pci/irq.h $(PROJECT_INCLUDE)/pci/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/pci/irq.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/pci/irq.h
endif

View File

@@ -232,10 +232,11 @@ $(PROJECT_INCLUDE)/rtems/fs.h: include/rtems/fs.h $(PROJECT_INCLUDE)/rtems/$(dir
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/fs.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/fs.h
if !LIBPCI
$(PROJECT_INCLUDE)/rtems/pci.h: include/rtems/pci.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/pci.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/pci.h
endif
$(PROJECT_INCLUDE)/rtems/concat.h: include/rtems/concat.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/concat.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/concat.h

View File

@@ -3480,6 +3480,52 @@ const rtems_libio_helper rtems_fs_init_helper =
#endif
#endif
/*
* Select PCI Configuration Library
*/
#ifdef RTEMS_PCI_CONFIG_LIB
#ifdef CONFIGURE_INIT
#define PCI_LIB_NONE 0
#define PCI_LIB_AUTO 1
#define PCI_LIB_STATIC 2
#define PCI_LIB_READ 3
#define PCI_LIB_PERIPHERAL 4
#if CONFIGURE_PCI_LIB == PCI_LIB_AUTO
#define PCI_CFG_AUTO_LIB
#include <pci/cfg.h>
struct pci_bus pci_hb;
#define PCI_LIB_INIT pci_config_auto
#define PCI_LIB_CONFIG pci_config_auto_register
#elif CONFIGURE_PCI_LIB == PCI_LIB_STATIC
#define PCI_CFG_STATIC_LIB
#include <pci/cfg.h>
#define PCI_LIB_INIT pci_config_static
#define PCI_LIB_CONFIG NULL
/* Let user define PCI configuration (struct pci_bus pci_hb) */
#elif CONFIGURE_PCI_LIB == PCI_LIB_READ
#define PCI_CFG_READ_LIB
#include <pci/cfg.h>
#define PCI_LIB_INIT pci_config_read
#define PCI_LIB_CONFIG NULL
struct pci_bus pci_hb;
#elif CONFIGURE_PCI_LIB == PCI_LIB_PERIPHERAL
#define PCI_LIB_INIT pci_config_peripheral
#define PCI_LIB_CONFIG NULL
/* Let user define PCI configuration (struct pci_bus pci_hb) */
#elif CONFIGURE_PCI_LIB == PCI_LIB_NONE
#define PCI_LIB_INIT NULL
#define PCI_LIB_CONFIG NULL
/* No PCI Configuration at all, user can use/debug access routines */
#else
#error NO PCI LIBRARY DEFINED
#endif
const int pci_config_lib_type = CONFIGURE_PCI_LIB;
int (*pci_config_lib_init)(void) = PCI_LIB_INIT;
void (*pci_config_lib_register)(void *config) = PCI_LIB_CONFIG;
#endif
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -66,6 +66,8 @@ TMP_LIBS += ../libmisc/libuuid.a
TMP_LIBS += ../libi2c/libi2c.a
TMP_LIBS += ../libpci/libpci.a
if LIBNETWORKING
TMP_LIBS += ../libnetworking/libnetworking.a
TMP_LIBS += ../libnetworking/libc.a

View File

@@ -16,6 +16,7 @@ COMMON_FILES += \
$(top_builddir)/user/event.texi $(top_builddir)/user/fatal.texi \
$(top_builddir)/user/glossary.texi $(top_builddir)/user/init.texi \
$(top_builddir)/user/intr.texi $(top_builddir)/user/io.texi \
$(top_builddir)/user/libpci.texi \
$(top_builddir)/user/mp.texi $(top_builddir)/user/msg.texi \
$(top_builddir)/user/overview.texi $(top_builddir)/user/part.texi \
$(top_builddir)/user/preface.texi $(top_builddir)/user/region.texi \

View File

@@ -108,6 +108,7 @@
* Configuring a System::
* Multiprocessing Manager::
* Symmetric Multiprocessing Services::
* PCI Library::
* Stack Bounds Checker::
* CPU Usage Statistics::
* Object Services::
@@ -153,6 +154,7 @@
@include user/conf.texi
@include user/mp.texi
@include user/smp.texi
@include user/libpci.texi
@include user/stackchk.texi
@include user/cpuuse.texi
@include user/object.texi

View File

@@ -448,6 +448,9 @@ TCP/IP stack to RTEMS.
This directory contains the port of the FreeBSD
RPC/XDR source to RTEMS.
@item $@{RTEMS_ROOT@}/cpukit/libpci/
This directory contains RTEMS PCI Library.
@item $@{RTEMS_ROOT@}/cpukit/posix/
This directory contains the RTEMS implementation
of the threading portions of the POSIX API.

View File

@@ -15,7 +15,7 @@ GENERATED_FILES = overview.texi concepts.texi datatypes.texi init.texi \
signal.texi part.texi region.texi dpmem.texi io.texi fatal.texi \
schedule.texi rtmon.texi barrier.texi bsp.texi userext.texi conf.texi \
mp.texi stackchk.texi cpuuse.texi object.texi chains.texi rbtree.texi \
timespec.texi cbs.texi dirstat.texi smp.texi
timespec.texi cbs.texi dirstat.texi smp.texi libpci.texi
COMMON_FILES += $(top_srcdir)/common/cpright.texi
@@ -165,11 +165,16 @@ mp.texi: mp.t
smp.texi: smp.t
$(BMENU2) -p "Multiprocessing Manager MULTIPROCESSING_ANNOUNCE - Announce the arrival of a packet"\
-u "Top" \
-n "PCI Library" < $< > $@
libpci.texi: libpci.t
$(BMENU2) -p "Symmetric Multiprocessing Services TASK_SET_AFFINITY - Set task processor affinity" \
-u "Top" \
-n "Stack Bounds Checker" < $< > $@
stackchk.texi: stackchk.t
$(BMENU2) -p "Symmetric Multiprocessing Services TASK_SET_AFFINITY - Set task processor affinity" \
$(BMENU2) -p "PCI Library PCI Shell command" \
-u "Top" \
-n "CPU Usage Statistics" < $< > $@

View File

@@ -107,6 +107,7 @@
* Configuring a System::
* Multiprocessing Manager::
* Symmetric Multiprocessing Services::
* PCI Library::
* Stack Bounds Checker::
* CPU Usage Statistics::
* Object Services::
@@ -152,6 +153,7 @@
@include conf.texi
@include mp.texi
@include smp.texi
@include libpci.texi
@include stackchk.texi
@include cpuuse.texi
@include object.texi

View File

@@ -5272,6 +5272,59 @@ uses the Ada run-time.
@subheading NOTES:
None.
@c
@c === PCI Library ===
@c
@section PCI Library
This section defines the system configuration paramters supported
by @code{rtems/confdefs.h} related to configuring the PCI Library
for RTEMS.
The PCI Library startup behaviour can be configured in four diffent
ways depending on how @code{CONFIGURE_PCI_CONFIG_LIB} is defined:
@itemize @bullet
@findex PCI_LIB_AUTO
@item @code{PCI_LIB_AUTO} is used to enable the PCI auto configuration
software. PCI will be automatically probed, PCI buses enumerated, all
devices and bridges will be initialized using Plug & Play software
routines. The PCI device tree will be populated based on the PCI devices
found in the system, PCI devices will be configured by allocating address
region resources automatically in PCI space according to the BSP or host
bridge driver set up.
@findex PCI_LIB_READ
@item @code{PCI_LIB_READ} is used to enable the PCI read configuration
software. The current PCI configuration is read to create the RAM
representation (the PCI device tree) of the PCI devices present. PCI devices
are assumed to already have been initialized and PCI buses enumrated, it is
therefore required that a BIOS or a boot loader has set up configuration space
prior to booting into RTEMS.
@findex PCI_LIB_STATIC
@item @code{PCI_LIB_STATIC} is used to enable the PCI static configuration
software. The user provides a PCI tree with information how all PCI devices
are to be configured at compile time by linking in a custom
@code{struct pci_bus pci_hb} tree. The static PCI library will not probe PCI
for devices, instead it will assume that all devices defined by the user is
present, it will enumerate the PCI buses and configure all PCI devices in
static configuration accordingly. Since probe and allocation software is not
needed the startup is faster, have smaller footprint and does not require
dynamic memory allocation.
@findex PCI_LIB_PERIPHERAL
@item @code{PCI_LIB_PERIPHERAL} is used to enable the PCI peripheral
configuration. It is similar to @code{PCI_LIB_STATIC}, but is will never write
the configuration to the PCI devices since PCI peripherals are not allowed to
access PCI configuration space.
@end itemize
Note that selecting PCI_LIB_STATIC or PCI_LIB_PERIPHERAL but not defining
@code{pci_hb} will reuslt in link errors. Note also that in these modes
Plug & Play is not performed.
@c
@c === Go Tasks ===
@c

409
doc/user/libpci.t Normal file
View File

@@ -0,0 +1,409 @@
@c
@c COPYRIGHT (c) 2011
@c Aeroflex Gaisler AB
@c All rights reserved.
@c
@c $Id: libpci.t,v v.vv xxxx/yy/zz xx:yy:zz ? Exp $
@c
@chapter PCI Library
@cindex libpci
@section Introduction
The Peripheral Component Interconnect (PCI) bus is a very common computer
bus architecture that is found in almost every PC today. The PCI bus is
normally located at the motherboard where some PCI devices are soldered
directly onto the PCB and expansion slots allows the user to add custom
devices easily. There is a wide range of PCI hardware available implementing
all sorts of interfaces and functions.
This section describes the PCI Library available in RTEMS used to access the
PCI bus in a portable way across computer architectures supported by RTEMS.
The PCI Library aims to be compatible with PCI 2.3 with a couple of
limitations, for example there is no support for hot-plugging, 64-bit
memory space and cardbus bridges.
In order to support different architectures and with small foot-print embedded
systems in mind the PCI Library offers four different configuration options
listed below. It is selected during compile time by defining the appropriate
macros in confdefs.h. It is also possible to enable NONE (No Configuration)
which can be used for debuging PCI access functions.
@itemize @bullet
@item Auto Configuration (do Plug & Play)
@item Read Configuration (read BIOS or boot loader configuration)
@item Static Configuration (write user defined configuration)
@item Peripheral Configuration (no access to cfg-space)
@end itemize
@section Background
The PCI bus is constructed in a way where on-board devices and devices
in expansion slots can be automatically found (probed) and configured
using Plug & Play completely implemented in software. The bus is set up once
during boot up. The Plug & Play information can be read and written from
PCI configuration space. A PCI device is identified in configuration space by
a unique bus, slot and function number. Each PCI slot can have up to 8
functions and interface to another PCI sub-bus by implementing a PCI-to-PCI
bridge according to the PCI Bridge Architecture specification.
Using the unique [bus:slot:func] any device can be configured regardless how PCI
is currently set up as long as all PCI buses are enumerated correctly. The
enumration is done during probing, all bridges are given a bus numbers in
order for the bridges to respond to accesses from both directions. The PCI
library can assign address ranges to which a PCI device should respond using
Plug & Play technique or a static user defined configuration. After the
configuration has been performed the PCI device drivers can find devices by
the read-only PCI Class type, Vendor ID and Device ID information found in
configuration space for each device.
In some systems there is a boot loader or BIOS which have already configured
all PCI devices, but on embedded targets it is quite common that there is no
BIOS or boot loader, thus RTEMS must configure the PCI bus. Only the PCI host
may do configuration space access, the host driver or BSP is responsible to
translate the [bus:slot:func] into a valid PCI configuration space access.
If the target is not a host, but a peripheral, configuration space can not be
accessed, the peripheral is set up by the host during start up. In complex
embedded PCI systems the peripheral may need to access other PCI boards than
then host. In such systems a custom (static) configuration of both the host
and peripheral may be a convenient solution.
The PCI bus defines four interrupt signals INTA#..INTD#. The interrupt signals
must be mapped into a system interrupt/vector, it is up to the BSP or host
driver to know the mapping, however the BIOS or boot loader may use the
8-bit read/write "Interrupt Line" register to pass the knowledge along to the
OS.
The PCI standard
defines and recommends that the backplane route the interupt lines in a
systematic way, however in
@subsection Software Components
The PCI library is located in cpukit/libpci, it consists of different parts:
@itemize @bullet
@item PCI Host bridge driver interface
@item Configuration routines
@item Access (Configuration, I/O and Memory space) routines
@item Interrupt routines (implemented by BSP)
@item Print routines
@item Static/peripheral configuration creation
@item PCI shell command
@end itemize
@subsection PCI Configuration
During start up the PCI bus must be configured in order for host and peripherals
to access one another using Memory or I/O accesses and that interrupts are
properly handled. Three different spaces are defined and mapped separately:
@enumerate
@item I/O space (IO)
@item non-prefetchable Memory space (MEMIO)
@item prefetchable Memory space (MEM)
@end enumerate
Regions of the same type (I/O or Memory) may not overlap which is guaranteed
by the software. MEM regions may be mapped into MEMIO regions, but MEMIO
regions can not be mapped into MEM, for that could lead to prefetching of
registers. The interrupt pin which a board is driving can be read out from
PCI configuration space, however it is up to software to know how interrupt
signals are routed between PCI-to-PCI bridges and how PCI INT[A..D]# pins are
mapped to system IRQ. In systems where previous software (boot loader or BIOS)
has already set up this the configuration overwritten or simply read out.
In order to support different configuration methods the following configuration
libraries are available can selectable by the user:
@itemize @bullet
@item Auto Configuration (run Plug & Play software)
@item Read Configuration (relies on a boot loader or BIOS)
@item Static Configuration (write user defined setup, no Plug & Play)
@item Peripheral Configuration (user defined setup, no access to configuration space)
@end itemize
A host driver can be made to support all three configuration methods, or any
combination. It may be defined by the BSP which approach is used.
The configuration software is called from the PCI driver (pci_config_init()).
Regardless of configuration method a PCI device tree is created in RAM during
initialization, the tree can be accessed to find devices and resources without
accessing configuration space later on. The user is responsible to create the
device tree at compile time when using the static/peripheral method.
@subsubsection RTEMS Configuration selection
The active configuration method can be selected at compile time in the same
way as other project parameters by including rtems/confdefs.h and setting
@itemize @bullet
@item CONFIGURE_INIT
@item RTEMS_PCI_CONFIG_LIB
@item CONFIGURE_PCI_LIB = PCI_LIB_(AUTO,STATIC,READ,PERIPHERAL)
@end itemize
See the RTEMS configuration section how to setup the PCI library.
@subsubsection Auto Configuration
The auto configuration software enumerate PCI buses and initializes all PCI
devices found using Plug & Play. The auto configuration software requires
that a configuration setup has been registered by the driver or BSP in order
to setup the I/O and Memory regions at the correct address ranges. PCI
interrupt pins can optionally be routed over PCI-to-PCI bridges and mapped
to a system interrupt number. Resources are sorted by size and required
alignment, unused "dead" space may be created when PCI bridges are present
due to the PCI bridge window size does not equal the alignment, to cope with
that resources are reordered to fit smaller BARs into the dead space to minimize
the PCI space required. If a BAR or ROM register can not be allocated a PCI
address region (due to too few resources available) the register will be given
the value of pci_invalid_address which defaults to 0.
The auto configuration routines support:
@itemize @bullet
@item PCI 2.3
@item Little and big endian PCI bus
@item one I/O 16 or 32-bit range (IO)
@item memory space (MEMIO)
@item prefetchable memory space (MEM), if not present MEM will be mapped into
MEMIO
@item multiple PCI buses - PCI-to-PCI bridges
@item standard BARs, PCI-to-PCI bridge BARs, ROM BARs
@item Interrupt routing over bridges
@item Interrupt pin to system interrupt mapping
@end itemize
Not supported:
@itemize @bullet
@item hot-pluggable devices
@item Cardbus bridges
@item 64-bit memory space
@item 16-bit and 32-bit I/O address ranges at the same time
@end itemize
In PCI 2.3 there may exist I/O BARs that must be located at the low 64kBytes
address range, in order to support this the host driver or BSP must make sure
that I/O addresses region is within this region.
@subsubsection Read Configuration
When a BIOS or boot loader already has setup the PCI bus the configuration can
be read directly from the PCI resource registers and buses are already
enumerated, this is a much simpler approach than configuring PCI ourselves. The
PCI device tree is automatically created based on the current configuration and
devices present. After initialization is done there is no difference between
the auto or read configuration approaches.
@subsubsection Static Configuration
To support custom configurations and small-footprint PCI systems, the user may
provide the PCI device tree which contains the current configuration. The
PCI buses are enumerated and all resources are written to PCI devices during
initialization. When this approach is selected PCI boards must be located at
the same slots every time and devices can not be removed or added, Plug & Play
is not performed. Boards of the same type may of course be exchanged.
The user can create a configuration by calling pci_cfg_print() on a running
system that has had PCI setup by the auto or read configuration routines, it
can be called from the PCI shell command. The user must provide the PCI device
tree named pci_hb.
@subsubsection Peripheral Configuration
On systems where a peripheral PCI device needs to access other PCI devices than
the host the peripheral configuration approach may be handy. Most PCI devices
answers on the PCI host's requests and start DMA accesses into the Hosts memory,
however in some complex systems PCI devices may want to access other devices
on the same bus or at another PCI bus.
A PCI peripheral is not allowed to do PCI configuration cycles, which means that
is must either rely on the host to give it the addresses it needs, or that the
addresses are predefined.
This configuration approach is very similar to the static option, however the
configuration is never written to PCI bus, instead it is only used for drivers
to find PCI devices and resources using the same PCI API as for the host
@subsection PCI Access
The PCI access routines are low-level routines provided for drivers,
configuration software, etc. in order to access different regions in a way
not dependent upon the host driver, BSP or platform.
@itemize @bullet
@item PCI configuration space
@item PCI I/O space
@item Registers over PCI memory space
@item Translate PCI address into CPU accessible address and vice verse
@end itemize
By using the access routines drivers can be made portable over different
architectures. The access routines take the architecture endianness into
consideration and let the host driver or BSP implement I/O space and
configuration space access.
Some non-standard hardware may also define the PCI bus big-endian, for example
the LEON2 AT697 PCI host bridge and some LEON3 systems may be configured that
way. It is up to the BSP to set the appropriate PCI endianness on compile time
(BSP_PCI_BIG_ENDIAN) in order for inline macros to be correctly defined.
Another possibility is to use the function pointers defined by the access
layer to implement drivers that support "run-time endianness detection".
@subsubsection Configuration space
Configuration space is accessed using the routines listed below. The
pci_dev_t type is used to specify a specific PCI bus, device and function. It
is up to the host driver or BSP to create a valid access to the requested
PCI slot. Requests made to slots that is not supported by hardware should
result in PCISTS_MSTABRT and/or data must be ignored (writes) or 0xffffffff
is always returned (reads).
@example
/* Configuration Space Access Read Routines */
extern int pci_cfg_r8(pci_dev_t dev, int ofs, uint8_t *data);
extern int pci_cfg_r16(pci_dev_t dev, int ofs, uint16_t *data);
extern int pci_cfg_r32(pci_dev_t dev, int ofs, uint32_t *data);
/* Configuration Space Access Write Routines */
extern int pci_cfg_w8(pci_dev_t dev, int ofs, uint8_t data);
extern int pci_cfg_w16(pci_dev_t dev, int ofs, uint16_t data);
extern int pci_cfg_w32(pci_dev_t dev, int ofs, uint32_t data);
@end example
@subsubsection I/O space
The BSP or driver provide special routines in order to access I/O space. Some
architectures have a special instruction accessing I/O space, others have it
mapped into a "PCI I/O window" in the standard address space accessed by the
CPU. The window size may vary and must be taken into consideration by the
host driver. The below routines must be used to access I/O space. The address
given to the functions is not the PCI I/O addresses, the caller must have
translated PCI I/O addresses (available in the PCI BARs) into a BSP or host
driver custom address, see @ref{Access functions} how addresses are
translated.
@example
/* Read a register over PCI I/O Space */
extern uint8_t pci_io_r8(uint32_t adr);
extern uint16_t pci_io_r16(uint32_t adr);
extern uint32_t pci_io_r32(uint32_t adr);
/* Write a register over PCI I/O Space */
extern void pci_io_w8(uint32_t adr, uint8_t data);
extern void pci_io_w16(uint32_t adr, uint16_t data);
extern void pci_io_w32(uint32_t adr, uint32_t data);
@end example
@subsubsection Registers over Memory space
PCI host bridge hardware normally swap data accesses into the endianness of the
host architecture in order to lower the load of the CPU, peripherals can do DMA
without swapping. However, the host controller can not separate a standard
memory access from a memory access to a register, registers may be mapped into
memory space. This leads to register content being swapped, which must be
swapped back. The below routines makes it possible to access registers over PCI
memory space in a portable way on different architectures, the BSP or
architecture must provide necessary functions in order to implement this.
@example
static inline uint16_t pci_ld_le16(volatile uint16_t *addr);
static inline void pci_st_le16(volatile uint16_t *addr, uint16_t val);
static inline uint32_t pci_ld_le32(volatile uint32_t *addr);
static inline void pci_st_le32(volatile uint32_t *addr, uint32_t val);
static inline uint16_t pci_ld_be16(volatile uint16_t *addr);
static inline void pci_st_be16(volatile uint16_t *addr, uint16_t val);
static inline uint32_t pci_ld_be32(volatile uint32_t *addr);
static inline void pci_st_be32(volatile uint32_t *addr, uint32_t val);
@end example
In order to support non-standard big-endian PCI bus the above pci_* functions
is required, pci_ld_le16 != ld_le16 on big endian PCI buses.
@subsubsection Access functions
The PCI Access Library can provide device drivers with function pointers
executing the above Configuration, I/O and Memory space accesses. The
functions have the same arguments and return values as the as the above
functions.
The pci_access_func() function defined below can be used to get a function
pointer of a specific access type.
@example
/* Get Read/Write function for accessing a register over PCI Memory Space
* (non-inline functions).
*
* Arguments
* wr 0(Read), 1(Write)
* size 1(Byte), 2(Word), 4(Double Word)
* func Where function pointer will be stored
* endian PCI_LITTLE_ENDIAN or PCI_BIG_ENDIAN
* type 1(I/O), 3(REG over MEM), 4(CFG)
*
* Return
* 0 Found function
* others No such function defined by host driver or BSP
*/
int pci_access_func(int wr, int size, void **func, int endian, int type);
@end example
PCI devices drivers may be written to support run-time detection of endianess,
this is mosly for debugging or for development systems. When the product is
finally deployed macros switch to using the inline functions instead which
have been configured for the correct endianness.
@subsubsection PCI address translation
When PCI addresses, both I/O and memory space, is not mapped 1:1 address
translation before access is needed. If drivers read the PCI resources directly
using configuration space routines or in the device tree, the addresses given
are PCI addresses. The below functions can be used to translate PCI addresses
into CPU accessible addresses or vise versa, translation may be different for
different PCI spaces/regions.
@example
/* Translate PCI address into CPU accessible address */
static inline int pci_pci2cpu(uint32_t *address, int type);
/* Translate CPU accessible address into PCI address (for DMA) */
static inline int pci_cpu2pci(uint32_t *address, int type);
@end example
@subsection PCI Interrupt
The PCI specification defines four different interrupt lines INTA#..INTD#,
the interrupts are low level sensitive which make it possible to support
multiple interrupt sources on the same interrupt line. Since the lines are
level sensitive the interrupt sources must be acknowledged before clearing the
interrupt contoller, or the interrupt controller must be masked. The BSP must
provide a routine for clearing/acknowledging the interrupt controller, it is
up to the interrupt service routine to acknowledge the interrupt source.
The PCI Library relies on the BSP for implementing shared interrupt handling
through the BSP_PCI_shared_interrupt_* functions/macros, they must be defined
when including bsp.h.
PCI device drivers may use the pci_interrupt_ routines in order to call the
BSP specific functions in a platform independent way. The PCI interrupt
interface has been made similar to the RTEMS IRQ extension so that a BSP can
use the standard RTEMS interrupt functions directly.
@subsection PCI Shell command
The RTEMS shell have a PCI command 'pci' which makes it possible to read/write
configuration space, print the current PCI configuration and print out a
configuration C-file for the static or peripheral library.