Xilinx DMA unable to Read the Data from Calloc 64bit Address

Viewed 40

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);

}
0 Answers
Related