// JP opened flex table

Click to See Complete Forum and Search --> : WDM Filter Driver - PCI Memory Resources Unaccessable


jhersh
January 6th, 2005, 08:47 PM
Background:

I believe I have a somewhat unique problem I'm trying to solve. The situation I have to deal with is we bought a specialized PCI card that I want to access from within another driver in kernel mode. It came with a driver, but I can't use the driver it came with. The driver was not developed by the company that makes the card. The driver is a WinRT driver and it is coupled with a user mode DLL to provide access to the functionality of the card. From what I can tell, all this driver does is map the memory resources to user space. The DLL then does all of the work of manipulating the card. The interface between the driver and the DLL is unknown.


My approach:

I need to leave the existing driver in tact, because I want to use the application that the company provides to configure he card. I simply want to have a way to read the time from the card from within another driver. I'm attempting to develop an upper filter driver for the card. The card has two 4k memory regions that I want to access from within the filter driver through which I can perform the tasks I need to to get the data from the card. These are the same memory regions on the PCI card that are mapped to user space by the WinRT driver. I have a filter driver installed above WinRT and I successfully get the the resource lists that tell me what physical memory addresses to use in the IRP_MN_START_DEVICE. One thing I noticed is that the translated address is identical to the raw address. I guess this is normal? Or at least not an obvious problem, right?

The problem:

I have attempted two approaches to access the memory regions on the PCI card. The first is the standard kernel mode mapping that I expected to work for sure. I use MmMapIoSpace and get what appears to be a valid kernel mode virtual address (above 0x8000000), get no errors, and get no bug check when accessing it. However it doesn't seem to act like valid memory. When the virtual memory is read using either READ_REGISTER_UCHAR or simple dereference, the result is always 0xFF. When writing with either WRITE_REGISTER_UCHAR or simple dereference, the memory is unchanged (at least according to the read). There are no errors or bug check or anything like that. I'm doing the test reads and writes in the IRP_MN_START_DEVICE handler immediately after mapping the memory.
I attempted another method by using ZwOpenSection to open \Device\PhysicalMemory and then used ZwMapViewOfSection to get a user mode virtual address to the memory I want to access, but have the exact same results. Write does nothing and read is all 0xFF. The DLL that came with the card still work great.

If anyone has attempted something like this or has any ideas of what I can try, please let me know. Your help will be greatly appreciated. Hopefully there is a glaring error that will stick out to someone a little more familiar with the NT kernel.

Thanks in advance!

Sincerely,
-Joe Hershberger

jhersh
January 17th, 2005, 01:51 AM
Wow. I'm surprised that I haven't had any responses on this problem I'm having. I still haven't made any headway on it.

Perhaps I can just ask some generic questions.

Is it posible to map the same memory space twice?

Does anyone know what would cause memory to map without error, but then not actually map where it is supposed to.

Thanks!

-Joe Hershberger

Mathew_vv
March 15th, 2005, 12:31 AM
hi,
I think there will be some address transalation done at the existing driver level. I have a ll'r problem here. In order to get a block of memory, I am restricting the the OS memory usage using MAXMEM switch in boot.ini and then mapping the physical memory locations to the driver. Once this memory map is over, this block I will be able to write and read.

I think this address transalation is done somewhere in your PCI driver or DLL which you are not doing. That could be the reason for the error..

I do not think this post will help you to solve the problem. But if you are able to solve it off, please help me with some doubts which I have about this process. :)

Mathew

ahoodin
March 15th, 2005, 07:24 AM
This maps kernel mode memory to user mode address. You will have to return the address in a DeviceIOControl.


PVOID buffer;
PMDL mdl;
PVOID userVAToReturn;

buffer = ExAllocatePool(NonPagedPool, 4*(PAGE_SIZE)/*, 'MpaM'*/);
memset (buffer,0/*45*/,4*PAGE_SIZE);
//specify user buffer alignment here eg pointers

if(!buffer) return(NULL);
// Allocate and initalize an MDL that describes the buffer
mdl = IoAllocateMdl(buffer,
4*PAGE_SIZE,
FALSE,
FALSE,
NULL);

if(!mdl) {
ExFreePool(buffer);
return(NULL);
}
// Finish building the MDL -- Fill in the "page portion"
MmBuildMdlForNonPagedPool(mdl);
//#if NT_40
//
//MmapLockedPages (Map the buffer into user space) returns a user mode address,
//but the hardware Memory management chip sets that address so that if it is
//accessed it points to the Physical address. A kernel virtual mode pointer
//can also be used to access this memory. NOTE: This function bug checks if out of PTEs
__try //MmMapLockedPages must be called with an exception handler statement.
{
userVAToReturn = MmMapLockedPages(mdl, UserMode);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
userVAToReturn = -1;
}
if(!userVAToReturn) {
IoFreeMdl(mdl);
ExFreePool(buffer);
return(NULL);
}


Also, OSR has a great list:
http://www.osr.com/

HTH,

ahoodin

//JP added flex table