Get Memory BARS of PCI bridge

Hi

I want to write user application to control my device internal registers.
My device map its internal registers to one of its memory BAR.

I thought to get the memory address, pin the memory and get user virtual address
then access the memory directly from the user application (no IOctronls)

  1. Is this the right approach ? or should I need to use IO_READ/IO_WRITE ?

My device is standart PCI bridge which use microsoft pci.sys driver .

How can I get the BAR info ? Do I need to write filter driver ?
Does MS supply standart way to get/access memory BARs for devices that handle by pci.sys driver?

Thanks
Yossi

Your most important problem is to replace pci.sys with your own driver for
your device.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

wrote in message news:xxxxx@ntdev…
> Hi
>
> I want to write user application to control my device internal registers.
> My device map its internal registers to one of its memory BAR.
>
> I thought to get the memory address, pin the memory and get user virtual
address
> then access the memory directly from the user application (no IOctronls)
>
> 1. Is this the right approach ? or should I need to use IO_READ/IO_WRITE ?
>
> My device is standart PCI bridge which use microsoft pci.sys driver .
>
> How can I get the BAR info ? Do I need to write filter driver ?
> Does MS supply standart way to get/access memory BARs for devices that
handle by pci.sys driver?
>
> Thanks
> Yossi
>
>

> I want to write user application to control my device internal registers. My device map its internal registers >to one of its memory BAR. I thought to get the memory address, pin the memory and get user virtual >address then access the memory directly from the user application (no IOctronls)

It depends on your target OS. If your target OS is something like MS-DOS, then you are on the right direction. However, if you target some more or less advanced OS that runs the system and applications
in respectively privileged and non-privileged modes, then you are on the very wrong direction - these systems don’t allow apps to access the hardware directly (although, if you are just desperate to prove the point, the above can, indeed, be achieved via PTE manipulations in your driver even under
Windows NT )…

Anton Bassov

You need to write a pci device upper filter driver for the bridge. User mode
is simply the wrong way to go.

Google is helpful. Try this thread:
http://www.osronline.com/showThread.cfm?link=83377

On Sun, May 4, 2008 at 5:06 AM, wrote:

> Hi
>
> I want to write user application to control my device internal registers.
> My device map its internal registers to one of its memory BAR.
>
> I thought to get the memory address, pin the memory and get user virtual
> address
> then access the memory directly from the user application (no IOctronls)
>
> 1. Is this the right approach ? or should I need to use IO_READ/IO_WRITE ?
>
> My device is standart PCI bridge which use microsoft pci.sys driver .
>
> How can I get the BAR info ? Do I need to write filter driver ?
> Does MS supply standart way to get/access memory BARs for devices that
> handle by pci.sys driver?
>
> Thanks
> Yossi
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>


Mark Roddy

Hi

Thanks for the responses ,
Although I might need to wirte filter driver to retrive the memory base address of the BAR still I can map the memory to user and made access directly from user like

ka = p_ext->bar[BAR_TYPE].virt;

// prepare for mapping to user space
p_mdl = IoAllocateMdl( ka, sz, FALSE,FALSE,NULL);

// fill MDL
MmBuildMdlForNonPagedPool(p_mdl);

// map the buffer into user space
__try
{
ua = MmMapLockedPagesSpecifyCache( p_mdl, UserMode, MmNonCached,
NULL, FALSE, NormalPagePriority );
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
status = STATUS_INSUFFICIENT_RESOURCES;
goto err_map_to_user;
}

Then the user application use ua as access address for the device register

Still do I need to write my own filter above the standard pci.sys driver or MS supply interface to retrive the memory BARS without writing new driver

Thanks
Yossi

For the purpose of this discussion let’s ignore all other " small nasties" and assume that you have successfully mapped BARs to your app’s address space, so that now your app is able to access them directly. You app wants to access BAR, and pci.sys wants to do the same. How are you going to synchronize access to BARS between PCI and your app???

Anton Bassov

Hi

If its my internal device registers why would pci.sys access this registers.
And if it does, still it read/write transaction on the PCI-ex bus each operation is atomic.

Yossi

Assuming that in fact these registers are not used for normal bridge
operations, and do not affect bridge state, then you can probably use them
independently of pci.sys.

This is a horrible hardware design. Independent PCI functions are supposed
to be implemented as independent PCI functions (duh!) and not within a
single PCI function.

Providing user mode access to PCI registers is just asking for trouble. You
can implement this functionality correctly by using a filter driver and
exporting a private api to user mode. Consider using KMDF as the development
effort is minimal.

On Mon, May 5, 2008 at 11:35 AM, wrote:

> Hi
>
> If its my internal device registers why would pci.sys access this
> registers.
> And if it does, still it read/write transaction on the PCI-ex bus each
> operation is atomic.
>
> Yossi
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>


Mark Roddy

Then write an upper filter for pci.sys, register it for your bridge
devnode, and use MN_QUERY_INTERFACE and then method calls to write to the
config space of your device.

Expose all of this to user mode via IOCTLs.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

wrote in message news:xxxxx@ntdev…
> Hi
>
> If its my internal device registers why would pci.sys access this registers.
> And if it does, still it read/write transaction on the PCI-ex bus each
operation is atomic.
>
> Yossi
>

“Maxim S. Shatskih” wrote in message
news:xxxxx@ntdev…
> Then write an upper filter for pci.sys, register it for your bridge
> devnode, and use MN_QUERY_INTERFACE and then method calls to write to the
> config space of your device.
>
> Expose all of this to user mode via IOCTLs.

Well if he has to use ioctls anyway, he could simply locate the BARs
in the kernel space, like windbg command !pci does it -
and just poke in there. The BARs of the bridge are permanently mapped
(or almost permanently… this depends on his app :).
The principal question was, map it to usermode or not.

–PA

> If its my internal device registers why would pci.sys access this registers.

Please look at what you have said in your very first post:

[begin quote]

My device is standart PCI bridge which use microsoft pci.sys driver .

[end quote]

Judging from this quote, your device is owned by PCI.SYS, so that it makes a perfect sense to assume that it is PCI.SYS and not some other driver who is going to access your device’s registers, don’t you think???

And if it does, still it read/write transaction on the PCI-ex bus each operation is atomic.

Really??? Please note that preparing an operation may involve writes to different device registers, and the whole logic of an operation may get screwed up if someone gets in the middle. For example, you set the state of the register X to A, and, before you have written to the register Y in order to start the actual operation, PCI.SYS sets the state of the register X to B. Therefore, atomicity of a single read/write operation does not yet mean that access to registers does not need to be synchronized…

The bottom line - as both Mark and Max told you already, what you need here is a filter for PCI.SYS and not an app…

Anton Bassov

Hi

Refer to this article
http://www.osronline.com/article.cfm?article=39
THat is exactly what I mean to do .
Creating a filter that will get IOCTL to open the device
This IOCTL will map the memory pointed by the BARS to use space usin the second method (mapping mmory to user)
and return the virtual address in the IOCTL .

Then the user can write simple application that access this memory

> Refer to this article http://www.osronline.com/article.cfm?article=39

THat is exactly what I mean to do .

No - this is NOT what you want to do. This article speaks about sharing memory that is owned by a driver between an app and driver - it does NOT speak about accessing the resources that are owned by someone else. Once it is PCI.SYS who owns your device, all your device’s resources are owned by PCI.SYS, and, under Windows NT ( as well as under any other advanced OS) you just don’t touch the resources that you don’t own. Period. If you want to access these resources, you have to do it by invoking methods that you have obtained via IRP_MN_QUERY_INTERFACE, because no one, apart from their owner, knows how to synchronize an access to these resources…

Anton Bassov

> No - this is NOT what you want to do. This article speaks about sharing
memory

that is owned by a driver between an app and driver - it does NOT speak about
accessing the resources that are owned by someone else. Once it is PCI.SYS
who

I think he wants to touch his vendor-specific BARs which are never touched by
PCI.SYS.

Anyway I would not do the mapping to user mode, and instead expose an IOCTL of
“read my BAR” or “write my BAR”.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

The OP is determined to do it his way. I agree with you regarding the vendor
specific bars - pci.sys will not touch them if they are truly vendor
specific and not in any way overlapped with the standard bridge bars.

On Tue, May 6, 2008 at 3:02 PM, Maxim S. Shatskih
wrote:

> > No - this is NOT what you want to do. This article speaks about sharing
> memory
> >that is owned by a driver between an app and driver - it does NOT speak
> about
> >accessing the resources that are owned by someone else. Once it is
> PCI.SYS
> >who
>
> I think he wants to touch his vendor-specific BARs which are never touched
> by
> PCI.SYS.
>
> Anyway I would not do the mapping to user mode, and instead expose an
> IOCTL of
> “read my BAR” or “write my BAR”.
>
> –
> Maxim Shatskih, Windows DDK MVP
> StorageCraft Corporation
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>


Mark Roddy

> I think he wants to touch his vendor-specific BARs which are never touched by PCI.SYS.

But, apparently, in addition to these vendor-specific registers he still has to access some standard BARs as well. Even if he does not, I still would say the idea with the app is not the best one that one could possibly imagine, although , for this or that reason, the OP seems to be just deadly determined to take this path…

Anton Bassov

Thank you all for you responses ,
Yes I am talking about my vendore specific register.
I am writing application for post silicon debuggin , my application will just enable the readin and writing to the device registers (internal register).
Our device expose the interanl register through the BARs .

Thanks