forked from Imagelibrary/rtems
LIBPCI: added PCI layer to cpukit/libpci
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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
46
cpukit/libpci/CHANGES
Normal 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
46
cpukit/libpci/Makefile.am
Normal 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
4
cpukit/libpci/README
Normal 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
375
cpukit/libpci/pci.h
Normal 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
351
cpukit/libpci/pci/access.h
Normal 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
244
cpukit/libpci/pci/cfg.h
Normal 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
|
||||
59
cpukit/libpci/pci/cfg_auto.h
Normal file
59
cpukit/libpci/pci/cfg_auto.h
Normal 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
|
||||
20
cpukit/libpci/pci/cfg_peripheral.h
Normal file
20
cpukit/libpci/pci/cfg_peripheral.h
Normal 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
|
||||
22
cpukit/libpci/pci/cfg_read.h
Normal file
22
cpukit/libpci/pci/cfg_read.h
Normal 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
|
||||
22
cpukit/libpci/pci/cfg_static.h
Normal file
22
cpukit/libpci/pci/cfg_static.h
Normal 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
802
cpukit/libpci/pci/ids.h
Normal 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__ */
|
||||
19
cpukit/libpci/pci/ids_extra.h
Normal file
19
cpukit/libpci/pci/ids_extra.h
Normal 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
105
cpukit/libpci/pci/irq.h
Normal 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__ */
|
||||
74
cpukit/libpci/pci_access.c
Normal file
74
cpukit/libpci/pci_access.c
Normal 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;
|
||||
}
|
||||
73
cpukit/libpci/pci_access_func.c
Normal file
73
cpukit/libpci/pci_access_func.c
Normal 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);
|
||||
}
|
||||
}
|
||||
48
cpukit/libpci/pci_access_io.c
Normal file
48
cpukit/libpci/pci_access_io.c
Normal 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);
|
||||
}
|
||||
22
cpukit/libpci/pci_access_mem.c
Normal file
22
cpukit/libpci/pci_access_mem.c
Normal 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;
|
||||
}
|
||||
67
cpukit/libpci/pci_access_mem_be.c
Normal file
67
cpukit/libpci/pci_access_mem_be.c
Normal 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,
|
||||
};
|
||||
66
cpukit/libpci/pci_access_mem_le.c
Normal file
66
cpukit/libpci/pci_access_mem_le.c
Normal 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
55
cpukit/libpci/pci_cfg.c
Normal 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
1014
cpukit/libpci/pci_cfg_auto.c
Normal file
File diff suppressed because it is too large
Load Diff
32
cpukit/libpci/pci_cfg_peripheral.c
Normal file
32
cpukit/libpci/pci_cfg_peripheral.c
Normal 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;
|
||||
}
|
||||
172
cpukit/libpci/pci_cfg_print_code.c
Normal file
172
cpukit/libpci/pci_cfg_print_code.c
Normal 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);
|
||||
}
|
||||
357
cpukit/libpci/pci_cfg_read.c
Normal file
357
cpukit/libpci/pci_cfg_read.c
Normal 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;
|
||||
}
|
||||
157
cpukit/libpci/pci_cfg_static.c
Normal file
157
cpukit/libpci/pci_cfg_static.c
Normal 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
52
cpukit/libpci/pci_find.c
Normal 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;
|
||||
}
|
||||
49
cpukit/libpci/pci_find_dev.c
Normal file
49
cpukit/libpci/pci_find_dev.c
Normal 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;
|
||||
}
|
||||
62
cpukit/libpci/pci_for_each.c
Normal file
62
cpukit/libpci/pci_for_each.c
Normal 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 */
|
||||
}
|
||||
41
cpukit/libpci/pci_for_each_child.c
Normal file
41
cpukit/libpci/pci_for_each_child.c
Normal 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;
|
||||
}
|
||||
18
cpukit/libpci/pci_for_each_dev.c
Normal file
18
cpukit/libpci/pci_for_each_dev.c
Normal 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);
|
||||
}
|
||||
36
cpukit/libpci/pci_get_dev.c
Normal file
36
cpukit/libpci/pci_get_dev.c
Normal 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
20
cpukit/libpci/pci_irq.c
Normal 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
190
cpukit/libpci/pci_print.c
Normal 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");
|
||||
}
|
||||
66
cpukit/libpci/preinstall.am
Normal file
66
cpukit/libpci/preinstall.am
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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" < $< > $@
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
409
doc/user/libpci.t
Normal 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.
|
||||
Reference in New Issue
Block a user