This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 69ed5bb67de73adae50c3e3afbab34f944eb14a2
Author: Brennan Ashton <bash...@brennanashton.com>
AuthorDate: Thu May 7 02:59:29 2020 -0700

    Various fixes for PCI work
    
    Squashed commits:
    
    1. Porting prior PCI work in place of jailhouse code
    
    At this point the PCI enumeration works for x86_64 including over
    pci-pci bridges.
    
    Running QEMU with this configuration we see the bridge and the
    device on the bridge.  It also detected the qemu test device
    
    qemu-system-x86_64 \
      -cpu host,+pcid,+x2apic,+tsc-deadline,+xsave,+rdrand \
      --enable-kvm -smp 1 -m 2G -cdrom boot.iso --nographic -no-reboot \
      -device pci-testdev \
      -device pci-bridge,id=bridge0,chassis_nr=2 \
      -device e1000,bus=bridge0,addr=0x3
    
    qemu_pci_init: Initializing PCI Bus
    pci_probe_device: [00:00.0] Found 8086:1237, class/revision 06000002
    pci_probe_device: [00:01.1] Found 8086:7010, class/revision 01018000
    pci_probe_device: [00:01.2] Found ffff:ffff, class/revision ffffffff
    pci_probe_device: [00:01.3] Found 8086:7113, class/revision 06800003
    pci_probe_device: [00:01.4] Found ffff:ffff, class/revision ffffffff
    pci_probe_device: [00:01.5] Found ffff:ffff, class/revision ffffffff
    pci_probe_device: [00:01.6] Found ffff:ffff, class/revision ffffffff
    pci_probe_device: [00:01.7] Found ffff:ffff, class/revision ffffffff
    pci_probe_device: [00:02.0] Found 1234:1111, class/revision 03000002
    pci_probe_device: [00:03.0] Found 8086:100e, class/revision 02000003
    pci_probe_device: [00:04.0] Found 1b36:0005, class/revision 00ff0000
    pci_probe_device: [00:04.0] Probing
    pci_check_pci_bridge: [00:05.0] Found Bridge
    pci_probe_device: [01:03.0] Found 8086:100e, class/revision 02000003
    pci_probe_device: [00:05.0] Found 1b36:0001, class/revision 06040000
    
    2. Remove unused CONFIG_PCI_MAX_BDF option
    
    3. Add a workaround for Jailhouse pci scanning
    
    4. Extend BAR parsing and handle PIO and MMIO for pci-testdev
    
    Signed-off-by: Brennan Ashton <bash...@brennanashton.com>
    
    5. PCI: Add initial support for QEMU 'edu' test device
    
    Signed-off-by: Brennan Ashton <bash...@brennanashton.com>
    
    6. Bring up PCI later in boot process
    
    Signed-off-by: Brennan Ashton <bash...@brennanashton.com>
    
    7. Add ISR and DMA support to QEMU edu test pci device
    
    Signed-off-by: Brennan Ashton <bash...@brennanashton.com>
    
    8. Fix bad function prototype definition in qemu_edu
    
    9. intel64:  Add a pci test configuration and instructions
    
    Signed-off-by: Brennan Ashton <bash...@brennanashton.com>
    
    10. PCI: Fix issue in identification of 64bit bar
    
    Signed-off-by: Brennan Ashton <bash...@brennanashton.com>
---
 .../x86_64/qemu/boards/qemu-intel64/index.rst      |   8 +
 Kconfig                                            |  31 +-
 boards/x86_64/intel64/qemu-intel64/Kconfig         |   8 +-
 .../intel64/qemu-intel64/configs/pcitest/defconfig |  76 ++
 boards/x86_64/intel64/qemu-intel64/include/board.h |   2 -
 boards/x86_64/intel64/qemu-intel64/src/Makefile    |   4 +-
 boards/x86_64/intel64/qemu-intel64/src/qemu_boot.c |   6 -
 .../x86_64/intel64/qemu-intel64/src/qemu_bringup.c |   5 +
 .../x86_64/intel64/qemu-intel64/src/qemu_intel64.h |   2 +
 boards/x86_64/intel64/qemu-intel64/src/qemu_pci.c  | 226 ++++++
 boards/x86_64/intel64/qemu-intel64/src/qemu_pcie.c | 398 -----------
 .../intel64/qemu-intel64/src/qemu_pcie_readwrite.h | 240 -------
 drivers/Kconfig                                    |   2 +-
 drivers/Makefile                                   |   2 +-
 .../intel64/qemu-intel64 => drivers/pci}/Kconfig   |  11 +-
 drivers/{pcie => pci}/Make.defs                    |  14 +-
 drivers/pci/pci.c                                  | 792 +++++++++++++++++++++
 drivers/pcie/Kconfig                               |  20 -
 drivers/pcie/pcie_root.c                           | 446 ------------
 drivers/virt/Kconfig                               |   9 +-
 drivers/virt/Make.defs                             |   8 +-
 drivers/virt/qemu_edu.c                            | 448 ++++++++++++
 drivers/virt/qemu_pci_test.c                       | 201 +++++-
 include/debug.h                                    |   6 +-
 include/nuttx/pci/pci.h                            | 458 ++++++++++++
 include/nuttx/pcie/pcie.h                          | 352 ---------
 include/nuttx/virt/qemu_pci.h                      |   6 +-
 27 files changed, 2237 insertions(+), 1544 deletions(-)

diff --git a/Documentation/platforms/x86_64/qemu/boards/qemu-intel64/index.rst 
b/Documentation/platforms/x86_64/qemu/boards/qemu-intel64/index.rst
index 74c4349133..d1fe76186d 100644
--- a/Documentation/platforms/x86_64/qemu/boards/qemu-intel64/index.rst
+++ b/Documentation/platforms/x86_64/qemu/boards/qemu-intel64/index.rst
@@ -71,6 +71,14 @@ Use control-a x to terminate the emulation.
 P.S. Make sure that you CPU supports the mandatory features. Look at Real 
machine
 section for more information.
 
+For testing the PCI bus and driver layers.  This QEMU configuration can be used
+with the pcitest NuttX configuration::
+
+    qemu-system-x86_64  -cpu host,+pcid,+x2apic,+tsc-deadline,+xsave,+rdrand 
--enable-kvm -smp 1 -m 2G -cdrom boot.iso --nographic -s -no-reboot -device edu 
-device pci-testdev
+  
+This will enable the QEMU pci-test and edu PCI test devices which test PIO, 
MMIO, IRQ, and DMA
+functions.  Additionally it will show detailed information about the 
enumeration of the PCI bus.
+
 Bochs
 =====
 
diff --git a/Kconfig b/Kconfig
index a0d8b941c5..69c13823d9 100644
--- a/Kconfig
+++ b/Kconfig
@@ -2196,41 +2196,40 @@ config DEBUG_IPC_INFO
 
 endif # DEBUG_IPC
 
-=======
-config DEBUG_PCIE
-       bool "PCI-E Debug Features"
+config DEBUG_PCI
+       bool "PCI Debug Features"
        default n
-       depends on PCIE
+       depends on PCI
        ---help---
-               Enable PCIE driver debug features.
+               Enable PCI driver debug features.
 
                Support for this debug option is architecture-specific and may 
not
                be available for some MCUs.
 
-if DEBUG_PCIE
+if DEBUG_PCI
 
-config DEBUG_PCIE_ERROR
-       bool "PCI-E Error Output"
+config DEBUG_PCI_ERROR
+       bool "PCI Error Output"
        default n
        depends on DEBUG_ERROR
        ---help---
-               Enable PCI-E driver error output to SYSLOG.
+               Enable PCI driver error output to SYSLOG.
 
-config DEBUG_PCIE_WARN
-       bool "PCI-E Warnings Output"
+config DEBUG_PCI_WARN
+       bool "PCI Warnings Output"
        default n
        depends on DEBUG_WARN
        ---help---
-               Enable PCI-E driver warning output to SYSLOG.
+               Enable PCI driver warning output to SYSLOG.
 
-config DEBUG_PCIE_INFO
-       bool "PCI-E Informational Output"
+config DEBUG_PCI_INFO
+       bool "PCI Informational Output"
        default n
        depends on DEBUG_INFO
        ---help---
-               Enable PCI-E driver informational output to SYSLOG.
+               Enable PCI driver informational output to SYSLOG.
 
-endif # DEBUG_PCIE
+endif # DEBUG_PCI
 endif # DEBUG_FEATURES
 
 config ARCH_HAVE_STACKCHECK
diff --git a/boards/x86_64/intel64/qemu-intel64/Kconfig 
b/boards/x86_64/intel64/qemu-intel64/Kconfig
index 595127192b..c9c77b73a4 100644
--- a/boards/x86_64/intel64/qemu-intel64/Kconfig
+++ b/boards/x86_64/intel64/qemu-intel64/Kconfig
@@ -3,10 +3,10 @@
 # see the file kconfig-language.txt in the NuttX tools repository.
 #
 #
-config QEMU_PCIE
-       bool "Initialize and enumerate PCI-E Bus"
+config QEMU_PCI
+       bool "Initialize and enumerate PCI Bus"
        default n
-       select PCIE
+       select PCI
 
        ---help---
-               Enables initialization and scaning of standard x86-64 pcie bus.
+               Enables initialization and scanning of standard x86-64 pci bus.
diff --git a/boards/x86_64/intel64/qemu-intel64/configs/pcitest/defconfig 
b/boards/x86_64/intel64/qemu-intel64/configs/pcitest/defconfig
new file mode 100644
index 0000000000..61e33fb0eb
--- /dev/null
+++ b/boards/x86_64/intel64/qemu-intel64/configs/pcitest/defconfig
@@ -0,0 +1,76 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed 
.config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that 
includes your
+# modifications.
+#
+CONFIG_16550_ADDRWIDTH=16
+CONFIG_16550_UART0=y
+CONFIG_16550_UART0_BASE=0x3f8
+CONFIG_16550_UART0_CLOCK=1843200
+CONFIG_16550_UART0_IRQ=36
+CONFIG_16550_UART0_RXBUFSIZE=16
+CONFIG_16550_UART0_SERIAL_CONSOLE=y
+CONFIG_16550_UART0_TXBUFSIZE=16
+CONFIG_16550_UART=y
+CONFIG_ARCH="x86_64"
+CONFIG_ARCH_BOARD="qemu-intel64"
+CONFIG_ARCH_BOARD_INTEL64_QEMU=y
+CONFIG_ARCH_CHIP="intel64"
+CONFIG_ARCH_INTEL64_CORE_FREQ_KHZ=2600000
+CONFIG_ARCH_SIZET_LONG=y
+CONFIG_ARCH_X86_64=y
+CONFIG_BOARD_LOOPSPERMSEC=999
+CONFIG_BOOT_RUNFROMEXTSRAM=y
+CONFIG_BUILTIN=y
+CONFIG_CLOCK_MONOTONIC=y
+CONFIG_CONSOLE_SYSLOG=y
+CONFIG_DEBUG_ERROR=y
+CONFIG_DEBUG_FEATURES=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_PCI=y
+CONFIG_DEBUG_PCI_ERROR=y
+CONFIG_DEBUG_PCI_INFO=y
+CONFIG_DEBUG_PCI_WARN=y
+CONFIG_DEBUG_WARN=y
+CONFIG_EXAMPLES_HELLO=y
+CONFIG_EXAMPLES_HELLO_STACKSIZE=4194304
+CONFIG_FS_PROCFS=y
+CONFIG_IDLETHREAD_STACKSIZE=4194304
+CONFIG_LIBM=y
+CONFIG_MAX_TASKS=64
+CONFIG_NFILE_DESCRIPTORS=32
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_DISABLE_IFCONFIG=y
+CONFIG_NSH_DISABLE_IFUPDOWN=y
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_CHILDSTATUS=16
+CONFIG_PRIORITY_INHERITANCE=y
+CONFIG_PTHREAD_MUTEX_TYPES=y
+CONFIG_PTHREAD_STACK_DEFAULT=4194304
+CONFIG_PTHREAD_STACK_MIN=4194304
+CONFIG_QEMU_PCI=y
+CONFIG_RAM_SIZE=268435456
+CONFIG_SCHED_CHILD_STATUS=y
+CONFIG_SCHED_HAVE_PARENT=y
+CONFIG_SCHED_IRQMONITOR=y
+CONFIG_SCHED_TICKLESS=y
+CONFIG_SCHED_TICKLESS_ALARM=y
+CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP=y
+CONFIG_SCHED_WAITPID=y
+CONFIG_SDCLONE_DISABLE=y
+CONFIG_SIG_DEFAULT=y
+CONFIG_START_DAY=3
+CONFIG_START_MONTH=3
+CONFIG_START_YEAR=2011
+CONFIG_SYSTEM_CLE=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_SYSTEM_TIME64=y
+CONFIG_USEC_PER_TICK=1
+CONFIG_USERMAIN_STACKSIZE=4194304
+CONFIG_USER_ENTRYPOINT="nsh_main"
+CONFIG_VIRT=y
+CONFIG_VIRT_QEMU_EDU=y
+CONFIG_VIRT_QEMU_PCI_TEST=y
diff --git a/boards/x86_64/intel64/qemu-intel64/include/board.h 
b/boards/x86_64/intel64/qemu-intel64/include/board.h
index ae7b588407..9cb23e995b 100644
--- a/boards/x86_64/intel64/qemu-intel64/include/board.h
+++ b/boards/x86_64/intel64/qemu-intel64/include/board.h
@@ -66,8 +66,6 @@ extern "C"
  * Public Function Prototypes
  ****************************************************************************/
 
-void qemu_pcie_init(void);
-
 #undef EXTERN
 #if defined(__cplusplus)
 }
diff --git a/boards/x86_64/intel64/qemu-intel64/src/Makefile 
b/boards/x86_64/intel64/qemu-intel64/src/Makefile
index 9ab32d1766..3441ce24e8 100644
--- a/boards/x86_64/intel64/qemu-intel64/src/Makefile
+++ b/boards/x86_64/intel64/qemu-intel64/src/Makefile
@@ -26,8 +26,8 @@ ifeq ($(CONFIG_BOARDCTL),y)
   CSRCS += qemu_appinit.c
 endif
 
