mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
added DMA memory managment functions
This commit is contained in:
parent
eb7391a4a3
commit
ac389a76ff
2 changed files with 73 additions and 6 deletions
|
@ -18,20 +18,32 @@
|
|||
|
||||
#include <xilinx/xaxidma.h>
|
||||
|
||||
#define FPGA_DMA_BASEADDR 0x00000000
|
||||
#define FPGA_DMA_BOUNDARY 0x1000
|
||||
#define FPGA_DMA_BD_OFFSET 0xC0000000
|
||||
#define FPGA_DMA_BD_SIZE (32 << 20) // 32 MB
|
||||
|
||||
#define XAXIDMA_SR_SGINCL_MASK 0x00000008
|
||||
|
||||
struct dma {
|
||||
XAxiDma inst;
|
||||
};
|
||||
|
||||
struct dma_mem {
|
||||
uint32_t base_virt;
|
||||
uint32_t base_phys;
|
||||
char *base_virt;
|
||||
char *base_phys;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
struct dma {
|
||||
XAxiDma inst;
|
||||
|
||||
struct dma_mem bd;
|
||||
};
|
||||
|
||||
struct ip;
|
||||
|
||||
int dma_mem_split(struct dma_mem *o, struct dma_mem *a, struct dma_mem *b);
|
||||
|
||||
int dma_alloc(struct ip *c, struct dma_mem *mem, size_t len, int flags);
|
||||
int dma_free(struct ip *c, struct dma_mem *mem);
|
||||
|
||||
int dma_write(struct ip *c, char *buf, size_t len);
|
||||
int dma_read(struct ip *c, char *buf, size_t len);
|
||||
int dma_read_complete(struct ip *c, char **buf, size_t *len);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <villas/log.h>
|
||||
|
||||
|
@ -18,6 +19,60 @@
|
|||
#include "fpga/dma.h"
|
||||
#include "fpga/ip.h"
|
||||
|
||||
int dma_mem_split(struct dma_mem *o, struct dma_mem *a, struct dma_mem *b)
|
||||
{
|
||||
int split = o->len / 2;
|
||||
|
||||
a->base_virt = o->base_virt;
|
||||
a->base_phys = o->base_phys;
|
||||
|
||||
b->base_virt = a->base_virt + split;
|
||||
b->base_phys = a->base_phys + split;
|
||||
|
||||
a->len = split;
|
||||
b->len = o->len - split;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dma_alloc(struct ip *c, struct dma_mem *mem, size_t len, int flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Align to next bigger page size chunk */
|
||||
if (len & 0xFFF) {
|
||||
len += 0x1000;
|
||||
len &= ~0xFFF;
|
||||
}
|
||||
|
||||
mem->len = len;
|
||||
mem->base_phys = -1; /* find free */
|
||||
mem->base_virt = mmap(0, mem->len, PROT_READ | PROT_WRITE, flags | MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, 0, 0);
|
||||
if (mem->base_virt == MAP_FAILED)
|
||||
return -1;
|
||||
|
||||
ret = vfio_map_dma(c->card->vd.group->container, mem);
|
||||
if (ret)
|
||||
return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dma_free(struct ip *c, struct dma_mem *mem)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = vfio_unmap_dma(c->card->vd.group->container, mem);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = munmap(mem->base_virt, mem->len);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dma_ping_pong(struct ip *c, char *src, char *dst, size_t len)
|
||||
{
|
||||
int ret;
|
||||
|
|
Loading…
Add table
Reference in a new issue