How to access SPD information in DIMM Memory Modules

Gordon Saxby
Gordon Saxby used Ask the Experts™
on
I am currently developing a program that detects details of the currently installed memory in a PC (Windows only), using WMI. However, WMI does not always contain enough information to identify the installed memory modules.

I would like to be able to read the information contained in the SPD (Serial Presence Detect) chip. From my searches today, I understand that access is gained via the SMBus ... but that is the limit of my knolwedge!

Does anyone have any guidance, sample code, links to API's or any other useful information?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
According to
"Enumerating the SMBus to get SPD data"
http://softwarecommunity.intel.com/isn/Community/en-US/forums/980357/ShowThread.aspx

even Intel doesn't know, how to do it :)

So why is

Win32_SMBIOSMemory
http://msdn2.microsoft.com/en-us/library/aa394452(VS.85).aspx

resp the descendants Win32_MemoryDevice etc. not good enough for you ? :)
Gordon SaxbySenior Web Developer

Author

Commented:
I am currently using Win32_PhysicalMemory which returns some details but for instance, on my own PC it does not return the MemoryType information. This means that I am unable to determine whether the installed memory is DDR, DDR-2, etc.

I didn't know about Win32_SMBIOSMemory - I have been using "ScriptomaticV2" to investigate the available details and Win32_SMBIOSMemory does not appear in the list. I have just tried to write a routine to gather the data and it appears as though it does not "enumerate"!

I assume there must be another method to access the information ... ?
	CComPtr<IEnumWbemClassObject> spEnumInst;
	hr = m_pIWbemServices->CreateInstanceEnum( L"Win32_SMBIOSMemory", WBEM_FLAG_SHALLOW, NULL, &spEnumInst);
 
	int i = 0;
	bool bFinished = false;
	InstalledMemory InstMem;
	while (!bFinished)
	{
		//Get the Win32_SMBIOSMemory instance
		ULONG uNumOfInstances = 0;
		CComPtr<IWbemClassObject> spInstance;
		HRESULT hrNext = spEnumInst->Next(10000, 1, &spInstance, &uNumOfInstances);
 
		if (hrNext == WBEM_S_FALSE)
			bFinished = true;
		else if (hrNext == WBEM_S_NO_ERROR)
		{
                       ....

Open in new window

jkr
Top Expert 2012

Commented:
I doubt that you will be able to obtain more information than WMI can, even if you would provide your own driver to gather the information (and a driver would be required to interact with the HW at that level for sure). Chances are that the DIMMs simply to not contain that information, and then there's hardly anything you can do about that.
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Gordon SaxbySenior Web Developer

Author

Commented:
jkr - it is definitely possible to gather more information than WMI provides - there are tools such as CPU-Z that display it. However, accessing the SPD (in)directly appears to be difficult and chipset dependent (i.e. you need to code for each chipset).

primeMover2004 - I tried running the following script (to call Win32_SMBIOSMemory) but the information returned was sparse to say the least!
On Error Resume Next
 
strServer = "."
 
Set objWMI = GetObject("winmgmts://" & strServer & "/root\cimv2")
Set objInstances = objWMI.InstancesOf("Win32_SMBIOSMemory",48)
 
For Each objInstance in objInstances
On Error Resume Next
    With objInstance
        WScript.Echo "Access = " + .Access
        WScript.Echo "AdditionalErrorData = " + Join(.AdditionalErrorData, ", ")
        WScript.Echo "Availability = " +.Availability
        WScript.Echo "BlockSize = " + .BlockSize
        WScript.Echo "Caption = " +  .Caption
        WScript.Echo "ConfigManagerErrorCode = " + .ConfigManagerErrorCode
        WScript.Echo "ConfigManagerUserConfig = " + .ConfigManagerUserConfig
        WScript.Echo "CorrectableError = " + .CorrectableError
        WScript.Echo "CreationClassName = " + .CreationClassName
        WScript.Echo "Description = " + .Description
        WScript.Echo "DeviceID = " + .DeviceID
        WScript.Echo "EndingAddress = " + .EndingAddress
        WScript.Echo "ErrorAccess = " + .ErrorAccess
        WScript.Echo "ErrorAddress = " + .ErrorAddress
        WScript.Echo "ErrorCleared = " + .ErrorCleared
        WScript.Echo "ErrorData = " + Join(.ErrorData, ", ")
        WScript.Echo "ErrorDataOrder = " + .ErrorDataOrder
        WScript.Echo "ErrorDescription = " + .ErrorDescription
        WScript.Echo "ErrorInfo = " + .ErrorInfo
        WScript.Echo "ErrorMethodology = " + .ErrorMethodology
        WScript.Echo "ErrorResolution = " + .ErrorResolution
        WScript.Echo "ErrorTime = " + .ErrorTime
        WScript.Echo "ErrorTransferSize = " + .ErrorTransferSize
        WScript.Echo "InstallDate = " + .InstallDate
        WScript.Echo "LastErrorCode = " + .LastErrorCode
        WScript.Echo "Name = " + .Name
        WScript.Echo "NumberOfBlocks = " + .NumberOfBlocks
        WScript.Echo "OtherErrorDescription = " + .OtherErrorDescription
        WScript.Echo "PNPDeviceID = " + .PNPDeviceID
        WScript.Echo "PowerManagementCapabilities = " + Join(.PowerManagementCapabilities, ", ")
        WScript.Echo "PowerManagementSupported = " + .PowerManagementSupported
        WScript.Echo "Purpose = " + .Purpose
        WScript.Echo "StartingAddress = " + .StartingAddress
        WScript.Echo "Status = " + .Status
        WScript.Echo "StatusInfo = " + .StatusInfo
        WScript.Echo "SystemCreationClassName = " + .SystemCreationClassName
        WScript.Echo "SystemLevelAddress = " + .SystemLevelAddress
        WScript.Echo "SystemName = " + .SystemName
    End With
On Error Goto 0
Next

Open in new window

Maybe this can help you:
"WMI also supports reading the entire contents of SMBIOS data in a single buffer using the MSSMBios_RawSMBiosTables class inside of the root\wmi namespace. The SMBiosData property returns a buffer containing the entire SMBIOS data table, except the SMBIOS Structure Table Entry Point as defined in section 2.1.1 of the SMBIOS specification."

And you might be interested in the offset for the memory module description.
The structure of the table can be found here:
http://www.dmtf.org/standards/smbios

Here's SMBios Demystified:
http://www.codeguru.com/cpp/w-p/system/systeminformation/article.php/c12347/

You could use the
EnumSystemFirmwareTables & GetSystemFirmwareTable API


Does this help?
Gordon SaxbySenior Web Developer

Author

Commented:
The information you provided was very interesting and would have helped, however we have now found a company that sells a SDK for gathering all the information we need!
"WMI also supports reading the entire contents of SMBIOS data in a single buffer using the MSSMBios_RawSMBiosTables class inside of the root\wmi namespace. The SMBiosData property returns a buffer containing the entire SMBIOS data table, except the SMBIOS Structure Table Entry Point as defined in section 2.1.1 of the SMBIOS specification."
is from
http://download.microsoft.com/download/5/D/6/5D6EAF2B-7DDF-476B-93DC-7CF0072878E6/SMBIOS.doc 
decode-dimm.pl

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial