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

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


The following commit(s) were added to refs/heads/master by this push:
     new 4fa6d4b791 drivers/pci: epc add dma heap
4fa6d4b791 is described below

commit 4fa6d4b7912c7d44d47bfc63c8ba9c549c10633c
Author: lipengfei28 <lipengfe...@xiaomi.com>
AuthorDate: Fri Jul 25 10:48:12 2025 +0800

    drivers/pci: epc add dma heap
    
    The PCI inbound address space and the CPU cache need to maintain cache 
coherence
    
    Signed-off-by: lipengfei28 <lipengfe...@xiaomi.com>
---
 drivers/pci/pci_epc.c       | 110 +++++++++++++++++++++++++++++++++++++++++++-
 drivers/pci/pci_epf.c       |   2 +-
 drivers/pci/pci_qemu_epc.c  |   4 +-
 include/nuttx/pci/pci_epc.h |  74 ++++++++++++++++++++++++++---
 4 files changed, 179 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/pci_epc.c b/drivers/pci/pci_epc.c
index 20f6ea8135..8d11480d64 100644
--- a/drivers/pci/pci_epc.c
+++ b/drivers/pci/pci_epc.c
@@ -30,6 +30,7 @@
 #include <debug.h>
 
 #include <nuttx/bits.h>
+#include <nuttx/mm/mm.h>
 #include <nuttx/kmalloc.h>
 #include <nuttx/lib/math32.h>
 #include <nuttx/pci/pci_epc.h>
@@ -967,6 +968,8 @@ void pci_epc_bme_notify(FAR struct pci_epc_ctrl_s *epc)
  * Input Parameters:
  *   name        - EPC name strings
  *   priv        - The epc priv data
+ *   dma_addr    - Used for inbound address
+ *   dma_len     - The dma memory len
  *   ops         - Function pointers for performing EPC operations
  *
  * Returned Value:
@@ -975,8 +978,8 @@ void pci_epc_bme_notify(FAR struct pci_epc_ctrl_s *epc)
  ****************************************************************************/
 
 FAR struct pci_epc_ctrl_s *
