阅读:2304回复:2
如何访问PCI 配置空间
我所知道的访问PCI配置空间的方法有这么几种:
1 DDK的API:HalSetBusDataByOffset 和 HalGetBusDataByOffset。这种方法不能访问4K的扩展空间,而且似乎有时候会失败 2 直接访问CF8、CFC的IO端口,这种方法在多核处理器下,非常容易出错导致蓝屏或死机(请问有没有办法加锁避免?) 3 MMIO的方法,基地址位置和CPU型号相关,而且某些BIOS没有正确映射。 我写的并不是一个正常的驱动程序,只是一个kernel service而已,为上层的应用程序提供访问硬件的权限。 请问有没有人有其他好的方法? |
|
沙发#
发布于:2008-09-11 20:54
http://support.microsoft.com/kb/253232
刚好前两天我也遇到这问题,用的是下面的 NTSTATUS ReadWriteConfigSpace( IN PDEVICE_OBJECT DeviceObject, IN ULONG ReadOrWrite, // 0 for read 1 for write IN PVOID Buffer, IN ULONG Offset, IN ULONG Length ) { KEVENT event; NTSTATUS status; PIRP irp; IO_STATUS_BLOCK ioStatusBlock; PIO_STACK_LOCATION irpStack; PDEVICE_OBJECT targetObject; PAGED_CODE(); KeInitializeEvent( &event, NotificationEvent, FALSE ); targetObject = IoGetAttachedDeviceReference( DeviceObject ); irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP, targetObject, NULL, 0, NULL, &event, &ioStatusBlock ); if (irp == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; goto End; } irpStack = IoGetNextIrpStackLocation( irp ); if (ReadOrWrite == 0) { irpStack->MinorFunction = IRP_MN_READ_CONFIG; }else { irpStack->MinorFunction = IRP_MN_WRITE_CONFIG; } irpStack->Parameters.ReadWriteConfig.WhichSpace = PCI_WHICHSPACE_CONFIG; irpStack->Parameters.ReadWriteConfig.Buffer = Buffer; irpStack->Parameters.ReadWriteConfig.Offset = Offset; irpStack->Parameters.ReadWriteConfig.Length = Length; // // Initialize the status to error in case the bus driver does not // set it correctly. // irp->IoStatus.Status = STATUS_NOT_SUPPORTED ; status = IoCallDriver( targetObject, irp ); if (status == STATUS_PENDING) { KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL ); status = ioStatusBlock.Status; } End: // // Done with reference // ObDereferenceObject( targetObject ); return status; } |
|
|
板凳#
发布于:2008-09-14 14:22
引用楼主holimion于2008-08-14 14:25发表的 如何访问PCI 配置空间 : BIOS没有正确映射的情况比较少见吧。基地址位置可以从ACPI拿到的。 |
|