xilinx PCIE的Linux驱动程序源代码.docx
《xilinx PCIE的Linux驱动程序源代码.docx》由会员分享,可在线阅读,更多相关《xilinx PCIE的Linux驱动程序源代码.docx(30页珍藏版)》请在冰点文库上搜索。
![xilinx PCIE的Linux驱动程序源代码.docx](https://file1.bingdoc.com/fileroot1/2023-5/6/f8e0f99e-f623-4d0b-a7f9-2c503298c546/f8e0f99e-f623-4d0b-a7f9-2c503298c5461.gif)
xilinxPCIE的Linux驱动程序源代码
//--------------------------------------------------------------------------------
//--Filename:
xbmd.h
//--
//--Description:
Mainheaderfileforkerneldriver
//--
//--XBMDisanexampleRedHatdevicedriverwhichexercisesXBMDdesign
//--DevicedriverhasbeentestedonRedHatFedoraFC92.6.15.
//--------------------------------------------------------------------------------
//DefineResultvalues
#defineSUCCESS0
#defineCRIT_ERR-1
//Debug-definewilloutputmoreinfo
#defineVerbose1
//MaxDMABufferSize
#defineBUF_SIZE(4096*1024)
enum{
INITCARD,
INITRST,
DISPREGS,
RDDCSR,
RDDDMACR,
RDWDMATLPA,
RDWDMATLPS,
RDWDMATLPC,
RDWDMATLPP,
RDRDMATLPP,
RDRDMATLPA,
RDRDMATLPS,
RDRDMATLPC,
RDWDMAPERF,
RDRDMAPERF,
RDRDMASTAT,
RDNRDCOMP,
RDRCOMPDSIZE,
RDDLWSTAT,
RDDLTRSSTAT,
RDDMISCCONT,
RDDMISCONT,
RDDLNKC,
DFCCTL,
DFCPINFO,
DFCNPINFO,
DFCINFO,
RDCFGREG,
WRCFGREG,
RDBMDREG,
WRBMDREG,
WRDDMACR,
WRWDMATLPS,
WRWDMATLPC,
WRWDMATLPP,
WRRDMATLPS,
WRRDMATLPC,
WRRDMATLPP,
WRDMISCCONT,
WRDDLNKC,
NUMCOMMANDS
};
//--------------------------------------------------------------------------------
//--Filename:
xbmd.c
//--
//--Description:
XBMDdevicedriver.
//--
//--XBMDisanexampleRedHatdevicedriverwhichexercisesXBMDdesign
//--DevicedriverhasbeentestedonRedHatFedoraFC92.6.15.
//--------------------------------------------------------------------------------
#include
#include
#include
#include
#include
//#include
//#include
#include/*copy_to_user*/
#include"xbmd.h"
//semaphores
enum{
SEM_READ,
SEM_WRITE,
SEM_WRITEREG,
SEM_READREG,
SEM_WAITFOR,
SEM_DMA,
NUM_SEMS
};
//semaphores
structsemaphoregSem[NUM_SEMS];
MODULE_LICENSE("DualBSD/GPL");
//DefinestheVendorID.MustbechangedifcoregenerateddidnotsettheVendorIDtothesamevalue
#definePCI_VENDOR_ID_XILINX0x10ee
//DefinestheDeviceID.MustbechangedifcoregenerateddidnotsettheDeviceIDtothesamevalue
#definePCI_DEVICE_ID_XILINX_PCIE0x0007
//Defining
#defineXBMD_REGISTER_SIZE(4*8)//Thereareeightregisters,andeachis4byteswide.
#defineHAVE_REGION0x01//I/OMemoryregion
#defineHAVE_IRQ0x02//Interupt
//StatusFlags:
//1=Resoucesuccessfullyacquired
//0=Resourcenotacquired.
#defineHAVE_REGION0x01//I/OMemoryregion
#defineHAVE_IRQ0x02//Interupt
#defineHAVE_KREG0x04//Kernelregistration
intgDrvrMajor=241;//Majornumbernotdynamic.
unsignedintgStatFlags=0x00;//Statusflagsusedforcleanup.
unsignedlonggBaseHdwr;//Baseregisteraddress(Hardwareaddress)
unsignedlonggBaseLen;//BaseregisteraddressLength
void*gBaseVirt=NULL;//Baseregisteraddress(Virtualaddress,forI/O).
chargDrvrName[]="xbmd";//Nameofdriverinproc.
structpci_dev*gDev=NULL;//PCIdevicestructure.
intgIrq;//IRQassignedbyPCIsystem.
char*gBufferUnaligned=NULL;//PointertoUnalignedDMAbuffer.
char*gReadBuffer=NULL;//PointertodwordalignedDMAbuffer.
char*gWriteBuffer=NULL;//PointertodwordalignedDMAbuffer.
dma_addr_tgReadHWAddr;
dma_addr_tgWriteHWAddr;
unsignedlongSA_SHIRQ=0;
unsignedlongSA_SAMPLE_RANDOM=0;
intpos;
//StructUsedforWritingCFGRegister.Holdsvalueandregistertobewritten
typedefstructcfgwrite{
intreg;
intvalue;
}cfgwr;
//StructUsedforWritingBMDRegister.Holdsvalueandregistertobewritten
typedefstructbmdwrite{
intreg;
intvalue;
}bmdwr;
//-----------------------------------------------------------------------------
//Prototypes
//-----------------------------------------------------------------------------
voidXPCIe_IRQHandler(intirq,void*dev_id,structpt_regs*regs);
u32XPCIe_ReadReg(u32dw_offset);
voidXPCIe_WriteReg(u32dw_offset,u32val);
voidXPCIe_InitCard(void);
voidXPCIe_InitiatorReset(void);
u32XPCIe_ReadCfgReg(u32byte);
u32XPCIe_WriteCfgReg(u32byte,u32value);
//---------------------------------------------------------------------------
//Name:
XPCIe_Open
//
//Description:
Bookkeepingroutineinvokedeachtimethedeviceisopened.
//
//Arguments:
inode:
//filp:
//
//Returns:
0onsuccess,errorcodeonfailure.
//
//Modificationlog:
//DateWhoDescription
//
//---------------------------------------------------------------------------
intXPCIe_Open(structinode*inode,structfile*filp)
{
printk(KERN_INFO"%s:
Open:
moduleopened\n",gDrvrName);
returnSUCCESS;
}
//---------------------------------------------------------------------------
//Name:
XPCIe_Release
//
//Description:
Bookkeepingroutineinvokedeachtimethedeviceisclosed.
//
//Arguments:
inode:
//filp:
//
//Returns:
0onsuccess,errorcodeonfailure.
//
//Modificationlog:
//DateWhoDescription
//
//---------------------------------------------------------------------------
intXPCIe_Release(structinode*inode,structfile*filp)
{
printk(KERN_INFO"%s:
Release:
modulereleased\n",gDrvrName);
return(SUCCESS);
}
//---------------------------------------------------------------------------
//Name:
XPCIe_Write
//
//Description:
Thisroutineisinvokedfromuserspacetowritedatato
//thePCIedevice.
//
//Arguments:
filp:
filepointertoopeneddevice.
//buf:
pointertolocationinusersspace,wheredataisto
//beacquired.
//count:
Amountofdatainbytesuserwishestosend.
//
//Returns:
SUCCESS=Success
//CRIT_ERR=Criticalfailure
//
//Modificationlog:
//DateWhoDescription
//
//---------------------------------------------------------------------------
ssize_tXPCIe_Write(structfile*filp,constchar*buf,size_tcount,
loff_t*f_pos)
{
intret=SUCCESS;
memcpy((char*)gWriteBuffer,buf,count);
printk(KERN_INFO"%s:
XPCIe_Write:
%dbyteshavebeenwritten...\n",gDrvrName,count);
memcpy((char*)gReadBuffer,buf,count);
printk(KERN_INFO"%s:
XPCIe_Write:
%dbyteshavebeenwritten...\n",gDrvrName,count);
return(ret);
}
//---------------------------------------------------------------------------
//Name:
XPCIe_Read
//
//Description:
Thisroutineisinvokedfromuserspacetoreaddatafrom
//thePCIedevice.***NOTE:
Thisroutinereturnstheentire
//buffer,(BUF_SIZE),countisignored!
.TheuserAppmust
//doanyneededprocessingonthebuffer.
//
//Arguments:
filp:
filepointertoopeneddevice.
//buf:
pointertolocationinusersspace,wheredataisto
//beplaced.
//count:
Amountofdatainbytesuserwishestoread.
//
//Returns:
SUCCESS=Success
//CRIT_ERR=Criticalfailure
//
//Modificationlog:
//DateWhoDescription
//----------------------------------------------------------------------------
ssize_tXPCIe_Read(structfile*filp,char*buf,size_tcount,loff_t*f_pos)
{
memcpy(buf,(char*)gWriteBuffer,count);
printk(KERN_INFO"%s:
XPCIe_Read:
%dbyteshavebeenread...\n",gDrvrName,count);
return(0);
}
//---------------------------------------------------------------------------
//Name:
XPCIe_Ioctl
//
//Description:
Thisroutineisinvokedfromuserspacetoconfigurethe
//runningdriver.
//
//Arguments:
inode:
//filp:
Filepointertoopeneddevice.
//cmd:
Ioctlcommandtoexecute.
//arg:
ArgumenttoIoctlcommand.
//
//Returns:
0onsuccess,errorcodeonfailure.
//
//Modificationlog:
//DateWhoDescription
//
//---------------------------------------------------------------------------
intXPCIe_Ioctl(structinode*inode,
structfile*filp,
unsignedintcmd,
unsignedlongarg)
{
u32regx;
intret=SUCCESS;
switch(cmd){
caseINITCARD:
//InitailizesXBMDapplication
XPCIe_InitCard();
break;
caseINITRST:
//ResetsXBMDapplications
XPCIe_InitiatorReset();
break;
caseDISPREGS:
break;
caseRDDCSR:
//Read:
DeviceControlStatusRegister
regx=XPCIe_ReadReg(0);
*((u32*)arg)=regx;
break;
caseRDDDMACR:
//Read:
DMAControlStatusRegister
regx=XPCIe_ReadReg
(1);
*((u32*)arg)=regx;
break;
caseRDWDMATLPA:
//Read:
WriteDMATLPAddressRegister
regx=XPCIe_ReadReg
(2);
*((u32*)arg)=regx;
break;
caseRDWDMATLPS:
//Read:
WriteDMATLPSizeRegister
regx=XPCIe_ReadReg(3);
*((u32*)arg)=regx;
break;
caseRDWDMATLPC:
//Read:
WriteDMATLPCountRegister
regx=XPCIe_ReadReg(4);
*((u32*)arg)=regx;
break;
caseRDWDMATLPP:
//Read:
WriteDMATLPPatternRegister
regx=XPCIe_ReadReg(5);
*((u32*)arg)=regx;
break;
caseRDRDMATLPP:
//Read:
ReadDMATLPPatternRegister
regx=XPCIe_ReadReg(6);
*((u32*)arg)=regx;
break;
caseRDRDMATLPA:
//Read:
ReadDMATLPAddressRegister
regx=XPCIe_ReadReg(7);
*((u32*)arg)=regx;
break;
caseRDRDMATLPS:
//Read:
ReadDMATLPSizeRegister
regx=XPCIe_ReadReg(8);
*((u32*)arg)=regx;
break;
caseRDRDMATLPC:
//Read:
ReadDMATLPCountRegister
regx=XPCIe_ReadReg(9);
*((u32*)arg)=regx;
break;
caseRDWDMAPERF:
//Read:
WriteDMAPerformanceRegister
regx=XPCIe_ReadReg(10);
*((u32*)arg)=regx;
break;
caseRDRDMAPERF:
//Read:
ReadDMAPerformanceRegister
regx=XPCIe_ReadReg(11);
*((u32*)arg)=regx;
break;
caseRDRDMASTAT:
//Read:
ReadDMAStatusRegister
regx=XPCIe_ReadReg(12);
*((u32*)arg)=regx;
break;
caseRDNRDCOMP:
//Read:
NumberofReadCompletionw/DataRegister
regx=XPCIe_ReadReg(13);
*((u32*)arg)=regx;
break;
caseRDRCOMPDSIZE:
//Read:
ReadCompletionSizeRegister
regx=XPCIe_ReadReg(14);
*((u32*)arg)=regx;
break;
caseR