You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ra...@apache.org on 2024/01/20 13:10:25 UTC
(nuttx) 01/06: pcie: add framework
This is an automated email from the ASF dual-hosted git repository.
raiden00 pushed a commit to branch pci
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 4a6cf9bba2bf65ca2011933ad297b00f88043059
Author: Yang Chung-Fan <so...@gmail.com>
AuthorDate: Mon May 4 18:44:11 2020 +0900
pcie: add framework
---
Kconfig | 34 ++++
drivers/Kconfig | 1 +
drivers/Makefile | 1 +
drivers/pcie/Kconfig | 20 +++
drivers/pcie/Make.defs | 32 ++++
drivers/pcie/pcie_root.c | 442 ++++++++++++++++++++++++++++++++++++++++++++++
include/debug.h | 17 ++
include/nuttx/pcie/pcie.h | 352 ++++++++++++++++++++++++++++++++++++
8 files changed, 899 insertions(+)
diff --git a/Kconfig b/Kconfig
index 603c6f924d..b2901f17a3 100644
--- a/Kconfig
+++ b/Kconfig
@@ -2196,6 +2196,40 @@ config DEBUG_IPC_INFO
endif # DEBUG_IPC
+config DEBUG_PCIE
+ bool "PCI-E Debug Features"
+ default n
+ depends on PCIE
+ ---help---
+ Enable PCIE driver debug features.
+
+ Support for this debug option is architecture-specific and may not
+ be available for some MCUs.
+
+if DEBUG_PCIE
+
+config DEBUG_PCIE_ERROR
+ bool "PCI-E Error Output"
+ default n
+ depends on DEBUG_ERROR
+ ---help---
+ Enable PCI-E driver error output to SYSLOG.
+
+config DEBUG_PCIE_WARN
+ bool "PCI-E Warnings Output"
+ default n
+ depends on DEBUG_WARN
+ ---help---
+ Enable PCI-E driver warning output to SYSLOG.
+
+config DEBUG_PCIE_INFO
+ bool "PCI-E Informational Output"
+ default n
+ depends on DEBUG_INFO
+ ---help---
+ Enable PCI-E driver informational output to SYSLOG.
+
+endif # DEBUG_PCIE
endif # DEBUG_FEATURES
config ARCH_HAVE_STACKCHECK
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 328b726641..43f8949994 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -59,3 +59,4 @@ source "drivers/usrsock/Kconfig"
source "drivers/dma/Kconfig"
source "drivers/devicetree/Kconfig"
source "drivers/reset/Kconfig"
+source "drivers/pcie/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 197ceb3215..7f94dfd2da 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -77,6 +77,7 @@ include rc/Make.defs
include segger/Make.defs
include usrsock/Make.defs
include reset/Make.defs
+include pcie/Make.defs
ifeq ($(CONFIG_SPECIFIC_DRIVERS),y)
-include platform/Make.defs
diff --git a/drivers/pcie/Kconfig b/drivers/pcie/Kconfig
new file mode 100644
index 0000000000..7ac9db568b
--- /dev/null
+++ b/drivers/pcie/Kconfig
@@ -0,0 +1,20 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+menuconfig PCIE
+ bool "Support for PCI-E Bus"
+ default n
+ ---help---
+ Enables support for the PCI-E bus.
+ Backend bust be provided by per-arch or per-board implementation..
+
+if PCIE
+config PCIE_MAX_BDF
+ hex "Maximum bdf to scan on PCI-E bus"
+ default 0x10000
+ ---help---
+ The maximum bdf number to be scaned on PCI-E bus
+
+endif
diff --git a/drivers/pcie/Make.defs b/drivers/pcie/Make.defs
new file mode 100644
index 0000000000..68efee8123
--- /dev/null
+++ b/drivers/pcie/Make.defs
@@ -0,0 +1,32 @@
+############################################################################
+# drivers/pcie/Make.defs
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+# Don't build anything if there is no CAN support
+
+ifeq ($(CONFIG_PCIE),y)
+
+CSRCS += pcie_root.c
+
+# Include PCIE device driver build support
+
+DEPPATH += --dep-path pcie
+VPATH += :pcie
+CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)pcie}
+endif
diff --git a/drivers/pcie/pcie_root.c b/drivers/pcie/pcie_root.c
new file mode 100644
index 0000000000..25718aa5ae
--- /dev/null
+++ b/drivers/pcie/pcie_root.c
@@ -0,0 +1,442 @@
+/****************************************************************************
+ * nuttx/drivers/pcie/pcie_root.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/pcie/pcie.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+struct pcie_dev_type_s *pci_device_types[] =
+{
+ NULL,
+};
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pci_enumerate
+ *
+ * Description:
+ * Scan the PCI bus and enumerate the devices.
+ * Initialize any recognized devices, given in types.
+ *
+ * Input Parameters:
+ * bus - PCI-E bus structure
+ * type - List of pointers to devices types recognized, NULL terminated
+ *
+ * Returned Value:
+ * 0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_enumerate(FAR struct pcie_bus_s *bus,
+ FAR struct pcie_dev_type_s **types)
+{
+ unsigned int bdf;
+ uint16_t vid;
+ uint16_t id;
+ uint16_t rev;
+ struct pcie_dev_s tmp_dev;
+ struct pcie_dev_type_s tmp_type =
+ {
+ .name = "Unknown",
+ .vendor = PCI_ID_ANY,
+ .device = PCI_ID_ANY,
+ .class_rev = PCI_ID_ANY,
+ .probe = NULL,
+ };
+
+ if (!bus)
+ return -EINVAL;
+ if (!types)
+ return -EINVAL;
+
+ for (bdf = 0; bdf < CONFIG_PCIE_MAX_BDF; bdf++)
+ {
+ tmp_dev.bus = bus;
+ tmp_dev.type = &tmp_type;
+ tmp_dev.bdf = bdf;
+
+ bus->ops->pci_cfg_read(&tmp_dev, PCI_CFG_VENDOR_ID, &vid, 2);
+ bus->ops->pci_cfg_read(&tmp_dev, PCI_CFG_DEVICE_ID, &id, 2);
+ bus->ops->pci_cfg_read(&tmp_dev, PCI_CFG_REVERSION, &rev, 2);
+
+ if (vid == PCI_ID_ANY)
+ continue;
+
+ pciinfo("[%02x:%02x.%x] Found %04x:%04x, class/reversion %08x\n",
+ bdf >> 8, (bdf >> 3) & 0x1f, bdf & 0x3,
+ vid, id, rev);
+
+ for (int i = 0; types[i] != NULL; i++)
+ {
+ if (types[i]->vendor == PCI_ID_ANY ||
+ types[i]->vendor == vid)
+ {
+ if (types[i]->device == PCI_ID_ANY ||
+ types[i]->device == id)
+ {
+ if (types[i]->class_rev == PCI_ID_ANY ||
+ types[i]->class_rev == rev)
+ {
+ if (types[i]->probe)
+ {
+ pciinfo("[%02x:%02x.%x] %s\n",
+ bdf >> 8, (bdf >> 3) & 0x1f, bdf & 0x3,
+ types[i]->name);
+ types[i]->probe(bus, types[i], bdf);
+ }
+ else
+ {
+ pcierr("[%02x:%02x.%x] Error: Invalid \
+ device probe function\n",
+ bdf >> 8, (bdf >> 3) & 0x1f, bdf & 0x3);
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: pcie_initialize
+ *
+ * Description:
+ * Initialize the PCI-E bus and enumerate the devices with give devices
+ * type array
+ *
+ * Input Parameters:
+ * bus - An PCIE bus
+ * types - A array of PCIE device types
+ * num - Number of device types
+ *
+ * Returned Value:
+ * OK if the driver was successfully register; A negated errno value is
+ * returned on any failure.
+ *
+ ****************************************************************************/
+
+int pcie_initialize(FAR struct pcie_bus_s *bus)
+{
+ return pci_enumerate(bus, pci_device_types);
+}
+
+/****************************************************************************
+ * Name: pci_enable_device
+ *
+ * Description:
+ * Enable device with MMIO
+ *
+ * Input Parameters:
+ * dev - device
+ *
+ * Return value:
+ * -EINVAL: error
+ * OK: OK
+ *
+ ****************************************************************************/
+
+int pci_enable_device(FAR struct pcie_dev_s *dev)
+{
+ uint16_t old_cmd;
+ uint16_t cmd;
+
+ dev->bus->ops->pci_cfg_read(dev, PCI_CFG_COMMAND, &old_cmd, 2);
+
+ cmd = old_cmd | (PCI_CMD_MASTER | PCI_CMD_MEM);
+
+ dev->bus->ops->pci_cfg_write(dev, PCI_CFG_COMMAND, &cmd, 2);
+
+ pciinfo("%02x:%02x.%x, CMD: %x -> %x\n",
+ dev->bdf >> 8, (dev->bdf >> 3) & 0x1f, dev->bdf & 0x3,
+ old_cmd, cmd);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: pci_find_cap
+ *
+ * Description:
+ * Search through the PCI-e device capability list to find given capability.
+ *
+ * Input Parameters:
+ * dev - Device
+ * cap - Bitmask of capability
+ *
+ * Returned Value:
+ * -1: Capability not supported
+ * other: the offset in PCI configuration space to the capability structure
+ *
+ ****************************************************************************/
+
+int pci_find_cap(FAR struct pcie_dev_s *dev, uint16_t cap)
+{
+ uint8_t pos = PCI_CFG_CAP_PTR - 1;
+ uint16_t status;
+ uint8_t rcap;
+
+ dev->bus->ops->pci_cfg_read(dev, PCI_CFG_STATUS, &status, 2);
+
+ if (!(status & PCI_STS_CAPS))
+ return -EINVAL;
+
+ while (1)
+ {
+ dev->bus->ops->pci_cfg_read(dev, pos + 1, &pos, 1);
+ if (pos == 0)
+ return -EINVAL;
+
+ dev->bus->ops->pci_cfg_read(dev, pos, &rcap, 1);
+
+ if (rcap == cap)
+ return pos;
+ }
+}
+
+/****************************************************************************
+ * Name: pci_get_bar
+ *
+ * Description:
+ * Get a 32 bits bar
+ *
+ * Input Parameters:
+ * dev - Device private data
+ * bar - Bar number
+ * ret - Bar Content
+ *
+ * Returned Value:
+ * 0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_get_bar(FAR struct pcie_dev_s *dev, uint32_t bar,
+ uint32_t *ret)
+{
+ if (bar > 5)
+ return -EINVAL;
+
+ dev->bus->ops->pci_cfg_read(dev, PCI_CFG_BAR + bar * 4, ret, 4);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: pci_get_bar64
+ *
+ * Description:
+ * Get a 64 bits bar
+ *
+ * Input Parameters:
+ * dev - Device private data
+ * bar - Bar number
+ * ret - Bar Content
+ *
+ * Returned Value:
+ * 0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_get_bar64(FAR struct pcie_dev_s *dev, uint32_t bar,
+ uint64_t *ret)
+{
+ if (bar > 4 || ((bar % 2) != 0))
+ return -EINVAL;
+
+ uint32_t barmem1;
+ uint32_t barmem2;
+
+ dev->bus->ops->pci_cfg_read(dev, PCI_CFG_BAR + bar * 4, &barmem1, 4);
+ dev->bus->ops->pci_cfg_read(dev, PCI_CFG_BAR + bar * 4 + 4, &barmem2, 4);
+
+ *ret = ((uint64_t)barmem2 << 32) | barmem1;
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: pci_set_bar
+ *
+ * Description:
+ * Set a 32 bits bar
+ *
+ * Input Parameters:
+ * dev - Device private data
+ * bar - Bar number
+ * val - Bar Content
+ *
+ * Returned Value:
+ * 0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_set_bar(FAR struct pcie_dev_s *dev, uint32_t bar,
+ uint32_t val)
+{
+ if (bar > 5)
+ return -EINVAL;
+
+ dev->bus->ops->pci_cfg_write(dev, PCI_CFG_BAR + bar * 4, &val, 4);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: pci_set_bar64
+ *
+ * Description:
+ * Set a 64 bits bar
+ *
+ * Input Parameters:
+ * dev - Device private data
+ * bar - Bar number
+ * val - Bar Content
+ *
+ * Returned Value:
+ * 0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_set_bar64(FAR struct pcie_dev_s *dev, uint32_t bar,
+ uint64_t val)
+{
+ if (bar > 4 || ((bar % 2) != 0))
+ return -EINVAL;
+
+ uint32_t barmem1 = (uint32_t)val;
+ uint32_t barmem2 = (uint32_t)(val >> 32);
+
+ dev->bus->ops->pci_cfg_write(dev, PCI_CFG_BAR + bar * 4, &barmem1, 4);
+ dev->bus->ops->pci_cfg_write(dev, PCI_CFG_BAR + bar * 4 + 4, &barmem2, 4);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: pci_map_bar
+ *
+ * Description:
+ * Map address in a 32 bits bar in the flat memory address space
+ *
+ * Input Parameters:
+ * dev - Device private data
+ * bar - Bar number
+ * length - Map length, multiple of PAGE_SIZE
+ * ret - Bar Content if not NULL
+ *
+ * Returned Value:
+ * 0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_map_bar(FAR struct pcie_dev_s *dev, uint32_t bar,
+ unsigned long length, uint32_t *ret)
+{
+ if (bar > 5)
+ return -EINVAL;
+
+ uint32_t barmem;
+
+ dev->bus->ops->pci_cfg_read(dev, PCI_CFG_BAR + bar * 4, &barmem, 4);
+
+ if (((bar % 2) == 0 &&
+ (barmem & PCI_BAR_64BIT) == PCI_BAR_64BIT) ||
+ (barmem & PCI_BAR_IO) == PCI_BAR_IO)
+ return -EINVAL;
+
+ if (!dev->bus->ops->pci_map_bar)
+ return -EINVAL;
+
+ dev->bus->ops->pci_map_bar(dev, barmem, length);
+
+ if (ret)
+ *ret = barmem;
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: pci_map_bar64
+ *
+ * Description:
+ * Map address in a 64 bits bar in the flat memory address space
+ *
+ * Input Parameters:
+ * dev - Device private data
+ * bar - Bar number
+ * length - Map length, multiple of PAGE_SIZE
+ * ret - Bar Content if not NULL
+ *
+ * Returned Value:
+ * 0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_map_bar64(FAR struct pcie_dev_s *dev, uint32_t bar,
+ unsigned long length, uint64_t *ret)
+{
+ if (bar > 4 || ((bar % 2) != 0))
+ return -EINVAL;
+
+ uint32_t barmem1;
+ uint32_t barmem2;
+ uint64_t barmem;
+
+ dev->bus->ops->pci_cfg_read(dev, PCI_CFG_BAR + bar * 4, &barmem1, 4);
+
+ if ((barmem1 & PCI_BAR_64BIT) != PCI_BAR_64BIT ||
+ (barmem1 & PCI_BAR_IO) == PCI_BAR_IO)
+ return -EINVAL;
+
+ dev->bus->ops->pci_cfg_read(dev, PCI_CFG_BAR + bar * 4 + 4, &barmem2, 4);
+
+ barmem = ((uint64_t)barmem2 << 32) | barmem1;
+
+ if (!dev->bus->ops->pci_map_bar64)
+ return -EINVAL;
+
+ dev->bus->ops->pci_map_bar64(dev, barmem, length);
+
+ if (ret)
+ *ret = barmem;
+
+ return OK;
+}
diff --git a/include/debug.h b/include/debug.h
index e6b9163cd7..b3171e40fc 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -918,6 +918,23 @@
# define ipcinfo _info
#else
# define ipcinfo _none
+
+#ifdef CONFIG_DEBUG_PCIE_ERROR
+# define pcierr _err
+#else
+# define pcierr _none
+#endif
+
+#ifdef CONFIG_DEBUG_PCIE_WARN
+# define pciwarn _warn
+#else
+# define pciwarn _none
+#endif
+
+#ifdef CONFIG_DEBUG_PCIE_INFO
+# define pciinfo _info
+#else
+# define pciinfo _none
#endif
/* Buffer dumping macros do not depend on varargs */
diff --git a/include/nuttx/pcie/pcie.h b/include/nuttx/pcie/pcie.h
new file mode 100644
index 0000000000..fffc791a2d
--- /dev/null
+++ b/include/nuttx/pcie/pcie.h
@@ -0,0 +1,352 @@
+/****************************************************************************
+ * include/nuttx/pcie/pcie.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_NUTTX_PCIE_PCIE_H
+#define __INCLUDE_NUTTX_PCIE_PCIE_H
+
+#ifdef CONFIG_PCIE
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+
+#include <nuttx/fs/ioctl.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define PCI_CFG_VENDOR_ID 0x000
+#define PCI_CFG_DEVICE_ID 0x002
+#define PCI_CFG_COMMAND 0x004
+# define PCI_CMD_IO (1 << 0)
+# define PCI_CMD_MEM (1 << 1)
+# define PCI_CMD_MASTER (1 << 2)
+# define PCI_CMD_INTX_OFF (1 << 10)
+#define PCI_CFG_STATUS 0x006
+# define PCI_STS_INT (1 << 3)
+# define PCI_STS_CAPS (1 << 4)
+#define PCI_CFG_REVERSION 0x008
+#define PCI_CFG_BAR 0x010
+# define PCI_BAR_IO 0x1
+# define PCI_BAR_1M 0x2
+# define PCI_BAR_64BIT 0x4
+#define PCI_CFG_CAP_PTR 0x034
+
+#define PCI_ID_ANY 0xffff
+#define PCI_DEV_CLASS_OTHER 0xff
+
+#define PCI_CAP_PM 0x01
+
+#define PCI_CAP_MSI 0x05
+# define PCI_MSI_MCR 0x02
+# define PCI_MSI_MCR_SIZE 2
+# define PCI_MSI_MCR_EN (1 << 0)
+# define PCI_MSI_MCR_64 (1 << 7)
+# define PCI_MSI_MAR 0x04
+# define PCI_MSI_MAR_SIZE 4
+# define PCI_MSI_MDR 0x08
+# define PCI_MSI_MDR_SIZE 2
+# define PCI_MSI_MAR64_HI 0x08
+# define PCI_MSI_MAR64_HI_SIZE 4
+# define PCI_MSI_MDR64 0x0c
+# define PCI_MSI_MDR64_SIZE 2
+# define PCI_MSI_APIC_ID_OFFSET 0xc
+
+#define PCI_CAP_MSIX 0x11
+# define PCI_MSIX_MCR 0x02
+# define PCI_MSIX_MCR_SIZE 2
+# define PCI_MSIX_MCR_EN (1 << 15)
+# define PCI_MSIX_MCR_FMASK 0x4000
+# define PCI_MSIX_MCR_TBL_MASK 0x03ff
+# define PCI_MSIX_TBL 0x04
+# define PCI_MSIX_TBL_SIZE 4
+# define PCI_MSIX_PBA 0x08
+# define PCI_MSIX_PBA_SIZE 4
+# define PCI_MSIX_BIR_MASK 0x07
+# define PCI_MSIX_TBL_ENTRY_SIZE 0x10
+# define PCI_MSIX_TBL_LO_ADDR 0x0
+# define PCI_MSIX_TBL_HI_ADDR 0x4
+# define PCI_MSIX_TBL_MSG_DATA 0x8
+# define PCI_MSIX_TBL_VEC_CTL 0xc
+# define PCI_MSIX_APIC_ID_OFFSET 0xc
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* The PCIE driver interface */
+
+struct pcie_bus_s;
+struct pcie_dev_type_s;
+struct pcie_dev_s;
+
+/* Bus related operations */
+
+struct pcie_bus_ops_s
+{
+ CODE int (*pcie_enumerate)(FAR struct pcie_bus_s *bus,
+ FAR struct pcie_dev_type_s **types);
+
+ CODE int (*pci_cfg_write)(FAR struct pcie_dev_s *dev, uintptr_t addr,
+ FAR const void *buffer, unsigned int size);
+
+ CODE int (*pci_cfg_read)(FAR struct pcie_dev_s *dev, uintptr_t addr,
+ FAR void *buffer, unsigned int size);
+
+ CODE int (*pci_map_bar)(FAR struct pcie_dev_s *dev, uint32_t addr,
+ unsigned long length);
+
+ CODE int (*pci_map_bar64)(FAR struct pcie_dev_s *dev, uint64_t addr,
+ unsigned long length);
+
+ CODE int (*pci_msi_register)(FAR struct pcie_dev_s *dev,
+ uint16_t vector);
+
+ CODE int (*pci_msix_register)(FAR struct pcie_dev_s *dev,
+ uint32_t vector, uint32_t index);
+};
+
+/* PCIE bus private data. */
+
+struct pcie_bus_s
+{
+ FAR const struct pcie_bus_ops_s *ops; /* operations */
+};
+
+/* PCIE device type, defines by vendor ID and device ID */
+
+struct pcie_dev_type_s
+{
+ uint16_t vendor; /* Device vendor ID */
+ uint16_t device; /* Device ID */
+ uint32_t class_rev; /* Device reversion */
+ const char *name; /* Human readable name */
+
+ /* Call back function when a device is probed */
+
+ CODE int (*probe)(FAR struct pcie_bus_s *bus,
+ FAR struct pcie_dev_type_s *type, uint16_t bdf);
+};
+
+/* PCIE device private data. */
+
+struct pcie_dev_s
+{
+ FAR struct pcie_bus_s *bus;
+ FAR struct pcie_dev_type_s *type;
+ uint16_t bdf;
+};
+
+/****************************************************************************
+ * Public Functions Prototypes
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Name: pcie_initialize
+ *
+ * Description:
+ * Initialize the PCI-E bus and enumerate the devices with give devices
+ * type array
+ *
+ * Input Parameters:
+ * bus - An PCIE bus
+ * types - A array of PCIE device types
+ * num - Number of device types
+ *
+ * Returned Value:
+ * OK if the driver was successfully register; A negated errno value is
+ * returned on any failure.
+ *
+ ****************************************************************************/
+
+int pcie_initialize(FAR struct pcie_bus_s *bus);
+
+/****************************************************************************
+ * Name: pci_enable_device
+ *
+ * Description:
+ * Enable device with MMIO
+ *
+ * Input Parameters:
+ * dev - device
+ *
+ * Return value:
+ * -EINVAL: error
+ * OK: OK
+ *
+ ****************************************************************************/
+
+int pci_enable_device(FAR struct pcie_dev_s *dev);
+
+/****************************************************************************
+ * Name: pci_find_cap
+ *
+ * Description:
+ * Search through the PCI-e device capability list to find given capability.
+ *
+ * Input Parameters:
+ * dev - Device
+ * cap - Bitmask of capability
+ *
+ * Returned Value:
+ * -1: Capability not supported
+ * other: the offset in PCI configuration space to the capability structure
+ *
+ ****************************************************************************/
+
+int pci_find_cap(FAR struct pcie_dev_s *dev, uint16_t cap);
+
+/****************************************************************************
+ * Name: pci_map_bar
+ *
+ * Description:
+ * Map address in a 32 bits bar in the flat memory address space
+ *
+ * Input Parameters:
+ * dev - Device private data
+ * bar - Bar number
+ * length - Map length, multiple of PAGE_SIZE
+ * ret - Bar Contentif not NULL
+ *
+ * Returned Value:
+ * 0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_map_bar(FAR struct pcie_dev_s *dev, uint32_t bar,
+ unsigned long length, uint32_t *ret);
+
+/****************************************************************************
+ * Name: pci_map_bar64
+ *
+ * Description:
+ * Map address in a 64 bits bar in the flat memory address space
+ *
+ * Input Parameters:
+ * dev - Device private data
+ * bar - Bar number
+ * length - Map length, multiple of PAGE_SIZE
+ * ret - Bar Content if not NULL
+ *
+ * Returned Value:
+ * 0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_map_bar64(FAR struct pcie_dev_s *dev, uint32_t bar,
+ unsigned long length, uint64_t *ret);
+
+/****************************************************************************
+ * Name: pci_get_bar
+ *
+ * Description:
+ * Get a 32 bits bar
+ *
+ * Input Parameters:
+ * dev - Device private data
+ * bar - Bar number
+ * ret - Bar Content
+ *
+ * Returned Value:
+ * 0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_get_bar(FAR struct pcie_dev_s *dev, uint32_t bar,
+ uint32_t *ret);
+
+/****************************************************************************
+ * Name: pci_get_bar64
+ *
+ * Description:
+ * Get a 64 bits bar
+ *
+ * Input Parameters:
+ * dev - Device private data
+ * bar - Bar number
+ * ret - Bar Content
+ *
+ * Returned Value:
+ * 0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_get_bar64(FAR struct pcie_dev_s *dev, uint32_t bar,
+ uint64_t *ret);
+
+/****************************************************************************
+ * Name: pci_set_bar
+ *
+ * Description:
+ * Set a 32 bits bar
+ *
+ * Input Parameters:
+ * dev - Device private data
+ * bar - Bar number
+ * val - Bar Content
+ *
+ * Returned Value:
+ * 0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_set_bar(FAR struct pcie_dev_s *dev, uint32_t bar,
+ uint32_t val);
+
+/****************************************************************************
+ * Name: pci_set_bar64
+ *
+ * Description:
+ * Set a 64 bits bar
+ *
+ * Input Parameters:
+ * dev - Device private data
+ * bar - Bar number
+ * val - Bar Content
+ *
+ * Returned Value:
+ * 0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_set_bar64(FAR struct pcie_dev_s *dev, uint32_t bar,
+ uint64_t val);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+#endif
+#endif /* __INCLUDE_NUTTX_I2C_I2C_MASTER_H */