-pci_epc_create(FAR const char *name, FAR void *priv,
-               FAR const struct pci_epc_ops_s *ops)
+pci_epc_create(FAR const char *name, FAR void *priv, FAR void *dma_addr,
+               size_t dma_len, FAR const struct pci_epc_ops_s *ops)
 {
   FAR struct pci_epc_ctrl_s *epc;
   size_t len;
@@ -993,6 +996,16 @@ pci_epc_create(FAR const char *name, FAR void *priv,
       return NULL;
     }
 
+  if (dma_addr != NULL && dma_len != 0)
+    {
+      epc->dmaheap = mm_initialize_pool("pci_dma", dma_addr, dma_len, NULL);
+      if (epc->dmaheap == NULL)
+        {
+          pcierr("Create DMA heap error \n");
+          goto free_epc;
+        }
+    }
+
   epc->priv = priv;
   memcpy(epc->name, name, len);
   nxmutex_init(&epc->lock);
@@ -1004,6 +1017,10 @@ pci_epc_create(FAR const char *name, FAR void *priv,
   nxmutex_unlock(&g_pci_epc_lock);
 
   return epc;
+
+free_epc:
+  kmm_free(epc);
+  return NULL;
 }
 
 /****************************************************************************
@@ -1036,3 +1053,92 @@ void pci_epc_destroy(FAR struct pci_epc_ctrl_s *epc)
   nxmutex_destroy(&epc->lock);
   kmm_free(epc);
 }
+
+/****************************************************************************
+ * Name: pci_epc_dma_alloc
+ *
+ * Description:
+ *   This function is used to create a new endpoint controller (EPC) device.
+ *
+ *   Invoke to destroy the PCI EPC device.
+ *
+ * Input Parameters:
+ *   epc  - The EPC device that has to be destroyed
+ *   size - The dma memory size
+ *
+ * Returned Value:
+ *   The point of dma memory if success, NULL if failed
+ *
+ ****************************************************************************/
+
+FAR void *pci_epc_dma_alloc(FAR struct pci_epc_ctrl_s *epc, size_t size)
+{
+  if (epc->dmaheap != NULL)
+    {
+      return mm_malloc(epc->dmaheap, size);
+    }
+  else
+    {
+      return kmm_malloc(size);
+    }
+}
+
+/****************************************************************************
+ * Name: pci_epc_dma_memalign
+ *
+ * Description:
+ *   This function is used to create a new endpoint controller (EPC) device.
+ *
+ *   Invoke to destroy the PCI EPC device.
+ *
+ * Input Parameters:
+ *   epc       - The EPC device that has to be destroyed
+ *   alignment - Alignment size
+ *   size      - The dma memory size
+ *
+ * Returned Value:
+ *   The point of dma memory if success, NULL if failed
+ *
+ ****************************************************************************/
+
+FAR void *pci_epc_dma_memalign(FAR struct pci_epc_ctrl_s *epc,
+                               size_t alignment, size_t size)
+{
+  if (epc->dmaheap != NULL)
+    {
+      return mm_memalign(epc->dmaheap, alignment, size);
+    }
+  else
+    {
+      return kmm_memalign(alignment, size);
+    }
+}
+
+/****************************************************************************
+ * Name: pci_epc_dma_free
+ *
+ * Description:
+ *   This function is used to create a new endpoint controller (EPC) device.
+ *
+ *   Invoke to destroy the PCI EPC device.
+ *
+ * Input Parameters:
+ *   epc       - The EPC device that has to be destroyed
+ *   mem       - The dma memory need ed to be free
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void pci_epc_dma_free(FAR struct pci_epc_ctrl_s *epc, FAR void *mem)
+{
+  if (epc->dmaheap != NULL)
+    {
+      mm_free(epc->dmaheap, mem);
+    }
+  else
+    {
+      kmm_free(mem);
+    }
+}
diff --git a/drivers/pci/pci_epf.c b/drivers/pci/pci_epf.c
index ddb3e1002b..b16e269d30 100644
--- a/drivers/pci/pci_epf.c
+++ b/drivers/pci/pci_epf.c
@@ -254,7 +254,7 @@ FAR void *pci_epf_alloc_space(FAR struct pci_epf_device_s 
*epf, int barno,
 
   bar = epf->bar;
 
-  space = kmm_zalloc(size);
+  space = pci_epc_dma_memalign(epf->epc, align, size);
   if (space == NULL)
     {
       pcierr("Failed to allocate mem space\n");
diff --git a/drivers/pci/pci_qemu_epc.c b/drivers/pci/pci_qemu_epc.c
index 39221741fd..f2d2924920 100644
--- a/drivers/pci/pci_qemu_epc.c
+++ b/drivers/pci/pci_qemu_epc.c
@@ -803,10 +803,10 @@ static int qemu_epc_probe(FAR struct pci_device_s *dev)
     }
 
   qep->pdev = dev;
-  epc = pci_epc_create("qemu_epc", qep, &g_qemu_epc_ops);
+  epc = pci_epc_create("qemu_epc", qep, NULL, 0, &g_qemu_epc_ops);
   if (epc == NULL)
     {
-      pcierr("Failed to create epc device\n");
+      pcierr("Failed to create qemu_epc device\n");
       ret = -ENOMEM;
       goto err_free_epc;
     }
diff --git a/include/nuttx/pci/pci_epc.h b/include/nuttx/pci/pci_epc.h
index 1330b57f16..0f317f352f 100644
--- a/include/nuttx/pci/pci_epc.h
+++ b/include/nuttx/pci/pci_epc.h
@@ -181,6 +181,7 @@ struct pci_epc_mem_s
  * num_windows: Number of mem supported by device
  * max_functions: Max number of functions that can be configured in this EPC
  * node: The node of epc list
+ * dmaheap: The dma heap
  * lock: Mutex to protect pci_epc ops
  * funcno_map: Bitmap to manage physical function number
  * priv: The private data
@@ -195,6 +196,7 @@ struct pci_epc_ctrl_s
   unsigned int num_windows;
   uint8_t max_functions;
   struct list_node node;
+  FAR struct mm_heap_s *dmaheap;
 
   /* Mutex to protect against concurrent access of EP controller */
 
@@ -714,9 +716,11 @@ void pci_epc_bme_notify(FAR struct pci_epc_ctrl_s *epc);
  *   Invoke to create a new EPC device and add it to pci_epc class.
  *
  * Input Parameters:
- *   name - EPC name strings
- *   priv - The epc priv data
- *   ops  - Function pointers for performing EPC operations
+ *   name        - EPC name strings
+ *   priv        - The epc priv data
+ *   dma_addr    - Used for inbound address
+ *   dma_len     - The dma memory len
+ *   ops         - Function pointers for performing EPC operations
  *
  * Returned Value:
  *   Return struct pci_epc_ctrl_s * if success, NULL if failed.
@@ -724,9 +728,8 @@ void pci_epc_bme_notify(FAR struct pci_epc_ctrl_s *epc);
  ****************************************************************************/
 
 FAR struct pci_epc_ctrl_s *
-pci_epc_create(FAR const char *name, FAR void *priv,
-               FAR const struct pci_epc_ops_s *ops);
-
+pci_epc_create(FAR const char *name, FAR void *priv, FAR void *dma_addr,
+               size_t dma_len, FAR const struct pci_epc_ops_s *ops);
 /****************************************************************************
  * Name: pci_epc_destroy
  *
@@ -852,4 +855,63 @@ FAR void *pci_epc_mem_alloc_addr(FAR struct pci_epc_ctrl_s 
*epc,
 void pci_epc_mem_free_addr(FAR struct pci_epc_ctrl_s *epc,
                            uintptr_t phys_addr, size_t size);
 
+/****************************************************************************
+ * Name: pci_epc_dma_alloc
+ *
+ * Description:
+ *   This function is used to create a new endpoint controller (EPC) device.
+ *
+ *   Invoke to destroy the PCI EPC device.
+ *
+ * Input Parameters:
+ *   epc  - The EPC device that has to be destroyed
+ *   size - The dma memory size
+ *
+ * Returned Value:
+ *   The point of dma memory if success, NULL if failed
+ *
+ ****************************************************************************/
+
+FAR void *pci_epc_dma_alloc(FAR struct pci_epc_ctrl_s *epc, size_t size);
+
+/****************************************************************************
+ * Name: pci_epc_dma_memalign
+ *
+ * Description:
+ *   This function is used to create a new endpoint controller (EPC) device.
+ *
+ *   Invoke to destroy the PCI EPC device.
+ *
+ * Input Parameters:
+ *   epc       - The EPC device that has to be destroyed
+ *   alignment - Alignment size
+ *   size      - The dma memory size
+ *
+ * Returned Value:
+ *   The point of dma memory if success, NULL if failed
+ *
+ ****************************************************************************/
+
+FAR void *pci_epc_dma_memalign(FAR struct pci_epc_ctrl_s *epc,
+                               size_t alignment, size_t size);
+
+/****************************************************************************
+ * Name: pci_epc_dma_free
+ *
+ * Description:
+ *   This function is used to create a new endpoint controller (EPC) device.
+ *
+ *   Invoke to destroy the PCI EPC device.
+ *
+ * Input Parameters:
+ *   epc       - The EPC device that has to be destroyed
+ *   mem       - The dma memory need ed to be free
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void pci_epc_dma_free(FAR struct pci_epc_ctrl_s *epc, FAR void *mem);
+
 #endif /* __INCLUDE_NUTTX_PCI_PCI_EPC_H */

Reply via email to