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...