-ifeq ($(CONFIG_QEMU_PCIE),y)
-  CSRCS += qemu_pcie.c
+ifeq ($(CONFIG_QEMU_PCI),y)
+  CSRCS += qemu_pci.c
 endif
 
 include $(TOPDIR)/boards/Board.mk
diff --git a/boards/x86_64/intel64/qemu-intel64/src/qemu_boot.c 
b/boards/x86_64/intel64/qemu-intel64/src/qemu_boot.c
index d4b02b1926..32cdcb33ec 100644
--- a/boards/x86_64/intel64/qemu-intel64/src/qemu_boot.c
+++ b/boards/x86_64/intel64/qemu-intel64/src/qemu_boot.c
@@ -66,12 +66,6 @@ void x86_64_boardinitialize(void)
   uart_putreg(CONFIG_16550_UART1_BASE, UART_MCR_OFFSET, UART_MCR_OUT2);
 #endif
 
-#ifdef CONFIG_QEMU_PCIE
-  /* Initialization of system */
-
-  qemu_pcie_init();
-#endif
-
   /* Configure on-board LEDs if LED support has been selected. */
 
 #ifdef CONFIG_ARCH_LEDS
diff --git a/boards/x86_64/intel64/qemu-intel64/src/qemu_bringup.c 
b/boards/x86_64/intel64/qemu-intel64/src/qemu_bringup.c
index 7cd5d55137..bf0112a4e5 100644
--- a/boards/x86_64/intel64/qemu-intel64/src/qemu_bringup.c
+++ b/boards/x86_64/intel64/qemu-intel64/src/qemu_bringup.c
@@ -57,5 +57,10 @@ int qemu_bringup(void)
     }
 #endif
 
+#ifdef CONFIG_QEMU_PCI
+  /* Initialization of system */
+
+  qemu_pci_init();
+#endif
   return ret;
 }
diff --git a/boards/x86_64/intel64/qemu-intel64/src/qemu_intel64.h 
b/boards/x86_64/intel64/qemu-intel64/src/qemu_intel64.h
index 9a711ee577..75989d0e25 100644
--- a/boards/x86_64/intel64/qemu-intel64/src/qemu_intel64.h
+++ b/boards/x86_64/intel64/qemu-intel64/src/qemu_intel64.h
@@ -48,6 +48,8 @@
  * Public Function Prototypes
  ****************************************************************************/
 
+void qemu_pci_init(void);
+
 int qemu_bringup(void);
 
 #endif /* __ASSEMBLY__ */
