📄 init.c
字号:
DMACSR2.bits.WriteDMADone = 0;
DMACSR2.bits.WriteDMAStart = 1;
DMACSR2.bits.ReadDMADone = 0;
DMACSR2.bits.ReadDMAStart = 0;
devExt->WriteEndTsc = 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->WriteEndTsc == 0 && (i64End - i64Start) < 0xffffffff);
if (devExt->WriteEndTsc == 0)
{
status = STATUS_SUCCESS;
*(ULONG *)outBuffer = (ULONG)-1;
length = sizeof(ULONG);
break;
}
*(ULONG *)outBuffer = READ_REGISTER_ULONG((PULONG)&devExt->Regs->WriteDMAPerformance);
*(ULONG *)((PUCHAR)outBuffer + sizeof(ULONG)) = (ULONG)(devExt->WriteEndTsc - i64Start);
status = STATUS_SUCCESS;
length = sizeof(ULONG) * 2;
break;
}
case IOCTL_DMA_PCI_TEST:
{
// DEVICE WRITE.
// in :
// for read : SIZE_T size, SIZE_T count
// for write: SIZE_T size, SIZE_T count, ULONG pattern
// out:
// for read : ULONG performance, ULONG tscCounter_Int, ULONG deviceReadCompletionSize
// for write: ULONG performance, ULONG tscCounter_Int
if (InputBufferLength != sizeof(SIZE_T) + sizeof(SIZE_T) + sizeof(ULONG) + sizeof(SIZE_T) + sizeof(SIZE_T))
{
status = STATUS_INVALID_PARAMETER;
length = 0;
break;
}
// SIZE_T length
if (OutputBufferLength != sizeof(ULONG) * 5)
{
status = STATUS_INVALID_PARAMETER;
length = 0;
break;
}
KdPrint(("DMA_PCI_TEST: begin"));
dwDMASize2 = *(SIZE_T *)((char *)inBuffer );
dwDMACount2 = *(SIZE_T *)((char *)inBuffer + sizeof(SIZE_T));
dwDMASize = *(SIZE_T *)((char *)inBuffer + sizeof(SIZE_T) + sizeof(SIZE_T));
dwDMACount = *(SIZE_T *)((char *)inBuffer + sizeof(SIZE_T) + sizeof(SIZE_T) + sizeof(SIZE_T));
dwDMAPattern = *(ULONG *)((char *)inBuffer + sizeof(SIZE_T) + sizeof(SIZE_T) + sizeof(SIZE_T) + sizeof(SIZE_T));
WRITE_REGISTER_ULONG((PULONG)&devExt->Regs->WriteDMATLPAddress, (ULONG)devExt->Buffer2PhysicalAddress);
WRITE_REGISTER_ULONG((PULONG)&devExt->Regs->WriteDMATLPSize, dwDMASize2);
WRITE_REGISTER_ULONG((PULONG)&devExt->Regs->WriteDMATLPCount, dwDMACount2);
WRITE_REGISTER_ULONG((PULONG)&devExt->Regs->WriteDMATLPDataPattern, dwDMAPattern);
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 = 1;
DMACSR2.bits.ReadDMADone = 0;
DMACSR2.bits.ReadDMAStart = 1;
devExt->WriteEndTsc = 0;
devExt->ReadEndTsc = 0;
i64End = 0;
i64End2 = 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 i64Temp, EAX
_asm mov DWORD PTR (i64Temp + 4), EDX
if (DMACSR2.bits.WriteDMADone && (i64End == 0))
{
i64End = i64Temp;
}
if (DMACSR2.bits.ReadDMADone && (i64End2 == 0))
{
i64End2 = i64Temp;
}
}while((devExt->ReadEndTsc == 0 || devExt->WriteEndTsc == 0) && (i64Temp - i64Start) < 0xffffffff);
if (devExt->ReadEndTsc == 0 || devExt->WriteEndTsc == 0)
{
*(PULONG)outBuffer = (ULONG)-1;
status = STATUS_SUCCESS;
length = sizeof(ULONG);
break;
}
pOutBuffer = (PULONG)outBuffer;
*pOutBuffer = READ_REGISTER_ULONG((PULONG)&devExt->Regs->ReadDMAPerformance);
++pOutBuffer;
*pOutBuffer = (ULONG)(devExt->ReadEndTsc - i64Start);
++pOutBuffer;
*pOutBuffer = READ_REGISTER_ULONG((PULONG)&devExt->Regs->NumberOfReadCompletionWithData);
++pOutBuffer;
*pOutBuffer = READ_REGISTER_ULONG((PULONG)&devExt->Regs->WriteDMAPerformance);
++pOutBuffer;
*pOutBuffer = (ULONG)(devExt->WriteEndTsc - i64Start);
status = STATUS_SUCCESS;
length = sizeof(ULONG) * 5;
break;
}
case IOCTL_GET_BUFFERADDRESS:
{
// SIZE_T length
if (OutputBufferLength != sizeof(ULONG) * 6)
{
status = STATUS_INVALID_PARAMETER;
length = 0;
KdPrint(("Length: %d", OutputBufferLength));
break;
}
// buffer
KdPrint(("PHYADDRESS : 0X%08X", devExt->BufferPhysicalAddress));
KdPrint(("LogicalADDRESS: 0X%08X", devExt->BufferLogicalAddress));
phyAddress.HighPart = 0;
phyAddress.LowPart = (ULONG)devExt->BufferPhysicalAddress;
devExt->BufferSystemVirtualAddress = MmMapIoSpace(phyAddress, PCIE_BUFFER_SIZE, MmNonCached);
devExt->BufferMdl = IoAllocateMdl(devExt->BufferSystemVirtualAddress, PCIE_BUFFER_SIZE, FALSE, FALSE, NULL);
MmBuildMdlForNonPagedPool(devExt->BufferMdl);
devExt->BufferUserVirtualAddress = (PVOID)(((ULONG)PAGE_ALIGN(MmMapLockedPages(devExt->BufferMdl, UserMode))) + MmGetMdlByteOffset(devExt->BufferMdl));
KdPrint(("SystemVirtualAddress: 0x%08X", devExt->BufferSystemVirtualAddress));
KdPrint(("UserVirtualAddress: 0x%08X", devExt->BufferUserVirtualAddress));
// buffer2
KdPrint(("PHYADDRESS2 : 0X%08X", devExt->Buffer2PhysicalAddress));
KdPrint(("LogicalADDRESS2: 0X%08X", devExt->Buffer2LogicalAddress));
phyAddress.HighPart = 0;
phyAddress.LowPart = (ULONG)devExt->Buffer2PhysicalAddress;
devExt->Buffer2SystemVirtualAddress = MmMapIoSpace(phyAddress, PCIE_BUFFER_SIZE, MmNonCached);
devExt->Buffer2Mdl = IoAllocateMdl(devExt->Buffer2SystemVirtualAddress, PCIE_BUFFER_SIZE, FALSE, FALSE, NULL);
MmBuildMdlForNonPagedPool(devExt->Buffer2Mdl);
devExt->Buffer2UserVirtualAddress = (PVOID)(((ULONG)PAGE_ALIGN(MmMapLockedPages(devExt->Buffer2Mdl, UserMode))) + MmGetMdlByteOffset(devExt->Buffer2Mdl));
KdPrint(("SystemVirtualAddress2: 0x%08X", devExt->Buffer2SystemVirtualAddress));
KdPrint(("UserVirtualAddress2: 0x%08X", devExt->Buffer2UserVirtualAddress));
*(PULONG)outBuffer = (ULONG)devExt->BufferUserVirtualAddress;
*(PULONG)((PUCHAR)outBuffer + sizeof(ULONG)) = (ULONG)devExt->BufferPhysicalAddress;
*(PULONG)((PUCHAR)outBuffer + sizeof(ULONG) * 2) = PCIE_BUFFER_SIZE;
*(PULONG)((PUCHAR)outBuffer + sizeof(ULONG) * 3) = (ULONG)devExt->Buffer2UserVirtualAddress;
*(PULONG)((PUCHAR)outBuffer + sizeof(ULONG) * 4) = (ULONG)devExt->Buffer2PhysicalAddress;
*(PULONG)((PUCHAR)outBuffer + sizeof(ULONG) * 5) = PCIE_BUFFER_SIZE;
status = STATUS_SUCCESS;
length = sizeof(ULONG) * 6;
break;
}
case IOCTL_FREE_BUFFERADDRESS:
{
if (devExt->BufferUserVirtualAddress && devExt->BufferSystemVirtualAddress && devExt->BufferMdl)
{
MmUnmapLockedPages(devExt->BufferUserVirtualAddress, devExt->BufferMdl);
IoFreeMdl(devExt->BufferMdl);
MmUnmapIoSpace(devExt->BufferSystemVirtualAddress, PCIE_BUFFER_SIZE);
devExt->BufferSystemVirtualAddress = NULL;
devExt->BufferUserVirtualAddress = NULL;
devExt->BufferMdl = NULL;
}
if (devExt->Buffer2UserVirtualAddress && devExt->Buffer2SystemVirtualAddress && devExt->Buffer2Mdl)
{
MmUnmapLockedPages(devExt->Buffer2UserVirtualAddress, devExt->Buffer2Mdl);
IoFreeMdl(devExt->Buffer2Mdl);
MmUnmapIoSpace(devExt->Buffer2SystemVirtualAddress, PCIE_BUFFER_SIZE);
devExt->Buffer2SystemVirtualAddress = NULL;
devExt->Buffer2UserVirtualAddress = NULL;
devExt->Buffer2Mdl = NULL;
}
status = STATUS_SUCCESS;
length = 0;
break;
}
case IOCTL_READ_REG:
{
// input : ULONG addr, ULONG repeat
if (InputBufferLength != sizeof(ULONG) * 2)
{
status = STATUS_INVALID_PARAMETER;
length = 0;
KdPrint(("Length: %d", InputBufferLength));
break;
}
// output : ULONG data, ULONG tsc
if (OutputBufferLength != sizeof(ULONG) * 2)
{
status = STATUS_INVALID_PARAMETER;
length = 0;
KdPrint(("Length: %d", OutputBufferLength));
break;
}
uLong = *(PULONG)inBuffer;
uTemp = *(PULONG)((PUCHAR)inBuffer + sizeof(ULONG));
if (uLong >= devExt->RegsLength)
{
status = STATUS_INVALID_PARAMETER;
length = 0;
KdPrint(("Offset address: %d", uLong));
break;
}
_asm rdtsc
_asm mov DWORD PTR i64Start, EAX
_asm mov DWORD PTR (i64Start + 4), EDX
for(i=0; i<uTemp; ++i)
*(PULONG)outBuffer = READ_REGISTER_ULONG((PULONG)(devExt->RegsBase + uLong));
_asm rdtsc
_asm mov DWORD PTR i64End, EAX
_asm mov DWORD PTR (i64End + 4), EDX
*(PULONG)((PUCHAR)outBuffer + sizeof(ULONG)) = (ULONG)(i64End - i64Start);
status = STATUS_SUCCESS;
length = sizeof(ULONG) * 2;
break;
}
case IOCTL_WRITE_REG:
{
// input : ULONG addr, ULONG data, ULONG repeattimes
if (InputBufferLength != sizeof(ULONG) * 3)
{
status = STATUS_INVALID_PARAMETER;
length = 0;
KdPrint(("Length: %d, should be %d", InputBufferLength, sizeof(ULONG) * 2));
break;
}
// output : ULONG data
if (OutputBufferLength != sizeof(ULONG))
{
status = STATUS_INVALID_PARAMETER;
length = 0;
KdPrint(("Length: %d", OutputBufferLength));
break;
}
uLong = *(PULONG)inBuffer;
uData = *(PULONG)((PUCHAR)inBuffer + sizeof(ULONG));
uTemp = *(PULONG)((PUCHAR)inBuffer + sizeof(ULONG)*2);
if (uLong >= devExt->RegsLength)
{
status = STATUS_INVALID_PARAMETER;
length = 0;
KdPrint(("Offset address: %d", uLong));
break;
}
_asm rdtsc
_asm mov DWORD PTR i64Start, EAX
_asm mov DWORD PTR (i64Start + 4), EDX
for(i=0; i<uTemp; ++i)
WRITE_REGISTER_ULONG((PULONG)(devExt->RegsBase + uLong), uData);
_asm rdtsc
_asm mov DWORD PTR i64End, EAX
_asm mov DWORD PTR (i64End + 4), EDX
*(PULONG)outBuffer = (ULONG)(i64End - i64Start);
status = STATUS_SUCCESS;
length = sizeof(ULONG);
break;
}
case IOCTL_DEVICE_RESET:
{
PCIEHardwareReset(devExt);
status = STATUS_SUCCESS;
length = 0;
break;
}
case IOCTL_GET_REGADDRESS:
{
// output : ULONG logical address, ULONG phyaddress, ULONG len
if (OutputBufferLength != sizeof(ULONG) * 3)
{
status = STATUS_INVALID_PARAMETER;
length = 0;
KdPrint(("Length: %d", OutputBufferLength));
break;
}
*(PULONG)outBuffer = (ULONG)devExt->RegsPhyBase;
*(PULONG)((PUCHAR)outBuffer + sizeof(ULONG)) = (ULONG)devExt->RegsBase;
*(PULONG)((PUCHAR)outBuffer + sizeof(ULONG) * 2) = (ULONG)devExt->RegsLength;
status = STATUS_SUCCESS;
length = sizeof(ULONG) * 3;
break;
}
default:
status = STATUS_INVALID_DEVICE_REQUEST;
length = 0;
break;
}
if (status != STATUS_PENDING)
{
WdfRequestCompleteWithInformation(Request, status, length);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -