Hello,
I seem to have a strange behaviour when writing to an I/O memory mapped adress. My problem is that I can’t seem to write Data to the PCI card using Memory mapped address.
On the DEVICE_START PnP message, I look at the Translated Ressource PCM_DESCRIPTOR to identify if it’s a Port or Memory. If it is a Memory, I will call MmMapIoSpace and keep the returned adress. If it’s a Port, I simply keep the Translated address.
I can read/write when accessing I/O ports but when accessing the memory, I can only read. Flags on the MEM give me 0 (so READ and WRITE access). From my limited knowledge, it seems the WRITE_REGISTER is waiting for some sort of trigger to send the data to the PCI card. The I/O ports work instantly.
Do any of you have an idea about this problem?
WinDDK build 6000
Here is the code (yes I know C++…):
NTSTATUS CIoRange::Initialize( PCM_RESOURCE_LIST ResTransList,
PCM_RESOURCE_LIST ResRawList,
ULONG MemoryBar)
{
PCM_FULL_RESOURCE_DESCRIPTOR pRawFullDescriptor, pTranslatedFullDescriptor;
PCM_PARTIAL_RESOURCE_LIST raw, translated;
PCM_PARTIAL_RESOURCE_DESCRIPTOR pPartialDescriptor;
PAGED_CODE();
if ((NULL != ResTransList) && (NULL != ResRawList))
{
pTranslatedFullDescriptor = ResTransList->List;
pRawFullDescriptor = ResRawList->List;
raw = &pRawFullDescriptor->PartialResourceList;
translated = &pTranslatedFullDescriptor->PartialResourceList;
if(MemoryBar < translated->Count)
{
ERROR((“Getting memory BAR %d\n”,MemoryBar));
pPartialDescriptor = &translated->PartialDescriptors[MemoryBar];
switch (pPartialDescriptor->Type)
{
default:
case CmResourceTypeInterrupt:
case CmResourceTypeDma:
break;
case CmResourceTypePort:
ERROR((“I/O\n”));
if (m_BaseAddress == NULL)
{
m_Type = IO;
m_PhysicalBaseAddress = pPartialDescriptor->u.Memory.Start;
m_Size = pPartialDescriptor->u.Memory.Length;
m_BaseAddress = &m_PhysicalBaseAddress.LowPart;
if(m_BaseAddress == NULL)
{
ERROR((“Could not map IO \n”));
return STATUS_NO_MEMORY;
}
ERROR((“IO_BAR Physical Base is: 0x%03X \n”, m_PhysicalBaseAddress));
ERROR((“IO_Length of mapping is 0x%03X \n”, m_Size));
ERROR((“IO_BAR Virtual Base is: 0x%03X \n”, m_BaseAddress));
} // End if NULL
break;
case CmResourceTypeMemory:
ERROR((“Mem\n”));
if (m_BaseAddress == NULL)
{
m_Type = MEMORY;
m_PhysicalBaseAddress = pPartialDescriptor->u.Memory.Start;
m_Size = pPartialDescriptor->u.Memory.Length;
m_BaseAddress = (PVOID) MmMapIoSpace (m_PhysicalBaseAddress, m_Size,MmNonCached);
if(m_BaseAddress == NULL)
{
ERROR((“Could not map memory \n”));
return STATUS_NO_MEMORY;
}
ERROR((“MEM_BAR Physical Base is: 0x%03X \n”, m_PhysicalBaseAddress));
ERROR((“MEM_Length of mapping is 0x%03X \n”, m_Size));
ERROR((“MEM_BAR Virtual Base is: 0x%03X \n”, m_BaseAddress));
ERROR((“MEM_BAR Flags is: 0x%03X \n”, pPartialDescriptor->Flags));
} // End if NULL
break;
} // End Switch
} // End if memory bar
} // End Res != NULL
return STATUS_SUCCESS;
}
To access memory I use the following functions:
ULONG CIoRange::ReadDWord(ULONG Offset)
{
if(Offset < m_Size && m_BaseAddress != NULL)
{
PULONG RealOffset;
ULONG ulValue;
if(m_Type == MEMORY)
{
RealOffset = (PULONG) ((PUCHAR) (m_BaseAddress) + (UCHAR) Offset);
ulValue = READ_REGISTER_ULONG(RealOffset);
ERROR((“Read DWord Reg @ 0x%X => 0x%X”,RealOffset,ulValue));
}
else
{
RealOffset = (PULONG) ((PUCHAR) (m_PhysicalBaseAddress.LowPart) + (UCHAR) Offset);
ulValue = READ_PORT_ULONG(RealOffset);
ERROR((“Read DWord @ 0x%X => 0x%X”,RealOffset,ulValue));
}
return ulValue;
}
else
return 0xFFFFFFFF;
}
AND
void CIoRange::WriteBufferDWord(ULONG Offset, ULONG* ptrBuffer, ULONG Size)
{
if(Offset < m_Size && m_BaseAddress != NULL)
{
PULONG RealOffset;
if(m_Type == MEMORY)
{
RealOffset = (PULONG) ((PUCHAR) (m_BaseAddress) + (UCHAR) Offset);
// This function should put DWORD by DWORD to the RealOffset
WRITE_REGISTER_BUFFER_ULONG(RealOffset,ptrBuffer,Size);
ERROR((“Write Buffer DWord Reg @ 0x%X => 0x%X - %d” ,RealOffset,ptrBuffer[0],Size));
}
else
{
RealOffset = (PULONG) ((PUCHAR) (m_PhysicalBaseAddress.LowPart) + (UCHAR) Offset);
WRITE_PORT_BUFFER_ULONG(RealOffset,ptrBuffer,Size);
}
}
}
Send a smile, make someone laugh, have some fun! Start now!
http://www.freemessengeremoticons.ca/?icid=EMENCA122