📄 wahpnp.cpp
字号:
// WAHPNP.cpp - main module for VxD WAHPNP
#define DEVICE_MAIN
#include "WAHPNP.h"
Declare_Virtual_Device(WAHPNP)
#undef DEVICE_MAIN
#include <vsd.h>
WORD ioport,io;
#define MCSR 0x3c;
#define INTCSR 0x38;
#define OMB1 0;
#define IMB1 0x10;
#define MBEF 0x34;
#define MWAR 0x24;
#define MWTC 0x28;
MyHwInt* pMyIRQ;
PVOID CallBackApc = 0;
THREADHANDLE TheThread = 0;
DWORD abox;
BeepTimeOut* pBeeper;
PVOID ClientBuffer; // address of client buffer to receive data
DWORD nBytes; // number of bytes to read
DWORD nPages; // number of pages spanned by buffer
ULONG PhysAddr; // physical address to send to DMA controller
PVOID DMABufferLinear; // linear address of the DMA buffer
BOOL bUsingInt = FALSE; // TRUE if int avalible
BOOL bUsingBuffer = FALSE; // TRUE if using buffer provided by VDMAD
MEMHANDLE hMem;
VOID Bufalloc();
VOID Buffree();
BOOL MyHwInt::OnSharedHardwareInt(VMHANDLE hVM)
{
DWORD sint,sbox;
io=ioport+INTCSR;
sint=_inpd(io);
if ((sint&0x800000)!=0x800000) return FALSE;
if ((sint&0x20000)==0x20000) {
io=ioport+INTCSR;
_outpd(io,sint&0xff02ffff);
io=ioport+MBEF;
sbox=_inpd(io);
if ((sbox&0x10000)==0x10000) {
io=ioport+IMB1;
abox=_inpd(io);
if (abox&0xaa==0xaa) {
#ifdef DEBUG
dout << "DMA: Start!" << endl;
#endif
io=ioport+MCSR;
_outpd(io,0x700);
}
}
}
else if ((sint&0x40000)==0x40000) {
io=ioport+INTCSR;
_outpd(io,sint&0xff04ffff);
VWIN32_QueueUserApc(CallBackApc, (DWORD)DMABufferLinear, TheThread);
}
else if ((sint&0x300000)!=0) {
io=ioport+INTCSR;
_outpd(io,sint&0xff03ffff);
#ifdef DEBUG
dout << "DMA: Abort!" << endl;
#endif
}
sendPhysicalEOI();
return TRUE;
}
BOOL WahpnpDevice::OnSysDynamicDeviceInit()
{
// pBeeper = new BeepTimeOut(500);
return TRUE;
}
BOOL WahpnpDevice::OnSysDynamicDeviceExit()
{
return TRUE;
}
DWORD WahpnpDevice::OnW32DeviceIoControl(PIOCTLPARAMS pDIOCParams)
{
DWORD status;
switch (pDIOCParams->dioc_IOCtlCode)
{
case DIOC_OPEN:
Bufalloc();
io=ioport+INTCSR;
_outpd(io,0x3f0000); // 清除所有中断源
if (bUsingBuffer) {
#ifdef DEBUG
dout << "DMA: set memory!" << endl;
#endif
io=ioport+MWAR;
_outpd(io,PhysAddr);
io=ioport+MWTC;
_outpd(io,128);
io=ioport+MCSR;
_outpd(io,0xc000000); //ADD-ON到PCI的FIFO复位,邮箱复位
io=ioport+INTCSR;
_outpd(io,0x20005000);
}
status = 0;
break;
case DIOC_CLOSEHANDLE:
io=ioport+INTCSR;
_outpd(io,0);
if (bUsingBuffer) Buffree();
if (bUsingInt) pMyIRQ->physicalMask();
status = 0;
break;
case TEST:
CallBackApc = pDIOCParams->dioc_InBuf;
TheThread = Get_Cur_Thread_Handle();
status = 0;
if (!bUsingBuffer) status += 1;
if (bUsingInt) pMyIRQ->physicalUnmask();
else status += 2;
io=ioport+OMB1;
_outp(io,0x55);
break;
case READ:
ClientBuffer = pDIOCParams->dioc_InBuf;
// nBytes = pDIOCParams->dioc_cbInBuf;
nBytes =128;
memcpy(ClientBuffer, DMABufferLinear, nBytes);
break;
default:
status = -1;
}
return status;
}
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];
ioport=config.wIOPortBase[0];
// Here we would initialize the device, doing things
// like VPICD_Virtualize_IRQ, etc.
if (irq != 0xff) {
pMyIRQ = new MyHwInt();
if (!pMyIRQ || !pMyIRQ->hook()) bUsingInt=FALSE;
else bUsingInt=TRUE;
};
return CR_SUCCESS;
case CONFIG_REMOVE /* 4 */:
case CONFIG_STOP /* 2 */:
// Here we would disable the device and do things
// like unvirtualizing our IRQ
if (pMyIRQ) delete pMyIRQ;
irq = 0xff;
return CR_SUCCESS;
default:
return CR_DEFAULT;
}
}
CONFIGRET WahpnpDevice::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;
}
}
VOID Bufalloc(void)
{
DWORD status;
nPages=2;
status=PageAllocate(
nPages,
PG_SYS,
0,
0, // align on 4K boundary
0,
0x100000,//4G
&PhysAddr,
PAGECONTIG | PAGEFIXED | PAGEUSEALIGN,
&hMem,
&DMABufferLinear);
if (status == FALSE)
{
#ifdef DEBUG
dout << "DMA: cannot get locked memory!" << endl;
#endif
bUsingBuffer=FALSE;
dprintf("DMA: cannot get locked memory\n");
}
else
{
#ifdef DEBUG
dout << "DMA: allocated a buffer with PageAllocate!" << endl;
#endif
bUsingBuffer=TRUE;
}
}
VOID Buffree(void)
{
PageFree(hMem, 0);
#ifdef DEBUG
dout << "DMA: free a buffer" << endl;
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -