i am trying to transfer data which is present in calloc heap memory to stream .
Firstly we have the 32bit DMA design where we used to take a 32bit
DDR Address and Memory Map that DDR address and Write Some Dummy Data and Stream it (MM2S) it is perfectly Working .But we have the Requirement to have a to Transfer the data from the Dynamic Memory(using calloc function) so we are using Calloc And then we fill the Array with Dummy Data and try to pass the Address of the Dynamic Memory to the DMA descriptor .
Calloc is returning 64bit Address so we splited it into MSB and LSB and stored into the offset address (0x8)and(0xc)[descriptor offsets] .DMA is triggering but when we debug through ILA ,it is showing always this [dec0dee3] data .
so we have checked that normal 64bit address is working or not so we have taken a address space 0x800000000 and tried to store some dummy data in 0x800000000 and tried to MM2S it is working Perfectly .
So,could you please help us how to pass Calloc Heap Address to dma descriptors ,so that i cant read the data from it .
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#define AXI_DMA_REGISTER_LOCATION 0xa0000000 //AXI DMA Register Address Map
#define NUM_OF_DESCRIPTORS 2 //number of descriptors for each direction
#define BUFFER_BLOCK_WIDTH 0x7D0000 //size of memory block per descriptor in bytes
#define DESCRIPTOR_REGISTERS_SIZE 0xFFFF
#define HP0_MM2S_DMA_DESCRIPTORS_ADDRESS 0x00a00000
#define HP0_MM2S_SOURCE_MEM_ADDRESS 0x00010000
// MM2S CONTROL
#define MM2S_CONTROL_REGISTER 0x00 // MM2S_DMACR
#define MM2S_STATUS_REGISTER 0x04 // MM2S_DMASR
#define MM2S_CURDESC 0x08 // must align 0x40 addresses
#define MM2S_CURDESC_MSB 0x0C // unused with 32bit addresses
#define MM2S_TAILDESC 0x10 // must align 0x40 addresses
#define MM2S_TAILDESC_MSB 0x14 // unused with 32bit addresses
void wn5gNr_User_init();
void wn5gNr_Status_init();
void wn5gNr_Descriptors_init();
void wn5gNr_Dma_init();
void wn5gNr_Status_init();
void wn5gNr_Memory_Map();
unsigned int* axi_dma_register_mmap;
uint32_t* mm2s_descriptor_register_mmap;
unsigned int* s2mm_descriptor_register_mmap;
__uint128_t* source_mem_map;
__uint128_t* dest_mem_map;
int controlregister_ok = 0,mm2s_status,s2mm_status;
uint32_t mm2s_current_descriptor_address;
uint32_t s2mm_current_descriptor_address;
uint32_t mm2s_tail_descriptor_address;
uint32_t s2mm_tail_descriptor_address;
uint32_t Case;
int ddr_memory;
uint64_t k=0;
//ptr=&k;
typedef union
{
int64_t u64;
int32_t u[1];
} U64_U32;
U64_U32 a;
int p=0;
int *ptr2=&p;
void main()
{
//***************************MemoryMap the Virtual Addresses************************
printf("MemoryMap the Virtual Addresses\n");
ddr_memory = open("/dev/mem", O_RDWR | O_SYNC)
;
axi_dma_register_mmap = mmap(NULL, DESCRIPTOR_REGISTERS_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, ddr_memory, AXI_DMA_REGISTER_LOCATION);
mm2s_descriptor_register_mmap = mmap(NULL, DESCRIPTOR_REGISTERS_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, ddr_memory, HP0_MM2S_DMA_DESCRIPTORS_ADDRESS);
source_mem_map = mmap(NULL,BUFFER_BLOCK_WIDTH * NUM_OF_DESCRIPTORS, PROT_READ | PROT_WRITE, MAP_SHARED, ddr_memory, (HP0_MM2S_SOURCE_MEM_ADDRESS));
//*********** Filling the MM2S Register with zeros*********
printf("Filling the MM2S Register with zeros\n");
for (int i = 0; i < DESCRIPTOR_REGISTERS_SIZE; i++)
{
char *p = (char *)mm2s_descriptor_register_mmap;
p[i] = 0x00000000;
}
//**********filling the Data in the Memory Map Source Address******
printf("filling the Data in the Memory Map Source Address\n");
for (int i = 0; i < 1920 ; i++)
{
__uint128_t *m = source_mem_map;
m[i] = 0x00000000+i;
}
//****************** Reset And Halt DMA *****************
printf("DMA Register Reset\n");
axi_dma_register_mmap[MM2S_CONTROL_REGISTER >> 2] = 0x4;
axi_dma_register_mmap[MM2S_CONTROL_REGISTER >> 2] = 0x0;
uint64_t *ptr =NULL;
uint64_t *ptr1 =NULL;
ptr1 =(uint32_t*)calloc(20,sizeof(uint32_t));
int l=0;
ptr=ptr1;
printf("Ptr address = %p %p\n",ptr,ptr1);
#if 1
for(uint32_t i=1;i<10;i++)
{
ptr1[i]=0x00000000+3;
printf("%x address = %p\n",ptr1[i],ptr1);
ptr1++;
}
#endif
//uint64_t *address = mmap(NULL, 100, PROT_READ | PROT_WRITE, MAP_SHARED, ddr_memory, ptr);
a.u64=ptr;
printf("%p %p %p %p",ptr,a.u64,a.u[0],a.u[1]);
printf("save current descriptor address\n");
mm2s_current_descriptor_address = HP0_MM2S_DMA_DESCRIPTORS_ADDRESS; // save current descriptor address
mm2s_descriptor_register_mmap[0x0 >> 2] = 0x00; //HP0_MM2S_DMA_DESCRIPTORS_ADDRESS + 0x40; // set next descriptor address
mm2s_descriptor_register_mmap[0x8 >> 2 ] =(const int)a.u[0]; // set target buffer address
mm2s_descriptor_register_mmap[0xC >> 2] =(const int)a.u[1];
mm2s_descriptor_register_mmap[0x18 >> 2] = 0x400001c; //set mm2s/s2mm buffer length to control register for First Descriptor
mm2s_tail_descriptor_address = HP0_MM2S_DMA_DESCRIPTORS_ADDRESS;//+0x40 ; // save tail descriptor address
printf("setting tail descriptor address\n");
//****************Trigger Dma******************
printf("Start DMA\n");
axi_dma_register_mmap[MM2S_CURDESC>>2] = mm2s_current_descriptor_address;
axi_dma_register_mmap[MM2S_CURDESC_MSB>>2] = 0x000;
axi_dma_register_mmap[MM2S_CONTROL_REGISTER >> 2] = 0x1;
axi_dma_register_mmap[MM2S_TAILDESC>>2] = mm2s_tail_descriptor_address;
axi_dma_register_mmap[MM2S_TAILDESC_MSB>>2] = 0x000;
printf("RUN DMA Sucessful\n");
close(ddr_memory);
}