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