none
How to read PCI config space RRS feed

  • Question

  • Please share a example kernel code (driver) and/or userspace code to read the PCI config space for a given PCI device (Bus , Device and Function number given).

    Tuesday, June 14, 2016 6:55 PM

Answers

  • Why do you want to do this?   In Windows the kernel gives the driver the resource data, and reading the config space is rarely done.  You can use IRP_MN_QUERY_INTERFACE if you can get access to the specific device, see https://msdn.microsoft.com/en-us/library/windows/hardware/ff551687(v=vs.85).aspx  but there is little need for this in most cases.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Tuesday, June 14, 2016 7:02 PM
  • There is not much in the way of sample code to do this.  You might want to look at http://www.hollistech.com/Resources/Misc%20articles/getbusdata.doc

    Your initial question was on how to get the configuration data for one specific device, but rweverything.com and your point #2 indicates you want all the devices.  The only way to do this is with a PCI Bus Filter, unfortunately bus filters are not well documented, and cannot be done with KMDF the preferred technology for drivers these days.  I know of no sample bus drivers, that can be recommended.  I've done a couple of PCI Bus Filters commercially, they are not a beginners project.

    DO NOT BE STUPID ENOUGH TO TRY TO ACCESS THE PCI CONFIG HARDWARE REGISTERS, this is a great way to cause subtle bugs in the system.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com


    Tuesday, June 14, 2016 7:18 PM

