#include <dirent.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <linux/types.h>
#include <time.h>
#include <ctype.h>
//PCIE参数相关
#define PCI_MAX_BUS 255
#define PCI_MAX_DEV 31
#define PCI_MAX_FUN 7
#define PCICFG_REG_VID 0x00
#define PCICFG_REG_DID 0x02
#define PCICFG_REG_RID 0x08
#define PCICFG_REG_CMD 0x04
#define PCICFG_REG_BAR0 0x10
#define memBase 0xe0000000 // Destination Address
unsigned char *map_mem_base = NULL;//Request memory to store data
clock_t clockBegin,clockEnd;
//struct timeval starttime,endtime;
int len_size = 0;
unsigned char *bar0_map_base = NULL;
//The BAR0 address after converting to a virtual address
unsigned char *base = NULL;
/****************************************************************************
Function name::gpdrv_getcount
FUNCTION��Get the function of the PCIE device
******************************************************************************/
unsigned int gpdrv_getcount(void)
{
unsigned int bus,dev,fun;
unsigned int bar0;
int pcinodenum = 0;
int cfg_handle;
unsigned int data;
unsigned short int vid,did;
unsigned char rid;
unsigned short int cmd;
char *proc_name = "/proc/bus/pci/0000:01/00.0";
cfg_handle = open(proc_name,O_RDWR);
if(cfg_handle<=0)
{
//continue;
}else{
printf("open is sucessed!!!\n");
}
lseek(cfg_handle,PCICFG_REG_VID,SEEK_SET);
read(cfg_handle,&data,sizeof(data));
if((data!=0xffffffff)&&(data!=0))
{
lseek(cfg_handle,PCICFG_REG_RID,SEEK_SET);
lseek(cfg_handle,PCICFG_REG_BAR0,SEEK_SET);
read(cfg_handle,&bar0,sizeof(bar0));
read(cfg_handle,&rid,sizeof(rid));
lseek(cfg_handle,PCICFG_REG_CMD,SEEK_SET);
read(cfg_handle,&cmd,sizeof(cmd));
vid =data&0xffff; //low 16
did=data>>16; //high 16
printf("%04x:%04x(rev %02x)\n\n",vid,did,rid);
if((0x7014==vid)&&(0x10ee==did))
{
pcinodenum++;
}
printf("0000:%02x:%02x;%02x;\n",bus,dev,fun);
if(rid > 0)
{
printf(" GPU DEVICE\n");
}
else
{
printf(" PCI DEVICE\n");
printf("%04x:%04x\n",vid,did);
cmd = cmd | 0x02;
cmd = cmd & 0xfe;
lseek(cfg_handle,PCICFG_REG_CMD,SEEK_SET);
write(cfg_handle,&cmd,sizeof(cmd));
}
}
printf("pcienum = %d\n",pcinodenum);
return bar0;
}
int main(int argc, char* argv[])
{
int ret = 0;
unsigned char bufferRGB[0x4000];
unsigned char Ctemp;
unsigned int addr_bar0;
int fdMem;
// unsigned int addr_bar0; //获取pcie接口bar0的地址
addr_bar0 = gpdrv_getcount(); //获取bar0的地址
fdMem = open("/dev/mem",O_RDWR|O_SYNC);
if(fdMem<0)
{
perror("open the /dev/mem error\n");
exit(0);
}
bar0_map_base = (unsigned char*)mmap(NULL,0x1000000,PROT_READ|PROT_WRITE,MAP_SHARED,fdMem,addr_bar0);
if( bar0_map_base == NULL)
{
perror("mamp error\n");
}
else
{
printf("the addr_bar0 is %x\n", addr_bar0);
printf("the bar0_map_base is %x\n", bar0_map_base);
}
usleep(1000 * 1000 *2);
map_mem_base = (unsigned char*)mmap(NULL,0x1000000,PROT_READ|PROT_WRITE,MAP_SHARED,fdMem,memBase);
if(map_mem_base == NULL)
{
perror("map_mem_base error\n");
}else{
printf("the map_mem_base is %x\n", map_mem_base);
}
*(unsigned int*)(bar0_map_base + 0x20) = memBase;
*(unsigned int*)(bar0_map_base + 0x2c) = memBase+0x1000000;
usleep(1000);
*(unsigned int*)(bar0_map_base + 0x130) = 0x4000;
usleep(1000);
*(unsigned int*)(bar0_map_base + 0x144) = 0x4000;
usleep(1000);
*(unsigned int*)(bar0_map_base + 0x34) = 0x4000;
usleep(1000);
*(unsigned int*)(bar0_map_base + 0x160) = 1;
unsigned char *FlagAddr;
FlagAddr = (unsigned char *)(map_mem_base);
memset(map_mem_base, 0x00, 0x400);
while(1)
{
// usleep(1000);
// memset(bufferRGB, 0x00, 0x400);
clockBegin = clock();
memcpy(bufferRGB, map_mem_base, 0x4000);
clockEnd = clock();
printf(" pcie speed is %f GB/s!!!!!\n",(16384.0*4/(clockEnd-clockBegin)/1024));
// printf("*******************************************\n");
// for(int i = 0; i < 0x4000; i++)
// {
// printf("the map_mem_base is %x\n", bufferRGB[i]);
// }
// printf("*******************************************\n");
}
return 0;
}