wdmWin10下遍历PCI配置空间
2021-06-30 22:05
阅读:415
标签:include nio context tab ima c++ NPU mat 建设

图右边是引用驱动开发技术详解书中的代码:
3环只增加了个死循环 驱动没变
#include
#include
//使用CTL_CODE必须加入winioctl.h
#include
#include "Ioctls.h"
DWORD In_32(HANDLE hDevice, USHORT port)
{
DWORD dwOutput;
DWORD inputBuffer[2] =
{
port,//对port进行操作
4//1代表8位操作,2代表16位操作,4代表32位操作
};
DWORD dResult;
DeviceIoControl(hDevice, READ_PORT, inputBuffer, sizeof(inputBuffer), &dResult, sizeof(DWORD), &dwOutput, NULL);
return dResult;
}
void Out_32(HANDLE hDevice, USHORT port, DWORD value)
{
DWORD dwOutput;
DWORD inputBuffer[3] =
{
port,//对port进行操作
4,//1代表8位操作,2代表16位操作,4代表32位操作
value//输出字节
};
DeviceIoControl(hDevice, WRITE_PORT, inputBuffer, sizeof(inputBuffer), NULL, 0, &dwOutput, NULL);
}
/* PCI配置空间寄存器 */
#define PCI_CONFIG_ADDRESS 0xCF8
#define PCI_CONFIG_DATA 0xCFC
#define PCI_TYPE0_ADDRESSES 6
#define PCI_TYPE1_ADDRESSES 2
#define PCI_TYPE2_ADDRESSES 5
typedef struct _PCI_COMMON_CONFIG {
USHORT VendorID; // (ro)
USHORT DeviceID; // (ro)
USHORT Command; // Device control
USHORT Status;
UCHAR RevisionID; // (ro)
UCHAR ProgIf; // (ro)
UCHAR SubClass; // (ro)
UCHAR BaseClass; // (ro)
UCHAR CacheLineSize; // (ro+)
UCHAR LatencyTimer; // (ro+)
UCHAR HeaderType; // (ro)
UCHAR BIST; // Built in self test
union {
struct _PCI_HEADER_TYPE_0 {
ULONG BaseAddresses[PCI_TYPE0_ADDRESSES];
ULONG CIS;
USHORT SubVendorID;
USHORT SubSystemID;
ULONG ROMBaseAddress;
UCHAR CapabilitiesPtr;
UCHAR Reserved1[3];
ULONG Reserved2;
UCHAR InterruptLine; //
UCHAR InterruptPin; // (ro)
UCHAR MinimumGrant; // (ro)
UCHAR MaximumLatency; // (ro)
} type0;
// end_wdm end_ntminiport end_ntndis
//
// PCI to PCI Bridge
//
struct _PCI_HEADER_TYPE_1 {
ULONG BaseAddresses[PCI_TYPE1_ADDRESSES];
UCHAR PrimaryBus;
UCHAR SecondaryBus;
UCHAR SubordinateBus;
UCHAR SecondaryLatency;
UCHAR IOBase;
UCHAR IOLimit;
USHORT SecondaryStatus;
USHORT MemoryBase;
USHORT MemoryLimit;
USHORT PrefetchBase;
USHORT PrefetchLimit;
ULONG PrefetchBaseUpper32;
ULONG PrefetchLimitUpper32;
USHORT IOBaseUpper16;
USHORT IOLimitUpper16;
UCHAR CapabilitiesPtr;
UCHAR Reserved1[3];
ULONG ROMBaseAddress;
UCHAR InterruptLine;
UCHAR InterruptPin;
USHORT BridgeControl;
} type1;
//
// PCI to CARDBUS Bridge
//
struct _PCI_HEADER_TYPE_2 {
ULONG SocketRegistersBaseAddress;
UCHAR CapabilitiesPtr;
UCHAR Reserved;
USHORT SecondaryStatus;
UCHAR PrimaryBus;
UCHAR SecondaryBus;
UCHAR SubordinateBus;
UCHAR SecondaryLatency;
struct {
ULONG Base;
ULONG Limit;
} Range[PCI_TYPE2_ADDRESSES - 1];
UCHAR InterruptLine;
UCHAR InterruptPin;
USHORT BridgeControl;
} type2;
// begin_wdm begin_ntminiport begin_ntndis
} u;
UCHAR DeviceSpecific[192];
} PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
typedef struct _PCI_SLOT_NUMBER {
union {
struct {
ULONG FunctionNumber : 3;
ULONG DeviceNumber : 5;
ULONG Reserved : 24;
} bits;
ULONG AsULONG;
} u;
} PCI_SLOT_NUMBER, *PPCI_SLOT_NUMBER;
void DisplayPCIConfiguation(HANDLE hDevice, int bus, int dev, int func)
{
DWORD dwAddr;
DWORD dwData;
PCI_COMMON_CONFIG pci_config;
PCI_SLOT_NUMBER SlotNumber;
SlotNumber.u.AsULONG = 0;
SlotNumber.u.bits.DeviceNumber = dev;
SlotNumber.u.bits.FunctionNumber = func;
dwAddr = 0x80000000 | (bus
图左边自己实现的用了俩种方式枚举pci
一种是用api HalGetBusDataByOffset
一种上是修改书的代码
0环
entry.c
#include "Driver.h"
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegistryPath)
{
NTSTATUS status;
//判断CPU类型
CPUType();
//枚举
EnumeratePCI();
//EnumPCI();
KdPrint(("Enter DriverEntry\n"));
//DbgBreakPoint();
//设置卸载函数
pDriverObject->DriverUnload =DDKUnload;
//设置派遣函数
pDriverObject->MajorFunction[IRP_MJ_CREATE] = DDKDispatchRoutin;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = DDKDispatchRoutin;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = DDKDispatchRoutin;
pDriverObject->MajorFunction[IRP_MJ_READ] = DDKDispatchRoutin;
pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = DDKDispatchRoutin;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DDKDispatchRoutin;
pDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = DDKDispatchRoutin;
pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DDKDispatchRoutin;
pDriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = DDKDispatchRoutin;
//创建驱动设备对象
status = CreateDevice(pDriverObject);
KdPrint(("Leave DriverEntry\n"));
return status;
}
NTSTATUS CreateDevice(
IN PDRIVER_OBJECT pDriverObject)
{
NTSTATUS status;
PDEVICE_OBJECT pDevObj;
PDEVICE_EXTENSION pDevExt;
//创建设备名称
UNICODE_STRING devName;
RtlInitUnicodeString(&devName, L"\\Device\\MyDDKDevice");
//创建设备
status = IoCreateDevice(pDriverObject,
sizeof(DEVICE_EXTENSION),
&devName,
FILE_DEVICE_UNKNOWN,
0, TRUE,
&pDevObj);
if (!NT_SUCCESS(status))
return status;
pDevObj->Flags |= DO_BUFFERED_IO;
pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
pDevExt->pDevice = pDevObj;
pDevExt->ustrDeviceName = devName;
//创建符号链接
UNICODE_STRING symLinkName;
RtlInitUnicodeString(&symLinkName, L"\\??\\TESTDDK");
pDevExt->ustrSymLinkName = symLinkName;
status = IoCreateSymbolicLink(&symLinkName, &devName);
if (!NT_SUCCESS(status))
{
IoDeleteDevice(pDevObj);
return status;
}
return STATUS_SUCCESS;
}
#pragma PAGEDCODE
VOID DDKUnload(IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pNextObj;
KdPrint(("Enter DriverUnload\n"));
pNextObj = pDriverObject->DeviceObject;
while (pNextObj != NULL)
{
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
pNextObj->DeviceExtension;
//删除符号链接
UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
IoDeleteSymbolicLink(&pLinkName);
pNextObj = pNextObj->NextDevice;
IoDeleteDevice(pDevExt->pDevice);
}
}
#pragma PAGEDCODE
NTSTATUS DDKDispatchRoutin(IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp)
{
KdPrint(("Enter HelloDDKDispatchRoutin\n"));
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
//建立一个字符串数组与IRP类型对应起来
static char* irpname[] =
{
"IRP_MJ_CREATE",
"IRP_MJ_CREATE_NAMED_PIPE",
"IRP_MJ_CLOSE",
"IRP_MJ_READ",
"IRP_MJ_WRITE",
"IRP_MJ_QUERY_INFORMATION",
"IRP_MJ_SET_INFORMATION",
"IRP_MJ_QUERY_EA",
"IRP_MJ_SET_EA",
"IRP_MJ_FLUSH_BUFFERS",
"IRP_MJ_QUERY_VOLUME_INFORMATION",
"IRP_MJ_SET_VOLUME_INFORMATION",
"IRP_MJ_DIRECTORY_CONTROL",
"IRP_MJ_FILE_SYSTEM_CONTROL",
"IRP_MJ_DEVICE_CONTROL",
"IRP_MJ_INTERNAL_DEVICE_CONTROL",
"IRP_MJ_SHUTDOWN",
"IRP_MJ_LOCK_CONTROL",
"IRP_MJ_CLEANUP",
"IRP_MJ_CREATE_MAILSLOT",
"IRP_MJ_QUERY_SECURITY",
"IRP_MJ_SET_SECURITY",
"IRP_MJ_POWER",
"IRP_MJ_SYSTEM_CONTROL",
"IRP_MJ_DEVICE_CHANGE",
"IRP_MJ_QUERY_QUOTA",
"IRP_MJ_SET_QUOTA",
"IRP_MJ_PNP",
};
UCHAR type = stack->MajorFunction;
if (type >= arraysize(irpname))
KdPrint((" - Unknown IRP, major type %X\n", type));
else
KdPrint(("\t%s\n", irpname[type]));
//对一般IRP的简单操作,后面会介绍对IRP更复杂的操作
NTSTATUS status = STATUS_SUCCESS;
// 完成IRP
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
KdPrint(("Leave DDKDispatchRoutin\n"));
return status;
}
stRet CPUType()
{
stRet st_Ret = {FALSE,FALSE};
ULONG CPUInfo[4] = { -1 };
CHAR cpu_string[48];
__cpuid(CPUInfo, 0);
INT num_ids = CPUInfo[0];
//GenuineIntel是Intel的CPU
//0x47, 0x65, 0x6E, 0x75, 0x69, 0x6E, 0x65, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x00, 0x00, 0x00, 0x00 GenuineIntel
if ((CPUInfo[1] == 0x756e6547) && (CPUInfo[2] == 0x6c65746e) && (CPUInfo[3] == 0x49656e69))
{
st_Ret.bIntelCPU=TRUE;
KdPrint(("GenuineIntel\n"));
}
//AuthenticAMD 是AMD的CPU
//0x41, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63, 0x41, 0x4D, 0x44, 0x00, 0x00, 0x00, 0x00 AuthenticAMD
if ((CPUInfo[1] == 0x68747541) && (CPUInfo[2] == 0x444d4163) && (CPUInfo[3] == 0x69746e65))
{
st_Ret.bIntelCPU = TRUE;
KdPrint(("AuthenticAMD\n"));
}
INT cpu_info[4] = { -1 };
__cpuid(cpu_info, 0);
// Interpret CPU feature information.
if (num_ids > 0) {
int cpu_info7[4] = { 0 };
__cpuid(cpu_info, 1);
if (num_ids >= 7) {
__cpuid(cpu_info7, 7);
}
signature_ = cpu_info[0];
stepping_ = cpu_info[0] & 0xf;
model_ = ((cpu_info[0] >> 4) & 0xf) + ((cpu_info[0] >> 12) & 0xf0);
family_ = (cpu_info[0] >> 8) & 0xf;
type_ = (cpu_info[0] >> 12) & 0x3;
ext_model_ = (cpu_info[0] >> 16) & 0xf;
ext_family_ = (cpu_info[0] >> 20) & 0xff;
has_mmx_ = (cpu_info[3] & 0x00800000) != 0;
has_sse_ = (cpu_info[3] & 0x02000000) != 0;
has_sse2_ = (cpu_info[3] & 0x04000000) != 0;
has_sse3_ = (cpu_info[2] & 0x00000001) != 0;
has_ssse3_ = (cpu_info[2] & 0x00000200) != 0;
has_sse41_ = (cpu_info[2] & 0x00080000) != 0;
has_sse42_ = (cpu_info[2] & 0x00100000) != 0;
has_aesni_ = (cpu_info[2] & 0x02000000) != 0;
has_avx2_ = has_avx_ && (cpu_info7[1] & 0x00000020) != 0;
}
// Get the brand string of the cpu.
__cpuid(cpu_info, 0x80000000);
const int parameter_end = 0x80000004;
int max_parameter = cpu_info[0];
//CHAR temp[40] = { -1 };
if (cpu_info[0] >= parameter_end) {
PCHAR cpu_string_ptr = cpu_string;
for (int parameter = 0x80000002; parameter = parameter_containing_non_stop_time_stamp_counter) {
__cpuid(cpu_info, parameter_containing_non_stop_time_stamp_counter);
has_non_stop_time_stamp_counter_ = (cpu_info[3] & (1 dwVendorID = tgaConfigInfo.VendorID;
//pHardWareInfo->dwDeviceID = tgaConfigInfo.DeviceID;
//pHardWareInfo->wSubSystemID = tgaConfigInfo.u.type0.SubSystemID;
//pHardWareInfo->wSubVendorID = tgaConfigInfo.u.type0.SubVendorID;
//pHardWareInfo->wRevisionID = tgaConfigInfo.RevisionID;
//wcscat(pHardWareInfo->wsHardwareID, pwcHardwareId);
//InsertTailList(&g_DisPlayInfo.VideoList, &pHardWareInfo->Next);
//MsgLog(L"枚举PCI成功");
break;
}
}
}
}
if (NULL != pwcHardwareId)
{
ExFreePool(pwcHardwareId);
pwcHardwareId = NULL;
}
} while (FALSE);
}
//Driver.h
#include
#include
#include
#include
#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")
#define PDI_BUS_MAX 0xFF
#define PDI_DEVICE_MAX 0x1F
#define PDI_FUNCTION_MAX 0x7
#define PAGEDDATA data_seg("PAGE")
#define LOCKEDDATA data_seg()
#define INITDATA data_seg("INIT")
#define arraysize(p) (sizeof(p)/sizeof((p)[0]))
#define DELAY_ONE_MICRSECOND (-10)
#define DELAY_ONE_MILLISECOND (1000 * DELAY_ONE_MICRSECOND)
typedef struct _DEVICE_EXTENSION {
PDEVICE_OBJECT pDevice;
UNICODE_STRING ustrDeviceName; //设备名称
UNICODE_STRING ustrSymLinkName; //符号链接名
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
typedef struct MyStruct
{
//Intel
BOOLEAN bIntelCPU;
//AMD
BOOLEAN bAMDCPU;
}stRet;
INT signature_; // raw form of type, family, model, and stepping
INT type_; // process type
INT family_; // family of the processor
INT model_; // model of processor
INT stepping_; // processor revision number
INT ext_model_;
INT ext_family_;
BOOLEAN has_mmx_;
BOOLEAN has_sse_;
BOOLEAN has_sse2_;
BOOLEAN has_sse3_;
BOOLEAN has_ssse3_;
BOOLEAN has_sse41_;
BOOLEAN has_sse42_;
BOOLEAN has_avx_;
BOOLEAN has_avx2_;
BOOLEAN has_aesni_;
BOOLEAN has_non_stop_time_stamp_counter_;
ULONG CPUInfo[4] = { -1 };
// 函数声明
stRet CPUType();
NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject);
VOID DDKUnload(IN PDRIVER_OBJECT pDriverObject);
NTSTATUS DDKDispatchRoutin(IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp);
// 字符串长度
DWORD lstrlen(PCHAR pSrc);
// 字符拷贝
VOID lstrcpy(PCHAR pDst, PCHAR pSrc, DWORD len);
//////////////////////////////////////////////////////////////
/* PCI配置空间寄存器 */
#define PCI_CONFIG_ADDRESS 0xCF8
#define PCI_CONFIG_DATA 0xCFC
#define PCI_TYPE0_ADDRESSES 6
#define PCI_TYPE1_ADDRESSES 2
#define PCI_TYPE2_ADDRESSES 5
typedef struct _MYPCI_COMMON_CONFIG {
USHORT VendorID; // (ro)
USHORT DeviceID; // (ro)
USHORT Command; // Device control
USHORT Status;
UCHAR RevisionID; // (ro)
UCHAR ProgIf; // (ro)
UCHAR SubClass; // (ro)
UCHAR BaseClass; // (ro)
UCHAR CacheLineSize; // (ro+)
UCHAR LatencyTimer; // (ro+)
UCHAR HeaderType; // (ro)
UCHAR BIST; // Built in self test
union {
struct _MYPCI_HEADER_TYPE_0 {
ULONG BaseAddresses[PCI_TYPE0_ADDRESSES];
ULONG CIS;
USHORT SubVendorID;
USHORT SubSystemID;
ULONG ROMBaseAddress;
UCHAR CapabilitiesPtr;
UCHAR Reserved1[3];
ULONG Reserved2;
UCHAR InterruptLine; //
UCHAR InterruptPin; // (ro)
UCHAR MinimumGrant; // (ro)
UCHAR MaximumLatency; // (ro)
} type0;
// end_wdm end_ntminiport end_ntndis
//
// PCI to PCI Bridge
//
struct _MYPCI_HEADER_TYPE_1 {
ULONG BaseAddresses[PCI_TYPE1_ADDRESSES];
UCHAR PrimaryBus;
UCHAR SecondaryBus;
UCHAR SubordinateBus;
UCHAR SecondaryLatency;
UCHAR IOBase;
UCHAR IOLimit;
USHORT SecondaryStatus;
USHORT MemoryBase;
USHORT MemoryLimit;
USHORT PrefetchBase;
USHORT PrefetchLimit;
ULONG PrefetchBaseUpper32;
ULONG PrefetchLimitUpper32;
USHORT IOBaseUpper16;
USHORT IOLimitUpper16;
UCHAR CapabilitiesPtr;
UCHAR Reserved1[3];
ULONG ROMBaseAddress;
UCHAR InterruptLine;
UCHAR InterruptPin;
USHORT BridgeControl;
} type1;
//
// PCI to CARDBUS Bridge
//
struct _MYPCI_HEADER_TYPE_2 {
ULONG SocketRegistersBaseAddress;
UCHAR CapabilitiesPtr;
UCHAR Reserved;
USHORT SecondaryStatus;
UCHAR PrimaryBus;
UCHAR SecondaryBus;
UCHAR SubordinateBus;
UCHAR SecondaryLatency;
struct {
ULONG Base;
ULONG Limit;
} Range[PCI_TYPE2_ADDRESSES - 1];
UCHAR InterruptLine;
UCHAR InterruptPin;
USHORT BridgeControl;
} type2;
// begin_wdm begin_ntminiport begin_ntndis
} u;
UCHAR DeviceSpecific[192];
} MYPCI_COMMON_CONFIG, *MYPPCI_COMMON_CONFIG;
typedef struct _MYPCI_SLOT_NUMBER {
union {
struct {
ULONG FunctionNumber : 3;
ULONG DeviceNumber : 5;
ULONG Reserved : 24;
} bits;
ULONG AsULONG;
} u;
} MYPCI_SLOT_NUMBER, *MYPPCI_SLOT_NUMBER;
VOID EnumeratePCI();
VOID EnumPCI();
VOID MySleep(LONG msec);
wdmWin10下遍历PCI配置空间
标签:include nio context tab ima c++ NPU mat 建设
原文地址:http://blog.51cto.com/haidragon/2317816
文章来自:搜素材网的编程语言模块,转载请注明文章出处。
文章标题:wdmWin10下遍历PCI配置空间
文章链接:http://soscw.com/index.php/essay/100027.html
文章标题:wdmWin10下遍历PCI配置空间
文章链接:http://soscw.com/index.php/essay/100027.html
评论
亲,登录后才可以留言!