I am writing a driver to access a specific read/write-once register in
the Intel ICH chipset configuration space.
My test is to set some write-once bits in the register, and then write
a clear to those same bits. This clear should silently fail and remain
at the first value written. (Verified in linux.)
The Intel spec states that the chipset configuration space mapped
location is set in the RCBA register. I can verify this also using
linux. So my physical memory location should be the address in the
RCBA plus any offset to the specific register I want. I looked in the
RCBA register to find the physical address of the chipset
configuration mapped memory block. Finding this, I then mapped it from
a physical into a virtual address using MmMapIoSpace() in the DDK.
Below is a snippet of my code, trying to run my tests and then convert
the location of that register into a unicode string to print to a
system log entry.
Am I doing something wrong here?
Thanks a bunch for the help,
Randy
– begin code snippet –
UNICODE_STRING uniErrorString ; // return string
VOID* virtAddr = NULL; // virtual address from MmMapIoSpace
ULONG memVal = 0; // value derived from memory mapped register
WCHAR addrBuffer[70]; // used to store the converted integer, or error
codes
PHYSICAL_ADDRESS memAddr2;
//ULONG addrSpace = 0x0; //memory, not IO space
ULONG oneBit = 0x010001; // for test write 1
ULONG zeroBit = 0x010000; // for test write 2
memAddr2.HighPart = 0x0;
// where xxx is replaced by the configuration register I am testing
memAddr2.LowPart = 0xFED1Cxxx; // address combined with offset as
indicated by RCBA
virtAddr = MmMapIoSpace(memAddr2,4,FALSE);
if ( virtAddr == NULL ) {
memVal = 0x00000002; // error condition
goto testDONE;
}
// should be able to set, and then the one should stay…clear bit
// should not replace it
// first test write
*(ULONG*)virtAddr = oneBit;
// test read
if ( *(ULONG*)virtAddr != oneBit ) {
RtlInitUnicodeString(&uniErrorString, L"0x0000000000000005");
// error condition
goto testDONE;
}
// test write, this should fail silently because of write-once bit
*(ULONGLONG*)virtAddr = zeroBit;
memVal = *(ULONGLONG*)virtAddr;
uniErrorString.Length = 0;
uniErrorString.MaximumLength = 70;
uniErrorString.Buffer = &addrBuffer[0];
// convert value to string
if ( STATUS_SUCCESS !=
RtlIntegerToUnicodeString(memVal,10,&uniErrorString) ) {
RtlInitUnicodeString(&uniErrorString, L"0x0000000000000003"); //
error
condition
}
testDONE:
// do error things…