3 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are licensed and made available under
6 the terms and conditions of the BSD License that accompanies this distribution.
7 The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 MiscMemoryDeviceFunction.c
22 Misc. subclass type 17.
28 #include "CommonHeader.h"
29 #include "MiscSubclassDriver.h"
30 #include <Protocol/DataHub.h>
31 #include <Guid/DataHubRecords.h>
32 #include <Protocol/MemInfo.h>
36 #define FREQ_1066 0x01
37 #define FREQ_1333 0x02
38 #define FREQ_1600 0x03
41 #define EfiMemoryTypeDdr3 0x18
55 EFI_PHYSICAL_ADDRESS MemoryArrayStartAddress
;
56 EFI_PHYSICAL_ADDRESS MemoryArrayEndAddress
;
57 EFI_INTER_LINK_DATA PhysicalMemoryArrayLink
;
58 UINT16 MemoryArrayPartitionWidth
;
59 } EFI_MEMORY_ARRAY_START_ADDRESS
;
62 This function makes boot time changes to the contents of the
63 MiscBiosVendor (Type 0).
65 @param RecordData Pointer to copy of RecordData from the Data Table.
67 @retval EFI_SUCCESS All parameters were valid.
68 @retval EFI_UNSUPPORTED Unexpected RecordType value.
69 @retval EFI_INVALID_PARAMETER Invalid parameter was found.
74 IN EFI_SMBIOS_PROTOCOL
*Smbios
,
75 OUT EFI_SMBIOS_HANDLE
*Handle
79 EFI_SMBIOS_TYPE RecordType
;
80 EFI_SMBIOS_TABLE_HEADER
*Buffer
;
83 RecordType
= EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY
;
85 Status
= Smbios
->GetNext (
92 if (!EFI_ERROR(Status
)) {
98 MISC_SMBIOS_TABLE_FUNCTION( MiscMemoryDevice
)
100 CHAR8
*OptionalStrStart
;
101 UINTN MemDeviceStrLen
;
102 UINTN MemBankLocatorStrLen
;
103 UINTN MemManufacturerStrLen
;
104 UINTN MemSerialNumberStrLen
;
105 UINTN MemAssetTagStrLen
;
106 UINTN MemPartNumberStrLen
;
108 CHAR16
*MemBankLocator
;
109 CHAR16
*MemManufacturer
;
110 CHAR16
*MemSerialNumber
;
112 CHAR16
*MemPartNumber
;
114 STRING_REF TokenToGet
;
115 SMBIOS_TABLE_TYPE17
*SmbiosRecord
;
116 EFI_SMBIOS_HANDLE SmbiosHandle
;
117 EFI_MEMORY_ARRAY_LINK_DATA
*ForType17InputData
;
119 UINT16 Type16Handle
=0;
120 MEM_INFO_PROTOCOL
*MemInfoHob
;
125 STRING_REF DevLocator
[] = {
126 STRING_TOKEN(STR_MISC_MEM_DEV_LOCATOR0
), STRING_TOKEN(STR_MISC_MEM_DEV_LOCATOR1
)
128 STRING_REF BankLocator
[] = {
129 STRING_TOKEN(STR_MISC_MEM_BANK_LOCATOR0
), STRING_TOKEN(STR_MISC_MEM_BANK_LOCATOR1
)
133 // First check for invalid parameters.
135 if (RecordData
== NULL
) {
136 return EFI_INVALID_PARAMETER
;
138 ForType17InputData
= (EFI_MEMORY_ARRAY_LINK_DATA
*)RecordData
;
141 // Get Memory size parameters for each rank from the chipset registers
143 Status
= gBS
->LocateProtocol (
144 &gMemInfoProtocolGuid
,
148 ASSERT_EFI_ERROR (Status
);
150 NumSlots
= (UINT8
)(MAX_SOCKETS
);
155 switch (MemInfoHob
->MemInfoData
.ddrFreq
){
176 switch (MemInfoHob
->MemInfoData
.ddrType
) {
178 MemoryType
= EfiMemoryTypeDdr2
;
184 MemoryType
= EfiMemoryTypeDdr3
;
187 MemoryType
= EfiMemoryTypeUnknown
;
191 for (Dimm
= 0; Dimm
< NumSlots
; Dimm
++) {
193 // Memory Device Locator
195 TokenToGet
= DevLocator
[Dimm
];
196 MemDevice
= SmbiosMiscGetString (TokenToGet
);
197 MemDeviceStrLen
= StrLen(MemDevice
);
198 if (MemDeviceStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
199 return EFI_UNSUPPORTED
;
202 TokenToGet
= DevLocator
[Dimm
];
203 MemDevice
= SmbiosMiscGetString (TokenToGet
);
204 MemDeviceStrLen
= StrLen(MemDevice
);
205 if (MemDeviceStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
206 return EFI_UNSUPPORTED
;
210 // Memory Bank Locator
212 TokenToGet
= BankLocator
[Dimm
];
213 MemBankLocator
= SmbiosMiscGetString (TokenToGet
);
214 MemBankLocatorStrLen
= StrLen(MemBankLocator
);
215 if (MemBankLocatorStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
216 return EFI_UNSUPPORTED
;
220 // Memory Manufacturer
222 TokenToGet
= STRING_TOKEN (STR_MISC_MEM_MANUFACTURER
);
223 MemManufacturer
= SmbiosMiscGetString (TokenToGet
);
224 MemManufacturerStrLen
= StrLen(MemManufacturer
);
225 if (MemManufacturerStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
226 return EFI_UNSUPPORTED
;
230 // Memory Serial Number
232 TokenToGet
= STRING_TOKEN (STR_MISC_MEM_SERIAL_NO
);
233 MemSerialNumber
= SmbiosMiscGetString (TokenToGet
);
234 MemSerialNumberStrLen
= StrLen(MemSerialNumber
);
235 if (MemSerialNumberStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
236 return EFI_UNSUPPORTED
;
240 // Memory Asset Tag Number
242 TokenToGet
= STRING_TOKEN (STR_MISC_MEM_ASSET_TAG
);
243 MemAssetTag
= SmbiosMiscGetString (TokenToGet
);
244 MemAssetTagStrLen
= StrLen(MemAssetTag
);
245 if (MemAssetTagStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
246 return EFI_UNSUPPORTED
;
250 // Memory Part Number
252 TokenToGet
= STRING_TOKEN (STR_MISC_MEM_PART_NUMBER
);
253 MemPartNumber
= SmbiosMiscGetString (TokenToGet
);
254 MemPartNumberStrLen
= StrLen(MemPartNumber
);
255 if (MemPartNumberStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
256 return EFI_UNSUPPORTED
;
260 // Two zeros following the last string.
262 SmbiosRecord
= AllocatePool(sizeof (SMBIOS_TABLE_TYPE17
) + MemDeviceStrLen
+ 1 + MemBankLocatorStrLen
+ 1 + MemManufacturerStrLen
+ 1 + MemSerialNumberStrLen
+ 1 + MemAssetTagStrLen
+1 + MemPartNumberStrLen
+ 1 + 1);
263 ZeroMem(SmbiosRecord
, sizeof (SMBIOS_TABLE_TYPE17
) + MemDeviceStrLen
+ 1 + MemBankLocatorStrLen
+ 1 + MemManufacturerStrLen
+ 1 + MemSerialNumberStrLen
+ 1 + MemAssetTagStrLen
+1 + MemPartNumberStrLen
+ 1 + 1);
265 SmbiosRecord
->Hdr
.Type
= EFI_SMBIOS_TYPE_MEMORY_DEVICE
;
266 SmbiosRecord
->Hdr
.Length
= sizeof (SMBIOS_TABLE_TYPE17
);
269 // Make handle chosen by smbios protocol.add automatically.
271 SmbiosRecord
->Hdr
.Handle
= 0;
274 // Memory Array Handle will be the 3rd optional string following the formatted structure.
276 GetType16Hndl( Smbios
, &Type16Handle
);
277 SmbiosRecord
->MemoryArrayHandle
= Type16Handle
;
282 if ((MemInfoHob
->MemInfoData
.dimmSize
[Dimm
])!=0){
283 SmbiosRecord
->TotalWidth
= 32;
284 SmbiosRecord
->DataWidth
= 32;
285 SmbiosRecord
->Size
= MemInfoHob
->MemInfoData
.dimmSize
[Dimm
];
286 SmbiosRecord
->Speed
= DdrFreq
;
287 SmbiosRecord
->ConfiguredMemoryClockSpeed
= DdrFreq
;
288 SmbiosRecord
->FormFactor
= EfiMemoryFormFactorDimm
;
291 SmbiosRecord
->DeviceSet
=(UINT8
) ForType17InputData
->MemoryDeviceSet
;
292 SmbiosRecord
->DeviceLocator
= 1;
293 SmbiosRecord
->BankLocator
= 2;
296 SmbiosRecord
->Manufacturer
= 3;
297 SmbiosRecord
->SerialNumber
= 4;
298 SmbiosRecord
->AssetTag
= 5;
299 SmbiosRecord
->PartNumber
= 6;
300 SmbiosRecord
->Attributes
= (UINT8
) ForType17InputData
->MemoryState
;
301 SmbiosRecord
->MemoryType
= MemoryType
;
303 OptionalStrStart
= (CHAR8
*)(SmbiosRecord
+ 1);
304 UnicodeStrToAsciiStr(MemDevice
, OptionalStrStart
);
305 UnicodeStrToAsciiStr(MemBankLocator
, OptionalStrStart
+ MemDeviceStrLen
+ 1);
306 UnicodeStrToAsciiStr(MemManufacturer
, OptionalStrStart
+ MemDeviceStrLen
+ 1 + MemBankLocatorStrLen
+ 1);
307 UnicodeStrToAsciiStr(MemSerialNumber
, OptionalStrStart
+ MemDeviceStrLen
+ 1 + MemBankLocatorStrLen
+ 1 + MemManufacturerStrLen
+ 1);
308 UnicodeStrToAsciiStr(MemAssetTag
, OptionalStrStart
+ MemDeviceStrLen
+ 1 + MemBankLocatorStrLen
+ 1 + MemManufacturerStrLen
+ 1 + MemSerialNumberStrLen
+ 1);
309 UnicodeStrToAsciiStr(MemPartNumber
, OptionalStrStart
+ MemDeviceStrLen
+ 1 + MemBankLocatorStrLen
+ 1 + MemManufacturerStrLen
+ 1 + MemSerialNumberStrLen
+ 1+ MemAssetTagStrLen
+1 );
312 // Now we have got the full smbios record, call smbios protocol to add this record.
314 SmbiosHandle
= SMBIOS_HANDLE_PI_RESERVED
;
315 Status
= Smbios
-> Add(
319 (EFI_SMBIOS_TABLE_HEADER
*) SmbiosRecord
321 FreePool(SmbiosRecord
);