All replies

  • Why do you want to do this?   In Windows the kernel gives the driver the resource data, and reading the config space is rarely done.  You can use IRP_MN_QUERY_INTERFACE if you can get access to the specific device, see https://msdn.microsoft.com/en-us/library/windows/hardware/ff551687(v=vs.85).aspx  but there is little need for this in most cases.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Tuesday, June 14, 2016 7:02 PM
  • I need the pci-config space information in user-space, for -
    1/ for understanding the PCI device
    2/ decode and get other information, as like rweverything.com that provide every details of a PCI-device

    Followed by need to to PCI-BAR mmio read/write. 

    Would you please point me a sample code to read the PCI config space?

     
    Tuesday, June 14, 2016 7:08 PM
  • There is not much in the way of sample code to do this.  You might want to look at http://www.hollistech.com/Resources/Misc%20articles/getbusdata.doc

    Your initial question was on how to get the configuration data for one specific device, but rweverything.com and your point #2 indicates you want all the devices.  The only way to do this is with a PCI Bus Filter, unfortunately bus filters are not well documented, and cannot be done with KMDF the preferred technology for drivers these days.  I know of no sample bus drivers, that can be recommended.  I've done a couple of PCI Bus Filters commercially, they are not a beginners project.

    DO NOT BE STUPID ENOUGH TO TRY TO ACCESS THE PCI CONFIG HARDWARE REGISTERS, this is a great way to cause subtle bugs in the system.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com


    Tuesday, June 14, 2016 7:18 PM
  • For debugging your device and understanding its config space, use windbg extension commands !pci, !pcitree

    Wednesday, June 15, 2016 1:54 AM
  •  Here is the sample code I refer as PCI-Filter Driver example: http://www.codeproject.com/Articles/35378/Access-Physical-Memory-Port-and-PCI-Configuration
    dro->DriverExtension->AddDevice=PCIFltAddDevice;
    However the PCIFltAddDevice() is not get called and hence the device object ("\\Device\\PhyMemPCIFilter") is not created for the PCI-Filter Driver.

    Follwed by IoGetDeviceObjectPointer(L"\\Device\\PhyMemPCIFilter") failed when i called from other driver.

    Any suggestion?

    Wednesday, June 15, 2016 10:54 AM
  • This is an example of the hacks that should never be used in any commercial driver.  All you are doing if you put this code on a customers system is invite a lawsuit that destroys the company you work for.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Wednesday, June 15, 2016 11:03 AM
  • Thx Don, for your feedback.
    I will to understate the  IRP_MN_QUERY_INTERFACE approach, that you suggested in your previous post. 


    Wednesday, June 15, 2016 11:15 AM
  • DriverObject->MajorFunction[IRP_MJ_CREATE] = myCreate;

    myCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
    {
    BUS_INTERFACE_STANDARD BusInterfaceStandard;
    status = GetPCIBusInterfaceStandard(DeviceObject, & BusInterfaceStandard);

    }

    I used the GetPCIBusInterfaceStandard() as it is from. https://msdn.microsoft.com/en-us/library/windows/hardware/ff558706%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

    Doubt: who initialize the BusInterfaceStandard in GetPCIBusInterfaceStandard()? i don't see initialize or assign any value above example.


    Wednesday, June 15, 2016 6:07 PM
  • I follow the instruction as in : https://msdn.microsoft.com/en-us/library/windows/hardware/ff558706(v=vs.85).aspx

    Please help me with actual code, to read the configuration space by function-number and device number.

    Tuesday, June 21, 2016 4:50 PM
  • The call you have does not map via function and device number, it is there for a function driver that was given a set of resources to read the PCI configuration space that goes with those resources. 

    Bottom line is if you want something that will act similar to the obsolete HalGetBusData https://msdn.microsoft.com/en-us/library/windows/hardware/ff546599(v=vs.85).aspx  You either have to use that call recognizing it can go away at any time (It is #ifdef'd out in the last several WDK's), or else write a PCI bus driver.   As I stated before this is a very challenging project.

     


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Tuesday, June 21, 2016 5:03 PM
  • WDFIOTARGET target = WdfDeviceGetIoTarget(DeviceContext->Device);
    		WDFREQUEST request; 
    		WdfRequestCreate(WDF_NO_OBJECT_ATTRIBUTES, target, &request);
    		//DeviceContext->stack = { 0 };
    		DeviceContext->stack.MajorFunction = IRP_MJ_PNP;
    		DeviceContext->stack.MinorFunction = IRP_MN_READ_CONFIG;
    		DeviceContext->stack.Parameters.ReadWriteConfig.Length = bufSize;
    		DeviceContext->stack.Parameters.ReadWriteConfig.WhichSpace = PCI_WHICHSPACE_CONFIG;
    		DeviceContext->stack.Parameters.ReadWriteConfig.Offset = 0;
    		DeviceContext->stack.Parameters.ReadWriteConfig.Buffer = buffer;
    
    		TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "befor callback , DeviceContext->stack.Parameters.ReadWriteConfig.Buffer = 0x%lX ",
    			DeviceContext->stack.Parameters.ReadWriteConfig.Buffer);
    		WdfRequestWdmFormatUsingStackLocation(request, &DeviceContext->stack);
    		WdfRequestSetCompletionRoutine(request, PciEvtCompleteReadConfigSpace,(WDFCONTEXT)DeviceContext);
    		WdfRequestWdmGetIrp(request)->IoStatus.Status = STATUS_NOT_SUPPORTED;
    		// all pnp irps are initialized to this status 
    		WDF_REQUEST_SEND_OPTIONS options;
    		WDF_REQUEST_SEND_OPTIONS_INIT(&options, WDF_REQUEST_SEND_OPTION_SYNCHRONOUS);
    		WdfRequestSend(request, target, &options);

    this is my code for reading configuration space of PCI. this code is part of pci express KMDF driver. configuration information are stored in buffer.
    • Edited by mahnaz329 Monday, January 22, 2018 8:08 AM
    Monday, January 22, 2018 8:06 AM
  • this is my code for reading configuration space of PCI. this code is part of pci express KMDF driver. 

    So this code basically sends IRP_MN_READ_CONFIG down its own stack, hopefully to the pci bus driver. How this is interesting? This does not target arbitrary bus/device/function.

    -- pa


    • Edited by Pavel A Monday, January 22, 2018 11:18 AM
    Monday, January 22, 2018 11:16 AM
  • So you already are the driver for the device, this is not what the OP was asking.   Yes you can get the PCI config space if you own it, but it you want to replace the old HalGetBusData call and be able to access things by bus and slot you are out of luck.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Monday, January 22, 2018 11:49 AM