drivers/pci: epc add dma heap
The PCI inbound address space and the CPU cache need to maintain cache coherence Signed-off-by: lipengfei28 <lipengfei28@xiaomi.com>
This commit is contained in:
parent
50d94863f2
commit
4fa6d4b791
4 changed files with 179 additions and 11 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue