3 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
12 MiscMemoryDeviceFunction.c
17 Misc. subclass type 17.
23 #include "CommonHeader.h"
24 #include "MiscSubclassDriver.h"
25 #include <Protocol/DataHub.h>
26 #include <Guid/DataHubRecords.h>
27 #include <Protocol/MemInfo.h>
31 #define FREQ_1066 0x01
32 #define FREQ_1333 0x02
33 #define FREQ_1600 0x03
36 #define EfiMemoryTypeDdr3 0x18
50 EFI_PHYSICAL_ADDRESS MemoryArrayStartAddress
;
51 EFI_PHYSICAL_ADDRESS MemoryArrayEndAddress
;
52 EFI_INTER_LINK_DATA PhysicalMemoryArrayLink
;
53 UINT16 MemoryArrayPartitionWidth
;
54 } EFI_MEMORY_ARRAY_START_ADDRESS
;
57 This function makes boot time changes to the contents of the
58 MiscBiosVendor (Type 0).
60 @param RecordData Pointer to copy of RecordData from the Data Table.
62 @retval EFI_SUCCESS All parameters were valid.
63 @retval EFI_UNSUPPORTED Unexpected RecordType value.
64 @retval EFI_INVALID_PARAMETER Invalid parameter was found.
69 IN EFI_SMBIOS_PROTOCOL
*Smbios
,
70 OUT EFI_SMBIOS_HANDLE
*Handle
74 EFI_SMBIOS_TYPE RecordType
;
75 EFI_SMBIOS_TABLE_HEADER
*Buffer
;
78 RecordType
= EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY
;
80 Status
= Smbios
->GetNext (
87 if (!EFI_ERROR(Status
)) {
93 MISC_SMBIOS_TABLE_FUNCTION( MiscMemoryDevice
)
95 CHAR8
*OptionalStrStart
;
96 UINTN MemDeviceStrLen
;
97 UINTN MemBankLocatorStrLen
;
98 UINTN MemManufacturerStrLen
;
99 UINTN MemSerialNumberStrLen
;
100 UINTN MemAssetTagStrLen
;
101 UINTN MemPartNumberStrLen
;
103 CHAR16
*MemBankLocator
;
104 CHAR16
*MemManufacturer
;
105 CHAR16
*MemSerialNumber
;
107 CHAR16
*MemPartNumber
;
109 STRING_REF TokenToGet
;
110 SMBIOS_TABLE_TYPE17
*SmbiosRecord
;
111 EFI_SMBIOS_HANDLE SmbiosHandle
;
112 EFI_MEMORY_ARRAY_LINK_DATA
*ForType17InputData
;
114 UINT16 Type16Handle
=0;
115 MEM_INFO_PROTOCOL
*MemInfoHob
;
120 STRING_REF DevLocator
[] = {
121 STRING_TOKEN(STR_MISC_MEM_DEV_LOCATOR0
), STRING_TOKEN(STR_MISC_MEM_DEV_LOCATOR1
)
123 STRING_REF BankLocator
[] = {
124 STRING_TOKEN(STR_MISC_MEM_BANK_LOCATOR0
), STRING_TOKEN(STR_MISC_MEM_BANK_LOCATOR1
)
128 // First check for invalid parameters.
130 if (RecordData
== NULL
) {
131 return EFI_INVALID_PARAMETER
;
133 ForType17InputData
= (EFI_MEMORY_ARRAY_LINK_DATA
*)RecordData
;
136 // Get Memory size parameters for each rank from the chipset registers
138 Status
= gBS
->LocateProtocol (
139 &gMemInfoProtocolGuid
,
143 ASSERT_EFI_ERROR (Status
);
145 NumSlots
= (UINT8
)(MAX_SOCKETS
);
150 switch (MemInfoHob
->MemInfoData
.ddrFreq
){
171 switch (MemInfoHob
->MemInfoData
.ddrType
) {
173 MemoryType
= EfiMemoryTypeDdr2
;
179 MemoryType
= EfiMemoryTypeDdr3
;
182 MemoryType
= EfiMemoryTypeUnknown
;
186 for (Dimm
= 0; Dimm
< NumSlots
; Dimm
++) {
188 // Memory Device Locator
190 TokenToGet
= DevLocator
[Dimm
];
191 MemDevice
= SmbiosMiscGetString (TokenToGet
);
192 MemDeviceStrLen
= StrLen(MemDevice
);
193 if (MemDeviceStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
194 return EFI_UNSUPPORTED
;
197 TokenToGet
= DevLocator
[Dimm
];
198 MemDevice
= SmbiosMiscGetString (TokenToGet
);
199 MemDeviceStrLen
= StrLen(MemDevice
);
200 if (MemDeviceStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
201 return EFI_UNSUPPORTED
;
205 // Memory Bank Locator
207 TokenToGet
= BankLocator
[Dimm
];
208 MemBankLocator
= SmbiosMiscGetString (TokenToGet
);
209 MemBankLocatorStrLen
= StrLen(MemBankLocator
);
210 if (MemBankLocatorStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
211 return EFI_UNSUPPORTED
;
215 // Memory Manufacturer
217 TokenToGet
= STRING_TOKEN (STR_MISC_MEM_MANUFACTURER
);
218 MemManufacturer
= SmbiosMiscGetString (TokenToGet
);
219 MemManufacturerStrLen
= StrLen(MemManufacturer
);
220 if (MemManufacturerStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
221 return EFI_UNSUPPORTED
;
225 // Memory Serial Number
227 TokenToGet
= STRING_TOKEN (STR_MISC_MEM_SERIAL_NO
);
228 MemSerialNumber
= SmbiosMiscGetString (TokenToGet
);
229 MemSerialNumberStrLen
= StrLen(MemSerialNumber
);
230 if (MemSerialNumberStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
231 return EFI_UNSUPPORTED
;
235 // Memory Asset Tag Number
237 TokenToGet
= STRING_TOKEN (STR_MISC_MEM_ASSET_TAG
);
238 MemAssetTag
= SmbiosMiscGetString (TokenToGet
);
239 MemAssetTagStrLen
= StrLen(MemAssetTag
);
240 if (MemAssetTagStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
241 return EFI_UNSUPPORTED
;
245 // Memory Part Number
247 TokenToGet
= STRING_TOKEN (STR_MISC_MEM_PART_NUMBER
);
248 MemPartNumber
= SmbiosMiscGetString (TokenToGet
);
249 MemPartNumberStrLen
= StrLen(MemPartNumber
);
250 if (MemPartNumberStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
251 return EFI_UNSUPPORTED
;
255 // Two zeros following the last string.
257 SmbiosRecord
= AllocatePool(sizeof (SMBIOS_TABLE_TYPE17
) + MemDeviceStrLen
+ 1 + MemBankLocatorStrLen
+ 1 + MemManufacturerStrLen
+ 1 + MemSerialNumberStrLen
+ 1 + MemAssetTagStrLen
+1 + MemPartNumberStrLen
+ 1 + 1);
258 ZeroMem(SmbiosRecord
, sizeof (SMBIOS_TABLE_TYPE17
) + MemDeviceStrLen
+ 1 + MemBankLocatorStrLen
+ 1 + MemManufacturerStrLen
+ 1 + MemSerialNumberStrLen
+ 1 + MemAssetTagStrLen
+1 + MemPartNumberStrLen
+ 1 + 1);
260 SmbiosRecord
->Hdr
.Type
= EFI_SMBIOS_TYPE_MEMORY_DEVICE
;
261 SmbiosRecord
->Hdr
.Length
= sizeof (SMBIOS_TABLE_TYPE17
);
264 // Make handle chosen by smbios protocol.add automatically.
266 SmbiosRecord
->Hdr
.Handle
= 0;
269 // Memory Array Handle will be the 3rd optional string following the formatted structure.
271 GetType16Hndl( Smbios
, &Type16Handle
);
272 SmbiosRecord
->MemoryArrayHandle
= Type16Handle
;
277 if ((MemInfoHob
->MemInfoData
.dimmSize
[Dimm
])!=0){
278 SmbiosRecord
->TotalWidth
= 32;
279 SmbiosRecord
->DataWidth
= 32;
280 SmbiosRecord
->Size
= MemInfoHob
->MemInfoData
.dimmSize
[Dimm
];
281 SmbiosRecord
->Speed
= DdrFreq
;
282 SmbiosRecord
->ConfiguredMemoryClockSpeed
= DdrFreq
;
283 SmbiosRecord
->FormFactor
= EfiMemoryFormFactorDimm
;
286 SmbiosRecord
->DeviceSet
=(UINT8
) ForType17InputData
->MemoryDeviceSet
;
287 SmbiosRecord
->DeviceLocator
= 1;
288 SmbiosRecord
->BankLocator
= 2;
291 SmbiosRecord
->Manufacturer
= 3;
292 SmbiosRecord
->SerialNumber
= 4;
293 SmbiosRecord
->AssetTag
= 5;
294 SmbiosRecord
->PartNumber
= 6;
295 SmbiosRecord
->Attributes
= (UINT8
) ForType17InputData
->MemoryState
;
296 SmbiosRecord
->MemoryType
= MemoryType
;
298 OptionalStrStart
= (CHAR8
*)(SmbiosRecord
+ 1);
299 UnicodeStrToAsciiStr(MemDevice
, OptionalStrStart
);
300 UnicodeStrToAsciiStr(MemBankLocator
, OptionalStrStart
+ MemDeviceStrLen
+ 1);
301 UnicodeStrToAsciiStr(MemManufacturer
, OptionalStrStart
+ MemDeviceStrLen
+ 1 + MemBankLocatorStrLen
+ 1);
302 UnicodeStrToAsciiStr(MemSerialNumber
, OptionalStrStart
+ MemDeviceStrLen
+ 1 + MemBankLocatorStrLen
+ 1 + MemManufacturerStrLen
+ 1);
303 UnicodeStrToAsciiStr(MemAssetTag
, OptionalStrStart
+ MemDeviceStrLen
+ 1 + MemBankLocatorStrLen
+ 1 + MemManufacturerStrLen
+ 1 + MemSerialNumberStrLen
+ 1);
304 UnicodeStrToAsciiStr(MemPartNumber
, OptionalStrStart
+ MemDeviceStrLen
+ 1 + MemBankLocatorStrLen
+ 1 + MemManufacturerStrLen
+ 1 + MemSerialNumberStrLen
+ 1+ MemAssetTagStrLen
+1 );
307 // Now we have got the full smbios record, call smbios protocol to add this record.
309 SmbiosHandle
= SMBIOS_HANDLE_PI_RESERVED
;
310 Status
= Smbios
-> Add(
314 (EFI_SMBIOS_TABLE_HEADER
*) SmbiosRecord
316 FreePool(SmbiosRecord
);