]>
Commit | Line | Data |
---|---|---|
b303605e MK |
1 | /** @file\r |
2 | This is the driver that locates the MemoryConfigurationData Variable, if it\r | |
3 | exists, and reports the data to the DataHub.\r | |
4 | \r | |
5 | Copyright (c) 2013-2015 Intel Corporation.\r | |
6 | \r | |
0eb3de2e | 7 | SPDX-License-Identifier: BSD-2-Clause-Patent\r |
b303605e MK |
8 | \r |
9 | **/\r | |
10 | \r | |
11 | #include "MemorySubClass.h"\r | |
12 | \r | |
13 | extern UINT8 MemorySubClassStrings[];\r | |
14 | \r | |
15 | EFI_GUID gEfiMemorySubClassDriverGuid = EFI_MEMORY_SUBCLASS_DRIVER_GUID;\r | |
16 | \r | |
17 | EFI_STATUS\r | |
18 | MemorySubClassEntryPoint (\r | |
19 | IN EFI_HANDLE ImageHandle,\r | |
20 | IN EFI_SYSTEM_TABLE *SystemTable\r | |
21 | )\r | |
22 | /*++\r | |
23 | \r | |
24 | Routine Description:\r | |
25 | This is the standard EFI driver point that detects whether there is a\r | |
26 | MemoryConfigurationData Variable and, if so, reports memory configuration info\r | |
27 | to the DataHub.\r | |
28 | \r | |
29 | Arguments:\r | |
30 | ImageHandle - Handle for the image of this driver\r | |
31 | SystemTable - Pointer to the EFI System Table\r | |
32 | \r | |
33 | Returns:\r | |
34 | EFI_SUCCESS if the data is successfully reported\r | |
35 | EFI_NOT_FOUND if the HOB list could not be located.\r | |
36 | \r | |
37 | --*/\r | |
38 | {\r | |
39 | // UINT8 Index;\r | |
40 | UINTN DataSize;\r | |
41 | UINT8 Dimm;\r | |
42 | UINTN StringBufferSize;\r | |
43 | UINT8 NumSlots;\r | |
44 | UINTN DevLocStrLen;\r | |
45 | UINTN BankLocStrLen;\r | |
46 | UINTN ManuStrLen;\r | |
47 | UINTN SerialNumStrLen;\r | |
48 | UINTN AssertTagStrLen;\r | |
49 | UINTN PartNumStrLen;\r | |
50 | UINTN MemoryDeviceSize;\r | |
51 | CHAR8* OptionalStrStart;\r | |
52 | UINT16 ArrayInstance;\r | |
53 | UINT64 DimmMemorySize;\r | |
54 | UINT64 TotalMemorySize;\r | |
55 | UINT32 Data;\r | |
56 | UINT32 MemoryCapacity;\r | |
57 | BOOLEAN MemoryDeviceSizeUnitMega;\r | |
58 | EFI_STATUS Status;\r | |
59 | EFI_STRING StringBuffer;\r | |
60 | EFI_STRING DevLocStr;\r | |
61 | EFI_STRING BankLocStr;\r | |
62 | EFI_STRING ManuStr;\r | |
63 | EFI_STRING SerialNumStr;\r | |
64 | EFI_STRING AssertTagStr;\r | |
65 | EFI_STRING PartNumStr;\r | |
66 | EFI_HII_HANDLE HiiHandle;\r | |
67 | EFI_SMBIOS_HANDLE MemArraySmbiosHandle;\r | |
68 | EFI_SMBIOS_HANDLE MemArrayMappedAddrSmbiosHandle;\r | |
69 | EFI_SMBIOS_HANDLE MemDevSmbiosHandle;\r | |
70 | EFI_SMBIOS_HANDLE MemDevMappedAddrSmbiosHandle;\r | |
71 | EFI_SMBIOS_HANDLE MemModuleInfoSmbiosHandle;\r | |
72 | SMBIOS_TABLE_TYPE6 *Type6Record;\r | |
73 | SMBIOS_TABLE_TYPE16 *Type16Record;\r | |
74 | SMBIOS_TABLE_TYPE17 *Type17Record;\r | |
75 | SMBIOS_TABLE_TYPE19 *Type19Record;\r | |
76 | SMBIOS_TABLE_TYPE20 *Type20Record;\r | |
77 | EFI_SMBIOS_PROTOCOL *Smbios;\r | |
78 | EFI_MEMORY_ARRAY_LINK_DATA ArrayLink;\r | |
79 | EFI_MEMORY_ARRAY_LOCATION_DATA ArrayLocationData;\r | |
80 | EFI_MEMORY_DEVICE_START_ADDRESS_DATA DeviceStartAddress;\r | |
81 | \r | |
82 | \r | |
83 | DataSize = 0;\r | |
84 | Dimm = 0;\r | |
85 | \r | |
86 | \r | |
87 | //\r | |
88 | // Allocate Buffers\r | |
89 | //\r | |
90 | StringBufferSize = (sizeof (CHAR16)) * 100;\r | |
91 | StringBuffer = AllocateZeroPool (StringBufferSize);\r | |
92 | ASSERT (StringBuffer != NULL);\r | |
93 | \r | |
94 | //\r | |
95 | // Locate dependent protocols\r | |
96 | //\r | |
97 | Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios);\r | |
98 | ASSERT_EFI_ERROR (Status);\r | |
99 | \r | |
100 | \r | |
101 | //\r | |
102 | // Add our default strings to the HII database. They will be modified later.\r | |
103 | //\r | |
104 | HiiHandle = HiiAddPackages (\r | |
105 | &gEfiMemorySubClassDriverGuid,\r | |
106 | NULL,\r | |
107 | MemorySubClassStrings,\r | |
108 | NULL\r | |
109 | );\r | |
110 | ASSERT (HiiHandle != NULL);\r | |
111 | \r | |
112 | //\r | |
113 | // Create physical array and associated data for all mainboard memory\r | |
114 | // This will translate into a Type 16 SMBIOS Record\r | |
115 | //\r | |
116 | ArrayInstance = 1;\r | |
117 | \r | |
118 | McD0PciCfg32 (QNC_ACCESS_PORT_MCR) = MESSAGE_READ_DW (0x3, 0x8);\r | |
119 | TotalMemorySize = McD0PciCfg32 (QNC_ACCESS_PORT_MDR);\r | |
120 | \r | |
121 | ArrayLocationData.MemoryArrayLocation = EfiMemoryArrayLocationSystemBoard;\r | |
122 | ArrayLocationData.MemoryArrayUse = EfiMemoryArrayUseSystemMemory;\r | |
123 | \r | |
124 | ArrayLocationData.MemoryErrorCorrection = EfiMemoryErrorCorrectionNone;\r | |
125 | \r | |
126 | Data = 0x40000000;//(UINT32) RShiftU64(MemConfigData->RowInfo.MaxMemory, 10);\r | |
127 | \r | |
128 | ArrayLocationData.MaximumMemoryCapacity.Exponent = (UINT16) LowBitSet32 (Data);\r | |
129 | ArrayLocationData.MaximumMemoryCapacity.Value = (UINT16) (Data >> ArrayLocationData.MaximumMemoryCapacity.Exponent);\r | |
130 | \r | |
131 | NumSlots = 2;// (UINT8)(MemConfigData->RowInfo.MaxRows >> 1);\r | |
132 | ArrayLocationData.NumberMemoryDevices = (UINT16)(NumSlots);\r | |
133 | \r | |
134 | //\r | |
135 | // Report top level physical array to Type 16 SMBIOS Record\r | |
136 | //\r | |
137 | Type16Record = AllocatePool(sizeof(SMBIOS_TABLE_TYPE16) + 1 + 1);\r | |
138 | ZeroMem(Type16Record, sizeof(SMBIOS_TABLE_TYPE16) + 1 + 1);\r | |
139 | \r | |
140 | Type16Record->Hdr.Type = EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY;\r | |
141 | Type16Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE16);\r | |
142 | Type16Record->Hdr.Handle = 0;\r | |
143 | \r | |
144 | Type16Record->Location = (UINT8)ArrayLocationData.MemoryArrayLocation;\r | |
145 | \r | |
146 | Type16Record->Use = (UINT8)ArrayLocationData.MemoryArrayUse;\r | |
147 | \r | |
148 | Type16Record->MemoryErrorCorrection = (UINT8)ArrayLocationData.MemoryErrorCorrection;\r | |
149 | \r | |
150 | MemoryCapacity = (UINT32) ArrayLocationData.MaximumMemoryCapacity.Value * (1 << ((UINT32) ArrayLocationData.MaximumMemoryCapacity.Exponent - 10));\r | |
151 | Type16Record->MaximumCapacity = MemoryCapacity;\r | |
152 | \r | |
153 | Type16Record->MemoryErrorInformationHandle = 0xfffe;\r | |
154 | \r | |
155 | Type16Record->NumberOfMemoryDevices = ArrayLocationData.NumberMemoryDevices;\r | |
156 | //\r | |
157 | // Don't change it. This handle will be referenced by type 17 records\r | |
158 | //\r | |
159 | MemArraySmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r | |
160 | Status = Smbios->Add (Smbios, NULL, &MemArraySmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type16Record);\r | |
161 | FreePool(Type16Record);\r | |
162 | ASSERT_EFI_ERROR (Status);\r | |
163 | \r | |
164 | // Do associated data for each DIMM\r | |
165 | //RowConfArray = &MemConfigData->RowConfArray;\r | |
166 | \r | |
167 | //\r | |
168 | // Get total memory size for the construction of smbios record type 19\r | |
169 | //\r | |
170 | //TotalMemorySize = 0;// MSG_BUS_READ(0x0208);\r | |
171 | \r | |
172 | //\r | |
173 | // Generate Memory Array Mapped Address info\r | |
174 | //\r | |
175 | Type19Record = AllocatePool(sizeof (SMBIOS_TABLE_TYPE19));\r | |
176 | ZeroMem(Type19Record, sizeof(SMBIOS_TABLE_TYPE19));\r | |
177 | Type19Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS;\r | |
178 | Type19Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE19);\r | |
179 | Type19Record->Hdr.Handle = 0;\r | |
180 | Type19Record->StartingAddress = 0;\r | |
181 | Type19Record->EndingAddress = (UINT32)RShiftU64(TotalMemorySize, 10) - 1;\r | |
182 | Type19Record->MemoryArrayHandle = MemArraySmbiosHandle;\r | |
183 | Type19Record->PartitionWidth = (UINT8)(NumSlots);\r | |
184 | \r | |
185 | //\r | |
186 | // Generate Memory Array Mapped Address info (TYPE 19)\r | |
187 | //\r | |
188 | MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r | |
189 | Status = Smbios->Add (Smbios, NULL, &MemArrayMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type19Record);\r | |
190 | FreePool(Type19Record);\r | |
191 | ASSERT_EFI_ERROR (Status);\r | |
192 | \r | |
193 | \r | |
194 | // Use SPD data to generate Device Type info\r | |
195 | ZeroMem (&ArrayLink, sizeof (EFI_MEMORY_ARRAY_LINK_DATA));\r | |
196 | ArrayLink.MemoryDeviceLocator = STRING_TOKEN(STR_MEMORY_SUBCLASS_DEVICE_LOCATOR_0);\r | |
197 | ArrayLink.MemoryBankLocator = STRING_TOKEN(STR_MEMORY_SUBCLASS_DEVICE_LOCATOR_0);\r | |
198 | ArrayLink.MemoryAssetTag = STRING_TOKEN(STR_MEMORY_SUBCLASS_UNKNOWN);\r | |
199 | ArrayLink.MemoryArrayLink.ProducerName = gEfiMemorySubClassDriverGuid;\r | |
200 | ArrayLink.MemoryArrayLink.Instance = ArrayInstance;\r | |
201 | ArrayLink.MemoryArrayLink.SubInstance = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE;\r | |
202 | ArrayLink.MemorySubArrayLink.ProducerName = gEfiMemorySubClassDriverGuid;\r | |
203 | ArrayLink.MemorySubArrayLink.SubInstance = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE;\r | |
204 | ArrayLink.MemoryFormFactor = EfiMemoryFormFactorChip;\r | |
205 | ArrayLink.MemoryType = EfiMemoryTypeDdr2;\r | |
206 | \r | |
207 | \r | |
208 | StrCpy (StringBuffer, L"NO DIMM,MEMROY DOWN");\r | |
209 | ArrayLink.MemoryManufacturer = HiiSetString (\r | |
210 | HiiHandle,\r | |
211 | 0,\r | |
212 | StringBuffer,\r | |
213 | NULL\r | |
214 | );\r | |
215 | ArrayLink.MemorySerialNumber = HiiSetString (\r | |
216 | HiiHandle,\r | |
217 | 0,\r | |
218 | StringBuffer,\r | |
219 | NULL\r | |
220 | );\r | |
221 | \r | |
222 | ArrayLink.MemoryPartNumber = HiiSetString (\r | |
223 | HiiHandle,\r | |
224 | 0,\r | |
225 | StringBuffer,\r | |
226 | NULL\r | |
227 | );\r | |
228 | \r | |
229 | //\r | |
230 | // Hardcode value. Need to revise for different configuration.\r | |
231 | //\r | |
232 | ArrayLink.MemoryTotalWidth = 64;\r | |
233 | ArrayLink.MemoryDataWidth = 64;\r | |
234 | \r | |
235 | DimmMemorySize = TotalMemorySize;// MSG_BUS_READ(0x0208);\r | |
236 | \r | |
237 | ArrayLink.MemoryDeviceSize.Exponent = (UINT16) LowBitSet64 (DimmMemorySize);\r | |
238 | ArrayLink.MemoryDeviceSize.Value = (UINT16) RShiftU64(DimmMemorySize, ArrayLink.MemoryDeviceSize.Exponent);\r | |
239 | ArrayLink.MemoryTypeDetail.Synchronous = 1;\r | |
240 | Data = 800;\r | |
241 | ArrayLink.MemorySpeed = *((EFI_EXP_BASE10_DATA *) &Data);\r | |
242 | \r | |
243 | \r | |
244 | \r | |
245 | DevLocStr = HiiGetPackageString(&gEfiMemorySubClassDriverGuid, ArrayLink.MemoryDeviceLocator, NULL);\r | |
246 | DevLocStrLen = StrLen(DevLocStr);\r | |
247 | ASSERT(DevLocStrLen <= SMBIOS_STRING_MAX_LENGTH);\r | |
248 | \r | |
249 | BankLocStr = HiiGetPackageString(&gEfiMemorySubClassDriverGuid, ArrayLink.MemoryBankLocator, NULL);\r | |
250 | BankLocStrLen = StrLen(BankLocStr);\r | |
251 | ASSERT(BankLocStrLen <= SMBIOS_STRING_MAX_LENGTH);\r | |
252 | \r | |
253 | ManuStr = HiiGetPackageString(&gEfiMemorySubClassDriverGuid, ArrayLink.MemoryManufacturer, NULL);\r | |
254 | ManuStrLen = StrLen(ManuStr);\r | |
255 | ASSERT(ManuStrLen <= SMBIOS_STRING_MAX_LENGTH);\r | |
256 | \r | |
257 | SerialNumStr = HiiGetPackageString(&gEfiMemorySubClassDriverGuid, ArrayLink.MemorySerialNumber, NULL);\r | |
258 | SerialNumStrLen = StrLen(SerialNumStr);\r | |
259 | ASSERT(SerialNumStrLen <= SMBIOS_STRING_MAX_LENGTH);\r | |
260 | \r | |
261 | AssertTagStr = HiiGetPackageString(&gEfiMemorySubClassDriverGuid, ArrayLink.MemoryAssetTag, NULL);\r | |
262 | AssertTagStrLen = StrLen(AssertTagStr);\r | |
263 | ASSERT(AssertTagStrLen <= SMBIOS_STRING_MAX_LENGTH);\r | |
264 | \r | |
265 | PartNumStr = HiiGetPackageString(&gEfiMemorySubClassDriverGuid, ArrayLink.MemoryPartNumber, NULL);\r | |
266 | PartNumStrLen = StrLen(PartNumStr);\r | |
267 | ASSERT(PartNumStrLen <= SMBIOS_STRING_MAX_LENGTH);\r | |
268 | \r | |
269 | //\r | |
270 | // Report DIMM level memory module information to smbios (Type 6)\r | |
271 | //\r | |
272 | DataSize = sizeof(SMBIOS_TABLE_TYPE6) + DevLocStrLen + 1 + 1;\r | |
273 | Type6Record = AllocatePool(DataSize);\r | |
274 | ZeroMem(Type6Record, DataSize);\r | |
275 | Type6Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_MODULE_INFORMATON;\r | |
276 | Type6Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE6);\r | |
277 | Type6Record->Hdr.Handle = 0;\r | |
278 | Type6Record->SocketDesignation = 1;\r | |
279 | if (ArrayLink.MemorySpeed.Value == 0) {\r | |
280 | Type6Record->CurrentSpeed = 0;\r | |
281 | } else {\r | |
282 | //\r | |
283 | // Memory speed is in ns unit\r | |
284 | //\r | |
285 | Type6Record->CurrentSpeed = (UINT8)(1000 / (ArrayLink.MemorySpeed.Value));\r | |
286 | }\r | |
287 | //\r | |
288 | // Device Size\r | |
289 | //\r | |
290 | MemoryDeviceSize = (UINTN)(ArrayLink.MemoryDeviceSize.Value) * (UINTN)(1 << ArrayLink.MemoryDeviceSize.Exponent);\r | |
291 | if (MemoryDeviceSize == 0) {\r | |
292 | *(UINT8*)&(Type6Record->InstalledSize) = 0x7F;\r | |
293 | *(UINT8*)&(Type6Record->EnabledSize) = 0x7F;\r | |
294 | } else {\r | |
295 | MemoryDeviceSize = (UINTN) RShiftU64 ((UINT64) MemoryDeviceSize, 21);\r | |
296 | while (MemoryDeviceSize != 0) {\r | |
297 | (*(UINT8*)&(Type6Record->InstalledSize))++;\r | |
298 | (*(UINT8*)&(Type6Record->EnabledSize))++;\r | |
299 | MemoryDeviceSize = (UINTN) RShiftU64 ((UINT64) MemoryDeviceSize,1);\r | |
300 | }\r | |
301 | }\r | |
302 | \r | |
303 | if (ArrayLink.MemoryFormFactor == EfiMemoryFormFactorDimm ||\r | |
304 | ArrayLink.MemoryFormFactor == EfiMemoryFormFactorFbDimm) {\r | |
305 | *(UINT16*)&Type6Record->CurrentMemoryType |= 1<<8;\r | |
306 | }\r | |
307 | if (ArrayLink.MemoryFormFactor == EfiMemoryFormFactorSimm) {\r | |
308 | *(UINT16*)&Type6Record->CurrentMemoryType |= 1<<7;\r | |
309 | }\r | |
310 | if (ArrayLink.MemoryType == EfiMemoryTypeSdram) {\r | |
311 | *(UINT16*)&Type6Record->CurrentMemoryType |= 1<<10;\r | |
312 | }\r | |
313 | if (ArrayLink.MemoryTypeDetail.Edo == 1) {\r | |
314 | *(UINT16*)&Type6Record->CurrentMemoryType |= 1<<4;\r | |
315 | }\r | |
316 | if (ArrayLink.MemoryTypeDetail.FastPaged == 1) {\r | |
317 | *(UINT16*)&Type6Record->CurrentMemoryType |= 1<<3;\r | |
318 | }\r | |
319 | OptionalStrStart = (CHAR8 *)(Type6Record + 1);\r | |
320 | UnicodeStrToAsciiStr(DevLocStr, OptionalStrStart);\r | |
321 | MemModuleInfoSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r | |
322 | Status = Smbios->Add (Smbios, NULL, &MemModuleInfoSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type6Record);\r | |
323 | FreePool(Type6Record);\r | |
324 | ASSERT_EFI_ERROR (Status);\r | |
325 | //\r | |
326 | // Report DIMM level Device Type to smbios (Type 17)\r | |
327 | //\r | |
328 | DataSize = sizeof (SMBIOS_TABLE_TYPE17) + DevLocStrLen + 1 + BankLocStrLen + 1 + ManuStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + PartNumStrLen + 1 + 1;\r | |
329 | Type17Record = AllocatePool(DataSize);\r | |
330 | ZeroMem(Type17Record, DataSize);\r | |
331 | Type17Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_DEVICE;\r | |
332 | Type17Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE17);\r | |
333 | Type17Record->Hdr.Handle = 0;\r | |
334 | \r | |
335 | Type17Record->MemoryArrayHandle = MemArraySmbiosHandle;\r | |
336 | Type17Record->MemoryErrorInformationHandle = 0xfffe;\r | |
337 | Type17Record->TotalWidth = ArrayLink.MemoryTotalWidth;\r | |
338 | Type17Record->DataWidth = ArrayLink.MemoryDataWidth;\r | |
339 | //\r | |
340 | // Device Size\r | |
341 | //\r | |
342 | MemoryDeviceSize = ((UINTN) ArrayLink.MemoryDeviceSize.Value) << (ArrayLink.MemoryDeviceSize.Exponent - 10);\r | |
343 | MemoryDeviceSizeUnitMega = FALSE;\r | |
344 | //\r | |
345 | // kilo as unit\r | |
346 | //\r | |
347 | if (MemoryDeviceSize > 0xffff) {\r | |
348 | MemoryDeviceSize = MemoryDeviceSize >> 10;\r | |
349 | //\r | |
350 | // Mega as unit\r | |
351 | //\r | |
352 | MemoryDeviceSizeUnitMega = TRUE;\r | |
353 | }\r | |
354 | \r | |
355 | MemoryDeviceSize = MemoryDeviceSize & 0x7fff;\r | |
356 | if (MemoryDeviceSize != 0 && MemoryDeviceSizeUnitMega == FALSE) {\r | |
357 | MemoryDeviceSize |= 0x8000;\r | |
358 | }\r | |
359 | Type17Record->Size = (UINT16)MemoryDeviceSize;\r | |
360 | \r | |
361 | Type17Record->FormFactor = (UINT8)ArrayLink.MemoryFormFactor;\r | |
362 | Type17Record->DeviceLocator = 1;\r | |
363 | Type17Record->BankLocator = 2;\r | |
364 | Type17Record->MemoryType = (UINT8)ArrayLink.MemoryType;\r | |
365 | CopyMem (\r | |
366 | (UINT8 *) &Type17Record->TypeDetail,\r | |
367 | &ArrayLink.MemoryTypeDetail,\r | |
368 | 2\r | |
369 | );\r | |
370 | \r | |
371 | Type17Record->Speed = ArrayLink.MemorySpeed.Value;\r | |
372 | Type17Record->Manufacturer = 3;\r | |
373 | Type17Record->SerialNumber = 4;\r | |
374 | Type17Record->AssetTag = 5;\r | |
375 | Type17Record->PartNumber = 6;\r | |
376 | //\r | |
377 | // temporary solution for save device label information.\r | |
378 | //\r | |
379 | Type17Record->Attributes = (UINT8)(Dimm + 1);\r | |
380 | \r | |
381 | OptionalStrStart = (CHAR8 *)(Type17Record + 1);\r | |
382 | UnicodeStrToAsciiStr(DevLocStr, OptionalStrStart);\r | |
383 | UnicodeStrToAsciiStr(BankLocStr, OptionalStrStart + DevLocStrLen + 1);\r | |
384 | UnicodeStrToAsciiStr(ManuStr, OptionalStrStart + DevLocStrLen + 1 + BankLocStrLen + 1);\r | |
385 | UnicodeStrToAsciiStr(SerialNumStr, OptionalStrStart + DevLocStrLen + 1 + BankLocStrLen + 1 + ManuStrLen + 1);\r | |
386 | UnicodeStrToAsciiStr(AssertTagStr, OptionalStrStart + DevLocStrLen + 1 + BankLocStrLen + 1 + ManuStrLen + 1 + SerialNumStrLen + 1);\r | |
387 | UnicodeStrToAsciiStr(PartNumStr, OptionalStrStart + DevLocStrLen + 1 + BankLocStrLen + 1 + ManuStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1);\r | |
388 | MemDevSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r | |
389 | Status = Smbios->Add (Smbios, NULL, &MemDevSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type17Record);\r | |
390 | FreePool(Type17Record);\r | |
391 | ASSERT_EFI_ERROR (Status);\r | |
392 | \r | |
393 | //\r | |
394 | // Generate Memory Device Mapped Address info\r | |
395 | //\r | |
396 | ZeroMem(&DeviceStartAddress, sizeof(EFI_MEMORY_DEVICE_START_ADDRESS_DATA));\r | |
397 | DeviceStartAddress.MemoryDeviceStartAddress = 0;\r | |
398 | DeviceStartAddress.MemoryDeviceEndAddress = DeviceStartAddress.MemoryDeviceStartAddress + DimmMemorySize-1;\r | |
399 | DeviceStartAddress.PhysicalMemoryDeviceLink.ProducerName = gEfiMemorySubClassDriverGuid;\r | |
400 | DeviceStartAddress.PhysicalMemoryDeviceLink.Instance = ArrayInstance;\r | |
401 | DeviceStartAddress.PhysicalMemoryDeviceLink.SubInstance = (UINT16)(Dimm + 1);\r | |
402 | DeviceStartAddress.PhysicalMemoryArrayLink.ProducerName = gEfiMemorySubClassDriverGuid;\r | |
403 | DeviceStartAddress.PhysicalMemoryArrayLink.Instance = ArrayInstance;\r | |
404 | DeviceStartAddress.PhysicalMemoryArrayLink.SubInstance = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE;\r | |
405 | \r | |
406 | //\r | |
407 | // Single channel mode\r | |
408 | //\r | |
409 | DeviceStartAddress.MemoryDevicePartitionRowPosition = 0x01;\r | |
410 | DeviceStartAddress.MemoryDeviceInterleavePosition = 0x00;\r | |
411 | DeviceStartAddress.MemoryDeviceInterleaveDataDepth = 0x00;\r | |
412 | \r | |
413 | //\r | |
414 | // Generate Memory Device Mapped Address info (TYPE 20)\r | |
415 | //\r | |
416 | Type20Record = AllocatePool(sizeof (SMBIOS_TABLE_TYPE20));\r | |
417 | ZeroMem(Type20Record, sizeof (SMBIOS_TABLE_TYPE20));\r | |
418 | Type20Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_DEVICE_MAPPED_ADDRESS;\r | |
419 | Type20Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE20);\r | |
420 | Type20Record->Hdr.Handle = 0;\r | |
421 | \r | |
422 | Type20Record->StartingAddress = (UINT32)RShiftU64 (DeviceStartAddress.MemoryDeviceStartAddress, 10);\r | |
423 | Type20Record->EndingAddress = (UINT32)RShiftU64 (DeviceStartAddress.MemoryDeviceEndAddress, 10);\r | |
424 | Type20Record->MemoryDeviceHandle = MemDevSmbiosHandle;\r | |
425 | Type20Record->MemoryArrayMappedAddressHandle = MemArrayMappedAddrSmbiosHandle;\r | |
426 | Type20Record->PartitionRowPosition = DeviceStartAddress.MemoryDevicePartitionRowPosition;\r | |
427 | Type20Record->InterleavePosition = DeviceStartAddress.MemoryDeviceInterleavePosition;\r | |
428 | Type20Record->InterleavedDataDepth = DeviceStartAddress.MemoryDeviceInterleaveDataDepth;\r | |
429 | MemDevMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r | |
430 | Status = Smbios->Add (Smbios, NULL, &MemDevMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type20Record);\r | |
431 | FreePool(Type20Record);\r | |
432 | ASSERT_EFI_ERROR (Status);\r | |
433 | \r | |
434 | return Status;\r | |
435 | }\r |