?? pci2040.cpp
字號:
// PCI2040.cpp - main module for VxD PCI2040
#define DEVICE_MAIN
#include "pci2040.h"
Declare_Virtual_Device(PCI2040)
#undef DEVICE_MAIN
WORD ioport;
DWORD membase[2];///0 hpi csr base, 1 control space
BOOL bVirIrq;
MyHwInt* pMyIRQ;
PVOID CallBackApc = 0;
THREADHANDLE TheThread = 0;
long int x;
#define PAGENUM(p) (((ULONG)(p))>>12)//除以4k得多少頁
#define PAGEOFF(p) (((ULONG)(p))&0xFFF)//偏移地址為低4k位
#define PAGEBASE(p) (((ULONG)(p))&~0xFFF)//基址為高位
#define _NPAGES_(p,k) ((PAGENUM((char*)p+(k-1))-PAGENUM(p))+1)
///三個全局函數地址映射用
PVOID MapDevice(PVOID PhysAddress, DWORD SizeInBytes)
{
#ifdef USE_MAP_PHYS_TO_LINEAR
return MapPhysToLinear(PhysAddress, SizeInBytes, 0);
#else
PVOID Linear;
ULONG nPages = _NPAGES_(PhysAddress, SizeInBytes);
Linear = PageReserve(
PR_SYSTEM,
nPages,
PR_FIXED
);
PageCommitPhys(
PAGENUM(Linear),
nPages,
PAGENUM(PhysAddress),
PC_INCR | PC_WRITEABLE | PC_USER
);
LinPageLock(PAGENUM(Linear), nPages, 0);
return (PVOID) ((ULONG)Linear+PAGEOFF(PhysAddress));
#endif
}
VOID UnmapDevice(PVOID LinearAddress, DWORD SizeInBytes)
{
#ifdef USE_MAP_PHYS_TO_LINEAR
// cannot unmap
#else
LinPageUnLock(
PAGENUM(LinearAddress),
_NPAGES_(LinearAddress, SizeInBytes),
0
);
PageDecommit(
PAGENUM(LinearAddress),
_NPAGES_(LinearAddress, SizeInBytes),
0
);
PageFree((MEMHANDLE)LinearAddress,0);
#endif
}
CONFIGRET OnConfigure(
CONFIGFUNC cf, // function id
SUBCONFIGFUNC scf, // subfunction id
DEVNODE devnode, // device node being configured
DWORD refdata, // context information (function specific)
ULONG flags // function specific flags
)
{
CMCONFIG config;
LOG_CONF logconf;
RES_DES hres;
switch (cf) // branch on function code
{
case CONFIG_START:
CONFIGMG_Get_Alloc_Log_Conf(&config, devnode, CM_GET_ALLOC_LOG_CONF_ALLOC);
irq=config.bIRQRegisters[0];
// irq=12;
membase[0]=config.dMemBase[0];
membase[1]=config.dMemBase[1];
ioport=config.wIOPortBase[0];
return CR_SUCCESS;
case CONFIG_REMOVE /* 4 */:
case CONFIG_STOP /* 2 */:
irq = 0xff;
return CR_SUCCESS;
default:
return CR_DEFAULT;
}
}
BOOL Pci2040Device::OnSysDynamicDeviceInit()
{
return TRUE;
}
BOOL Pci2040Device::OnSysDynamicDeviceExit()
{
return TRUE;
}
CONFIGRET Pci2040Device::OnPnpNewDevnode(DEVNODE devNode, DWORD loadType)
{
switch(loadType)
{
case DLVXD_LOAD_DEVLOADER:
return CONFIGMG_Register_Device_Driver(devNode,OnConfigure,
0,CM_REGISTER_DEVICE_DRIVER_DISABLEABLE | CM_REGISTER_DEVICE_DRIVER_REMOVABLE);
default:
return CR_DEFAULT;
}
return CR_DEFAULT;
}
DWORD Pci2040Device::OnW32DeviceIoControl(PIOCTLPARAMS pDIOCParams)
{
PMAPDEVREQUEST pReq;
switch (pDIOCParams->dioc_IOCtlCode)
{
case DIOC_OPEN:
dout<<"open"<<endl;
x=0;
if(irq!=0xff)
{
pMyIRQ=new MyHwInt();
if(!pMyIRQ||!pMyIRQ->hook())
bVirIrq=FALSE;
else
{
bVirIrq=TRUE;
pMyIRQ->physicalUnmask();
}
}
break;
case DIOC_CLOSEHANDLE:
dout<<"close"<<endl;
pMyIRQ->physicalMask();
if(bVirIrq) delete pMyIRQ;
break;
case MDR_SERVICE_UNMAP:
dout<<"unmap"<<endl;
pReq = *(PMAPDEVREQUEST*)pDIOCParams->dioc_InBuf;
UnmapDevice(
pReq->mdr_LinearAddress,
pReq->mdr_SizeInBytes
);
pReq->mdr_Status = MDR_STATUS_SUCCESS;
break;
case MDR_SERVICE_MAP:
dout<<"map"<<endl;
pReq = *(PMAPDEVREQUEST*)pDIOCParams->dioc_InBuf;
pReq->mdr_LinearAddress = MapDevice(
pReq->mdr_PhysicalAddress,
pReq->mdr_SizeInBytes
);
if (pReq->mdr_LinearAddress == NULL)
pReq->mdr_Status=MDR_STATUS_ERROR;
else
pReq->mdr_Status=MDR_STATUS_SUCCESS;
break;
case GETMEMBASE0:
dout<<"getmembase0"<<endl;
*(DWORD*)pDIOCParams->dioc_OutBuf=membase[0];
break;
case GETMEMBASE1:
dout<<"getmembase1"<<endl;
*(DWORD*)pDIOCParams->dioc_OutBuf=membase[1];
break;
case GETIOBASE:
dout<<"GETIOBASE"<<endl;
*(DWORD*)pDIOCParams->dioc_OutBuf=ioport;
break;
case GETIRQ:
dout<<"GETIRQ"<<endl;
*(int*)pDIOCParams->dioc_OutBuf=irq;
break;
case ADDRPASS:
dout<<"addrpass"<<endl;
CallBackApc = pDIOCParams->dioc_InBuf;
TheThread = Get_Cur_Thread_Handle();
break;
default:
return -1;
}
return 0;
}
BOOL MyHwInt::OnSharedHardwareInt(VMHANDLE)
{
pMyIRQ->physicalMask();
x++;
if(x>70&&x<75)
{
VWIN32_QueueUserApc(CallBackApc, (DWORD)&x, TheThread);
}
for(int temp=0;temp<10000;temp++);
sendPhysicalEOI();
pMyIRQ->physicalUnmask();
if(x>200)
{
pMyIRQ->physicalMask();
}
return FALSE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -