xiaoxiang781216 commented on code in PR #11583:
URL: https://github.com/apache/nuttx/pull/11583#discussion_r1465361744


##########
arch/x86_64/src/intel64/intel64_mbfb.c:
##########
@@ -0,0 +1,321 @@
+/****************************************************************************
+ * arch/x86_64/src/intel64/intel64_mbfb.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 <string.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+#include <arch/multiboot2.h>
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+#include <nuttx/nx/nxfonts.h>
+#endif
+
+#include "x86_64_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions

Review Comment:
   Private Types
   ```suggestion
    * Private Types
   ```



##########
arch/x86_64/src/intel64/intel64_mbfb.c:
##########
@@ -0,0 +1,321 @@
+/****************************************************************************
+ * arch/x86_64/src/intel64/intel64_mbfb.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 <string.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+#include <arch/multiboot2.h>
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+#include <nuttx/nx/nxfonts.h>
+#endif
+
+#include "x86_64_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+struct multiboot_fb_s
+{
+  void     *baseaddr;
+  uint32_t  height;
+  uint32_t  width;
+  uint32_t  pitch;
+  uint8_t   bpp;
+  uint8_t   type;
+};
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+struct fb_term_s
+{
+  const struct nx_fontpackage_s *font;
+  uint32_t                       cursor_x;
+  uint32_t                       cursor_y;
+};
+
+void fb_term_initialize(void);
+#endif  /* CONFIG_MULTBOOT2_FB_TERM */
+
+void fb_clear(void);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct multiboot_fb_s fb =
+{
+  .baseaddr = NULL
+};
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+struct fb_term_s fb_term;
+#endif
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function:  fb_draw_pixel
+ *
+ * Description:
+ *   Draw a pixel on the framebuffer.  Note that the color paramter must
+ *   be in the format specified by the bpp of the framebuffer.
+ *
+ ****************************************************************************/
+
+static void fb_draw_pixel(uint32_t color, uint32_t x, uint32_t y)
+{
+  /* Check if we support this type of framebuffer */
+
+  if (fb.type != MULTIBOOT_FRAMEBUFFER_TYPE_RGB)
+    {
+      return;
+    }
+
+  /* Make sure we are within the bounds */
+
+  if (x >= fb.width || y >= fb.height)
+    {
+      return;
+    }
+
+  switch (fb.bpp)
+    {
+      case 8:
+        {
+          uint8_t *pixel = (uint8_t *)(
+              (uintptr_t)fb.baseaddr + (fb.pitch * y) + x);
+          *pixel = (uint8_t)color;
+          break;
+        }
+
+      case 15:
+      case 16:
+        {
+          uint16_t *pixel = (uint16_t *)(
+            (uintptr_t)fb.baseaddr + (fb.pitch * y) + x * 2);
+          *pixel = (uint16_t)color;
+          break;
+        }
+
+      case 24:
+        {
+          /* We have to be careful here to not overwrite the lower 8bits
+            * of the next pixel in the buffer.
+            */
+
+          uint32_t *pixel = (uint32_t *)(
+            (uintptr_t)fb.baseaddr + (fb.pitch * y) + x * 3);
+          *pixel = (color & 0xffffff) | (*pixel & 0xff000000);
+          break;
+        }
+
+      case 32:
+        {
+          uint32_t *pixel = (uint32_t *)(
+            (uintptr_t)fb.baseaddr + (fb.pitch * y) + x * 4);
+          *pixel = color;
+          break;
+        }
+    }
+}
+
+#if 0

Review Comment:
   remove the dead code



