]>
Commit | Line | Data |
---|---|---|
3cbfba02 DW |
1 | /*++\r |
2 | \r | |
3 | Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r | |
4 | \r\r | |
5 | This program and the accompanying materials are licensed and made available under\r\r | |
6 | the terms and conditions of the BSD License that accompanies this distribution. \r\r | |
7 | The full text of the license may be found at \r\r | |
8 | http://opensource.org/licenses/bsd-license.php. \r\r | |
9 | \r\r | |
10 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r\r | |
11 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r\r | |
12 | \r\r | |
13 | \r | |
14 | \r | |
15 | Module Name:\r | |
16 | \r | |
17 | MiscMemoryDeviceFunction.c\r | |
18 | \r | |
19 | Abstract:\r | |
20 | \r | |
21 | Memory Device\r | |
22 | Misc. subclass type 17.\r | |
23 | SMBIOS type 17.\r | |
24 | \r | |
25 | --*/\r | |
26 | \r | |
27 | \r | |
28 | #include "CommonHeader.h"\r | |
29 | #include "MiscSubclassDriver.h"\r | |
30 | #include <Protocol/DataHub.h>\r | |
31 | #include <Guid/DataHubRecords.h>\r | |
32 | #include <Protocol/MemInfo.h>\r | |
33 | \r | |
34 | \r | |
35 | #define FREQ_800 0x00\r | |
36 | #define FREQ_1066 0x01\r | |
37 | #define FREQ_1333 0x02\r | |
38 | #define FREQ_1600 0x03\r | |
39 | \r | |
40 | #define MAX_SOCKETS 2\r | |
41 | #define EfiMemoryTypeDdr3 0x18\r | |
42 | \r | |
43 | enum {\r | |
44 | DDRType_DDR3 = 0,\r | |
45 | DDRType_DDR3L = 1,\r | |
46 | DDRType_DDR3U = 2,\r | |
47 | DDRType_DDR3All = 3,\r | |
48 | DDRType_LPDDR2 = 4,\r | |
49 | DDRType_LPDDR3 = 5,\r | |
50 | DDRType_DDR4 = 6\r | |
51 | };\r | |
52 | \r | |
53 | \r | |
54 | typedef struct {\r | |
55 | EFI_PHYSICAL_ADDRESS MemoryArrayStartAddress;\r | |
56 | EFI_PHYSICAL_ADDRESS MemoryArrayEndAddress;\r | |
57 | EFI_INTER_LINK_DATA PhysicalMemoryArrayLink;\r | |
58 | UINT16 MemoryArrayPartitionWidth;\r | |
59 | } EFI_MEMORY_ARRAY_START_ADDRESS;\r | |
60 | \r | |
61 | /**\r | |
62 | This function makes boot time changes to the contents of the\r | |
63 | MiscBiosVendor (Type 0).\r | |
64 | \r | |
65 | @param RecordData Pointer to copy of RecordData from the Data Table.\r | |
66 | \r | |
67 | @retval EFI_SUCCESS All parameters were valid.\r | |
68 | @retval EFI_UNSUPPORTED Unexpected RecordType value.\r | |
69 | @retval EFI_INVALID_PARAMETER Invalid parameter was found.\r | |
70 | \r | |
71 | **/\r | |
72 | VOID\r | |
73 | GetType16Hndl (\r | |
74 | IN EFI_SMBIOS_PROTOCOL *Smbios,\r | |
75 | OUT EFI_SMBIOS_HANDLE *Handle\r | |
76 | )\r | |
77 | {\r | |
78 | EFI_STATUS Status;\r | |
79 | EFI_SMBIOS_TYPE RecordType;\r | |
80 | EFI_SMBIOS_TABLE_HEADER *Buffer;\r | |
81 | \r | |
82 | *Handle = 0;\r | |
83 | RecordType = EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY;\r | |
84 | \r | |
85 | Status = Smbios->GetNext (\r | |
86 | Smbios,\r | |
87 | Handle,\r | |
88 | &RecordType,\r | |
89 | &Buffer,\r | |
90 | NULL\r | |
91 | );\r | |
92 | if (!EFI_ERROR(Status)) {\r | |
93 | return;\r | |
94 | }\r | |
95 | *Handle = 0xFFFF;\r | |
96 | }\r | |
97 | \r | |
98 | MISC_SMBIOS_TABLE_FUNCTION( MiscMemoryDevice )\r | |
99 | {\r | |
100 | CHAR8 *OptionalStrStart;\r | |
101 | UINTN MemDeviceStrLen;\r | |
102 | UINTN MemBankLocatorStrLen;\r | |
103 | UINTN MemManufacturerStrLen;\r | |
104 | UINTN MemSerialNumberStrLen;\r | |
105 | UINTN MemAssetTagStrLen;\r | |
106 | UINTN MemPartNumberStrLen;\r | |
107 | CHAR16 *MemDevice;\r | |
108 | CHAR16 *MemBankLocator;\r | |
109 | CHAR16 *MemManufacturer;\r | |
110 | CHAR16 *MemSerialNumber;\r | |
111 | CHAR16 *MemAssetTag;\r | |
112 | CHAR16 *MemPartNumber;\r | |
113 | EFI_STATUS Status;\r | |
114 | STRING_REF TokenToGet;\r | |
115 | SMBIOS_TABLE_TYPE17 *SmbiosRecord;\r | |
116 | EFI_SMBIOS_HANDLE SmbiosHandle;\r | |
117 | EFI_MEMORY_ARRAY_LINK_DATA *ForType17InputData;\r | |
118 | UINT16 DdrFreq=0;\r | |
119 | UINT16 Type16Handle=0;\r | |
120 | MEM_INFO_PROTOCOL *MemInfoHob;\r | |
121 | UINT8 MemoryType;\r | |
122 | \r | |
123 | UINT8 Dimm;\r | |
124 | UINT8 NumSlots;\r | |
125 | STRING_REF DevLocator[] = {\r | |
126 | STRING_TOKEN(STR_MISC_MEM_DEV_LOCATOR0), STRING_TOKEN(STR_MISC_MEM_DEV_LOCATOR1)\r | |
127 | };\r | |
128 | STRING_REF BankLocator[] = {\r | |
129 | STRING_TOKEN(STR_MISC_MEM_BANK_LOCATOR0), STRING_TOKEN(STR_MISC_MEM_BANK_LOCATOR1)\r | |
130 | };\r | |
131 | \r | |
132 | //\r | |
133 | // First check for invalid parameters.\r | |
134 | //\r | |
135 | if (RecordData == NULL) {\r | |
136 | return EFI_INVALID_PARAMETER;\r | |
137 | }\r | |
138 | ForType17InputData = (EFI_MEMORY_ARRAY_LINK_DATA *)RecordData;\r | |
139 | \r | |
140 | //\r | |
141 | // Get Memory size parameters for each rank from the chipset registers\r | |
142 | //\r | |
143 | Status = gBS->LocateProtocol (\r | |
144 | &gMemInfoProtocolGuid,\r | |
145 | NULL,\r | |
146 | (void **)&MemInfoHob\r | |
147 | );\r | |
148 | ASSERT_EFI_ERROR (Status);\r | |
149 | \r | |
150 | NumSlots = (UINT8)(MAX_SOCKETS);\r | |
151 | \r | |
152 | //\r | |
153 | // Memory Freq\r | |
154 | //\r | |
155 | switch (MemInfoHob->MemInfoData.ddrFreq){\r | |
156 | case FREQ_800:\r | |
157 | DdrFreq = 800;\r | |
158 | break;\r | |
159 | case FREQ_1066:\r | |
160 | DdrFreq = 1066;\r | |
161 | break;\r | |
162 | case FREQ_1333:\r | |
163 | DdrFreq = 1333;\r | |
164 | break;\r | |
165 | case FREQ_1600:\r | |
166 | DdrFreq = 1600;\r | |
167 | break;\r | |
168 | default:\r | |
169 | DdrFreq = 0;\r | |
170 | break;\r | |
171 | }\r | |
172 | \r | |
173 | //\r | |
174 | // Memory Type\r | |
175 | //\r | |
176 | switch (MemInfoHob->MemInfoData.ddrType) {\r | |
177 | case DDRType_LPDDR2:\r | |
178 | MemoryType = EfiMemoryTypeDdr2;\r | |
179 | break;\r | |
180 | case DDRType_DDR3:\r | |
181 | case DDRType_DDR3L:\r | |
182 | case DDRType_DDR3U:\r | |
183 | case DDRType_LPDDR3:\r | |
184 | MemoryType = EfiMemoryTypeDdr3;\r | |
185 | break;\r | |
186 | default:\r | |
187 | MemoryType = EfiMemoryTypeUnknown;\r | |
188 | break;\r | |
189 | }\r | |
190 | \r | |
191 | for (Dimm = 0; Dimm < NumSlots; Dimm++) {\r | |
192 | //\r | |
193 | // Memory Device Locator\r | |
194 | //\r | |
195 | TokenToGet = DevLocator[Dimm];\r | |
196 | MemDevice = SmbiosMiscGetString (TokenToGet);\r | |
197 | MemDeviceStrLen = StrLen(MemDevice);\r | |
198 | if (MemDeviceStrLen > SMBIOS_STRING_MAX_LENGTH) {\r | |
199 | return EFI_UNSUPPORTED;\r | |
200 | }\r | |
201 | \r | |
202 | TokenToGet = DevLocator[Dimm];\r | |
203 | MemDevice = SmbiosMiscGetString (TokenToGet);\r | |
204 | MemDeviceStrLen = StrLen(MemDevice);\r | |
205 | if (MemDeviceStrLen > SMBIOS_STRING_MAX_LENGTH) {\r | |
206 | return EFI_UNSUPPORTED;\r | |
207 | }\r | |
208 | \r | |
209 | //\r | |
210 | // Memory Bank Locator\r | |
211 | //\r | |
212 | TokenToGet = BankLocator[Dimm];\r | |
213 | MemBankLocator = SmbiosMiscGetString (TokenToGet);\r | |
214 | MemBankLocatorStrLen = StrLen(MemBankLocator);\r | |
215 | if (MemBankLocatorStrLen > SMBIOS_STRING_MAX_LENGTH) {\r | |
216 | return EFI_UNSUPPORTED;\r | |
217 | }\r | |
218 | \r | |
219 | //\r | |
220 | // Memory Manufacturer\r | |
221 | //\r | |
222 | TokenToGet = STRING_TOKEN (STR_MISC_MEM_MANUFACTURER);\r | |
223 | MemManufacturer = SmbiosMiscGetString (TokenToGet);\r | |
224 | MemManufacturerStrLen = StrLen(MemManufacturer);\r | |
225 | if (MemManufacturerStrLen > SMBIOS_STRING_MAX_LENGTH) {\r | |
226 | return EFI_UNSUPPORTED;\r | |
227 | }\r | |
228 | \r | |
229 | //\r | |
230 | // Memory Serial Number\r | |
231 | //\r | |
232 | TokenToGet = STRING_TOKEN (STR_MISC_MEM_SERIAL_NO);\r | |
233 | MemSerialNumber = SmbiosMiscGetString (TokenToGet);\r | |
234 | MemSerialNumberStrLen = StrLen(MemSerialNumber);\r | |
235 | if (MemSerialNumberStrLen > SMBIOS_STRING_MAX_LENGTH) {\r | |
236 | return EFI_UNSUPPORTED;\r | |
237 | }\r | |
238 | \r | |
239 | //\r | |
240 | // Memory Asset Tag Number\r | |
241 | //\r | |
242 | TokenToGet = STRING_TOKEN (STR_MISC_MEM_ASSET_TAG);\r | |
243 | MemAssetTag = SmbiosMiscGetString (TokenToGet);\r | |
244 | MemAssetTagStrLen = StrLen(MemAssetTag);\r | |
245 | if (MemAssetTagStrLen > SMBIOS_STRING_MAX_LENGTH) {\r | |
246 | return EFI_UNSUPPORTED;\r | |
247 | }\r | |
248 | \r | |
249 | //\r | |
250 | // Memory Part Number\r | |
251 | //\r | |
252 | TokenToGet = STRING_TOKEN (STR_MISC_MEM_PART_NUMBER);\r | |
253 | MemPartNumber = SmbiosMiscGetString (TokenToGet);\r | |
254 | MemPartNumberStrLen = StrLen(MemPartNumber);\r | |
255 | if (MemPartNumberStrLen > SMBIOS_STRING_MAX_LENGTH) {\r | |
256 | return EFI_UNSUPPORTED;\r | |
257 | }\r | |
258 | \r | |
259 | //\r | |
260 | // Two zeros following the last string.\r | |
261 | //\r | |
262 | SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE17) + MemDeviceStrLen + 1 + MemBankLocatorStrLen + 1 + MemManufacturerStrLen + 1 + MemSerialNumberStrLen + 1 + MemAssetTagStrLen+1 + MemPartNumberStrLen + 1 + 1);\r | |
263 | ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE17) + MemDeviceStrLen + 1 + MemBankLocatorStrLen + 1 + MemManufacturerStrLen + 1 + MemSerialNumberStrLen + 1 + MemAssetTagStrLen+1 + MemPartNumberStrLen + 1 + 1);\r | |
264 | \r | |
265 | SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_DEVICE;\r | |
266 | SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE17);\r | |
267 | \r | |
268 | //\r | |
269 | // Make handle chosen by smbios protocol.add automatically.\r | |
270 | //\r | |
271 | SmbiosRecord->Hdr.Handle = 0;\r | |
272 | \r | |
273 | //\r | |
274 | // Memory Array Handle will be the 3rd optional string following the formatted structure.\r | |
275 | //\r | |
276 | GetType16Hndl( Smbios, &Type16Handle);\r | |
277 | SmbiosRecord->MemoryArrayHandle = Type16Handle;\r | |
278 | \r | |
279 | //\r | |
280 | // Memory Size\r | |
281 | //\r | |
282 | if ((MemInfoHob->MemInfoData.dimmSize[Dimm])!=0){\r | |
283 | SmbiosRecord->TotalWidth = 32;\r | |
284 | SmbiosRecord->DataWidth = 32;\r | |
285 | SmbiosRecord->Size = MemInfoHob->MemInfoData.dimmSize[Dimm];\r | |
286 | SmbiosRecord->Speed = DdrFreq;\r | |
287 | SmbiosRecord->ConfiguredMemoryClockSpeed = DdrFreq;\r | |
288 | SmbiosRecord->FormFactor = EfiMemoryFormFactorDimm;\r | |
289 | }\r | |
290 | \r | |
291 | SmbiosRecord->DeviceSet =(UINT8) ForType17InputData->MemoryDeviceSet;\r | |
292 | SmbiosRecord->DeviceLocator= 1;\r | |
293 | SmbiosRecord->BankLocator = 2;\r | |
294 | \r | |
295 | \r | |
296 | SmbiosRecord->Manufacturer = 3;\r | |
297 | SmbiosRecord->SerialNumber= 4;\r | |
298 | SmbiosRecord->AssetTag= 5;\r | |
299 | SmbiosRecord->PartNumber= 6;\r | |
300 | SmbiosRecord->Attributes = (UINT8) ForType17InputData->MemoryState;\r | |
301 | SmbiosRecord->MemoryType = MemoryType;\r | |
302 | \r | |
303 | OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);\r | |
304 | UnicodeStrToAsciiStr(MemDevice, OptionalStrStart);\r | |
305 | UnicodeStrToAsciiStr(MemBankLocator, OptionalStrStart + MemDeviceStrLen + 1);\r | |
306 | UnicodeStrToAsciiStr(MemManufacturer, OptionalStrStart + MemDeviceStrLen + 1 + MemBankLocatorStrLen + 1);\r | |
307 | UnicodeStrToAsciiStr(MemSerialNumber, OptionalStrStart + MemDeviceStrLen + 1 + MemBankLocatorStrLen + 1 + MemManufacturerStrLen + 1);\r | |
308 | UnicodeStrToAsciiStr(MemAssetTag, OptionalStrStart + MemDeviceStrLen + 1 + MemBankLocatorStrLen + 1 + MemManufacturerStrLen + 1 + MemSerialNumberStrLen + 1);\r | |
309 | UnicodeStrToAsciiStr(MemPartNumber, OptionalStrStart + MemDeviceStrLen + 1 + MemBankLocatorStrLen + 1 + MemManufacturerStrLen + 1 + MemSerialNumberStrLen + 1+ MemAssetTagStrLen+1 );\r | |
310 | \r | |
311 | //\r | |
312 | // Now we have got the full smbios record, call smbios protocol to add this record.\r | |
313 | //\r | |
314 | SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r | |
315 | Status = Smbios-> Add(\r | |
316 | Smbios,\r | |
317 | NULL,\r | |
318 | &SmbiosHandle,\r | |
319 | (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord\r | |
320 | );\r | |
321 | FreePool(SmbiosRecord);\r | |
322 | }\r | |
323 | return Status;\r | |
324 | }\r |