📄 init.c
字号:
KeDelayExecutionThread( KernelMode, TRUE, &delay );
}
// IoDeviceControl is called for IRP_MJ_DEVICE_CONTROL
VOID PCIEIOCtrlCode(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t OutputBufferLength,
IN size_t InputBufferLength,
IN ULONG IoControlCode
)
/*++
Routine Description:
This event is called when the framework receives IRP_MJ_DEVICE_CONTROL
requests from the system.
Arguments:
Queue - Handle to the framework queue object that is associated
with the I/O request.
Request - Handle to a framework request object.
OutputBufferLength - length of the request's output buffer,
if an output buffer is available.
InputBufferLength - length of the request's input buffer,
if an input buffer is available.
IoControlCode - the driver-defined or system-defined I/O control code
(IOCTL) that is associated with the request.
Return Value:
VOID
--*/
{
PDEVICE_EXTENSION devExt;
ULONG length;
NTSTATUS status = STATUS_SUCCESS;
PVOID inBuffer;
PVOID outBuffer;
PHYSICAL_ADDRESS phyAddress;
SIZE_T copySize;
PVOID logicalAddress;
PVOID logicalAddress2;
ULONG uLong;
ULONG uData;
ULONG dwDMASize;
ULONG dwDMACount;
ULONG dwDMAPattern;
ULONG dwDMASize2;
ULONG dwDMACount2;
size_t InBufferSize;
size_t OutBufferSize;
ULONG i;
ULONG uTemp;
__int64 i64Start;
__int64 i64End;
__int64 i64End2;
__int64 i64Temp;
PVOID pSrc;
PVOID pDst;
PHYSICAL_ADDRESS phyAddress1;
PHYSICAL_ADDRESS phyAddress2;
LARGE_INTEGER delay;
PULONG pOutBuffer;
union
{
DMA_CSR2 bits;
ULONG ulong;
}DMACSR2;
union
{
DMA_CSR1 bits;
ULONG ulong;
}DMACSR1;
UNREFERENCED_PARAMETER( InputBufferLength );
//
// Get the device extension.
//
devExt = PCIEGetDeviceContext(WdfIoQueueGetDevice( Queue ));
if (InputBufferLength > 0)
{
status = WdfRequestRetrieveInputBuffer(Request, InputBufferLength, &inBuffer, &InBufferSize);
if( !NT_SUCCESS(status) )
{
TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTLS,
"WdfRequestRetrieveBuffer failed 0x%x\n", status);
WdfRequestComplete(Request, status);
return;
}
}
else
{
inBuffer = NULL;
InBufferSize = 0;
}
if (OutputBufferLength > 0)
{
status = WdfRequestRetrieveOutputBuffer(Request, OutputBufferLength, &outBuffer, &OutBufferSize);
if( !NT_SUCCESS(status) )
{
TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTLS,
"WdfRequestRetrieveBuffer failed 0x%x\n", status);
WdfRequestComplete(Request, status);
return;
}
}
else
{
outBuffer = NULL;
OutBufferSize = 0;
}
//
// Handle this request's specific code.
//
switch (IoControlCode)
{
case IOCTL_GET_VERSION:
{
// ULONG version
if (OutputBufferLength < sizeof(ULONG))
{
status = STATUS_INVALID_PARAMETER;
length = 0;
break;
}
*(PULONG) outBuffer = 0x0004000A;
status = STATUS_SUCCESS;
length = sizeof(ULONG);
break;
}
case IOCTL_PHY_TO_LOGICAL:
{
// ULONG phyaddress, SIZE_T length
if (InputBufferLength != sizeof(ULONG) + sizeof(SIZE_T))
{
status = STATUS_INVALID_PARAMETER;
length = 0;
break;
}
// PVOID logicalAddress
if (OutputBufferLength < sizeof(PVOID))
{
status = STATUS_INVALID_PARAMETER;
length = 0;
break;
}
phyAddress.LowPart = *(PULONG)inBuffer;
phyAddress.HighPart = 0;
copySize = *(SIZE_T *)((BYTE *)inBuffer + sizeof(ULONG));
*(PVOID *)outBuffer = MmMapIoSpace(phyAddress, copySize, MmNonCached);
status = STATUS_SUCCESS;
length = sizeof(PVOID);
break;
}
case IOCTL_LOGICAL_TO_PHY:
{
// PVOID logicaladdress
if (InputBufferLength != sizeof(PVOID))
{
status = STATUS_INVALID_PARAMETER;
length = 0;
break;
}
// ULONG physicalAddress
if (OutputBufferLength < sizeof(ULONG))
{
status = STATUS_INVALID_PARAMETER;
length = 0;
break;
}
logicalAddress = *(PVOID *)inBuffer;
// Get physical address
phyAddress = MmGetPhysicalAddress(logicalAddress);
*(PULONG)outBuffer = phyAddress.LowPart;
status = STATUS_SUCCESS;
length = sizeof(ULONG);
break;
}
case IOCTL_ALLOC:
{
// ULONG length
if (InputBufferLength != sizeof(ULONG))
{
status = STATUS_INVALID_PARAMETER;
length = 0;
break;
}
// PVOID address
if (OutputBufferLength < sizeof(PVOID))
{
status = STATUS_INVALID_PARAMETER;
length = 0;
break;
}
uLong = *(ULONG *)inBuffer;
logicalAddress = MmAllocateNonCachedMemory(uLong);
*(PVOID *)outBuffer = logicalAddress;
status = STATUS_SUCCESS;
length = sizeof(PVOID);
break;
}
case IOCTL_FREE:
{
// PVOID address, SIZE_T length
if (InputBufferLength != sizeof(PVOID) + sizeof(SIZE_T))
{
status = STATUS_INVALID_PARAMETER;
length = 0;
break;
}
logicalAddress = *(PVOID *)inBuffer;
copySize = *(SIZE_T *)((BYTE *)inBuffer + sizeof(PVOID));
MmFreeNonCachedMemory(logicalAddress, copySize);
status = STATUS_SUCCESS;
length = 0;
break;
}
case IOCTL_COPY_LOGICAL:
{
// PVOID sourceaddress, PVOID destaddress, SIZE_t length
if (InputBufferLength != sizeof(PVOID) + sizeof(PVOID) + sizeof(SIZE_T))
{
status = STATUS_INVALID_PARAMETER;
length = 0;
break;
}
// SIZE_t length
if (OutputBufferLength != sizeof(SIZE_T))
{
status = STATUS_INVALID_PARAMETER;
length = 0;
break;
}
logicalAddress = *(PVOID *)inBuffer;
logicalAddress2 = *(PVOID *)((BYTE *)inBuffer + sizeof(PVOID));
copySize = *(SIZE_T *)((BYTE *)inBuffer + sizeof(PVOID) + sizeof(PVOID));
RtlCopyMemory(logicalAddress2, logicalAddress, copySize);
*(SIZE_T *)outBuffer = copySize;
status = STATUS_SUCCESS;
length = sizeof(SIZE_T);
break;
}
case IOCTL_DMA_HOST_DEVICE:
{
// DEVICE READ.
// in : SIZE_t size, SIZE_t count
// out: ULONG performance, ULONG tscCounter_Int, ULONG deviceReadCompletionSize
if (InputBufferLength != sizeof(SIZE_T) + sizeof(SIZE_T))
{
status = STATUS_INVALID_PARAMETER;
length = 0;
break;
}
// SIZE_t length
if (OutputBufferLength != sizeof(ULONG) * 3)
{
status = STATUS_INVALID_PARAMETER;
length = 0;
break;
}
KdPrint(("DMA_HOST_DEVICE: begin"));
dwDMASize = *(SIZE_T *)((char *)inBuffer);
dwDMACount = *(SIZE_T *)((char *)inBuffer + sizeof(SIZE_T));
WRITE_REGISTER_ULONG((PULONG)&devExt->Regs->ReadDMATLPAddress, (ULONG)devExt->BufferPhysicalAddress);
WRITE_REGISTER_ULONG((PULONG)&devExt->Regs->ReadDMATLPSize, dwDMASize);
WRITE_REGISTER_ULONG((PULONG)&devExt->Regs->ReadDMATLPCount, dwDMACount);
DMACSR2.ulong = READ_REGISTER_ULONG((PULONG)&devExt->Regs->DCSR2);
DMACSR2.bits.WriteDMADone = 0;
DMACSR2.bits.WriteDMAStart = 0;
DMACSR2.bits.ReadDMADone = 0;
DMACSR2.bits.ReadDMAStart = 1;
devExt->ReadEndTsc = 0;
i = 0;
_asm rdtsc
_asm mov DWORD PTR i64Start, EAX
_asm mov DWORD PTR (i64Start+4), EDX
WRITE_REGISTER_ULONG((PULONG)&devExt->Regs->DCSR2, DMACSR2.ulong);
// wait while dmadone signal
do{
_asm rdtsc
_asm mov DWORD PTR i64End, EAX
_asm mov DWORD PTR (i64End+4), EDX
}while(devExt->ReadEndTsc == 0 && (i64End - i64Start) < 0xffffffff); // wait for 2 second(for 2GHZ)
if (devExt->ReadEndTsc == 0)
{
status = STATUS_SUCCESS;
*(ULONG *)outBuffer = (ULONG)-1;
length = sizeof(ULONG);
break;
}
*(ULONG *)outBuffer = READ_REGISTER_ULONG((PULONG)&devExt->Regs->ReadDMAPerformance);
*(ULONG *)((PUCHAR)outBuffer + sizeof(ULONG)) = (ULONG)(devExt->ReadEndTsc - i64Start);
*(ULONG *)((PUCHAR)outBuffer + sizeof(ULONG) + sizeof(ULONG)) = READ_REGISTER_ULONG((PULONG)&devExt->Regs->NumberOfReadCompletionWithData);
status = STATUS_SUCCESS;
length = sizeof(ULONG) * 3;
break;
}
case IOCTL_DMA_DEVICE_HOST:
{
// DEVICE WRITE.
// in : SIZE_T size, SIZE_T count, ULONG pattern
// out: ULONG performance, ULONG tscCounter_Int
if (InputBufferLength != sizeof(SIZE_T) + sizeof(SIZE_T) + sizeof(ULONG))
{
status = STATUS_INVALID_PARAMETER;
length = 0;
break;
}
// SIZE_T length
if (OutputBufferLength != sizeof(ULONG) + sizeof(ULONG))
{
status = STATUS_INVALID_PARAMETER;
length = 0;
break;
}
KdPrint(("DMA_DEVICE_HOST: begin"));
dwDMASize = *(SIZE_T *)((char *)inBuffer);
dwDMACount = *(SIZE_T *)((char *)inBuffer + sizeof(SIZE_T));
dwDMAPattern = *(ULONG *)((char *)inBuffer + sizeof(SIZE_T) + sizeof(SIZE_T));
WRITE_REGISTER_ULONG((PULONG)&devExt->Regs->WriteDMATLPAddress, (ULONG)devExt->Buffer2PhysicalAddress);
WRITE_REGISTER_ULONG((PULONG)&devExt->Regs->WriteDMATLPSize, dwDMASize);
WRITE_REGISTER_ULONG((PULONG)&devExt->Regs->WriteDMATLPCount, dwDMACount);
WRITE_REGISTER_ULONG((PULONG)&devExt->Regs->WriteDMATLPDataPattern, dwDMAPattern);
DMACSR2.ulong = READ_REGISTER_ULONG((PULONG)&devExt->Regs->DCSR2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -