]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscMemoryDeviceFunction.c
Upload BSD-licensed Vlv2TbltDevicePkg and Vlv2DeviceRefCodePkg to
[mirror_edk2.git] / Vlv2TbltDevicePkg / SmBiosMiscDxe / MiscMemoryDeviceFunction.c
1 /*++
2
3 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
4
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.
9
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.
12
13
14
15 Module Name:
16
17 MiscMemoryDeviceFunction.c
18
19 Abstract:
20
21 Memory Device
22 Misc. subclass type 17.
23 SMBIOS type 17.
24
25 --*/
26
27
28 #include "CommonHeader.h"
29 #include "MiscSubclassDriver.h"
30 #include <Protocol/DataHub.h>
31 #include <Guid/DataHubRecords.h>
32 #include <Protocol/MemInfo.h>
33
34
35 #define FREQ_800 0x00
36 #define FREQ_1066 0x01
37 #define FREQ_1333 0x02
38 #define FREQ_1600 0x03
39
40 #define MAX_SOCKETS 2
41 #define EfiMemoryTypeDdr3 0x18
42
43 enum {
44 DDRType_DDR3 = 0,
45 DDRType_DDR3L = 1,
46 DDRType_DDR3U = 2,
47 DDRType_DDR3All = 3,
48 DDRType_LPDDR2 = 4,
49 DDRType_LPDDR3 = 5,
50 DDRType_DDR4 = 6
51 };
52
53
54 typedef struct {
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;
60
61 /**
62 This function makes boot time changes to the contents of the
63 MiscBiosVendor (Type 0).
64
65 @param RecordData Pointer to copy of RecordData from the Data Table.
66
67 @retval EFI_SUCCESS All parameters were valid.
68 @retval EFI_UNSUPPORTED Unexpected RecordType value.
69 @retval EFI_INVALID_PARAMETER Invalid parameter was found.
70
71 **/
72 VOID
73 GetType16Hndl (
74 IN EFI_SMBIOS_PROTOCOL *Smbios,
75 OUT EFI_SMBIOS_HANDLE *Handle
76 )
77 {
78 EFI_STATUS Status;
79 EFI_SMBIOS_TYPE RecordType;
80 EFI_SMBIOS_TABLE_HEADER *Buffer;
81
82 *Handle = 0;
83 RecordType = EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY;
84
85 Status = Smbios->GetNext (
86 Smbios,
87 Handle,
88 &RecordType,
89 &Buffer,
90 NULL
91 );
92 if (!EFI_ERROR(Status)) {
93 return;
94 }
95 *Handle = 0xFFFF;
96 }
97
98 MISC_SMBIOS_TABLE_FUNCTION( MiscMemoryDevice )
99 {
100 CHAR8 *OptionalStrStart;
101 UINTN MemDeviceStrLen;
102 UINTN MemBankLocatorStrLen;
103 UINTN MemManufacturerStrLen;
104 UINTN MemSerialNumberStrLen;
105 UINTN MemAssetTagStrLen;
106 UINTN MemPartNumberStrLen;
107 CHAR16 *MemDevice;
108 CHAR16 *MemBankLocator;
109 CHAR16 *MemManufacturer;
110 CHAR16 *MemSerialNumber;
111 CHAR16 *MemAssetTag;
112 CHAR16 *MemPartNumber;
113 EFI_STATUS Status;
114 STRING_REF TokenToGet;
115 SMBIOS_TABLE_TYPE17 *SmbiosRecord;
116 EFI_SMBIOS_HANDLE SmbiosHandle;
117 EFI_MEMORY_ARRAY_LINK_DATA *ForType17InputData;
118 UINT16 DdrFreq=0;
119 UINT16 Type16Handle=0;
120 MEM_INFO_PROTOCOL *MemInfoHob;
121 UINT8 MemoryType;
122
123 UINT8 Dimm;
124 UINT8 NumSlots;
125 STRING_REF DevLocator[] = {
126 STRING_TOKEN(STR_MISC_MEM_DEV_LOCATOR0), STRING_TOKEN(STR_MISC_MEM_DEV_LOCATOR1)
127 };
128 STRING_REF BankLocator[] = {
129 STRING_TOKEN(STR_MISC_MEM_BANK_LOCATOR0), STRING_TOKEN(STR_MISC_MEM_BANK_LOCATOR1)
130 };
131
132 //
133 // First check for invalid parameters.
134 //
135 if (RecordData == NULL) {
136 return EFI_INVALID_PARAMETER;
137 }
138 ForType17InputData = (EFI_MEMORY_ARRAY_LINK_DATA *)RecordData;
139
140 //
141 // Get Memory size parameters for each rank from the chipset registers
142 //
143 Status = gBS->LocateProtocol (
144 &gMemInfoProtocolGuid,
145 NULL,
146 (void **)&MemInfoHob
147 );
148 ASSERT_EFI_ERROR (Status);
149
150 NumSlots = (UINT8)(MAX_SOCKETS);
151
152 //
153 // Memory Freq
154 //
155 switch (MemInfoHob->MemInfoData.ddrFreq){
156 case FREQ_800:
157 DdrFreq = 800;
158 break;
159 case FREQ_1066:
160 DdrFreq = 1066;
161 break;
162 case FREQ_1333:
163 DdrFreq = 1333;
164 break;
165 case FREQ_1600:
166 DdrFreq = 1600;
167 break;
168 default:
169 DdrFreq = 0;
170 break;
171 }
172
173 //
174 // Memory Type
175 //
176 switch (MemInfoHob->MemInfoData.ddrType) {
177 case DDRType_LPDDR2:
178 MemoryType = EfiMemoryTypeDdr2;
179 break;
180 case DDRType_DDR3:
181 case DDRType_DDR3L:
182 case DDRType_DDR3U:
183 case DDRType_LPDDR3:
184 MemoryType = EfiMemoryTypeDdr3;
185 break;
186 default:
187 MemoryType = EfiMemoryTypeUnknown;
188 break;
189 }
190
191 for (Dimm = 0; Dimm < NumSlots; Dimm++) {
192 //
193 // Memory Device Locator
194 //
195 TokenToGet = DevLocator[Dimm];
196 MemDevice = SmbiosMiscGetString (TokenToGet);
197 MemDeviceStrLen = StrLen(MemDevice);
198 if (MemDeviceStrLen > SMBIOS_STRING_MAX_LENGTH) {
199 return EFI_UNSUPPORTED;
200 }
201
202 TokenToGet = DevLocator[Dimm];
203 MemDevice = SmbiosMiscGetString (TokenToGet);
204 MemDeviceStrLen = StrLen(MemDevice);
205 if (MemDeviceStrLen > SMBIOS_STRING_MAX_LENGTH) {
206 return EFI_UNSUPPORTED;
207 }
208
209 //
210 // Memory Bank Locator
211 //
212 TokenToGet = BankLocator[Dimm];
213 MemBankLocator = SmbiosMiscGetString (TokenToGet);
214 MemBankLocatorStrLen = StrLen(MemBankLocator);
215 if (MemBankLocatorStrLen > SMBIOS_STRING_MAX_LENGTH) {
216 return EFI_UNSUPPORTED;
217 }
218
219 //
220 // Memory Manufacturer
221 //
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;
227 }
228
229 //
230 // Memory Serial Number
231 //
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;
237 }
238
239 //
240 // Memory Asset Tag Number
241 //
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;
247 }
248
249 //
250 // Memory Part Number
251 //
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;
257 }
258
259 //
260 // Two zeros following the last string.
261 //
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);
264
265 SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_DEVICE;
266 SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE17);
267
268 //
269 // Make handle chosen by smbios protocol.add automatically.
270 //
271 SmbiosRecord->Hdr.Handle = 0;
272
273 //
274 // Memory Array Handle will be the 3rd optional string following the formatted structure.
275 //
276 GetType16Hndl( Smbios, &Type16Handle);
277 SmbiosRecord->MemoryArrayHandle = Type16Handle;
278
279 //
280 // Memory Size
281 //
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;
289 }
290
291 SmbiosRecord->DeviceSet =(UINT8) ForType17InputData->MemoryDeviceSet;
292 SmbiosRecord->DeviceLocator= 1;
293 SmbiosRecord->BankLocator = 2;
294
295
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;
302
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 );
310
311 //
312 // Now we have got the full smbios record, call smbios protocol to add this record.
313 //
314 SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
315 Status = Smbios-> Add(
316 Smbios,
317 NULL,
318 &SmbiosHandle,
319 (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
320 );
321 FreePool(SmbiosRecord);
322 }
323 return Status;
324 }