|
@@ -11,6 +11,12 @@
|
|
|
#include "ipedma.h"
|
|
|
#include <unistd.h>
|
|
|
|
|
|
+#define KMEM_DEFAULT_FLAGS (pcilib_kmem_flags_t)(PCILIB_KMEM_FLAG_HARDWARE | PCILIB_KMEM_FLAG_PERSISTENT | PCILIB_KMEM_FLAG_EXCLUSIVE)
|
|
|
+
|
|
|
+#define KMEM_USE_RING PCILIB_KMEM_USE(PCILIB_KMEM_USE_USER, 1)
|
|
|
+#define KMEM_USE_DEFAULT PCILIB_KMEM_USE(PCILIB_KMEM_USE_USER, 2)
|
|
|
+
|
|
|
+
|
|
|
|
|
|
int main()
|
|
|
{
|
|
@@ -18,64 +24,59 @@ int main()
|
|
|
assert_cu( cuInit(0) );
|
|
|
gdr_t g = gdr_open();
|
|
|
|
|
|
- /* First check if a NVIDIA GPU is on the system and see which to use */
|
|
|
- /* For the time being, use number 0 */
|
|
|
+ /* Try some stuff... */
|
|
|
+ printf("Using binary data to feed FPGA...\n");
|
|
|
+ char* data=(char*)calloc(4096,sizeof(*data));
|
|
|
+ memset(data,0xBB,4096);
|
|
|
+ init_to_send(data);
|
|
|
+ system("/home/mathiasb/sources/gpuFirstComm/launch.sh");
|
|
|
+
|
|
|
+ /* Manage NVIDIA GPU */
|
|
|
printf("\nInitialisation of the GPU\n");
|
|
|
- int i;
|
|
|
- int countGPU;
|
|
|
CUdevice GPU;
|
|
|
- char nameGPU[GPU_NAME_LENGTH];
|
|
|
CUdevprop GPUProp;
|
|
|
-
|
|
|
- assert_cuda( cudaGetDeviceCount(&countGPU) );
|
|
|
- for(i=0; i<countGPU; i++)
|
|
|
- {
|
|
|
- assert_cu( cuDeviceGet(&GPU,i) );
|
|
|
- assert_cu( cuDeviceGetName(nameGPU,GPU_NAME_LENGTH,GPU) );
|
|
|
- printf("GPU %d is %s\n",i,nameGPU);
|
|
|
- }
|
|
|
-
|
|
|
assert_cuda( cudaSetDevice(0) );
|
|
|
assert_cu( cuDeviceGet(&GPU,0) );
|
|
|
assert_cu( cuDeviceGetProperties(&GPUProp,GPU) );
|
|
|
|
|
|
/* Check context */
|
|
|
assert_cu( cuCtxGetDevice(&GPU) );
|
|
|
- printf("Device for this context: %d\n",GPU);
|
|
|
CUcontext cuCtx;
|
|
|
- assert_cu( cuCtxCreate(&cuCtx,0,GPU) );
|
|
|
+ assert_cu( cuCtxCreate(&cuCtx,CU_CTX_MAP_HOST,GPU) );
|
|
|
assert_cu( cuCtxGetDevice(&GPU) );
|
|
|
- printf("Device for this context: %d\n",GPU);
|
|
|
- int pi;
|
|
|
- assert_cu( cuDeviceGetAttribute(&pi,CU_DEVICE_ATTRIBUTE_UNIFIED_ADDRESSING,GPU) );
|
|
|
- printf("Support unified addressing? %d\n",pi);
|
|
|
-
|
|
|
- /* Allocate memory on the device, pin and map */
|
|
|
- printf("\nMemory mapping with the GPU\n");
|
|
|
- CUdeviceptr dptr;
|
|
|
- assert_cu( cuMemAlloc(&dptr,(size_t) GPUProp.sharedMemPerBlock) );
|
|
|
- gdr_mh_t GPUMemHandle;
|
|
|
- assert_gdr( gdr_pin_buffer(g,dptr,(size_t) GPUProp.sharedMemPerBlock,0,0,&GPUMemHandle) );
|
|
|
- void* va;
|
|
|
- assert_gdr( gdr_map(g,GPUMemHandle,&va,(size_t) GPUProp.sharedMemPerBlock) );
|
|
|
- /*CHECK THE OFFSET*/
|
|
|
- gdr_info_t GPUInfo;
|
|
|
- int offset;
|
|
|
- assert_gdr( gdr_get_info(g,GPUMemHandle,&GPUInfo) );
|
|
|
- offset = (GPUInfo.va > dptr) ? GPUInfo.va - dptr:dptr - GPUInfo.va;
|
|
|
- uint32_t *buf_ptr = (uint32_t *)((char *)va + offset);
|
|
|
|
|
|
+ /* Allocate memory on the device, pin and map */
|
|
|
+ uint8_t flagValueToSet = 1;
|
|
|
+ printf("\nMemory mapping with the GPU for pages\n");
|
|
|
+ CUdeviceptr gpuPagePtr;
|
|
|
+ assert_cu( cuMemAlloc(&gpuPagePtr,3*PAGE_SIZE) );
|
|
|
+ assert_cu( cuPointerSetAttribute(&flagValueToSet,CU_POINTER_ATTRIBUTE_SYNC_MEMOPS,gpuPagePtr) );
|
|
|
+ gdr_mh_t GPUMemHandlePage;
|
|
|
+ assert_gdr( gdr_pin_buffer(g,gpuPagePtr,3*PAGE_SIZE,0,0,&GPUMemHandlePage) );
|
|
|
+ void* gpuPageVa;
|
|
|
+ assert_gdr( gdr_map(g,GPUMemHandlePage,&gpuPageVa,3*PAGE_SIZE) );
|
|
|
+ gdr_info_t pageInfo;
|
|
|
+ assert_gdr( gdr_get_info(g,GPUMemHandlePage,&pageInfo) );
|
|
|
+ printf("Bus ptr = %lx\nVA = 0x%lx\nSize = %lu\n",pageInfo.bus_addr,pageInfo.va,pageInfo.mapped_size);
|
|
|
+ printf("Memory mapping with the GPU for descriptors\n");
|
|
|
+ CUdeviceptr gpuDescPtr;
|
|
|
+ assert_cu( cuMemAlloc(&gpuDescPtr,PAGE_SIZE) );
|
|
|
+ assert_cu( cuPointerSetAttribute(&flagValueToSet,CU_POINTER_ATTRIBUTE_SYNC_MEMOPS,gpuDescPtr) );
|
|
|
+ gdr_mh_t GPUMemHandleDesc;
|
|
|
+ assert_gdr( gdr_pin_buffer(g,gpuDescPtr,PAGE_SIZE,0,0,&GPUMemHandleDesc) );
|
|
|
+ void* gpuDescVa;
|
|
|
+ assert_gdr( gdr_map(g,GPUMemHandleDesc,&gpuDescVa,PAGE_SIZE) );
|
|
|
+
|
|
|
printf("All set\n");
|
|
|
- printf("va: 0x%lx\ndptr: 0x%llx\nGPUInfo.va: 0x%lx\noffset: 0x%x\nbuf_ptr: 0x%lx\n",
|
|
|
- (uint64_t) va,dptr,GPUInfo.va,offset,buf_ptr);
|
|
|
+ gdr_info_t descInfo;
|
|
|
+ assert_gdr( gdr_get_info(g,GPUMemHandleDesc,&descInfo) );
|
|
|
+ printf("Bus ptr = %lx\nVA = 0x%lx\nSize = %lu\n",descInfo.bus_addr,descInfo.va,descInfo.mapped_size);
|
|
|
|
|
|
- /* At this point the GPU's mem is mapped to a CPU buffer to enable DMA */
|
|
|
-
|
|
|
/* PCI */
|
|
|
printf("\nSetting up the PCI\n");
|
|
|
pcilib_t* pciCtx;
|
|
|
char* pciVa;
|
|
|
- pciCtx = pcilib_open("/dev/fpga0",NULL);
|
|
|
+ pciCtx = pcilib_open("/dev/fpga0",PCILIB_MODEL_DETECT);
|
|
|
if( pciCtx == NULL )
|
|
|
{
|
|
|
printf("Cannot open a context for pci\n");
|
|
@@ -89,89 +90,108 @@ int main()
|
|
|
}
|
|
|
|
|
|
CUdeviceptr dBAR;
|
|
|
- int getdBAR = 10;
|
|
|
assert_cu( cuMemHostRegister((void*)pciVa,128,CU_MEMHOSTREGISTER_IOMEMORY) );
|
|
|
assert_cu( cuMemHostGetDevicePointer(&dBAR,(void*)pciVa, 0) );
|
|
|
- printf("pciVa = %p\ndBar = 0x%llx\n",pciVa,dBAR);
|
|
|
- assert_cu( cuMemcpyDtoH(&getdBAR,dBAR,sizeof(int)) );
|
|
|
- printf("getdBAR = %d\n",getdBAR);
|
|
|
|
|
|
- pcilib_kmem_handle_t* pciHandle;
|
|
|
- pciHandle = pcilib_alloc_kernel_memory(pciCtx,PCILIB_KMEM_TYPE_CONSISTENT,1,64,4096,PCILIB_KMEM_USE_STANDARD,PCILIB_KMEM_FLAG_REUSE);
|
|
|
- if( pciHandle == NULL )
|
|
|
+ /* Config PCI for Pages*/
|
|
|
+ pcilib_kmem_handle_t* pciHandlePage;
|
|
|
+ pciHandlePage = pcilib_alloc_kernel_memory(pciCtx, PCILIB_KMEM_TYPE_DMA_C2S_PAGE, 1, ((PAGE_SIZE%4096)?(4096 * (1 + PAGE_SIZE/4096)):PAGE_SIZE), 4096, KMEM_USE_DEFAULT, KMEM_DEFAULT_FLAGS);
|
|
|
+ if( pciHandlePage == NULL )
|
|
|
{
|
|
|
printf("Cannot allocate PCI kernel memory\n");
|
|
|
exit( EXIT_FAILURE );
|
|
|
}
|
|
|
- volatile void* pciMemPtr;
|
|
|
- uintptr_t pciBus;
|
|
|
- pciMemPtr = pcilib_kmem_get_ua(pciCtx,pciHandle);
|
|
|
- if( pciMemPtr == NULL )
|
|
|
+ volatile void* pciMemPtrPage;
|
|
|
+ uintptr_t pciBusPage;
|
|
|
+ pciMemPtrPage = (uint32_t*) pcilib_kmem_get_block_ua(pciCtx,pciHandlePage,0);
|
|
|
+ if( pciMemPtrPage == NULL )
|
|
|
{
|
|
|
printf("Cannot get PCI pointer to kernel memory\n");
|
|
|
exit( EXIT_FAILURE );
|
|
|
}
|
|
|
- pciBus = pcilib_kmem_get_ba(pciCtx,pciHandle);
|
|
|
- if( pciBus == 0 )
|
|
|
+ pciBusPage = pcilib_kmem_get_block_ba(pciCtx,pciHandlePage,0);
|
|
|
+ if( pciBusPage == 0 )
|
|
|
{
|
|
|
printf("Cannot get PCI Bus address on kernel memory\n");
|
|
|
exit( EXIT_FAILURE );
|
|
|
}
|
|
|
|
|
|
- printf("pciMemPtr = %p\npciBus = %p\n",pciMemPtr,pciBus);
|
|
|
-
|
|
|
- const pcilib_bar_info_t* bar_info;
|
|
|
- bar_info = pcilib_get_bar_info(pciCtx,0);
|
|
|
- if( bar_info == NULL )
|
|
|
+ /* Config PCI for Desc */
|
|
|
+ pcilib_kmem_handle_t* pciHandleDesc;
|
|
|
+ pciHandleDesc = pcilib_alloc_kernel_memory(pciCtx,PCILIB_KMEM_TYPE_CONSISTENT, 1, 128, 4096, KMEM_USE_RING, KMEM_DEFAULT_FLAGS);
|
|
|
+ if( pciHandleDesc == NULL )
|
|
|
{
|
|
|
- printf("Cannot get BAR info\n");
|
|
|
+ printf("Cannot allocate PCI kernel memory\n");
|
|
|
exit( EXIT_FAILURE );
|
|
|
}
|
|
|
- else
|
|
|
- printf("bar = %d\nsize = %lu\nphys_addr = %p\nvirt_addr = %p\n",bar_info->bar,bar_info->size,bar_info->phys_addr,bar_info->virt_addr);
|
|
|
-
|
|
|
- /* Try some stuff... */
|
|
|
- printf("\nRunning some tests\n");
|
|
|
- *(int*) pciMemPtr = 65;
|
|
|
- printf("Try to read pciMem in another way : %d %d\n",*(int*)pciMemPtr,*(int*)dBAR);
|
|
|
- assert_cu( cuMemcpyHtoD(dptr,(void*)pciMemPtr,sizeof(int)) );
|
|
|
- assert_cu( cuMemcpyHtoD(dBAR,(void*)pciMemPtr,sizeof(int)) );
|
|
|
- assert_cu( cuMemcpyDtoH(&getdBAR,dBAR,sizeof(int)) );
|
|
|
- printf("getdBAR = %d\n",getdBAR);
|
|
|
- printf("Try to read pciMem in another way : %d %d\n",*(int*)pciMemPtr,*(int*)dBAR);
|
|
|
- printf("Try to read pciMem in another way : %d\n",*(int*)va);
|
|
|
- printf("A small computation\n");
|
|
|
- add_three_global<<< 1,1 >>>(dptr);
|
|
|
- assert_cuda( cudaDeviceSynchronize() );
|
|
|
- int foo;
|
|
|
- assert_gdr( gdr_copy_from_bar(&foo,va,sizeof(foo)) );
|
|
|
- printf("foo = %d\nva = %d\n",foo,*(int*) va);
|
|
|
- printf("Now the other way around\n");
|
|
|
- foo = 100;
|
|
|
- assert_gdr( gdr_copy_to_bar(va,&foo,sizeof(foo)) );
|
|
|
- add_three_global<<< 1,1 >>>(dptr);
|
|
|
- assert_cuda( cudaDeviceSynchronize() );
|
|
|
- assert_cu( cuMemcpyDtoH((void*)pciMemPtr,dptr,sizeof(int)) );
|
|
|
- printf("pciMem = %d\n",*(int*)pciMemPtr);
|
|
|
-
|
|
|
+ volatile void* pciMemPtrDesc;
|
|
|
+ uintptr_t pciBusDesc;
|
|
|
+ pciMemPtrDesc = (uint32_t*) pcilib_kmem_get_block_ua(pciCtx,pciHandleDesc,0);
|
|
|
+ if( pciMemPtrDesc == NULL )
|
|
|
+ {
|
|
|
+ printf("Cannot get PCI pointer to kernel memory\n");
|
|
|
+ exit( EXIT_FAILURE );
|
|
|
+ }
|
|
|
+ pciBusDesc = pcilib_kmem_get_block_ba(pciCtx,pciHandleDesc,0);
|
|
|
+ if( pciBusDesc == 0 )
|
|
|
+ {
|
|
|
+ printf("Cannot get PCI Bus address on kernel memory\n");
|
|
|
+ exit( EXIT_FAILURE );
|
|
|
+ }
|
|
|
+
|
|
|
/* FPGA */
|
|
|
printf("\nWorking on the FPGA\n");
|
|
|
- WR32 (REG_RESET_DMA, 1);
|
|
|
- usleep (100000);
|
|
|
- WR32 (REG_RESET_DMA, 0);
|
|
|
- usleep (100000);
|
|
|
-
|
|
|
+ WR32(REG_RESET_DMA, 1);
|
|
|
+ usleep(100000);
|
|
|
+ WR32(REG_RESET_DMA, 0);
|
|
|
+ usleep(100000);
|
|
|
+ WR32_sleep(REG_NUM_PACKETS_PER_DESCRIPTOR,16);
|
|
|
+ WR32_sleep(REG_PACKET_LENGTH,64);
|
|
|
+ WR32_sleep(REG_UPDATE_THRESHOLD, 0x1);
|
|
|
+ /* WR64_sleep(REG_UPDATE_COUNTER,descInfo.bus_addr); */
|
|
|
+ WR64_sleep(REG_UPDATE_ADDRESS,pciBusPage+DESCRIPTOR_OFFSET);
|
|
|
+ WR32_sleep(REG_CONTROL,CONTROL_ENABLE_READ|CONTROL_SOURCE_RX_FIFO);
|
|
|
+ WR64_sleep(REG_DESCRIPTOR_ADDRESS,descInfo.bus_addr);
|
|
|
+ WR32_sleep(REG_DMA,1);
|
|
|
+ WR32_sleep(REG_INTERCONNECT, 0x262);
|
|
|
+ /* WR32_sleep(REG_COUNTER,1); */
|
|
|
+ usleep(100000);
|
|
|
+
|
|
|
+ WR64_sleep(REG_DESCRIPTOR_ADDRESS,descInfo.bus_addr);
|
|
|
+ printf("pciVa = %x\npciMemPtrPage = %lx\npciMemPtrDesc = %lx\n",pciVa,*(uint64_t*)pciMemPtrPage,*(uint64_t*)pciMemPtrDesc);
|
|
|
|
|
|
|
|
|
+ char* getBack=(char*)calloc(4096,sizeof(*getBack));
|
|
|
+ memcpy(getBack,(const void*)gpuDescVa,4096);
|
|
|
+ int i;
|
|
|
+ for(i=0;i<4096;i++)
|
|
|
+ {
|
|
|
+ printf("%hhx",getBack[i]);
|
|
|
+ }
|
|
|
+ printf("\n");
|
|
|
+
|
|
|
+
|
|
|
/* Close everything */
|
|
|
printf("\nClosing the connections\n");
|
|
|
+ WR32(REG_COUNTER, 0);
|
|
|
+ WR32(REG_DMA, 0);
|
|
|
+ WR32(REG_RESET_DMA, 1);
|
|
|
+ usleep (100000);
|
|
|
+ WR32(REG_RESET_DMA, 0);
|
|
|
+ usleep (100000);
|
|
|
+
|
|
|
+ pcilib_free_kernel_memory(pciCtx,pciHandleDesc,(pcilib_kmem_flags_t)(PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_HARDWARE));
|
|
|
+ pcilib_free_kernel_memory(pciCtx,pciHandlePage,(pcilib_kmem_flags_t)(PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_HARDWARE));
|
|
|
assert_cu( cuMemHostUnregister((void*) pciVa) );
|
|
|
pcilib_close(pciCtx);
|
|
|
- assert_gdr( gdr_unmap(g,GPUMemHandle,va,(size_t) GPUProp.sharedMemPerBlock) );
|
|
|
- assert_gdr( gdr_unpin_buffer(g,GPUMemHandle) );
|
|
|
+ assert_gdr( gdr_unmap(g,GPUMemHandlePage,gpuPageVa,3*PAGE_SIZE) );
|
|
|
+ assert_gdr( gdr_unpin_buffer(g,GPUMemHandlePage) );
|
|
|
+ assert_gdr( gdr_unmap(g,GPUMemHandleDesc,gpuDescVa,3*PAGE_SIZE) );
|
|
|
+ assert_gdr( gdr_unpin_buffer(g,GPUMemHandleDesc) );
|
|
|
assert_gdr( gdr_close(g) );
|
|
|
- assert_cu( cuMemFree(dptr) );
|
|
|
-
|
|
|
+ assert_cu( cuMemFree(gpuPagePtr) );
|
|
|
+ assert_cu( cuMemFree(gpuDescPtr) );
|
|
|
+
|
|
|
printf("All Cleared\n");
|
|
|
|
|
|
exit(EXIT_SUCCESS);
|