##########
drivers/pci/pci.c:
##########
@@ -0,0 +1,832 @@
+/****************************************************************************
+ * 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 const 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 const struct pci_dev_type_s **types);
+
+static void pci_scan_bus(FAR struct pci_bus_s *root_bus,
+                         uint8_t bus_idx,
+                         FAR const 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
+ ****************************************************************************/
+
+const struct pci_dev_type_s *pci_device_types[] =
+{
+#ifdef CONFIG_VIRT_QEMU_PCI_TEST
+  &g_pci_type_qemu_pci_test,
+#endif
+#ifdef CONFIG_VIRT_QEMU_EDU
+  &g_pci_type_qemu_edu,
+#endif
+  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 const struct pci_dev_type_s **types)
+{
+  struct pci_dev_s tmp_dev;
+  uint32_t         class_rev;
+  uint16_t         vid;
+  uint16_t         id;
+  int              i;
+
+  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 (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 const struct pci_dev_type_s **types)
+{
+  struct pci_dev_s tmp_dev;
+  uint8_t          multi_function;
+  uint8_t          dev_func = 0;
+  uint16_t         vid;
+  uint8_t          sec_bus;
+
+  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);

Review Comment:
   dup with line 276



##########
arch/x86_64/src/intel64/intel64_mbfb.c:
##########
@@ -0,0 +1,321 @@
+/****************************************************************************
+ * arch/x86_64/src/intel64/intel64_mbfb.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 <string.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+#include <arch/multiboot2.h>
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+#include <nuttx/nx/nxfonts.h>
+#endif
+
+#include "x86_64_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+struct multiboot_fb_s
+{
+  void     *baseaddr;
+  uint32_t  height;
+  uint32_t  width;
+  uint32_t  pitch;
+  uint8_t   bpp;
+  uint8_t   type;
+};
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+struct fb_term_s
+{
+  const struct nx_fontpackage_s *font;
+  uint32_t                       cursor_x;
+  uint32_t                       cursor_y;
+};
+
+void fb_term_initialize(void);
+#endif  /* CONFIG_MULTBOOT2_FB_TERM */
+
+void fb_clear(void);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct multiboot_fb_s fb =

Review Comment:
   ```suggestion
   static struct multiboot_fb_s g_fb =
   ```



##########
arch/x86_64/src/intel64/intel64_mbfb.c:
##########
@@ -0,0 +1,321 @@
+/****************************************************************************
+ * arch/x86_64/src/intel64/intel64_mbfb.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 <string.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+#include <arch/multiboot2.h>
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+#include <nuttx/nx/nxfonts.h>
+#endif
+
+#include "x86_64_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+struct multiboot_fb_s
+{
+  void     *baseaddr;
+  uint32_t  height;
+  uint32_t  width;
+  uint32_t  pitch;
+  uint8_t   bpp;
+  uint8_t   type;
+};
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+struct fb_term_s
+{
+  const struct nx_fontpackage_s *font;
+  uint32_t                       cursor_x;
+  uint32_t                       cursor_y;
+};
+
+void fb_term_initialize(void);
+#endif  /* CONFIG_MULTBOOT2_FB_TERM */
+
+void fb_clear(void);

Review Comment:
   ```suggestion
   static void fb_clear(void);
   ```



##########
drivers/pci/pci.c:
##########
@@ -0,0 +1,832 @@
+/****************************************************************************
+ * 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 const 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 const struct pci_dev_type_s **types);
+
+static void pci_scan_bus(FAR struct pci_bus_s *root_bus,
+                         uint8_t bus_idx,
+                         FAR const 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
+ ****************************************************************************/
+
+const struct pci_dev_type_s *pci_device_types[] =

Review Comment:
   ```suggestion
   const struct pci_dev_type_s *g_pci_device_types[] =
   ```



##########
arch/x86_64/src/intel64/intel64_mbfb.c:
##########
@@ -0,0 +1,321 @@
+/****************************************************************************
+ * arch/x86_64/src/intel64/intel64_mbfb.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 <string.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+#include <arch/multiboot2.h>
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+#include <nuttx/nx/nxfonts.h>
+#endif
+
+#include "x86_64_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+struct multiboot_fb_s
+{
+  void     *baseaddr;
+  uint32_t  height;
+  uint32_t  width;
+  uint32_t  pitch;
+  uint8_t   bpp;
+  uint8_t   type;
+};
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+struct fb_term_s
+{
+  const struct nx_fontpackage_s *font;
+  uint32_t                       cursor_x;
+  uint32_t                       cursor_y;
+};
+
+void fb_term_initialize(void);

Review Comment:
   ```suggestion
   static void fb_term_initialize(void);
   ```



##########
arch/x86_64/src/intel64/intel64_mbfb.c:
##########
@@ -0,0 +1,321 @@
+/****************************************************************************
+ * arch/x86_64/src/intel64/intel64_mbfb.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 <string.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+#include <arch/multiboot2.h>
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+#include <nuttx/nx/nxfonts.h>
+#endif
+
+#include "x86_64_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+struct multiboot_fb_s
+{
+  void     *baseaddr;
+  uint32_t  height;
+  uint32_t  width;
+  uint32_t  pitch;
+  uint8_t   bpp;
+  uint8_t   type;
+};
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+struct fb_term_s
+{
+  const struct nx_fontpackage_s *font;
+  uint32_t                       cursor_x;
+  uint32_t                       cursor_y;
+};
+

Review Comment:
   add private function banner:
   ````
   /****************************************************************************
    * Private Function Prototypes
    
****************************************************************************/
   ```



##########
arch/x86_64/src/intel64/intel64_mbfb.c:
##########
@@ -0,0 +1,321 @@
+/****************************************************************************
+ * arch/x86_64/src/intel64/intel64_mbfb.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 <string.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+#include <arch/multiboot2.h>
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+#include <nuttx/nx/nxfonts.h>
+#endif
+
+#include "x86_64_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+struct multiboot_fb_s
+{
+  void     *baseaddr;
+  uint32_t  height;
+  uint32_t  width;
+  uint32_t  pitch;
+  uint8_t   bpp;
+  uint8_t   type;
+};
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+struct fb_term_s
+{
+  const struct nx_fontpackage_s *font;
+  uint32_t                       cursor_x;
+  uint32_t                       cursor_y;
+};
+
+void fb_term_initialize(void);
+#endif  /* CONFIG_MULTBOOT2_FB_TERM */
+
+void fb_clear(void);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct multiboot_fb_s fb =
+{
+  .baseaddr = NULL
+};
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+struct fb_term_s fb_term;

Review Comment:
   ```suggestion
   static struct fb_term_s g_fb_term;
   ```



##########
arch/x86_64/src/intel64/intel64_mbfb.c:
##########
@@ -0,0 +1,321 @@
+/****************************************************************************
+ * arch/x86_64/src/intel64/intel64_mbfb.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 <string.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+#include <arch/multiboot2.h>
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+#include <nuttx/nx/nxfonts.h>
+#endif
+
+#include "x86_64_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+struct multiboot_fb_s
+{
+  void     *baseaddr;
+  uint32_t  height;
+  uint32_t  width;
+  uint32_t  pitch;
+  uint8_t   bpp;
+  uint8_t   type;
+};
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+struct fb_term_s
+{
+  const struct nx_fontpackage_s *font;
+  uint32_t                       cursor_x;
+  uint32_t                       cursor_y;
+};
+
+void fb_term_initialize(void);
+#endif  /* CONFIG_MULTBOOT2_FB_TERM */
+
+void fb_clear(void);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct multiboot_fb_s fb =
+{
+  .baseaddr = NULL
+};
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+struct fb_term_s fb_term;
+#endif
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function:  fb_draw_pixel
+ *
+ * Description:
+ *   Draw a pixel on the framebuffer.  Note that the color paramter must
+ *   be in the format specified by the bpp of the framebuffer.
+ *
+ ****************************************************************************/
+
+static void fb_draw_pixel(uint32_t color, uint32_t x, uint32_t y)
+{
+  /* Check if we support this type of framebuffer */
+
+  if (fb.type != MULTIBOOT_FRAMEBUFFER_TYPE_RGB)
+    {
+      return;
+    }
+
+  /* Make sure we are within the bounds */
+
+  if (x >= fb.width || y >= fb.height)
+    {
+      return;
+    }
+
+  switch (fb.bpp)
+    {
+      case 8:
+        {
+          uint8_t *pixel = (uint8_t *)(
+              (uintptr_t)fb.baseaddr + (fb.pitch * y) + x);
+          *pixel = (uint8_t)color;
+          break;
+        }
+
+      case 15:
+      case 16:
+        {
+          uint16_t *pixel = (uint16_t *)(
+            (uintptr_t)fb.baseaddr + (fb.pitch * y) + x * 2);
+          *pixel = (uint16_t)color;
+          break;
+        }
+
+      case 24:
+        {
+          /* We have to be careful here to not overwrite the lower 8bits
+            * of the next pixel in the buffer.
+            */
+
+          uint32_t *pixel = (uint32_t *)(
+            (uintptr_t)fb.baseaddr + (fb.pitch * y) + x * 3);
+          *pixel = (color & 0xffffff) | (*pixel & 0xff000000);
+          break;
+        }
+
+      case 32:
+        {
+          uint32_t *pixel = (uint32_t *)(
+            (uintptr_t)fb.baseaddr + (fb.pitch * y) + x * 4);
+          *pixel = color;
+          break;
+        }
+    }
+}
+
+#if 0
+/****************************************************************************
+ * Function:  fb_test_line
+ *
+ * Description:
+ *   This is a simple test function that can be used to draw a 45deg
+ *   line across the screen.
+ *
+ ****************************************************************************/
+
+static void fb_test_line(void)
+{
+  size_t   idx;
+  uint32_t color;
+
+  switch (fb.bpp)
+    {
+      case 8:
+        color = 0xff;
+        break;
+      case 15:
+      case 16:
+        color = 0x7fff;
+        break;
+      case 24:
+        color = 0xffffff;
+        break;
+      case 32:
+        color = 0xffffffff;
+        break;
+      default:
+        return;
+    }
+
+  for (idx = 0; (idx < fb.height) && (idx < fb.width); idx++)
+    {
+      fb_draw_pixel(color, idx, idx);
+    }
+}
+#endif
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+static void fb_scroll(void)
+{
+  void     *destp     = fb.baseaddr;
+  uint32_t  save_rows = ((fb.height / fb_term.font->metrics.mxheight) - 1);
+  size_t    row_size  = fb.pitch * fb_term.font->metrics.mxheight;
+  uint32_t  pxl_row   = 0;
+
+  for (; pxl_row < save_rows * fb_term.font->metrics.mxheight; pxl_row++)
+    {
+      memcpy(destp, destp + row_size, fb.pitch);
+      destp += fb.pitch;
+    }
+
+  memset(destp, 0, fb.pitch * (fb.height - pxl_row));
+
+  fb_term.cursor_y -= fb_term.font->metrics.mxheight;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+void x86_64_mb2_fbinitialize(struct multiboot_tag_framebuffer *fbt)
+{
+  fb.baseaddr = (void *)(uintptr_t)fbt->common.framebuffer_addr;
+  fb.width    = fbt->common.framebuffer_width;
+  fb.height   = fbt->common.framebuffer_height;
+  fb.pitch    = fbt->common.framebuffer_pitch;
+  fb.bpp      = fbt->common.framebuffer_bpp;
+  fb.type     = fbt->common.framebuffer_type;
+
+  up_map_region(fb.baseaddr, fb.pitch * fb.height,
+    X86_PAGE_WR | X86_PAGE_PRESENT |
+    X86_PAGE_NOCACHE | X86_PAGE_GLOBAL);
+
+  fb_clear();
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+  fb_term_initialize();
+#endif
+}
+
+void fb_clear(void)
+{
+  if (fb.baseaddr == NULL)
+    {
+      return;
+    }
+
+  memset(fb.baseaddr, 0, fb.pitch * fb.height);
+}
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+void fb_term_initialize(void)

Review Comment:
   move to private section



##########
arch/x86_64/src/intel64/intel64_mbfb.c:
##########
@@ -0,0 +1,321 @@
+/****************************************************************************
+ * arch/x86_64/src/intel64/intel64_mbfb.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 <string.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+#include <arch/multiboot2.h>
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+#include <nuttx/nx/nxfonts.h>
+#endif
+
+#include "x86_64_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+struct multiboot_fb_s
+{
+  void     *baseaddr;
+  uint32_t  height;
+  uint32_t  width;
+  uint32_t  pitch;
+  uint8_t   bpp;
+  uint8_t   type;
+};
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+struct fb_term_s
+{
+  const struct nx_fontpackage_s *font;
+  uint32_t                       cursor_x;
+  uint32_t                       cursor_y;
+};
+
+void fb_term_initialize(void);
+#endif  /* CONFIG_MULTBOOT2_FB_TERM */
+
+void fb_clear(void);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct multiboot_fb_s fb =
+{
+  .baseaddr = NULL
+};
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+struct fb_term_s fb_term;
+#endif
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function:  fb_draw_pixel
+ *
+ * Description:
+ *   Draw a pixel on the framebuffer.  Note that the color paramter must
+ *   be in the format specified by the bpp of the framebuffer.
+ *
+ ****************************************************************************/
+
+static void fb_draw_pixel(uint32_t color, uint32_t x, uint32_t y)
+{
+  /* Check if we support this type of framebuffer */
+
+  if (fb.type != MULTIBOOT_FRAMEBUFFER_TYPE_RGB)
+    {
+      return;
+    }
+
+  /* Make sure we are within the bounds */
+
+  if (x >= fb.width || y >= fb.height)
+    {
+      return;
+    }
+
+  switch (fb.bpp)
+    {
+      case 8:
+        {
+          uint8_t *pixel = (uint8_t *)(
+              (uintptr_t)fb.baseaddr + (fb.pitch * y) + x);
+          *pixel = (uint8_t)color;
+          break;
+        }
+
+      case 15:
+      case 16:
+        {
+          uint16_t *pixel = (uint16_t *)(
+            (uintptr_t)fb.baseaddr + (fb.pitch * y) + x * 2);
+          *pixel = (uint16_t)color;
+          break;
+        }
+
+      case 24:
+        {
+          /* We have to be careful here to not overwrite the lower 8bits
+            * of the next pixel in the buffer.
+            */
+
+          uint32_t *pixel = (uint32_t *)(
+            (uintptr_t)fb.baseaddr + (fb.pitch * y) + x * 3);
+          *pixel = (color & 0xffffff) | (*pixel & 0xff000000);
+          break;
+        }
+
+      case 32:
+        {
+          uint32_t *pixel = (uint32_t *)(
+            (uintptr_t)fb.baseaddr + (fb.pitch * y) + x * 4);
+          *pixel = color;
+          break;
+        }
+    }
+}
+
+#if 0
+/****************************************************************************
+ * Function:  fb_test_line
+ *
+ * Description:
+ *   This is a simple test function that can be used to draw a 45deg
+ *   line across the screen.
+ *
+ ****************************************************************************/
+
+static void fb_test_line(void)
+{
+  size_t   idx;
+  uint32_t color;
+
+  switch (fb.bpp)
+    {
+      case 8:
+        color = 0xff;
+        break;
+      case 15:
+      case 16:
+        color = 0x7fff;
+        break;
+      case 24:
+        color = 0xffffff;
+        break;
+      case 32:
+        color = 0xffffffff;
+        break;
+      default:
+        return;
+    }
+
+  for (idx = 0; (idx < fb.height) && (idx < fb.width); idx++)
+    {
+      fb_draw_pixel(color, idx, idx);
+    }
+}
+#endif
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+static void fb_scroll(void)
+{
+  void     *destp     = fb.baseaddr;
+  uint32_t  save_rows = ((fb.height / fb_term.font->metrics.mxheight) - 1);
+  size_t    row_size  = fb.pitch * fb_term.font->metrics.mxheight;
+  uint32_t  pxl_row   = 0;
+
+  for (; pxl_row < save_rows * fb_term.font->metrics.mxheight; pxl_row++)
+    {
+      memcpy(destp, destp + row_size, fb.pitch);
+      destp += fb.pitch;
+    }
+
+  memset(destp, 0, fb.pitch * (fb.height - pxl_row));
+
+  fb_term.cursor_y -= fb_term.font->metrics.mxheight;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+void x86_64_mb2_fbinitialize(struct multiboot_tag_framebuffer *fbt)
+{
+  fb.baseaddr = (void *)(uintptr_t)fbt->common.framebuffer_addr;
+  fb.width    = fbt->common.framebuffer_width;
+  fb.height   = fbt->common.framebuffer_height;
+  fb.pitch    = fbt->common.framebuffer_pitch;
+  fb.bpp      = fbt->common.framebuffer_bpp;
+  fb.type     = fbt->common.framebuffer_type;
+
+  up_map_region(fb.baseaddr, fb.pitch * fb.height,
+    X86_PAGE_WR | X86_PAGE_PRESENT |
+    X86_PAGE_NOCACHE | X86_PAGE_GLOBAL);
+
+  fb_clear();
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+  fb_term_initialize();
+#endif
+}
+
+void fb_clear(void)

Review Comment:
   move to private section



##########
arch/x86_64/src/intel64/intel64_mbfb.c:
##########
@@ -0,0 +1,321 @@
+/****************************************************************************
+ * arch/x86_64/src/intel64/intel64_mbfb.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 <string.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+#include <arch/multiboot2.h>
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+#include <nuttx/nx/nxfonts.h>
+#endif
+
+#include "x86_64_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+struct multiboot_fb_s
+{
+  void     *baseaddr;
+  uint32_t  height;
+  uint32_t  width;
+  uint32_t  pitch;
+  uint8_t   bpp;
+  uint8_t   type;
+};
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+struct fb_term_s
+{
+  const struct nx_fontpackage_s *font;
+  uint32_t                       cursor_x;
+  uint32_t                       cursor_y;
+};
+
+void fb_term_initialize(void);
+#endif  /* CONFIG_MULTBOOT2_FB_TERM */
+
+void fb_clear(void);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct multiboot_fb_s fb =
+{
+  .baseaddr = NULL
+};
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+struct fb_term_s fb_term;
+#endif
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function:  fb_draw_pixel
+ *
+ * Description:
+ *   Draw a pixel on the framebuffer.  Note that the color paramter must
+ *   be in the format specified by the bpp of the framebuffer.
+ *
+ ****************************************************************************/
+
+static void fb_draw_pixel(uint32_t color, uint32_t x, uint32_t y)
+{
+  /* Check if we support this type of framebuffer */
+
+  if (fb.type != MULTIBOOT_FRAMEBUFFER_TYPE_RGB)
+    {
+      return;
+    }
+
+  /* Make sure we are within the bounds */
+
+  if (x >= fb.width || y >= fb.height)
+    {
+      return;
+    }
+
+  switch (fb.bpp)
+    {
+      case 8:
+        {
+          uint8_t *pixel = (uint8_t *)(
+              (uintptr_t)fb.baseaddr + (fb.pitch * y) + x);
+          *pixel = (uint8_t)color;
+          break;
+        }
+
+      case 15:
+      case 16:
+        {
+          uint16_t *pixel = (uint16_t *)(
+            (uintptr_t)fb.baseaddr + (fb.pitch * y) + x * 2);
+          *pixel = (uint16_t)color;
+          break;
+        }
+
+      case 24:
+        {
+          /* We have to be careful here to not overwrite the lower 8bits
+            * of the next pixel in the buffer.
+            */
+
+          uint32_t *pixel = (uint32_t *)(
+            (uintptr_t)fb.baseaddr + (fb.pitch * y) + x * 3);
+          *pixel = (color & 0xffffff) | (*pixel & 0xff000000);
+          break;
+        }
+
+      case 32:
+        {
+          uint32_t *pixel = (uint32_t *)(
+            (uintptr_t)fb.baseaddr + (fb.pitch * y) + x * 4);
+          *pixel = color;
+          break;
+        }
+    }
+}
+
+#if 0
+/****************************************************************************
+ * Function:  fb_test_line
+ *
+ * Description:
+ *   This is a simple test function that can be used to draw a 45deg
+ *   line across the screen.
+ *
+ ****************************************************************************/
+
+static void fb_test_line(void)
+{
+  size_t   idx;
+  uint32_t color;
+
+  switch (fb.bpp)
+    {
+      case 8:
+        color = 0xff;
+        break;
+      case 15:
+      case 16:
+        color = 0x7fff;
+        break;
+      case 24:
+        color = 0xffffff;
+        break;
+      case 32:
+        color = 0xffffffff;
+        break;
+      default:
+        return;
+    }
+
+  for (idx = 0; (idx < fb.height) && (idx < fb.width); idx++)
+    {
+      fb_draw_pixel(color, idx, idx);
+    }
+}
+#endif
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+static void fb_scroll(void)
+{
+  void     *destp     = fb.baseaddr;
+  uint32_t  save_rows = ((fb.height / fb_term.font->metrics.mxheight) - 1);
+  size_t    row_size  = fb.pitch * fb_term.font->metrics.mxheight;
+  uint32_t  pxl_row   = 0;
+
+  for (; pxl_row < save_rows * fb_term.font->metrics.mxheight; pxl_row++)

Review Comment:
   ```suggestion
     for (; pxl_row < save_rows; pxl_row++)
   ```



##########
boards/x86_64/intel64/qemu-intel64/src/qemu_pci.c:
##########
@@ -0,0 +1,229 @@
+/****************************************************************************
+ * 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 "x86_64_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(struct pci_dev_s *dev, int reg,
+                               uint32_t val, int width);
+
+static uint32_t qemu_pci_cfg_read(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(const volatile void *addr, int width);
+
+static void qemu_pci_io_write(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 =

Review Comment:
   ```suggestion
   static struct pci_bus_s g_qemu_pci_bus =
   ```



##########
boards/x86_64/intel64/qemu-intel64/src/qemu_pci.c:
##########
@@ -0,0 +1,229 @@
+/****************************************************************************
+ * 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 "x86_64_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(struct pci_dev_s *dev, int reg,
+                               uint32_t val, int width);
+
+static uint32_t qemu_pci_cfg_read(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(const volatile void *addr, int width);
+
+static void qemu_pci_io_write(const volatile void *addr, uint32_t val,
+                              int width);
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+struct pci_bus_ops_s qemu_pci_bus_ops =

Review Comment:
   ```suggestion
   static const struct pci_bus_ops_s g_qemu_pci_bus_ops =
   ```
   move to private section



##########
boards/x86_64/intel64/qemu-intel64/src/qemu_pci.c:
##########
@@ -0,0 +1,229 @@
+/****************************************************************************
+ * 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 "x86_64_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(struct pci_dev_s *dev, int reg,
+                               uint32_t val, int width);
+
+static uint32_t qemu_pci_cfg_read(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(const volatile void *addr, int width);
+
+static void qemu_pci_io_write(const volatile void *addr, uint32_t val,
+                              int width);
+
+/****************************************************************************
+ * Public Data

Review Comment:
   ```suggestion
    * Private Data
   ```



##########
boards/x86_64/intel64/qemu-intel64/src/qemu_pci.c:
##########
@@ -0,0 +1,229 @@
+/****************************************************************************
+ * 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 "x86_64_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(struct pci_dev_s *dev, int reg,
+                               uint32_t val, int width);
+
+static uint32_t qemu_pci_cfg_read(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(const volatile void *addr, int width);
+
+static void qemu_pci_io_write(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(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(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(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(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);

Review Comment:
   ```suggestion
         outw((uint16_t)val, portaddr);
   ```



##########
drivers/pci/pci.c:
##########
@@ -0,0 +1,832 @@
+/****************************************************************************
+ * 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 const 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 const struct pci_dev_type_s **types);
+
+static void pci_scan_bus(FAR struct pci_bus_s *root_bus,
+                         uint8_t bus_idx,
+                         FAR const 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
+ ****************************************************************************/
+
+const struct pci_dev_type_s *pci_device_types[] =
+{
+#ifdef CONFIG_VIRT_QEMU_PCI_TEST
+  &g_pci_type_qemu_pci_test,
+#endif
+#ifdef CONFIG_VIRT_QEMU_EDU
+  &g_pci_type_qemu_edu,
+#endif
+  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 const struct pci_dev_type_s **types)
+{
+  struct pci_dev_s tmp_dev;
+  uint32_t         class_rev;
+  uint16_t         vid;
+  uint16_t         id;
+  int              i;
+
+  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 (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 const struct pci_dev_type_s **types)
+{
+  struct pci_dev_s tmp_dev;
+  uint8_t          multi_function;
+  uint8_t          dev_func = 0;
+  uint16_t         vid;
+  uint8_t          sec_bus;
+
+  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 const 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;

Review Comment:
   removee



##########
arch/x86_64/src/intel64/intel64_mbfb.c:
##########
@@ -0,0 +1,321 @@
+/****************************************************************************
+ * arch/x86_64/src/intel64/intel64_mbfb.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 <string.h>
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+#include <arch/multiboot2.h>
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+#include <nuttx/nx/nxfonts.h>
+#endif
+
+#include "x86_64_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+struct multiboot_fb_s
+{
+  void     *baseaddr;
+  uint32_t  height;
+  uint32_t  width;
+  uint32_t  pitch;
+  uint8_t   bpp;
+  uint8_t   type;
+};
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+struct fb_term_s
+{
+  const struct nx_fontpackage_s *font;
+  uint32_t                       cursor_x;
+  uint32_t                       cursor_y;
+};
+
+void fb_term_initialize(void);
+#endif  /* CONFIG_MULTBOOT2_FB_TERM */
+
+void fb_clear(void);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct multiboot_fb_s fb =
+{
+  .baseaddr = NULL
+};
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+struct fb_term_s fb_term;
+#endif
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function:  fb_draw_pixel
+ *
+ * Description:
+ *   Draw a pixel on the framebuffer.  Note that the color paramter must
+ *   be in the format specified by the bpp of the framebuffer.
+ *
+ ****************************************************************************/
+
+static void fb_draw_pixel(uint32_t color, uint32_t x, uint32_t y)
+{
+  /* Check if we support this type of framebuffer */
+
+  if (fb.type != MULTIBOOT_FRAMEBUFFER_TYPE_RGB)
+    {
+      return;
+    }
+
+  /* Make sure we are within the bounds */
+
+  if (x >= fb.width || y >= fb.height)
+    {
+      return;
+    }
+
+  switch (fb.bpp)
+    {
+      case 8:
+        {
+          uint8_t *pixel = (uint8_t *)(
+              (uintptr_t)fb.baseaddr + (fb.pitch * y) + x);
+          *pixel = (uint8_t)color;
+          break;
+        }
+
+      case 15:
+      case 16:
+        {
+          uint16_t *pixel = (uint16_t *)(
+            (uintptr_t)fb.baseaddr + (fb.pitch * y) + x * 2);
+          *pixel = (uint16_t)color;
+          break;
+        }
+
+      case 24:
+        {
+          /* We have to be careful here to not overwrite the lower 8bits
+            * of the next pixel in the buffer.
+            */
+
+          uint32_t *pixel = (uint32_t *)(
+            (uintptr_t)fb.baseaddr + (fb.pitch * y) + x * 3);
+          *pixel = (color & 0xffffff) | (*pixel & 0xff000000);
+          break;
+        }
+
+      case 32:
+        {
+          uint32_t *pixel = (uint32_t *)(
+            (uintptr_t)fb.baseaddr + (fb.pitch * y) + x * 4);
+          *pixel = color;
+          break;
+        }
+    }
+}
+
+#if 0
+/****************************************************************************
+ * Function:  fb_test_line
+ *
+ * Description:
+ *   This is a simple test function that can be used to draw a 45deg
+ *   line across the screen.
+ *
+ ****************************************************************************/
+
+static void fb_test_line(void)
+{
+  size_t   idx;
+  uint32_t color;
+
+  switch (fb.bpp)
+    {
+      case 8:
+        color = 0xff;
+        break;
+      case 15:
+      case 16:
+        color = 0x7fff;
+        break;
+      case 24:
+        color = 0xffffff;
+        break;
+      case 32:
+        color = 0xffffffff;
+        break;
+      default:
+        return;
+    }
+
+  for (idx = 0; (idx < fb.height) && (idx < fb.width); idx++)
+    {
+      fb_draw_pixel(color, idx, idx);
+    }
+}
+#endif
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+static void fb_scroll(void)
+{
+  void     *destp     = fb.baseaddr;
+  uint32_t  save_rows = ((fb.height / fb_term.font->metrics.mxheight) - 1);
+  size_t    row_size  = fb.pitch * fb_term.font->metrics.mxheight;
+  uint32_t  pxl_row   = 0;
+
+  for (; pxl_row < save_rows * fb_term.font->metrics.mxheight; pxl_row++)
+    {
+      memcpy(destp, destp + row_size, fb.pitch);
+      destp += fb.pitch;
+    }
+
+  memset(destp, 0, fb.pitch * (fb.height - pxl_row));
+
+  fb_term.cursor_y -= fb_term.font->metrics.mxheight;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+void x86_64_mb2_fbinitialize(struct multiboot_tag_framebuffer *fbt)
+{
+  fb.baseaddr = (void *)(uintptr_t)fbt->common.framebuffer_addr;
+  fb.width    = fbt->common.framebuffer_width;
+  fb.height   = fbt->common.framebuffer_height;
+  fb.pitch    = fbt->common.framebuffer_pitch;
+  fb.bpp      = fbt->common.framebuffer_bpp;
+  fb.type     = fbt->common.framebuffer_type;
+
+  up_map_region(fb.baseaddr, fb.pitch * fb.height,
+    X86_PAGE_WR | X86_PAGE_PRESENT |
+    X86_PAGE_NOCACHE | X86_PAGE_GLOBAL);
+
+  fb_clear();
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+  fb_term_initialize();
+#endif
+}
+
+void fb_clear(void)
+{
+  if (fb.baseaddr == NULL)
+    {
+      return;
+    }
+
+  memset(fb.baseaddr, 0, fb.pitch * fb.height);
+}
+
+#ifdef CONFIG_MULTBOOT2_FB_TERM
+void fb_term_initialize(void)
+{
+  fb_term.font = nxf_getfonthandle(FONTID_DEFAULT);
+  fb_term.cursor_x = 0;
+  fb_term.cursor_y = 0;
+}
+
+void fb_putc(char ch)
+{
+  const struct nx_fontbitmap_s *fbm;
+  uint8_t                       gly_x;
+  uint8_t                       gly_y;
+
+  if (fb.baseaddr == NULL)
+    {
+      return;
+    }
+
+  if (ch == '\n')
+    {
+      fb_term.cursor_y += fb_term.font->metrics.mxheight;
+      return;
+    }
+
+  if (ch == '\r')
+    {
+      fb_term.cursor_x = 0;
+      return;
+    }
+
+  fbm = nxf_getbitmap((NXHANDLE)fb_term.font, ch);
+  if (fbm == NULL)
+    {
+      fb_putc('.');
+      return;
+    }
+
+  for (gly_y = 0; gly_y < fbm->metric.height; gly_y++)
+    {
+      if (fb_term.cursor_y + gly_y >= fb.height)
+        {
+          fb_scroll();
+          fb_putc(ch);
+          return;
+        }
+
+      for (gly_x = 0; gly_x < fbm->metric.width; gly_x++)
+        {
+          if (fb_term.cursor_x + gly_x >= fb.width)
+            {
+              break;
+            }
+
+          uint8_t  stride   = (fbm->metric.width + 7) >> 3;
+          uint8_t  gly_byte = stride * gly_y + (gly_x >> 3);
+          uint8_t  gly_bit  = gly_x & 0x7;
+          uint32_t color    = 0;
+
+          if ((fbm->bitmap[gly_byte] >> (7 - gly_bit)) & 0x01)
+            {
+              /* Black no matter the color depth */

Review Comment:
   ```suggestion
                 /* White no matter the color depth */
   ```



##########
drivers/pci/pci.c:
##########
@@ -0,0 +1,832 @@
+/****************************************************************************
+ * 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 const 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 const struct pci_dev_type_s **types);
+
+static void pci_scan_bus(FAR struct pci_bus_s *root_bus,
+                         uint8_t bus_idx,
+                         FAR const 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
+ ****************************************************************************/
+
+const struct pci_dev_type_s *pci_device_types[] =
+{
+#ifdef CONFIG_VIRT_QEMU_PCI_TEST
+  &g_pci_type_qemu_pci_test,
+#endif
+#ifdef CONFIG_VIRT_QEMU_EDU
+  &g_pci_type_qemu_edu,
+#endif
+  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 const struct pci_dev_type_s **types)
+{
+  struct pci_dev_s tmp_dev;
+  uint32_t         class_rev;
+  uint16_t         vid;
+  uint16_t         id;
+  int              i;
+
+  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 (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 \

Review Comment:
   ```suggestion
                         pcierr("[%02x:%02x.%x] Error: Invalid ”
                                “device probe function\n”,
   ```



##########
boards/x86_64/intel64/qemu-intel64/src/qemu_pci.c:
##########
@@ -0,0 +1,229 @@
+/****************************************************************************
+ * 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 "x86_64_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(struct pci_dev_s *dev, int reg,
+                               uint32_t val, int width);
+
+static uint32_t qemu_pci_cfg_read(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(const volatile void *addr, int width);
+
+static void qemu_pci_io_write(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(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(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(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(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);

Review Comment:
   ```suggestion
         outl((uint32_t)val, portaddr);
   ```



##########
drivers/pci/pci.c:
##########
@@ -0,0 +1,832 @@
+/****************************************************************************
+ * 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 const 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 const struct pci_dev_type_s **types);
+
+static void pci_scan_bus(FAR struct pci_bus_s *root_bus,
+                         uint8_t bus_idx,
+                         FAR const 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
+ ****************************************************************************/
+
+const struct pci_dev_type_s *pci_device_types[] =
+{
+#ifdef CONFIG_VIRT_QEMU_PCI_TEST
+  &g_pci_type_qemu_pci_test,
+#endif
+#ifdef CONFIG_VIRT_QEMU_EDU
+  &g_pci_type_qemu_edu,
+#endif
+  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 const struct pci_dev_type_s **types)
+{
+  struct pci_dev_s tmp_dev;
+  uint32_t         class_rev;
+  uint16_t         vid;
+  uint16_t         id;
+  int              i;
+
+  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 (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

Review Comment:
   ```suggestion
         /* This is a bridge device we need to determine the bus idx and
   ```



##########
drivers/pci/pci.c:
##########
@@ -0,0 +1,832 @@
+/****************************************************************************
+ * 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 const 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 const struct pci_dev_type_s **types);
+
+static void pci_scan_bus(FAR struct pci_bus_s *root_bus,
+                         uint8_t bus_idx,
+                         FAR const 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
+ ****************************************************************************/
+
+const struct pci_dev_type_s *pci_device_types[] =
+{
+#ifdef CONFIG_VIRT_QEMU_PCI_TEST
+  &g_pci_type_qemu_pci_test,
+#endif
+#ifdef CONFIG_VIRT_QEMU_EDU
+  &g_pci_type_qemu_edu,
+#endif
+  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 const struct pci_dev_type_s **types)
+{
+  struct pci_dev_s tmp_dev;
+  uint32_t         class_rev;
+  uint16_t         vid;
+  uint16_t         id;
+  int              i;
+
+  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 (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);

Review Comment:
   ```suggestion
               bus_idx, slot_idx, dev_func);
   ```



##########
drivers/pci/pci.c:
##########
@@ -0,0 +1,832 @@
+/****************************************************************************
+ * 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 const 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 const struct pci_dev_type_s **types);
+
+static void pci_scan_bus(FAR struct pci_bus_s *root_bus,
+                         uint8_t bus_idx,
+                         FAR const 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
+ ****************************************************************************/
+
+const struct pci_dev_type_s *pci_device_types[] =
+{
+#ifdef CONFIG_VIRT_QEMU_PCI_TEST
+  &g_pci_type_qemu_pci_test,
+#endif
+#ifdef CONFIG_VIRT_QEMU_EDU
+  &g_pci_type_qemu_edu,
+#endif
+  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 const struct pci_dev_type_s **types)
+{
+  struct pci_dev_s tmp_dev;
+  uint32_t         class_rev;
+  uint16_t         vid;
+  uint16_t         id;
+  int              i;
+
+  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 (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))

Review Comment:
   ```suggestion
         (sub_class == PCI_CLASS_SUB_PCI_BRG))
   ```



##########
include/nuttx/pci/pci.h:
##########
@@ -0,0 +1,472 @@
+/****************************************************************************
+ * 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
+{
+  /* Write 8, 16, 32, 64 bits data to PCI-E configuration space of device
+   * specified by dev.
+   */
+
+  CODE void (*pci_cfg_write)(FAR struct pci_dev_s *dev, int reg,
+                             uint32_t val, int width);
+
+  /* Read 8, 16, 32, 64 bits data to PCI-E configuration space of device
+   * specified by dev.
+   */
+
+  CODE uint32_t (*pci_cfg_read)(FAR struct pci_dev_s *dev, int reg,
+                                int width);
+
+  /* Map address in a 32 bits bar in the memory address space */
+
+  CODE int (*pci_map_bar)(uint64_t addr, uint64_t len);

Review Comment:
   should we support map return a different address?



##########
drivers/virt/qemu_edu.c:
##########
@@ -0,0 +1,464 @@
+/*****************************************************************************
+ * 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 <debug.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);
+
+static int qemu_edu_probe(FAR struct pci_bus_s *bus,
+                          FAR const struct pci_dev_type_s *type,
+                          uint16_t bdf);
+
+/*****************************************************************************
+ * Public Data
+ *****************************************************************************/
+
+const struct pci_dev_type_s g_pci_type_qemu_edu =
+{
+  .vendor    = 0x1234,
+  .device    = 0x11e8,
+  .class_rev = PCI_ID_ANY,
+  .name      = "Qemu PCI EDU device",
+  .probe     = qemu_edu_probe
+};
+
+/*****************************************************************************
+ * 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,
+                               FAR 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,
+                              FAR struct qemu_edu_priv_s *drv_priv)
+{
+  uintptr_t  base_addr  = drv_priv->base_addr;
+  FAR 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;

Review Comment:
   is it good to use a hard code address



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to