summaryrefslogtreecommitdiffstats
path: root/cpukit/libpci/pci_access_func.c
diff options
context:
space:
mode:
authorDaniel Hellstrom <daniel@gaisler.com>2011-11-28 10:11:10 +0100
committerDaniel Hellstrom <daniel@gaisler.com>2015-04-17 01:10:15 +0200
commita31845f7f9b4770cf9ddd8b6820641d2f4f4c1da (patch)
tree0d7f215ec45d7c4cf6f1293af72ece2fbde1ddc3 /cpukit/libpci/pci_access_func.c
parentleon3,ngmp: simplify cpucounter initialization (diff)
downloadrtems-a31845f7f9b4770cf9ddd8b6820641d2f4f4c1da.tar.bz2
LIBPCI: added PCI layer to cpukit/libpci
Diffstat (limited to 'cpukit/libpci/pci_access_func.c')
-rw-r--r--cpukit/libpci/pci_access_func.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/cpukit/libpci/pci_access_func.c b/cpukit/libpci/pci_access_func.c
new file mode 100644
index 0000000000..d86ccab357
--- /dev/null
+++ b/cpukit/libpci/pci_access_func.c
@@ -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);
+ }
+}