diff --git a/boards/x86_64/intel64/qemu-intel64/src/qemu_pci.c 
b/boards/x86_64/intel64/qemu-intel64/src/qemu_pci.c
new file mode 100644
index 0000000000..d2bbd79102
--- /dev/null
+++ b/boards/x86_64/intel64/qemu-intel64/src/qemu_pci.c
@@ -0,0 +1,226 @@
+/****************************************************************************
+ * boards/x86_64/intel64/qemu-intel64/src/qemu_pci.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 <debug.h>
+
+#include <nuttx/pci/pci.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define PCI_CFG_ADDR       0xcf8
+#define PCI_DATA_ADDR      0xcfc
+#define PCI_CFG_EN         (1 << 31)
+
+/****************************************************************************
+ * Private Functions Definitions
+ ****************************************************************************/
+
+static void qemu_pci_cfg_write(FAR struct pci_dev_s *dev, int reg,
+                              uint32_t val, int width);
+
+static uint32_t qemu_pci_cfg_read(FAR struct pci_dev_s *dev, int reg,
+                                  int width);
+
+static int qemu_pci_map_bar(uint64_t addr, uint64_t len);
+
+static uint32_t qemu_pci_io_read(FAR const volatile void *addr, int width);
+
+static void qemu_pci_io_write(FAR const volatile void *addr, uint32_t val,
+                              int width);
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+struct pci_bus_ops_s qemu_pci_bus_ops =
+{
+    .pci_cfg_write     =   qemu_pci_cfg_write,
+    .pci_cfg_read      =   qemu_pci_cfg_read,
+    .pci_map_bar       =   qemu_pci_map_bar,
+    .pci_io_read       =   qemu_pci_io_read,
+    .pci_io_write      =   qemu_pci_io_write,
+};
+
+struct pci_bus_s qemu_pci_bus =
+{
+    .ops = &qemu_pci_bus_ops,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: qemu_pci_cfg_write
+ *
+ * Description:
+ *  Write 8, 16, 32, 64 bits data to PCI-E configuration space of device
+ *  specified by dev
+ *
+ * Input Parameters:
+ *   bdf    - Device private data
+ *   reg - A pointer to the read-only buffer of data to be written
+ *   size   - The number of bytes to send from the buffer
+ *
+ * Returned Value:
+ *   0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+static void qemu_pci_cfg_write(FAR struct pci_dev_s *dev, int reg,
+                               uint32_t val, int width)
+{
+  uint8_t offset_mask = (4 - width);
+  outl(PCI_CFG_EN | (dev->bdf << 8) | reg, PCI_CFG_ADDR);
+  switch (width)
+    {
+      case 1:
+        outb(val, PCI_DATA_ADDR + (reg & offset_mask));
+        return;
+      case 2:
+        outw(val, PCI_DATA_ADDR + (reg & offset_mask));
+        return;
+      case 4:
+        outl(val, PCI_DATA_ADDR);
+        return;
+      default:
+        pcierr("Invalid cfg write width %d\n", width);
+    }
+}
+
+/****************************************************************************
+ * Name: qemu_pci_cfg_read
+ *
+ * Description:
+ *  Read 8, 16, 32, 64 bits data from PCI-E configuration space of device
+ *  specified by dev
+ *
+ * Input Parameters:
+ *   dev    - Device private data
+ *   buffer - A pointer to a buffer to receive the data from the device
+ *   size   - The requested number of bytes to be read
+ *
+ * Returned Value:
+ *   0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+static uint32_t qemu_pci_cfg_read(FAR struct pci_dev_s *dev, int reg,
+                                  int width)
+{
+  uint32_t ret;
+  uint8_t offset_mask = 4 - width;
+  outl(PCI_CFG_EN | (dev->bdf << 8) | reg, PCI_CFG_ADDR);
+
+  switch (width)
+    {
+      case 1:
+        ret = inb(PCI_DATA_ADDR + (reg & offset_mask));
+        return ret;
+
+      case 2:
+        ret = inw(PCI_DATA_ADDR + (reg & offset_mask));
+        return ret;
+      case 4:
+        ret = inl(PCI_DATA_ADDR);
+        return ret;
+      default:
+        pcierr("Invalid cfg read width %d\n", width);
+    }
+
+  return 0;
+}
+
+static uint32_t qemu_pci_io_read(FAR const volatile void *addr, int width)
+{
+  uint16_t portaddr = (uint16_t)(intptr_t)addr;
+  switch (width)
+  {
+    case 1:
+      return (uint32_t)inb(portaddr);
+    case 2:
+      return (uint32_t)inw(portaddr);
+    case 4:
+      return (uint32_t)inl(portaddr);
+    default:
+      pcierr("Invalid read width %d\n", width);
+      DEBUGPANIC();
+  }
+
+  return 0;
+}
+
+static void qemu_pci_io_write(FAR const volatile void *addr, uint32_t val,
+                              int width)
+{
+  uint16_t portaddr = (uint16_t)(intptr_t)addr;
+  switch (width)
+  {
+    case 1:
+      outb((uint8_t)val, portaddr);
+      return;
+    case 2:
+      outw((uint8_t)val, portaddr);
+      return;
+    case 4:
+      outl((uint8_t)val, portaddr);
+      return;
+    default:
+      pcierr("Invalid write width %d\n", width);
+      DEBUGPANIC();
+  }
+}
+
+static int qemu_pci_map_bar(uint64_t addr, uint64_t len)
+{
+  up_map_region((void *)(uintptr_t)addr, len,
+      X86_PAGE_WR | X86_PAGE_PRESENT | X86_PAGE_NOCACHE | X86_PAGE_GLOBAL);
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: qemu_pci_init
+ *
+ * Description:
+ *  Initialize the PCI-E bus *
+ *
+ ****************************************************************************/
+
+void qemu_pci_init(void)
+{
+  pciinfo("Initializing PCI Bus\n");
+  pci_initialize(&qemu_pci_bus);
+}
diff --git a/boards/x86_64/intel64/qemu-intel64/src/qemu_pcie.c 
b/boards/x86_64/intel64/qemu-intel64/src/qemu_pcie.c
deleted file mode 100644
index 0580593fad..0000000000
--- a/boards/x86_64/intel64/qemu-intel64/src/qemu_pcie.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/****************************************************************************
- * boards/x86_64/intel64/qemu-intel64/src/qemu_pcie.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.
- *
- ****************************************************************************/
-
-/* The MSI and MSI-X vector setup function are taken from Jailhouse inmate
- * library
- *
- * Jailhouse, a Linux-based partitioning hypervisor
- *
- * Copyright (c) Siemens AG, 2014
- *
- * Authors:
- *  Jan Kiszka <jan.kis...@siemens.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- * Alternatively, you can use or redistribute this file under the following
- * BSD license:
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <assert.h>
-
-#include <nuttx/pcie/pcie.h>
-
-#include "qemu_pcie_readwrite.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions Definitions
- ****************************************************************************/
-
-static int qemu_pci_cfg_write(FAR struct pcie_dev_s *dev, uintptr_t addr,
-                              FAR const void *buffer, unsigned int size);
-
-static int qemu_pci_cfg_read(FAR struct pcie_dev_s *dev, uintptr_t addr,
-                             FAR void *buffer, unsigned int size);
-
-static int qemu_pci_map_bar(FAR struct pcie_dev_s *dev, uint32_t addr,
-                            unsigned long length);
-
-static int qemu_pci_map_bar64(FAR struct pcie_dev_s *dev, uint64_t addr,
-                              unsigned long length);
-
-static int qemu_pci_msix_register(FAR struct pcie_dev_s *dev,
-                                  uint32_t vector, uint32_t index);
-
-static int qemu_pci_msi_register(FAR struct pcie_dev_s *dev,
-                                 uint16_t vector);
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-struct pcie_bus_ops_s qemu_pcie_bus_ops =
-{
-    .pci_cfg_write     =   qemu_pci_cfg_write,
-    .pci_cfg_read      =   qemu_pci_cfg_read,
-    .pci_map_bar       =   qemu_pci_map_bar,
-    .pci_map_bar64     =   qemu_pci_map_bar64,
-    .pci_msix_register = qemu_pci_msix_register,
-    .pci_msi_register  = qemu_pci_msi_register,
-};
-
-struct pcie_bus_s qemu_pcie_bus =
-{
-    .ops = &qemu_pcie_bus_ops,
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: qemu_pci_cfg_write
- *
- * Description:
- *  Write 8, 16, 32, 64 bits data to PCI-E configuration space of device
- *  specified by dev
- *
- * Input Parameters:
- *   bdf    - Device private data
- *   buffer - A pointer to the read-only buffer of data to be written
- *   size   - The number of bytes to send from the buffer
- *
- * Returned Value:
- *   0: success, <0: A negated errno
- *
- ****************************************************************************/
-
-static int qemu_pci_cfg_write(FAR struct pcie_dev_s *dev, uintptr_t addr,
-                              FAR const void *buffer, unsigned int size)
-{
-  if (!buffer)
-      return -EINVAL;
-
-  switch (size)
-    {
-      case 1:
-      case 2:
-      case 4:
-        return __qemu_pci_cfg_write(dev->bdf, addr, buffer, size);
-      case 8:
-        return __qemu_pci_cfg_write(dev->bdf, addr, buffer, size);
-      default:
-        return -EINVAL;
-    }
-}
-
-/****************************************************************************
- * Name: qemu_pci_cfg_read
- *
- * Description:
- *  Read 8, 16, 32, 64 bits data from PCI-E configuration space of device
- *  specified by dev
- *
- * Input Parameters:
- *   dev    - Device private data
- *   buffer - A pointer to a buffer to receive the data from the device
- *   size   - The requested number of bytes to be read
- *
- * Returned Value:
- *   0: success, <0: A negated errno
- *
- ****************************************************************************/
-
-static int qemu_pci_cfg_read(FAR struct pcie_dev_s *dev, uintptr_t addr,
-                             FAR void *buffer, unsigned int size)
-{
-  if (!buffer)
-      return -EINVAL;
-
-  switch (size)
-    {
-      case 1:
-      case 2:
-      case 4:
-        return __qemu_pci_cfg_read(dev->bdf, addr, buffer, size);
-      case 8:
-        return __qemu_pci_cfg_read64(dev->bdf, addr, buffer, size);
-      default:
-        return -EINVAL;
-    }
-}
-
-/****************************************************************************
- * Name: qemu_pci_map_bar
- *
- * Description:
- *  Map address in a 32 bits bar in the memory address space
- *
- * Input Parameters:
- *   dev    - Device private data
- *   bar    - Bar number
- *   length - Map length, multiple of PAGE_SIZE
- *   ret    - Bar Content
- *
- * Returned Value:
- *   0: success, <0: A negated errno
- *
- ****************************************************************************/
-
-static int qemu_pci_map_bar(FAR struct pcie_dev_s *dev, uint32_t addr,
-                            unsigned long length)
-{
-  up_map_region((void *)((uintptr_t)addr), length,
-      X86_PAGE_WR | X86_PAGE_PRESENT | X86_PAGE_NOCACHE | X86_PAGE_GLOBAL);
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: qemu_pci_map_bar64
- *
- * Description:
- *  Map address in a 64 bits bar in the memory address space
- *
- * Input Parameters:
- *   dev    - Device private data
- *   bar    - Bar number
- *   length - Map length, multiple of PAGE_SIZE
- *   ret    - Bar Content
- *
- * Returned Value:
- *   0: success, <0: A negated errno
- *
- ****************************************************************************/
-
-static int qemu_pci_map_bar64(FAR struct pcie_dev_s *dev, uint64_t addr,
-                              unsigned long length)
-{
-  up_map_region((void *)((uintptr_t)addr), length,
-      X86_PAGE_WR | X86_PAGE_PRESENT | X86_PAGE_NOCACHE | X86_PAGE_GLOBAL);
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: qemu_pci_msix_register
- *
- * Description:
- *  Map a device MSI-X vector to a platform IRQ vector
- *
- * Input Parameters:
- *   dev - Device
- *   vector - IRQ number of the platform
- *   index  - Device MSI-X vector number
- *
- * Returned Value:
- *   <0: Mapping failed
- *    0: Mapping succeed
- *
- ****************************************************************************/
-
-static int qemu_pci_msix_register(FAR struct pcie_dev_s *dev,
-                                  uint32_t vector, uint32_t index)
-{
-  unsigned int bar;
-  uint16_t message_control;
-  uint32_t table_bar_ind;
-  uint32_t table_addr_32;
-  uint64_t msix_table_addr = 0;
-
-  int cap = pci_find_cap(dev, PCI_CAP_MSIX);
-  if (cap < 0)
-      return -EINVAL;
-
-  __qemu_pci_cfg_read(dev->bdf, cap + PCI_MSIX_MCR,
-                      &message_control, PCI_MSIX_MCR_SIZE);
-
-  /* bounds check */
-
-  if (index > (message_control & PCI_MSIX_MCR_TBL_MASK))
-      return -EINVAL;
-
-  __qemu_pci_cfg_read(dev->bdf, cap + PCI_MSIX_TBL,
-                      &table_bar_ind, PCI_MSIX_TBL_SIZE);
-
-  bar = (table_bar_ind & PCI_MSIX_BIR_MASK);
-
-  if (!pci_get_bar(dev, bar, &table_addr_32))
-    {
-      /* 32 bit bar */
-
-      msix_table_addr = table_addr_32;
-    }
-  else
-    {
-      pci_get_bar64(dev, bar, &msix_table_addr);
-    }
-
-  msix_table_addr &= ~0xf;
-  msix_table_addr += table_bar_ind & ~PCI_MSIX_BIR_MASK;
-
-  /* enable and mask */
-
-  message_control |= (PCI_MSIX_MCR_EN | PCI_MSIX_MCR_FMASK);
-  __qemu_pci_cfg_write(dev->bdf, cap + PCI_MSIX_MCR,
-                       &message_control, PCI_MSIX_MCR_SIZE);
-
-  msix_table_addr += PCI_MSIX_TBL_ENTRY_SIZE * index;
-  mmio_write32((uint32_t *)(msix_table_addr + PCI_MSIX_TBL_LO_ADDR),
-               0xfee00000 | up_apic_cpu_id() << PCI_MSIX_APIC_ID_OFFSET);
-  mmio_write32((uint32_t *)(msix_table_addr + PCI_MSIX_TBL_HI_ADDR),
-               0);
-  mmio_write32((uint32_t *)(msix_table_addr + PCI_MSIX_TBL_MSG_DATA),
-               vector);
-  mmio_write32((uint32_t *)(msix_table_addr + PCI_MSIX_TBL_VEC_CTL),
-               0);
-
-  /* enable and unmask */
-
-  message_control &= ~PCI_MSIX_MCR_FMASK;
-
-  __qemu_pci_cfg_write(dev->bdf, cap + PCI_MSIX_MCR,
-                       &message_control, PCI_MSIX_MCR_SIZE);
-
-  return 0;
-}
-
-/****************************************************************************
- * Name: qemu_pci_msi_register
- *
- * Description:
- *  Map device MSI vectors to a platform IRQ vector
- *
- * Input Parameters:
- *   dev - Device
- *   vector - IRQ number of the platform
- *
- * Returned Value:
- *   <0: Mapping failed
- *    0: Mapping succeed
- *
- ****************************************************************************/
-
-static int qemu_pci_msi_register(FAR struct pcie_dev_s *dev, uint16_t vector)
-{
-  uint16_t ctl;
-  uint16_t data;
-
-  int cap = pci_find_cap(dev, PCI_CAP_MSI);
-  if (cap < 0)
-      return -1;
-
-  uint32_t dest = 0xfee00000 | (up_apic_cpu_id() << PCI_MSI_APIC_ID_OFFSET);
-  __qemu_pci_cfg_write(dev->bdf, cap + PCI_MSI_MAR, &dest, PCI_MSI_MAR_SIZE);
-
-  __qemu_pci_cfg_read(dev->bdf, cap + PCI_MSI_MCR, &ctl, PCI_MSI_MCR_SIZE);
-  if ((ctl & PCI_MSI_MCR_64) == PCI_MSI_MCR_64)
-    {
-      uint32_t tmp = 0;
-      __qemu_pci_cfg_write(dev->bdf,
-                           cap + PCI_MSI_MAR64_HI, &tmp,
-                           PCI_MSI_MAR64_HI_SIZE);
-      data = cap + PCI_MSI_MDR64;
-    }
-  else
-    {
-      data = cap + PCI_MSI_MDR;
-    }
-
-  __qemu_pci_cfg_write(dev->bdf, data, &vector, PCI_MSI_MDR_SIZE);
-
-  __qemu_pci_cfg_write(dev->bdf, cap + PCI_MSI_MCR, &vector,
-                       PCI_MSI_MCR_SIZE);
-
-  uint16_t tmp = PCI_MSI_MCR_EN;
-
-  __qemu_pci_cfg_write(dev->bdf, cap + PCI_MSI_MCR, &tmp, PCI_MSI_MCR_SIZE);
-
-  return OK;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: qemu_pcie_init
- *
- * Description:
- *  Initialize the PCI-E bus *
- *
- ****************************************************************************/
-
-void qemu_pcie_init(void)
-{
-  pcie_initialize(&qemu_pcie_bus);
-}
diff --git a/boards/x86_64/intel64/qemu-intel64/src/qemu_pcie_readwrite.h 
b/boards/x86_64/intel64/qemu-intel64/src/qemu_pcie_readwrite.h
deleted file mode 100644
index 01fc2712fe..0000000000
--- a/boards/x86_64/intel64/qemu-intel64/src/qemu_pcie_readwrite.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/****************************************************************************
- * boards/x86_64/intel64/qemu-intel64/src/qemu_pcie_readwrite.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.
- *
- ****************************************************************************/
-
-/* The PCI-E Definitions and part of the access routines are taken from
- * Jailhouse inmate library
- *
- * Jailhouse, a Linux-based partitioning hypervisor
- *
- * Copyright (c) Siemens AG, 2014
- *
- * Authors:
- *  Jan Kiszka <jan.kis...@siemens.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- * Alternatively, you can use or redistribute this file under the following
- * BSD license:
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __INCLUDE_NUTTX_PCIE_PCIE_READWRITE_H
-#define __INCLUDE_NUTTX_PCIE_PCIE_READWRITE_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <assert.h>
-
-#include <nuttx/pcie/pcie.h>
-
-#include <nuttx/board.h>
-#include <arch/board/board.h>
-
-#include "up_arch.h"
-#include "up_internal.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-#define PCI_REG_ADDR_PORT       0xcf8
-#define PCI_REG_DATA_PORT       0xcfc
-
-#define PCI_CONE                (1 << 31)
-
-/****************************************************************************
- * Name: __qemu_pci_cfg_write
- *
- * Description:
- *  Write 8, 16, 32 bits data to PCI-E configuration space of device
- *  specified by dev
- *
- * Input Parameters:
- *   bfd    - Device private data
- *   buffer - A pointer to the read-only buffer of data to be written
- *   size   - The number of bytes to send from the buffer
- *
- * Returned Value:
- *   0: success, <0: A negated errno
- *
- ****************************************************************************/
-
-static inline int __qemu_pci_cfg_write(uint16_t bfd, uintptr_t addr,
-                                       FAR const void *buffer,
-                                       unsigned int size)
-{
-  if (!buffer)
-      return -EINVAL;
-
-  outl(PCI_CONE | ((uint32_t)bfd << 8) | (addr & 0xfc), PCI_REG_ADDR_PORT);
-
-  switch (size)
-    {
-      case 1:
-        outb(*(uint8_t *)(buffer), PCI_REG_DATA_PORT + (addr & 0x3));
-        break;
-      case 2:
-        outw(*(uint16_t *)(buffer), PCI_REG_DATA_PORT + (addr & 0x3));
-        break;
-      case 4:
-        outl(*(uint32_t *)(buffer), PCI_REG_DATA_PORT);
-        break;
-      default:
-        return -EINVAL;
-    }
-  return OK;
-}
-
-/****************************************************************************
- * Name: __qemu_pci_cfg_write64
- *
- * Description:
- *  Write 64 bits data to PCI-E configuration space of device
- *  specified by dev
- *
- * Input Parameters:
- *   bfd    - Device private data
- *   buffer - A pointer to the read-only buffer of data to be written
- *   size   - The number of bytes to send from the buffer
- *
- * Returned Value:
- *   0: success, <0: A negated errno
- *
- ****************************************************************************/
-
-static inline int __qemu_pci_cfg_write64(uint16_t bfd, uintptr_t addr,
-                                         FAR const void *buffer,
-                                         unsigned int size)
-{
-  int ret;
-
-  if (!buffer)
-      return -EINVAL;
-
-  ret = __qemu_pci_cfg_write(bfd, addr + 4, buffer + 4, 4);
-  ret |= __qemu_pci_cfg_write(bfd, addr, buffer, 4);
-
-  return ret;
-}
-
-/****************************************************************************
- * Name: __qemu_pci_cfg_read
- *
- * Description:
- *  Read 8, 16, 32 bits data from PCI-E configuration space of device
- *  specified by dev
- *
- * Input Parameters:
- *   dev    - Device private data
- *   buffer - A pointer to a buffer to receive the data from the device
- *   size   - The requested number of bytes to be read
- *
- * Returned Value:
- *   0: success, <0: A negated errno
- *
- ****************************************************************************/
-
-static inline int __qemu_pci_cfg_read(uint16_t bfd, uintptr_t addr,
-                                      FAR void *buffer, unsigned int size)
-{
-  if (!buffer)
-      return -EINVAL;
-
-  outl(PCI_CONE | ((uint32_t)bfd << 8) | (addr & 0xfc), PCI_REG_ADDR_PORT);
-
-  switch (size)
-    {
-      case 1:
-        *(uint8_t *)(buffer) = inb(PCI_REG_DATA_PORT + (addr & 0x3));
-        break;
-      case 2:
-        *(uint16_t *)(buffer) = inw(PCI_REG_DATA_PORT + (addr & 0x3));
-        break;
-      case 4:
-        *(uint32_t *)(buffer) = inl(PCI_REG_DATA_PORT);
-        break;
-      default:
-        return -EINVAL;
-    }
-
-    return OK;
-}
-
-/****************************************************************************
- * Name: __qemu_pci_cfg_read
- *
- * Description:
- *  Read 64 bits data from PCI-E configuration space of device
- *  specified by dev
- *
- * Input Parameters:
- *   dev    - Device private data
- *   buffer - A pointer to a buffer to receive the data from the device
- *   size   - The requested number of bytes to be read
- *
- * Returned Value:
- *   0: success, <0: A negated errno
- *
- ****************************************************************************/
-
-static inline int __qemu_pci_cfg_read64(uint16_t bfd,
-                                        uintptr_t addr,
-                                        FAR void *buffer,
-                                        unsigned int size)
-{
-  int ret;
-
-  if (!buffer)
-      return -EINVAL;
-
-  ret = __qemu_pci_cfg_read(bfd, addr + 4, buffer + 4, 4);
-  ret |= __qemu_pci_cfg_read(bfd, addr, buffer, 4);
-
-  return ret;
-}
-
-#endif /* __INCLUDE_NUTTX_PCIE_PCIE_READWRITE_H */
diff --git a/drivers/Kconfig b/drivers/Kconfig
index da93ca190f..22603be331 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -59,5 +59,5 @@ source "drivers/usrsock/Kconfig"
 source "drivers/dma/Kconfig"
 source "drivers/devicetree/Kconfig"
 source "drivers/reset/Kconfig"
-source "drivers/pcie/Kconfig"
+source "drivers/pci/Kconfig"
 source "drivers/virt/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index f5584c5370..40ed2d38af 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -77,7 +77,7 @@ include rc/Make.defs
 include segger/Make.defs
 include usrsock/Make.defs
 include reset/Make.defs
-include pcie/Make.defs
+include pci/Make.defs
 include virt/Make.defs
 
 ifeq ($(CONFIG_SPECIFIC_DRIVERS),y)
diff --git a/boards/x86_64/intel64/qemu-intel64/Kconfig b/drivers/pci/Kconfig
similarity index 51%
copy from boards/x86_64/intel64/qemu-intel64/Kconfig
copy to drivers/pci/Kconfig
index 595127192b..85aa4a7988 100644
--- a/boards/x86_64/intel64/qemu-intel64/Kconfig
+++ b/drivers/pci/Kconfig
@@ -2,11 +2,10 @@
 # For a description of the syntax of this configuration file,
 # see the file kconfig-language.txt in the NuttX tools repository.
 #
-#
-config QEMU_PCIE
-       bool "Initialize and enumerate PCI-E Bus"
-       default n
-       select PCIE
 
+menuconfig PCI
+       bool "Support for PCI Bus"
+       default n
        ---help---
-               Enables initialization and scaning of standard x86-64 pcie bus.
+               Enables support for the PCI bus.
+               Backend bust be provided by per-arch or per-board 
implementation.
diff --git a/drivers/pcie/Make.defs b/drivers/pci/Make.defs
similarity index 85%
rename from drivers/pcie/Make.defs
rename to drivers/pci/Make.defs
index 68efee8123..d890993e62 100644
--- a/drivers/pcie/Make.defs
+++ b/drivers/pci/Make.defs
@@ -1,5 +1,5 @@
 ############################################################################
-# drivers/pcie/Make.defs
+# drivers/pci/Make.defs
 #
 # Licensed to the Apache Software Foundation (ASF) under one or more
 # contributor license agreements.  See the NOTICE file distributed with
@@ -20,13 +20,13 @@
 
 # Don't build anything if there is no CAN support
 
-ifeq ($(CONFIG_PCIE),y)
+ifeq ($(CONFIG_PCI),y)
 
-CSRCS += pcie_root.c
+CSRCS += pci.c
 
-# Include PCIE device driver build support
+# Include PCI device driver build support
 
-DEPPATH += --dep-path pcie
-VPATH += :pcie
-CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" 
$(TOPDIR)$(DELIM)drivers$(DELIM)pcie}
+DEPPATH += --dep-path pci
+VPATH += :pci
+CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" 
$(TOPDIR)$(DELIM)drivers$(DELIM)pci}
 endif
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
new file mode 100644
index 0000000000..0ae67a515d
--- /dev/null
+++ b/drivers/pci/pci.c
@@ -0,0 +1,792 @@
+/****************************************************************************
+ * nuttx/drivers/pci/pci.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/pci/pci.h>
+#include <nuttx/virt/qemu_pci.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* For now hard code jailhouse as a flag. In the future we can determine this
+ * by looking at the CPUID base for "Jailhouse\0\0\0"
+ */
+
+#define JAILHOUSE_ENABLED 1
+
+#define PCI_BDF(bus, slot, func) (((uint32_t)bus << 8) | \
+                                  ((uint32_t)slot << 3) | \
+                                  func)
+
+/****************************************************************************
+ * Private Functions Definitions
+ ****************************************************************************/
+
+static void pci_probe_device(FAR struct pci_bus_s *root_bus,
+                             uint8_t bus_idx, uint8_t slot_idx, uint8_t func,
+                             FAR struct pci_dev_type_s **types);
+
+static uint8_t pci_check_pci_bridge(FAR struct pci_bus_s *root_bus,
+                                    uint8_t bus_idx, uint8_t slot_idx,
+                                    uint8_t dev_func);
+
+static void pci_scan_device(FAR struct pci_bus_s *root_bus,
+                            uint8_t bus_idx, uint8_t slot_idx,
+                            FAR struct pci_dev_type_s **types);
+
+static void pci_scan_bus(FAR struct pci_bus_s *root_bus,
+                         uint8_t bus_idx,
+                         FAR struct pci_dev_type_s **types);
+
+static void pci_set_cmd_bit(FAR struct pci_dev_s *dev, uint16_t bitmask);
+
+static void pci_clear_cmd_bit(FAR struct pci_dev_s *dev, uint16_t bitmask);
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+struct pci_dev_type_s *pci_device_types[] =
+{
+#ifdef CONFIG_VIRT_QEMU_PCI_TEST
+  &pci_type_qemu_pci_test,
+#endif /* CONFIG_VIRT_QEMU_PCI_TEST */
+#ifdef CONFIG_VIRT_QEMU_EDU
+  &pci_type_qemu_edu,
+#endif /* CONFIG_VIRT_QEMU_EDU */
+  NULL,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pci_probe
+ *
+ * Description:
+ *  Checks if the specified device is supported and if so calls probe on it
+ *
+ * Input Parameters:
+ *   root_bus - The root bus device that lets us address the whole tree
+ *   bus      - Bus ID
+ *   slot     - Device Slot
+ *   func     - Device Function
+ *   types    - List of pointers to devices types recognized, NULL terminated
+ *
+ ****************************************************************************/
+
+static void pci_probe_device(FAR struct pci_bus_s *root_bus,
+                             uint8_t bus_idx, uint8_t slot_idx, uint8_t func,
+                             FAR struct pci_dev_type_s **types)
+{
+  struct pci_dev_s tmp_dev;
+  uint16_t vid;
+  uint16_t id;
+  uint32_t class_rev;
+
+  tmp_dev.bus = root_bus;
+  tmp_dev.bdf = PCI_BDF(bus_idx, slot_idx, func);
+
+  vid = root_bus->ops->pci_cfg_read(&tmp_dev, PCI_CONFIG_VENDOR, 2);
+  id = root_bus->ops->pci_cfg_read(&tmp_dev, PCI_CONFIG_DEVICE, 2);
+
+  /* This is reading rev prog_if subclass and class */
+
+  class_rev = root_bus->ops->pci_cfg_read(&tmp_dev, PCI_CONFIG_REV_ID, 4);
+
+  pci_dev_dump(&tmp_dev);
+
+  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 == class_rev)
+                {
+                  pciinfo("Found: %s\n", types[i]->name);
+                  if (types[i]->probe)
+                    {
+                      pciinfo("[%02x:%02x.%x] Probing\n",
+                        bus_idx, slot_idx, func);
+                      types[i]->probe(root_bus, types[i], tmp_dev.bdf);
+                    }
+                  else
+                    {
+                      pcierr("[%02x:%02x.%x] Error: Invalid \
+                              device probe function\n",
+                              bus_idx, slot_idx, func);
+                    }
+                  break;
+                }
+            }
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: pci_check_pci_bridge
+ *
+ * Description:
+ *  Checks if the specified device is PCI bridge and return the sub-bridge
+ *  idx if found.  Otherwise return 0.
+ *
+ * Input Parameters:
+ *   root_bus - The root bus device that lets us address the whole tree
+ *   bus      - Bus ID
+ *   slot     - Device Slot
+ *   func     - Device Function
+ *
+ ****************************************************************************/
+
+static uint8_t pci_check_pci_bridge(FAR struct pci_bus_s *root_bus,
+                                    uint8_t bus_idx, uint8_t slot_idx,
+                                    uint8_t dev_func)
+{
+  struct pci_dev_s tmp_dev;
+  uint8_t base_class;
+  uint8_t sub_class;
+  uint8_t secondary_bus;
+
+  tmp_dev.bus = root_bus;
+  tmp_dev.bdf = PCI_BDF(bus_idx, slot_idx, dev_func);
+
+  /* Check if this is a PCI-PCI bridge device */
+
+  base_class = root_bus->ops->pci_cfg_read(&tmp_dev, PCI_CONFIG_CLASS, 1);
+  sub_class = root_bus->ops->pci_cfg_read(&tmp_dev, PCI_CONFIG_SUBCLASS, 1);
+
+  if ((base_class == PCI_CLASS_BASE_BRG_DEV) && \
+     (sub_class == PCI_CLASS_SUB_PCI_BRG))
+    {
+      /* This is a bridge device we need to determin the bus idx and
+       * enumerate it just like we do the root.
+       */
+
+      pciinfo("[%02x:%02x.%x] Found Bridge\n",
+        bus_idx, slot_idx, dev_func);
+
+      secondary_bus = root_bus->ops->pci_cfg_read(
+        &tmp_dev, PCI_CONFIG_SEC_BUS, 1);
+      return secondary_bus;
+    }
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: pci_scan_device
+ *
+ * Description:
+ *  Checks if the specified device is a bus and iterates over it or
+ *  if it is a real device initializes it if recognized.
+ *
+ * Input Parameters:
+ *   root_bus - The root bus device that lets us address the whole tree
+ *   bus      - Bus ID
+ *   slot     - Device Slot
+ *   types    - List of pointers to devices types recognized, NULL terminated
+ *
+ ****************************************************************************/
+
+static void pci_scan_device(FAR struct pci_bus_s *root_bus,
+                            uint8_t bus_idx, uint8_t slot_idx,
+                            FAR struct pci_dev_type_s **types)
+{
+  struct pci_dev_s tmp_dev;
+  uint8_t dev_func = 0;
+  uint16_t vid;
+  uint8_t sec_bus;
+  uint8_t multi_function;
+
+  tmp_dev.bus = root_bus;
+  tmp_dev.bdf = PCI_BDF(bus_idx, slot_idx, dev_func);
+  vid = root_bus->ops->pci_cfg_read(&tmp_dev, PCI_CONFIG_VENDOR, 2);
+  if (vid == 0xffff)
+      return;
+
+  /* Check if this is a PCI-PCI bridge device */
+
+  sec_bus = pci_check_pci_bridge(root_bus, bus_idx, slot_idx, dev_func);
+  if (sec_bus)
+    pci_scan_bus(root_bus, sec_bus, types);
+
+  multi_function = root_bus->ops->pci_cfg_read(
+    &tmp_dev, PCI_CONFIG_HEADER_TYPE, 1) & PCI_HEADER_MASK_MULTI;
+
+  /* Jailhouse breaks the PCI spec by allowing you to pass individual
+   * functions of a multi-function device.  In this case we need to
+   * scan each of the functions not just function 0.
+   */
+
+  if (multi_function || JAILHOUSE_ENABLED)
+    {
+      /* This is a multi-function device that we need to iterate over */
+
+      for (dev_func = 0; dev_func < 8; dev_func++)
+        {
+          tmp_dev.bdf = PCI_BDF(bus_idx, slot_idx, dev_func);
+          vid = root_bus->ops->pci_cfg_read(&tmp_dev, PCI_CONFIG_VENDOR, 2);
+          if (vid != 0xffff)
+            {
+              sec_bus = pci_check_pci_bridge(
+                root_bus, bus_idx, slot_idx, dev_func);
+              if (sec_bus)
+                {
+                  pci_scan_bus(root_bus, sec_bus, types);
+                  continue;
+                }
+
+              pci_probe_device(root_bus, bus_idx, slot_idx, dev_func, types);
+            }
+        }
+    }
+  else
+    {
+      pci_probe_device(root_bus, bus_idx, slot_idx, dev_func, types);
+    }
+}
+
+/****************************************************************************
+ * Name: pci_scan_bus
+ *
+ * Description:
+ *  Iterates over all slots on bus looking for devices and buses to
+ *  enumerate.
+ *
+ * Input Parameters:
+ *   root_bus - The root bus device that lets us address the whole tree
+ *   bus      - Bus ID
+ *   types    - List of pointers to devices types recognized, NULL terminated
+ *
+ ****************************************************************************/
+
+static void pci_scan_bus(FAR struct pci_bus_s *root_bus,
+                         uint8_t bus_idx,
+                         FAR struct pci_dev_type_s **types)
+{
+  uint8_t slot_idx;
+
+  for (slot_idx = 0; slot_idx < 32; slot_idx++)
+    {
+      pci_scan_device(root_bus, bus_idx, slot_idx, types);
+    }
+
+  return;
+}
+
+/****************************************************************************
+ * Name: pci_set_cmd_bit
+ *
+ * Description:
+ *  This sets an individual bit in the command register for a device.
+ *
+ * Input Parameters:
+ *   dev - device
+ *   bit - Bit to set
+ *
+ ****************************************************************************/
+
+static void pci_set_cmd_bit(FAR struct pci_dev_s *dev, uint16_t bitmask)
+{
+  uint16_t     cmd;
+
+  cmd = dev->bus->ops->pci_cfg_read(dev, PCI_CONFIG_COMMAND, 2);
+  dev->bus->ops->pci_cfg_write(dev, PCI_CONFIG_COMMAND,
+    (cmd | bitmask), 2);
+}
+
+/****************************************************************************
+ * Name: pci_clear_cmd_bit
+ *
+ * Description:
+ *  This clears an individual bit in the command register for a device.
+ *
+ * Input Parameters:
+ *   dev - device
+ *   bit - Bit to set
+ *
+ ****************************************************************************/
+
+static void pci_clear_cmd_bit(FAR struct pci_dev_s *dev, uint16_t bitmask)
+{
+  uint16_t     cmd;
+
+  cmd = dev->bus->ops->pci_cfg_read(dev, PCI_CONFIG_COMMAND, 2);
+  dev->bus->ops->pci_cfg_write(dev, PCI_CONFIG_COMMAND,
+    (cmd & ~bitmask), 2);
+}
+
+/****************************************************************************
+ * 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
+ *   types  - List of pointers to devices types recognized, NULL terminated
+ *
+ * Returned Value:
+ *   0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+int pci_enumerate(FAR struct pci_bus_s *bus,
+                  FAR struct pci_dev_type_s **types)
+{
+  if (!bus)
+      return -EINVAL;
+  if (!types)
+      return -EINVAL;
+
+  pci_scan_bus(bus, 0, types);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: pci_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 pci_initialize(FAR struct pci_bus_s *bus)
+{
+  return pci_enumerate(bus, pci_device_types);
+}
+
+/****************************************************************************
+ * Name: pci_enable_io
+ *
+ * Description:
+ *  Enable MMIO or IOPORT
+ *
+ * Input Parameters:
+ *   dev   - device
+ *   space - which resource is being enabled
+ *           PCI_SYS_RES_IOPORT for io port address decoding or
+ *           PCI_SYS_RES_MEM for memory
+ *
+ * Return value:
+ *   -EINVAL: error
+ *   OK: OK
+ *
+ ****************************************************************************/
+
+int pci_enable_io(FAR struct pci_dev_s *dev, int res)
+{
+  switch (res)
+    {
+    case PCI_SYS_RES_IOPORT:
+      pci_set_cmd_bit(dev, PCI_CMD_IO_SPACE);
+      return OK;
+    case PCI_SYS_RES_MEM:
+      pci_set_cmd_bit(dev, PCI_CMD_MEM_SPACE);
+      return OK;
+    }
+
+  return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: pci_disable_io
+ *
+ * Description:
+ *  Enable MMIO or IOPORT
+ *
+ * Input Parameters:
+ *   dev   - device
+ *   space - which resource is being disabled
+ *           PCI_SYS_RES_IOPORT for io port address decoding or
+ *           PCI_SYS_RES_MEM for memory
+ *
+ * Return value:
+ *   -EINVAL: error
+ *   OK: OK
+ *
+ ****************************************************************************/
+
+int pci_disable_io(FAR struct pci_dev_s *dev, int res)
+{
+  switch (res)
+    {
+    case PCI_SYS_RES_IOPORT:
+      pci_clear_cmd_bit(dev, PCI_CMD_IO_SPACE);
+      return OK;
+    case PCI_SYS_RES_MEM:
+      pci_clear_cmd_bit(dev, PCI_CMD_MEM_SPACE);
+      return OK;
+    }
+
+  return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: pci_enable_bus_master
+ *
+ * Description:
+ *  Enable bus mastering for device so it can perform PCI accesses
+ *
+ * Input Parameters:
+ *   dev   - device
+ *
+ * Return value:
+ *   -EINVAL: error
+ *   OK: OK
+ *
+ ****************************************************************************/
+
+int pci_enable_bus_master(FAR struct pci_dev_s *dev)
+{
+  pci_set_cmd_bit(dev, PCI_CMD_BUS_MSTR);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: pci_disable_bus_master
+ *
+ * Description:
+ *  Disable bus mastering for device
+ *
+ * Input Parameters:
+ *   dev   - device
+ *
+ * Return value:
+ *   -EINVAL: error
+ *   OK: OK
+ *
+ ****************************************************************************/
+
+int pci_disable_bus_master(FAR struct pci_dev_s *dev)
+{
+  pci_clear_cmd_bit(dev, PCI_CMD_BUS_MSTR);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: pci_bar_valid
+ *
+ * Description:
+ *  Determine in if the address in the BAR is valid
+ *
+ * Input Parameters:
+ *   dev   - device
+ *   bar_id - bar number
+ *
+ * Return value:
+ *   -EINVAL: error
+ *   OK: OK
+ *
+ ****************************************************************************/
+
+int pci_bar_valid(FAR struct pci_dev_s *dev, uint8_t bar_id)
+{
+  uint32_t bar = dev->bus->ops->pci_cfg_read(dev,
+      PCI_HEADER_NORM_BAR0 + (bar_id * 4), 4);
+
+  if (bar == PCI_BAR_INVALID)
+    {
+      return -EINVAL;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: pci_bar_is_64
+ *
+ * Description:
+ *  Determine in if the bar address is 64 bit.  If it is the address includes
+ *  the address in the next bar location.
+ *
+ * Input Parameters:
+ *   dev   - device
+ *   bar_id - bar number
+ *
+ * Return value:
+ *   true: 64bit address
+ *
+ ****************************************************************************/
+
+bool pci_bar_is_64(FAR struct pci_dev_s *dev, uint8_t bar_id)
+{
+  uint32_t bar = dev->bus->ops->pci_cfg_read(dev,
+      PCI_HEADER_NORM_BAR0 + (bar_id * 4), 4);
+
+  /* Check that it is memory and not io port */
+
+  if ((bar & PCI_BAR_LAYOUT_MASK) != PCI_BAR_LAYOUT_MEM)
+      return false;
+
+  if (((bar & PCI_BAR_TYPE_MASK) >> PCI_BAR_TYPE_OFFSET) == PCI_BAR_TYPE_64)
+    {
+      return true;
+    }
+
+  return false;
+}
+
+/****************************************************************************
+ * Name: pci_bar_size
+ *
+ * Description:
+ *  Determine the size of the address space required by the BAR
+ *
+ * Input Parameters:
+ *   dev   - device
+ *   bar_id - bar number
+ *
+ * Return value:
+ *   Size of address space
+ *
+ ****************************************************************************/
+
+uint64_t pci_bar_size(FAR struct pci_dev_s *dev, uint8_t bar_id)
+{
+  uint32_t bar;
+  uint32_t size;
+  uint64_t full_size;
+  uint8_t bar_offset = PCI_HEADER_NORM_BAR0 + (bar_id * 4);
+  const struct pci_bus_ops_s *dev_ops = dev->bus->ops;
+
+  bar = dev_ops->pci_cfg_read(dev, bar_offset, 4);
+
+  /* Write all 1 to the BAR.  We are looking for which bits will change */
+
+  dev_ops->pci_cfg_write(dev, bar_offset, 0xffffffff, 4);
+  full_size = dev_ops->pci_cfg_read(dev, bar_offset, 4);
+
+  /* Resore BAR to original values */
+
+  dev_ops->pci_cfg_write(dev, bar_offset, bar, 4);
+
+  if (full_size == 0)
+    {
+      /* This is not a valid bar */
+
+      return 0;
+    }
+
+  if ((bar & PCI_BAR_LAYOUT_MASK) == PCI_BAR_LAYOUT_MEM)
+    {
+      full_size &= PCI_BAR_MEM_BASE_MASK;
+    }
+  else
+    {
+      full_size &= PCI_BAR_IO_BASE_MASK;
+    }
+
+  /* If it is 64 bit address check the next bar as well */
+
+  if (pci_bar_is_64(dev, bar_id))
+    {
+      bar_offset += 4;
+      bar = dev_ops->pci_cfg_read(dev, bar_offset, 4);
+      dev_ops->pci_cfg_write(dev, bar_offset, 0xffffffff, 4);
+      size = dev_ops->pci_cfg_read(dev, bar_offset, 4);
+      dev_ops->pci_cfg_write(dev, bar_offset, bar, 4);
+      full_size |= ((uint64_t)size << 32);
+    }
+  else
+    {
+      full_size |= (uint64_t)(0xffffffff) << 32;
+    }
+
+  return ~full_size + 1;
+}
+
+/****************************************************************************
+ * Name: pci_bar_addr
+ *
+ * Description:
+ *  Determine the size of the address space required by the BAR
+ *
+ * Input Parameters:
+ *   dev   - device
+ *   bar_id - bar number
+ *
+ * Return value:
+ *   full bar address
+ *
+ ****************************************************************************/
+
+uint64_t pci_bar_addr(FAR struct pci_dev_s *dev, uint8_t bar_id)
+{
+  uint64_t addr;
+  uint8_t bar_offset = PCI_HEADER_NORM_BAR0 + (bar_id * 4);
+  const struct pci_bus_ops_s *dev_ops = dev->bus->ops;
+
+  addr = dev_ops->pci_cfg_read(dev, bar_offset, 4);
+
+  if ((addr & PCI_BAR_LAYOUT_MASK) == PCI_BAR_LAYOUT_MEM)
+    {
+      addr &= PCI_BAR_MEM_BASE_MASK;
+    }
+  else
+    {
+      addr &= PCI_BAR_IO_BASE_MASK;
+    }
+
+  /* If it is 64 bit address check the next bar as well */
+
+  if (pci_bar_is_64(dev, bar_id))
+    {
+      bar_offset += 4;
+      addr |= (uint64_t)(dev_ops->pci_cfg_read(dev, bar_offset, 4)) << 32;
+    }
+
+  return addr;
+}
+
+/****************************************************************************
+ * Name: pci_dev_dump
+ *
+ * Description:
+ *  Dump the configuration information for the device
+ *
+ * Input Parameters:
+ *   dev   - device
+ *
+ ****************************************************************************/
+
+void pci_dev_dump(FAR struct pci_dev_s *dev)
+{
+  uint8_t bar_id;
+  uint8_t bar_mem_type = 0;
+  uint32_t bar;
+  uint64_t bar_size;
+  uint64_t bar_addr;
+
+  uint8_t cap_id;
+  uint8_t cap_offset;
+
+  const struct pci_bus_ops_s *dev_ops = dev->bus->ops;
+  uint32_t bdf = dev->bdf;
+  uint16_t vid = dev_ops->pci_cfg_read(dev, PCI_CONFIG_VENDOR, 2);
+  uint16_t pid = dev_ops->pci_cfg_read(dev, PCI_CONFIG_DEVICE, 2);
+  uint8_t header = dev_ops->pci_cfg_read(dev, PCI_CONFIG_HEADER_TYPE, 1);
+  uint8_t progif = dev_ops->pci_cfg_read(dev, PCI_CONFIG_PROG_IF, 1);
+  uint8_t subclass = dev_ops->pci_cfg_read(dev, PCI_CONFIG_SUBCLASS, 1);
+  uint8_t class = dev_ops->pci_cfg_read(dev, PCI_CONFIG_CLASS, 1);
+  uint8_t int_pin;
+  uint8_t int_line;
+
+  pciinfo("[%02x:%02x.%x] %04x:%04x\n",
+          bdf >> 8, (bdf & 0xff) >> 3, bdf & 0x7, vid, pid);
+  pciinfo("\ttype %02x Prog IF %02x Class %02x Subclass %02x\n",
+          header, progif, class, subclass);
+
+  cap_offset = dev_ops->pci_cfg_read(dev, PCI_HEADER_NORM_CAP, 1);
+  while (cap_offset)
+    {
+      cap_id = dev_ops->pci_cfg_read(dev, cap_offset, 1);
+      if (cap_id > PCI_CAP_ID_END)
+        {
+          pcierr("Invalid PCI Capability Found, Skipping. %d\n", cap_id);
+          DEBUGPANIC();
+          break;
+        }
+
+      pciinfo("\tCAP %02x\n", cap_id);
+      cap_offset = dev_ops->pci_cfg_read(dev, cap_offset + 1, 1);
+    }
+
+  if ((header & PCI_HEADER_TYPE_MASK) != PCI_HEADER_NORMAL)
+      return;
+
+  int_pin = dev_ops->pci_cfg_read(dev, PCI_HEADER_NORM_INT_PIN, 1);
+  int_line = dev_ops->pci_cfg_read(dev, PCI_HEADER_NORM_INT_LINE, 1);
+  pciinfo("\tINT Pin %02x Line %02x\n", int_pin, int_line);
+
+  for (bar_id = 0; bar_id < PCI_BAR_CNT; bar_id++)
+    {
+      if (pci_bar_valid(dev, bar_id) != OK)
+        continue;
+
+      bar = dev_ops->pci_cfg_read(dev,
+        PCI_HEADER_NORM_BAR0 + (bar_id * 4), 4);
+
+      bar_size = pci_bar_size(dev, bar_id);
+      bar_addr = pci_bar_addr(dev, bar_id);
+      if ((bar & PCI_BAR_LAYOUT_MASK) == PCI_BAR_LAYOUT_MEM)
+        {
+          switch ((bar & PCI_BAR_TYPE_MASK) >> PCI_BAR_TYPE_OFFSET)
+            {
+              case PCI_BAR_TYPE_64:
+                bar_mem_type = 64;
+                break;
+              case PCI_BAR_TYPE_32:
+                bar_mem_type = 32;
+                break;
+              case PCI_BAR_TYPE_16:
+                bar_mem_type = 16;
+                break;
+              default:
+                bar_mem_type = 0;
+            }
+
+          pciinfo("\tBAR [%d] MEM %db range %p-%p (%p)\n",
+                  bar_id, bar_mem_type,
+                  bar_addr, bar_addr + bar_size - 1, bar_size);
+        }
+      else
+        {
+          pciinfo("\tBAR [%d] PIO range %p-%p (%p)\n",
+                  bar_id,
+                  bar_addr, bar_addr + bar_size - 1, bar_size);
+        }
+
+      /* Skip next bar if this one was 64bit */
+
+      if (bar_mem_type == 64)
+          bar_id++;
+    }
+}
diff --git a/drivers/pcie/Kconfig b/drivers/pcie/Kconfig
deleted file mode 100644
index 7ac9db568b..0000000000
--- a/drivers/pcie/Kconfig
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# 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/pcie_root.c b/drivers/pcie/pcie_root.c
deleted file mode 100644
index b85c5862fa..0000000000
--- a/drivers/pcie/pcie_root.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/****************************************************************************
- * 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>
-#include <nuttx/virt/qemu_pci.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-struct pcie_dev_type_s *pci_device_types[] =
-{
-#ifdef CONFIG_VIRT_QEMU_PCI_TEST
-  &pcie_type_qemu_pci_test,
-#endif /* CONFIG_VIRT_QEMU_PCI_TEST */
-  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/drivers/virt/Kconfig b/drivers/virt/Kconfig
index bf8fb8591c..6eee0ff10d 100644
--- a/drivers/virt/Kconfig
+++ b/drivers/virt/Kconfig
@@ -15,8 +15,15 @@ if VIRT
 config VIRT_QEMU_PCI_TEST
        bool "Driver for QEMU PCI test device"
        default n
-       select PCIE
+       select PCI
        ---help---
                Driver for QEMU PCI test device
 
+config VIRT_QEMU_EDU
+       bool "Driver for QEMU EDU test device"
+       default n
+       select PCI
+       ---help---
+               Driver for QEMU EDU test device
+
 endif # VIRT
diff --git a/drivers/virt/Make.defs b/drivers/virt/Make.defs
index 8ccfbe06c5..a65cce26f4 100644
--- a/drivers/virt/Make.defs
+++ b/drivers/virt/Make.defs
@@ -1,5 +1,5 @@
 ############################################################################
-# drivers/pcie/Make.defs
+# drivers/pci/Make.defs
 #
 # Licensed to the Apache Software Foundation (ASF) under one or more
 # contributor license agreements.  See the NOTICE file distributed with
@@ -26,6 +26,12 @@ CSRCS += qemu_pci_test.c
 
 endif
 
+ifeq ($(CONFIG_VIRT_QEMU_EDU),y)
+
+CSRCS += qemu_edu.c
+
+endif
+
 # Include virt device driver build support
 #
 ifeq ($(CONFIG_VIRT),y)
diff --git a/drivers/virt/qemu_edu.c b/drivers/virt/qemu_edu.c
new file mode 100644
index 0000000000..953d161a52
--- /dev/null
+++ b/drivers/virt/qemu_edu.c
@@ -0,0 +1,448 @@
+/*****************************************************************************
+ * drivers/virt/qemu_edu.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 <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kmalloc.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sched.h>
+
+#include <nuttx/pci/pci.h>
+#include <nuttx/virt/qemu_pci.h>
+
+/*****************************************************************************
+ * Pre-processor Definitions
+ *****************************************************************************/
+
+/* Registers defined for device.  Size 4 for < 0x80.  Size 8 for >= 0x80. */
+
+#define EDU_REG_ID          0x00  /* Identification */
+#define EDU_REG_LIVE        0x04  /* Liveness Check */
+#define EDU_REG_FAC         0x08  /* Factorial Computation */
+#define EDU_REG_STATUS      0x20  /* Status */
+#define EDU_REG_INT_STATUS  0x24  /* Interupt Status */
+#define EDU_REG_INT_RAISE   0x60  /* Raise an interrupt */
+#define EDU_REG_INT_ACK     0x64  /* Acknowledge interrupt */
+#define EDU_REG_DMA_SOURCE  0x80  /* Source address for DMA transfer */
+#define EDU_REG_DMA_DEST    0x88  /* Destination address for DMA transfer */
+#define EDU_REG_DMA_COUNT   0x90  /* Size of area to transfer with DMA */
+#define EDU_REG_DMA_CMD     0x98  /* Control DMA tranfer */
+
+#define EDU_CONTROL_BAR_ID      0
+#define EDU_CONTROL_BAR_OFFSET  PCI_HEADER_NORM_BAR0
+
+/*****************************************************************************
+ * Private Types
+ *****************************************************************************/
+
+struct qemu_edu_priv_s
+{
+  uintptr_t base_addr;
+  sem_t isr_done;
+  uint32_t test_result;
+};
+
+/*****************************************************************************
+ * Private Functions Definitions
+ *****************************************************************************/
+
+static void qemu_edu_write_reg32(uintptr_t addr, uint32_t val);
+
+static uint32_t qemu_edu_read_reg32(uintptr_t addr);
+
+static void qemu_edu_write_reg64(uintptr_t addr, uint64_t val);
+
+static void qemu_edu_test_poll(FAR struct pci_dev_s *dev,
+                               uintptr_t base_addr);
+
+static void qemu_edu_test_intx(FAR struct pci_dev_s *dev,
+                               struct qemu_edu_priv_s *drv_priv);
+
+static int qemu_edu_interrupt(int irq, void *context, FAR void *arg);
+
+/*****************************************************************************
+ * Private Data
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Private Functions
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Name: qemu_edu_write_reg32
+ *
+ * Description:
+ *   Provide a write interface for 32bit mapped registers
+ *
+ * Input Parameters:
+ *   addr - Register address
+ *   val  - Value to assign to register
+ *
+ *****************************************************************************/
+
+static void qemu_edu_write_reg32(uintptr_t addr, uint32_t val)
+{
+  *(volatile uint32_t *)addr = val;
+}
+
+/*****************************************************************************
+ * Name: qemu_edu_read_reg32
+ *
+ * Description:
+ *   Provide a read interface for 32bit mapped registers
+ *
+ * Returned Value:
+ *   Register value
+ *
+ *****************************************************************************/
+
+static uint32_t qemu_edu_read_reg32(uintptr_t addr)
+{
+  return *(volatile uint32_t *)addr;
+}
+
+/*****************************************************************************
+ * Name: qemu_edu_write_reg64
+ *
+ * Description:
+ *   Provide a write interface for 64bit mapped registers
+ *
+ * Input Parameters:
+ *   addr - Register address
+ *   val  - Value to assign to register
+ *
+ *****************************************************************************/
+
+static void qemu_edu_write_reg64(uintptr_t addr, uint64_t val)
+{
+  *(volatile uint64_t *)addr = val;
+}
+
+/*****************************************************************************
+ * Name: qemu_edu_test_poll
+ *
+ * Description:
+ *   Performs basic functional test of PCI device and MMIO using polling
+ *   of mapped register interfaces.
+ *
+ * Input Parameters:
+ *   bus       - An PCI device
+ *   base_addr - Base address of device register space
+ *
+ *****************************************************************************/
+
+static void qemu_edu_test_poll(FAR struct pci_dev_s *dev, uintptr_t base_addr)
+{
+  uint32_t test_value;
+  uint32_t test_read;
+
+  pciinfo("Identification: 0x%08xu\n",
+          qemu_edu_read_reg32(base_addr + EDU_REG_ID));
+
+  /* Test Live Check */
+
+  test_value = 0xdeadbeef;
+  qemu_edu_write_reg32(base_addr + EDU_REG_LIVE, test_value);
+  test_read = qemu_edu_read_reg32(base_addr + EDU_REG_LIVE);
+  pciinfo("Live Check: Wrote: 0x%08x Read: 0x%08x Error Bits 0x%08x\n",
+          test_value, test_read, test_read ^ ~test_value);
+  pciinfo("TEST %s\n", ((test_read ^ ~test_value) == 0) ? "PASS" : "FAIL");
+
+  /* Test Factorial */
+
+  test_value = 10;
+  qemu_edu_write_reg32(base_addr + EDU_REG_STATUS, 0);
+  qemu_edu_write_reg32(base_addr + EDU_REG_FAC, test_value);
+  while (qemu_edu_read_reg32(base_addr + EDU_REG_STATUS) & 0x01)
+    {
+      pciinfo("Waiting to compute factorial...");
+      usleep(10000);
+    }
+
+  test_read = qemu_edu_read_reg32(base_addr + EDU_REG_FAC);
+  pciinfo("Computed factorial of %d as %d\n", test_value, test_read);
+  pciinfo("TEST %s\n", (test_read == 3628800) ? "PASS" : "FAIL");
+}
+
+/*****************************************************************************
+ * Name: qemu_edu_test_intx
+ *
+ * Description:
+ *   Performs basic functional test of PCI device and MMIO using INTx
+ *
+ * Input Parameters:
+ *   bus       - An PCI device
+ *   drv_priv  - Struct containing internal state of driver
+ *
+ *****************************************************************************/
+
+static void qemu_edu_test_intx(FAR struct pci_dev_s *dev,
+                               struct qemu_edu_priv_s *drv_priv)
+{
+  uintptr_t base_addr = drv_priv->base_addr;
+  uint32_t test_value;
+
+  pciinfo("Identification: 0x%08xu\n",
+          qemu_edu_read_reg32(base_addr + EDU_REG_ID));
+
+  /* Test Read/Write */
+
+  test_value = 0xdeadbeef;
+  pciinfo("Triggering interrupt with value 0x%08x\n", test_value);
+  qemu_edu_write_reg32(base_addr + EDU_REG_INT_RAISE, test_value);
+  sem_wait(&drv_priv->isr_done);
+  pciinfo("TEST %s\n",
+      (drv_priv->test_result == test_value) ? "PASS" : "FAIL");
+
+  /* Test Factorial */
+
+  test_value = 5;
+  pciinfo("Computing factorial of %d\n", test_value);
+  qemu_edu_write_reg32(base_addr + EDU_REG_STATUS, 0x80);
+  qemu_edu_write_reg32(base_addr + EDU_REG_FAC, test_value);
+  sem_wait(&drv_priv->isr_done);
+  pciinfo("TEST %s\n", (drv_priv->test_result == 120) ? "PASS" : "FAIL");
+
+  /* Test ISR Status Cleanup */
+
+  qemu_edu_write_reg32(base_addr + EDU_REG_INT_RAISE, test_value);
+  sem_wait(&drv_priv->isr_done);
+  pciinfo("TEST %s\n",
+      (drv_priv->test_result == test_value) ? "PASS" : "FAIL");
+}
+
+/*****************************************************************************
+ * Name: qemu_edu_test_dma
+ *
+ * Description:
+ *   Performs dma functional test of PCI device
+ *
+ * Input Parameters:
+ *   bus       - An PCI device
+ *   drv_priv  - Struct containing internal state of driver
+ *
+ *****************************************************************************/
+
+static void qemu_edu_test_dma(FAR struct pci_dev_s *dev,
+                               struct qemu_edu_priv_s *drv_priv)
+{
+  uintptr_t base_addr = drv_priv->base_addr;
+  void *test_block;
+  size_t block_size = 2048;
+  int i;
+  uint32_t psrand;
+  uint32_t tx_checksum;
+  uint32_t rx_checksum;
+  uint32_t dev_addr = 0x40000;
+
+  pciinfo("Identification: 0x%08xu\n",
+          qemu_edu_read_reg32(base_addr + EDU_REG_ID));
+
+  test_block = kmm_malloc(block_size);
+  for (i = 0; i < block_size; i++)
+    {
+      *((uint8_t *)test_block + i) = i & 0xff;
+    }
+
+  tx_checksum = 0;
+  psrand = 0x0011223344;
+  for (i = 0; i < (block_size / 4); i++)
+    {
+      /* Fill the memory block with "random" data */
+
+      psrand ^= psrand << 13;
+      psrand ^= psrand >> 17;
+      psrand ^= psrand << 5;
+      *((uint32_t *)test_block + i) = psrand;
+      tx_checksum += psrand;
+    }
+
+  pciinfo("Test block checksum 0x%08x\n", tx_checksum);
+  qemu_edu_write_reg64(base_addr + EDU_REG_DMA_SOURCE, (uint64_t)test_block);
+  qemu_edu_write_reg64(base_addr + EDU_REG_DMA_DEST, (uint64_t)dev_addr);
+  qemu_edu_write_reg64(base_addr + EDU_REG_DMA_COUNT, (uint64_t)block_size);
+  qemu_edu_write_reg32(base_addr + EDU_REG_STATUS, 0x00);
+  qemu_edu_write_reg64(base_addr + EDU_REG_DMA_CMD, 0x01 | 0x04);
+  sem_wait(&drv_priv->isr_done);
+
+  pciinfo("DMA transfer to device complete.\n");
+
+  qemu_edu_write_reg64(base_addr + EDU_REG_DMA_DEST, (uint64_t)test_block);
+  qemu_edu_write_reg64(base_addr + EDU_REG_DMA_SOURCE, (uint64_t)dev_addr);
+  qemu_edu_write_reg64(base_addr + EDU_REG_DMA_COUNT, (uint64_t)block_size);
+  qemu_edu_write_reg32(base_addr + EDU_REG_STATUS, 0x00);
+  qemu_edu_write_reg64(base_addr + EDU_REG_DMA_CMD, 0x01 | 0x02 | 0x04);
+  sem_wait(&drv_priv->isr_done);
+
+  pciinfo("DMA transfer from device complete.\n");
+  rx_checksum = 0;
+  for (i = 0; i < block_size / 4; i++)
+    {
+      rx_checksum += *((uint32_t *)test_block + i);
+    }
+
+  pciinfo("Received block checksum 0x%08x\n", rx_checksum);
+  pciinfo("TEST %s\n", (rx_checksum == tx_checksum) ? "PASS" : "FAIL");
+}
+
+/*****************************************************************************
+ * Name: qemu_edu_interrupt
+ *
+ * Description:
+ *  EDU interrupt handler
+ *
+ *****************************************************************************/
+
+static int qemu_edu_interrupt(int irq, void *context, FAR void *arg)
+{
+  struct qemu_edu_priv_s *drv_priv = (struct qemu_edu_priv_s *)arg;
+  uintptr_t base_addr = drv_priv->base_addr;
+
+  uint32_t status = qemu_edu_read_reg32(base_addr + EDU_REG_INT_STATUS);
+
+  qemu_edu_write_reg32(base_addr + EDU_REG_INT_ACK, ~0U);
+  switch (status)
+    {
+    case 0x1:    /* Factorial triggered */
+      drv_priv->test_result = qemu_edu_read_reg32(base_addr + EDU_REG_FAC);
+      pciinfo("Computed factorial: %d\n",
+              drv_priv->test_result);
+      break;
+    case 0x100:  /* DMA triggered */
+      pciinfo("DMA transfer complete\n");
+      break;
+    default:     /* Generic write */
+      drv_priv->test_result = status;
+      pciinfo("Received value: 0x%08x\n", status);
+    }
+
+  sem_post(&drv_priv->isr_done);
+  return OK;
+}
+
+/*****************************************************************************
+ * Public Functions
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Name: qemu_edu_probe
+ *
+ * Description:
+ *   Initialize device
+ *****************************************************************************/
+
+int qemu_edu_probe(FAR struct pci_bus_s *bus,
+                   FAR struct pci_dev_type_s *type, uint16_t bdf)
+{
+  uint32_t bar;
+  uintptr_t bar_addr;
+  struct pci_dev_s dev =
+    {
+      .bus = bus,
+      .type = type,
+      .bdf = bdf,
+    };
+
+  uint8_t irq;
+  struct qemu_edu_priv_s drv_priv;
+
+  pci_enable_bus_master(&dev);
+  pciinfo("Enabled bus mastering\n");
+  pci_enable_io(&dev, PCI_SYS_RES_MEM);
+  pciinfo("Enabled memory resources\n");
+
+  if (pci_bar_valid(&dev, EDU_CONTROL_BAR_ID) != OK)
+    {
+      pcierr("Control BAR is not valid\n");
+      DEBUGPANIC();
+      return -EINVAL;
+    }
+
+  bar_addr = pci_bar_addr(&dev, EDU_CONTROL_BAR_ID);
+  bar = bus->ops->pci_cfg_read(&dev, EDU_CONTROL_BAR_OFFSET, 4);
+  if ((bar & PCI_BAR_LAYOUT_MASK) != PCI_BAR_LAYOUT_MEM)
+    {
+      pcierr("Control bar expected to be MMIO\n");
+      DEBUGPANIC();
+      return -EINVAL;
+    }
+
+  if (bus->ops->pci_map_bar(bar_addr,
+      pci_bar_size(&dev, EDU_CONTROL_BAR_ID)) != OK)
+    {
+      pcierr("Failed to map address space\n");
+      DEBUGPANIC();
+      return -EINVAL;
+    }
+
+  pciinfo("Device Initialized\n");
+
+  /* Run Poll Tests */
+
+  qemu_edu_test_poll(&dev, bar_addr);
+
+  /* Run IRQ Tests */
+
+  drv_priv.base_addr = bar_addr;
+  sem_init(&drv_priv.isr_done, 0, 0);
+  sem_setprotocol(&drv_priv.isr_done, SEM_PRIO_NONE);
+
+  irq = IRQ0 + bus->ops->pci_cfg_read(&dev, PCI_HEADER_NORM_INT_LINE, 1);
+  pciinfo("Attaching IRQ %d to %p\n", irq, qemu_edu_interrupt);
+  irq_attach(irq, (xcpt_t)qemu_edu_interrupt, (void *)&drv_priv);
+  up_enable_irq(irq);
+
+  qemu_edu_test_intx(&dev, &drv_priv);
+  qemu_edu_test_dma(&dev, &drv_priv);
+
+  up_disable_irq(irq);
+  irq_detach(irq);
+  sem_destroy(&drv_priv.isr_done);
+
+  /* Run MSI Tests */
+
+  /* Really should be cleaning up the mapped memory */
+
+  return OK;
+}
+
+/*****************************************************************************
+ * Public Data
+ *****************************************************************************/
+
+struct pci_dev_type_s pci_type_qemu_edu =
+{
+    .vendor = 0x1234,
+    .device = 0x11e8,
+    .class_rev = PCI_ID_ANY,
+    .name = "Qemu PCI EDU device",
+    .probe = qemu_edu_probe
+};
diff --git a/drivers/virt/qemu_pci_test.c b/drivers/virt/qemu_pci_test.c
index d0df753121..b0556b4d9f 100644
--- a/drivers/virt/qemu_pci_test.c
+++ b/drivers/virt/qemu_pci_test.c
@@ -33,30 +33,133 @@
 #include <errno.h>
 #include <sched.h>
 
-#include <nuttx/pcie/pcie.h>
+#include <nuttx/pci/pci.h>
 #include <nuttx/virt/qemu_pci.h>
 
 /*****************************************************************************
  * Pre-processor Definitions
  *****************************************************************************/
 
+/*****************************************************************************
+ * Private Functions Definitions
+ *****************************************************************************/
+
+static uint32_t mem_read(FAR const volatile void *addr, int width);
+
+static void mem_write(FAR const volatile void *addr, uint32_t val, int width);
+
 /*****************************************************************************
  * Private Types
  *****************************************************************************/
 
 struct pci_test_dev_hdr_s
 {
-    volatile uint8_t test;       /* write-only, starts a given test number */
-    volatile uint8_t width_type; /* read-only, type and width of access for a 
given test.
-                                  * 1,2,4 for byte,word or long write.
-                                  * any other value if test not supported on 
this BAR */
-    volatile uint8_t pad0[2];
-    volatile uint32_t offset;    /* read-only, offset in this BAR for a given 
test */
-    volatile uint32_t data;      /* read-only, data to use for a given test */
-    volatile uint32_t count;     /* for debugging. number of writes detected. 
*/
-    volatile uint8_t name[];     /* for debugging. 0-terminated ASCII string. 
*/
+    uint8_t test;       /* write-only, starts a given test number */
+    uint8_t width;      /* read-only, type and width of access for a test */
+    uint8_t pad0[2];
+    uint32_t offset;    /* read-only, offset in this BAR for a given test */
+    uint32_t data;      /* read-only, data to use for a given test */
+    uint32_t count;     /* for debugging. number of writes detected. */
+    uint8_t name[];     /* for debugging. 0-terminated ASCII string. */
+};
+
+/* Structure the read and write helpers */
+
+struct pci_test_dev_ops_s
+{
+    uint32_t (*read)(FAR const volatile void *addr, int width);
+    void (*write)(FAR const volatile void *addr, uint32_t val, int width);
+};
+
+/*****************************************************************************
+ * Private Data
+ *****************************************************************************/
+
+static struct pci_test_dev_ops_s mem_ops =
+{
+    .read = mem_read,
+    .write = mem_write
 };
 
+/*****************************************************************************
+ * Private Functions
+ *****************************************************************************/
+
+static uint32_t mem_read(FAR const volatile void *addr, int unused)
+{
+  return *(volatile uint32_t *)addr;
+}
+
+static void mem_write(FAR const volatile void *addr, uint32_t val, int unused)
+{
+  *(volatile uint32_t *)addr = val;
+}
+
+static bool qemu_pci_test_bar(FAR struct pci_test_dev_ops_s *test_ops,
+                             FAR struct pci_test_dev_hdr_s *test_hdr,
+                             uint16_t test_num)
+{
+  uint32_t count;
+  uint32_t data;
+  uint32_t offset;
+  uint8_t width;
+  const int write_limit = 8;
+  int write_cnt;
+  int i;
+  char testname[32];
+
+  pciinfo("WRITING Test# %d %p\n", test_num, &test_hdr->test);
+  test_ops->write(&test_hdr->test, test_num, 1);
+
+  /* Reading of the string is a little ugly to handle the case where
+   * we must use the port access methods.  For memory map we would
+   * be able to just read directly.
+   */
+
+  testname[sizeof(testname) - 1] = 0;
+  for (i = 0; i < sizeof(testname); i++)
+    {
+      testname[i] = (char)test_ops->read((void *)&test_hdr->name + i, 1);
+      if (testname[i] == 0)
+        break;
+    }
+
+  pciinfo("Running test: %s\n", testname);
+
+  count = test_ops->read(&test_hdr->count, 4);
+  pciinfo("COUNT: %04x\n", count);
+  if (count != 0)
+      return false;
+
+  width = test_ops->read(&test_hdr->width, 1);
+  pciinfo("Width: %d\n", width);
+
+  if (width == 0 || width > 4)
+      return false;
+
+  data = test_ops->read(&test_hdr->data, 4);
+  pciinfo("Data: %04x\n", data);
+
+  offset = test_ops->read(&test_hdr->offset, 4);
+  pciinfo("Offset: %04x\n", offset);
+
+  for (write_cnt = 0; write_cnt < write_limit; write_cnt++)
+    {
+      pciinfo("Issuing WRITE to %p %x %d\n",
+              (void *)test_hdr + offset,
+              data, width);
+      test_ops->write((void *)test_hdr + offset, data, width);
+    }
+
+  count = test_ops->read(&test_hdr->count, 4);
+  pciinfo("COUNT: %04x\n", count);
+
+  if (!count)
+      return true;
+
+  return (int)count == write_cnt;
+}
+
 /*****************************************************************************
  * Public Functions
  *****************************************************************************/
@@ -68,49 +171,73 @@ struct pci_test_dev_hdr_s
  *   Initialize device
  *****************************************************************************/
 
-int qemu_pci_test_probe(FAR struct pcie_bus_s *bus,
-                        FAR struct pcie_dev_type_s *type, uint16_t bdf)
+int qemu_pci_test_probe(FAR struct pci_bus_s *bus,
+                        FAR struct pci_dev_type_s *type, uint16_t bdf)
 {
-  uint32_t bar[2];
-  struct pcie_dev_s dev =
+  uint8_t bar_id;
+  uint32_t bar;
+  uint64_t bar_addr;
+  struct pci_test_dev_hdr_s *test_hdr;
+  struct pci_dev_s dev =
     {
       .bus = bus,
       .type = type,
       .bdf = bdf,
     };
 
-  pci_enable_device(&dev);
+  struct pci_test_dev_ops_s io_ops =
+    {
+      .read = bus->ops->pci_io_read,
+      .write = bus->ops->pci_io_write
+    };
+
+  struct pci_test_dev_ops_s *test_ops;
+
+  uint16_t test_cnt;
+
+  pci_enable_bus_master(&dev);
+  pciinfo("Enabled bus mastering\n");
+  pci_enable_io(&dev, PCI_SYS_RES_MEM);
+  pci_enable_io(&dev, PCI_SYS_RES_IOPORT);
+  pciinfo("Enabled i/o port and memory resources\n");
 
-  for (int ii = 0; ii < 2; ii++)
+  for (bar_id = 0; bar_id < PCI_BAR_CNT; bar_id++)
     {
-      pci_get_bar(&dev, ii, bar + ii);
+      /* Need to query the BAR for IO vs MEM
+       * Also handle if the bar is 64bit address
+       */
 
-      if ((bar[ii] & PCI_BAR_IO) != PCI_BAR_IO)
-        {
-          pciinfo("Mapping BAR%d: %x\n", ii, bar[ii]);
+      if (pci_bar_valid(&dev, bar_id) != OK)
+        continue;
 
-          pci_map_bar(&dev, ii, 0x1000, NULL);
+      bar = bus->ops->pci_cfg_read(&dev,
+          PCI_HEADER_NORM_BAR0 + (bar_id * 4), 4);
 
-          struct pci_test_dev_hdr_s *ptr =
-            (struct pci_test_dev_hdr_s *)(uintptr_t)bar[ii];
+      bar_addr = pci_bar_addr(&dev, bar_id);
+      test_hdr = (struct pci_test_dev_hdr_s *)bar_addr;
 
-          int i = 0;
-          while (1)
-            {
-              ptr->test = i;
+      if ((bar & PCI_BAR_LAYOUT_MASK) == PCI_BAR_LAYOUT_MEM)
+        {
+          test_ops = &mem_ops;
 
-              if (ptr->width_type != 1 &&
-                  ptr->width_type != 2 &&
-                  ptr->width_type != 4)
-                break;
+          /* If the BAR is MMIO the it must be mapped */
 
-              pciinfo("Test[%d] Size:%d %s\n",
-                  i, ptr->width_type,
-                  ptr->name);
+          bus->ops->pci_map_bar(bar_addr, pci_bar_size(&dev, bar_id));
+        }
+      else
+        {
+          test_ops = &io_ops;
+        }
 
-              i++;
-            }
+      for (test_cnt = 0; test_cnt < 0xffff; test_cnt++)
+        {
+          if (!qemu_pci_test_bar(test_ops, test_hdr, test_cnt))
+            break;
+          pciinfo("Test Completed BAR [%d] TEST [%d]\n", bar_id, test_cnt);
         }
+
+      if (pci_bar_is_64(&dev, bar_id))
+        bar_id++;
     }
 
   return OK;
@@ -120,7 +247,7 @@ int qemu_pci_test_probe(FAR struct pcie_bus_s *bus,
  * Public Data
  *****************************************************************************/
 
-struct pcie_dev_type_s pcie_type_qemu_pci_test =
+struct pci_dev_type_s pci_type_qemu_pci_test =
 {
     .vendor = 0x1b36,
     .device = 0x0005,
diff --git a/include/debug.h b/include/debug.h
index 955ddf6e2c..94b5448b32 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -920,19 +920,19 @@
 #  define ipcinfo     _none
 #endif
 
-#ifdef CONFIG_DEBUG_PCIE_ERROR
+#ifdef CONFIG_DEBUG_PCI_ERROR
 #  define pcierr       _err
 #else
 #  define pcierr      _none
 #endif
 
-#ifdef CONFIG_DEBUG_PCIE_WARN
+#ifdef CONFIG_DEBUG_PCI_WARN
 #  define pciwarn     _warn
 #else
 #  define pciwarn     _none
 #endif
 
-#ifdef CONFIG_DEBUG_PCIE_INFO
+#ifdef CONFIG_DEBUG_PCI_INFO
 #  define pciinfo     _info
 #else
 #  define pciinfo     _none
diff --git a/include/nuttx/pci/pci.h b/include/nuttx/pci/pci.h
new file mode 100644
index 0000000000..0b420a04c0
--- /dev/null
+++ b/include/nuttx/pci/pci.h
@@ -0,0 +1,458 @@
+/****************************************************************************
+ * include/nuttx/pci/pci.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_PCI_PCI_H
+#define __INCLUDE_NUTTX_PCI_PCI_H
+
+#ifdef CONFIG_PCI
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+
+#include <nuttx/fs/ioctl.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* PCI config common registers */
+
+#define        PCI_CONFIG_VENDOR                 0x00
+#define        PCI_CONFIG_DEVICE                 0x02
+#define        PCI_CONFIG_COMMAND              0x04
+#define        PCI_CONFIG_REV_ID                 0x08
+#define        PCI_CONFIG_PROG_IF          0x09
+#define        PCI_CONFIG_SUBCLASS             0x0A
+#define        PCI_CONFIG_CLASS                  0x0B
+#define        PCI_CONFIG_CACHE_LINE_SIZE      0x0C
+#define        PCI_CONFIG_LATENCY_TIMER          0x0D
+#define        PCI_CONFIG_HEADER_TYPE      0x0E
+#define        PCI_CONFIG_BIST             0x0F
+
+/* PCI config header types */
+
+#define PCI_HEADER_NORMAL      0x00
+#define PCI_HEADER_BRIDGE      0x01
+#define PCI_HEADER_CARDBUS     0x02
+#define PCI_HEADER_TYPE_MASK   0x3F
+#define PCI_HEADER_MASK_MULTI  0x80
+
+/* PCI config registers type 0 (Normal devices) */
+
+#define PCI_HEADER_NORM_BAR0      0x10
+#define PCI_HEADER_NORM_BAR1      0x14
+#define PCI_HEADER_NORM_BAR2      0x18
+#define PCI_HEADER_NORM_BAR3      0x1C
+#define PCI_HEADER_NORM_BAR4      0x20
+#define PCI_HEADER_NORM_BAR5      0x24
+#define PCI_HEADER_NORM_CB_CIS    0x28
+#define PCI_HEADER_NORM_SUB_VID   0x2C
+#define PCI_HEADER_NORM_SUB_ID    0x2E
+#define PCI_HEADER_NORM_EXP_ROM   0x30
+#define PCI_HEADER_NORM_CAP       0x34
+#define PCI_HEADER_NORM_INT_LINE  0x3C
+#define PCI_HEADER_NORM_INT_PIN   0x3D
+#define PCI_HEADER_NORM_MIN_GRANT 0x3E
+#define PCI_HEADER_NORM_MAX_LAT   0x3E
+
+/* PCI config registers type 1 (PCI-PCI bridge) */
+
+#define PCI_CONFIG_SEC_BUS 0x19
+
+/* PCI config registers type 2 (CardBus) */
+
+/* PCI Base Class Codes */
+
+#define PCI_CLASS_BASE_UNCLASSIFIED      0x00
+#define PCI_CLASS_BASE_MASS_STORAGE_CTRL 0x01
+#define PCI_CLASS_BASE_NETWORK_CTRL      0x02
+#define PCI_CLASS_BASE_DISPLAY_CTRL      0x03
+#define PCI_CLASS_BASE_MULTIMEDIA_CTRL   0x04
+#define PCI_CLASS_BASE_MEM_CTRL          0x05
+#define PCI_CLASS_BASE_BRG_DEV           0x06
+#define PCI_CLASS_BASE_SMPL_COM_CTRL     0x07
+#define PCI_CLASS_BASE_BSP               0x08
+#define PCI_CLASS_BASE_INPUT_DEV_CTRL    0x09
+#define PCI_CLASS_BASE_DOCK_STN          0x0A
+#define PCI_CLASS_BASE_PROCESSOR         0x0B
+#define PCI_CLASS_BASE_SBC               0x0C
+#define PCI_CLASS_BASE_WIRELESS_CTRL     0x0D
+#define PCI_CLASS_BASE_INTL_CTRL         0x0E
+#define PCI_CLASS_BASE_SAT_COM_CTRL      0x0F
+#define PCI_CLASS_BASE_ENCRYPT_CTRL      0x10
+#define PCI_CLASS_BASE_SPC               0x11
+#define PCI_CLASS_BASE_PROC_ACCEL        0x12
+#define PCI_CLASS_BASE_NON_ES_INST       0x13
+
+/* Reserved 0x14-0x3F */
+
+#define PCI_CLASS_BASE_CO_PROC           0x40   
+
+/* Reserved 0x41-0xFE */
+
+#define PCI_CLASS_BASE_UNASSIGNED        0xFF
+
+/* PCI Sub Class Codes (most missing) */
+
+/* Bridge Class */
+
+#define PCI_CLASS_SUB_HOST_BRG           0x00
+#define PCI_CLASS_SUB_ISA_BRG            0x01
+#define PCI_CLASS_SUB_EISA_BRG           0x02
+#define PCI_CLASS_SUB_MCA_BRG            0x03
+#define PCI_CLASS_SUB_PCI_BRG            0x04
+#define PCI_CLASS_SUB_PCMCIA_BRG         0x05
+#define PCI_CLASS_SUB_NUBUS_BRG          0x06
+#define PCI_CLASS_SUB_CARDBUS_BRG        0x07
+#define PCI_CLASS_SUB_RACEWAY_BRG        0x08
+#define PCI_CLASS_SUB_PCI_TRNSP_BRG      0x09
+#define PCI_CLASS_SUB_INFINI_BRG         0x0A
+#define PCI_CLASS_SUB_NUBUS_BRG          0x80
+
+#define PCI_ID_ANY                       0xffff
+
+/* PCI Command Register Bitmasks */
+
+#define PCI_CMD_IO_SPACE    0x0001
+#define PCI_CMD_MEM_SPACE   0x0002
+#define PCI_CMD_BUS_MSTR    0x0004
+#define PCI_CMD_SPECIAL_CYC 0x0008
+#define PCI_CMD_MEM_INV     0x0030
+#define PCI_CMD_VGA_PLT     0x0040
+#define PCI_CMD_PAR_ERR     0x0080
+#define PCI_CMD_SERR        0x0100
+#define PCI_CMD_FST_B2B     0x0200
+#define PCI_CMD_INT         0x0400
+
+/* PCI BAR Bitmasks */
+
+#define PCI_BAR_LAYOUT_MASK     0x00000001
+#define PCI_BAR_TYPE_MASK       0x00000006
+#define PCI_BAR_MEM_PF_MASK     0x00000008
+#define PCI_BAR_MEM_BASE_MASK   0xfffffff0
+#define PCI_BAR_IO_BASE_MASK    0xfffffffc
+
+/* PCI BAR OFFSETS */
+
+#define PCI_BAR_LAYOUT_OFFSET   0
+#define PCI_BAR_TYPE_OFFSET     1
+#define PCI_BAR_MEM_PF_OFFSET   3
+#define PCI_BAR_MEM_BASE_OFFSET 4
+#define PCI_BAR_IO_BASE_OFFSET  2
+
+/* PCI BAR */
+
+#define PCI_BAR_CNT         6
+#define PCI_BAR_INVALID     0
+#define PCI_BAR_LAYOUT_MEM  0
+#define PCI_BAR_LAYOUT_IO   1
+#define PCI_BAR_TYPE_32     0x00
+#define PCI_BAR_TYPE_16     0x01  /* This mode is not used */
+#define PCI_BAR_TYPE_64     0x02
+
+/* PCI CAP */
+
+#define PCI_CAP_ID_PM       0x01  /* Power Management */
+#define PCI_CAP_ID_AGP      0x02  /* Accelerated Graphics */
+#define PCI_CAP_ID_VPD      0x03  /* Vital Product Data */
+#define PCI_CAP_ID_SLOT     0x04  /* Slot ID */
+#define PCI_CAP_ID_MSI      0x05  /* MSI */
+#define PCI_CAP_ID_CHP      0x06  /* CompactPCI Hot-Swap */
+#define PCI_CAP_ID_PCIX     0x07  /* PCI-X */
+#define PCI_CAP_ID_HT       0x08  /* HyperTransport */
+#define PCI_CAP_ID_VNDR     0x09  /* Vendor */
+#define PCI_CAP_ID_DBG      0x0A  /* Debug */
+#define PCI_CAP_ID_CCRC     0x0B  /* CompactPCI Central Resource Control */
+#define PCI_CAP_ID_HOT      0x0C  /* Hot-Plug Controller */
+#define PCI_CAP_ID_BRG_VID  0x0D  /* Bridge Vendor/Device ID */
+#define PCI_CAP_ID_AGP_BRG  0x0E  /* AGP PCI-PCI Bridge */
+#define PCI_CAP_ID_SEC_DEV  0x0F  /* Secure Device */
+#define PCI_CAP_ID_PCIE     0x10  /* PCIe */
+#define PCI_CAP_ID_MSIX     0x11  /* MSI-X */
+#define PCI_CAP_ID_SATA     0x12  /* SATA */
+#define PCI_CAP_ID_ADVF     0x13  /* Advanced Features */
+
+#define PCI_CAP_ID_END PCI_CAP_ID_ADVF
+
+/* Resource types used by PCI devices */
+
+#define PCI_SYS_RES_IOPORT 0x00
+#define PCI_SYS_RES_MEM    0x01
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* The PCI driver interface */
+
+struct pci_bus_s;
+struct pci_dev_type_s;
+struct pci_dev_s;
+
+/* Bus related operations */
+
+struct pci_bus_ops_s
+{
+    CODE void (*pci_cfg_write)(FAR struct pci_dev_s *dev, int reg,
+                               uint32_t val, int width);
+
+    CODE uint32_t (*pci_cfg_read)(FAR struct pci_dev_s *dev, int reg,
+                                  int width);
+
+    CODE int (*pci_map_bar)(uint64_t addr, uint64_t len);
+
+    CODE uint32_t (*pci_io_read)(FAR const volatile void *addr, int width);
+
+    CODE void (*pci_io_write)(FAR const volatile void *addr, uint32_t val,
+                              int width);
+};
+
+/* PCI bus private data. */
+
+struct pci_bus_s
+{
+  FAR const struct pci_bus_ops_s *ops; /* operations */
+};
+
+/* PCI device type, defines by vendor ID and device ID */
+
+struct pci_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 pci_bus_s *bus,
+                    FAR struct pci_dev_type_s *type, uint16_t bdf);
+};
+
+/* PCI device private data. */
+
+struct pci_dev_s
+{
+    FAR struct pci_bus_s       *bus;
+    FAR struct pci_dev_type_s  *type;
+    uint32_t                    bdf;
+};
+
+/****************************************************************************
+ * Public Functions Prototypes
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Name: pci_initialize
+ *
+ * Description:
+ *  Initialize the PCI bus and enumerate the devices with give devices
+ *  type array
+ *
+ * Input Parameters:
+ *   bus    - An PCI bus
+ *   types  - A array of PCI device types
+ *
+ * Returned Value:
+ *   OK if the driver was successfully register; A negated errno value is
+ *   returned on any failure.
+ *
+ ****************************************************************************/
+
+int pci_initialize(FAR struct pci_bus_s *bus);
+
+/****************************************************************************
+ * Name: pci_enable_io
+ *
+ * Description:
+ *  Enable MMIO or IOPORT
+ *
+ * Input Parameters:
+ *   dev   - device
+ *   space - which resource is being enabled
+ *           PCI_SYS_RES_IOPORT for io port address decoding or
+ *           PCI_RES_MEM for memory
+ *
+ * Return value:
+ *   -EINVAL: error
+ *   OK: OK
+ *
+ ****************************************************************************/
+
+int pci_enable_io(FAR struct pci_dev_s *dev, int res);
+
+/****************************************************************************
+ * Name: pci_disable_io
+ *
+ * Description:
+ *  Enable MMIO or IOPORT
+ *
+ * Input Parameters:
+ *   dev   - device
+ *   space - which resource is being disabled
+ *           PCI_SYS_RES_IOPORT for io port address decoding or
+ *           PCI_SYS_RES_MEM for memory
+ *
+ * Return value:
+ *   -EINVAL: error
+ *   OK: OK
+ *
+ ****************************************************************************/
+
+int pci_disable_io(FAR struct pci_dev_s *dev, int res);
+
+/****************************************************************************
+ * Name: pci_enable_bus_master
+ *
+ * Description:
+ *  Enable bus mastering for device so it can perform PCI accesses
+ *
+ * Input Parameters:
+ *   dev   - device
+ *
+ * Return value:
+ *   -EINVAL: error
+ *   OK: OK
+ *
+ ****************************************************************************/
+
+int pci_enable_bus_master(FAR struct pci_dev_s *dev);
+
+/****************************************************************************
+ * Name: pci_disable_bus_master
+ *
+ * Description:
+ *  Disable bus mastering for device
+ *
+ * Input Parameters:
+ *   dev   - device
+ *
+ * Return value:
+ *   -EINVAL: error
+ *   OK: OK
+ *
+ ****************************************************************************/
+
+int pci_disable_bus_master(FAR struct pci_dev_s *dev);
+
+/****************************************************************************
+ * Name: pci_bar_valid
+ *
+ * Description:
+ *  Determine in if the address in the BAR is valid
+ *
+ * Input Parameters:
+ *   dev   - device
+ *   bar_id - bar number
+ *
+ * Return value:
+ *   -EINVAL: error
+ *   OK: OK
+ *
+ ****************************************************************************/
+
+int pci_bar_valid(FAR struct pci_dev_s *dev, uint8_t bar_id);
+
+/****************************************************************************
+ * Name: pci_bar_is_64
+ *
+ * Description:
+ *  Determine in if the bar address is 64 bit.  If it is the address includes
+ *  the address in the next bar location.
+ *
+ * Input Parameters:
+ *   dev   - device
+ *   bar_id - bar number
+ *
+ * Return value:
+ *   true: 64bit address
+ *
+ ****************************************************************************/
+
+bool pci_bar_is_64(FAR struct pci_dev_s *dev, uint8_t bar_id);
+
+/****************************************************************************
+ * Name: pci_bar_size
+ *
+ * Description:
+ *  Determine the size of the address space required by the BAR
+ *
+ * Input Parameters:
+ *   dev   - device
+ *   bar_id - bar number
+ *
+ * Return value:
+ *   Size of address space
+ *
+ ****************************************************************************/
+
+uint64_t pci_bar_size(FAR struct pci_dev_s *dev, uint8_t bar_id);
+
+/****************************************************************************
+ * Name: pci_bar_addr
+ *
+ * Description:
+ *  Determine the size of the address space required by the BAR
+ *
+ * Input Parameters:
+ *   dev   - device
+ *   bar_id - bar number
+ *
+ * Return value:
+ *   full bar address
+ *
+ ****************************************************************************/
+
+uint64_t pci_bar_addr(FAR struct pci_dev_s *dev, uint8_t bar_id);
+
+/****************************************************************************
+ * Name: pci_dev_dump
+ *
+ * Description:
+ *  Dump the configuration information for the device
+ *
+ * Input Parameters:
+ *   dev   - device
+ *
+ ****************************************************************************/
+
+void pci_dev_dump(FAR struct pci_dev_s *dev);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+#endif
+#endif /* __INCLUDE_NUTTX_PCI_PCI_H */
diff --git a/include/nuttx/pcie/pcie.h b/include/nuttx/pcie/pcie.h
deleted file mode 100644
index fffc791a2d..0000000000
--- a/include/nuttx/pcie/pcie.h
+++ /dev/null
@@ -1,352 +0,0 @@
-/****************************************************************************
- * 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 */
diff --git a/include/nuttx/virt/qemu_pci.h b/include/nuttx/virt/qemu_pci.h
index f8e38f9241..3c3379ed00 100644
--- a/include/nuttx/virt/qemu_pci.h
+++ b/include/nuttx/virt/qemu_pci.h
@@ -42,9 +42,13 @@ extern "C"
 #endif
 
 #ifdef CONFIG_VIRT_QEMU_PCI_TEST
-extern struct pcie_dev_type_s pcie_type_qemu_pci_test;
+extern struct pci_dev_type_s pci_type_qemu_pci_test;
 #endif /* CONFIG_VIRT_QEMU_PCI_TEST */
 
+#ifdef CONFIG_VIRT_QEMU_EDU
+extern struct pci_dev_type_s pci_type_qemu_edu;
+#endif /* CONFIG_VIRT_QEMU_EDU */
+
 #undef EXTERN
 #ifdef __cplusplus
 }

Reply via email to