]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c
NetworkPkg:Fix the issue Http boot hang when network failed.
[mirror_edk2.git] / MdeModulePkg / Universal / SmbiosMeasurementDxe / SmbiosMeasurementDxe.c
CommitLineData
c00a0c87
JY
1/** @file\r
2 This driver measures SMBIOS table to TPM.\r
14c218b3 3\r
c00a0c87 4Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
14c218b3
SZ
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
c00a0c87
JY
12\r
13**/\r
14\r
15#include <PiDxe.h>\r
16\r
17#include <Protocol/Smbios.h>\r
18#include <IndustryStandard/SmBios.h>\r
19#include <IndustryStandard/UefiTcgPlatform.h>\r
20#include <Guid/EventGroup.h>\r
21#include <Guid/SmBios.h>\r
22#include <Library/DebugLib.h>\r
23#include <Library/UefiDriverEntryPoint.h>\r
24#include <Library/UefiLib.h>\r
25#include <Library/BaseLib.h>\r
26#include <Library/BaseMemoryLib.h>\r
27#include <Library/MemoryAllocationLib.h>\r
28#include <Library/UefiBootServicesTableLib.h>\r
29#include <Library/TpmMeasurementLib.h>\r
30\r
31#define FIELD_SIZE_OF(TYPE, Field) ((UINTN)sizeof(((TYPE *)0)->Field))\r
32\r
33typedef struct {\r
34 UINT8 Type;\r
35 UINTN Offset;\r
36 UINTN Size;\r
37 UINT32 Flags;\r
38} SMBIOS_FILTER_TABLE;\r
39#define SMBIOS_FILTER_TABLE_FLAG_IS_STRING BIT0\r
40\r
41typedef struct {\r
42 UINT8 Type;\r
43 SMBIOS_FILTER_TABLE *Filter; // NULL means all fields\r
44 UINTN FilterCount;\r
45} SMBIOS_FILTER_STRUCT;\r
46\r
47//\r
48// Platform Specific Policy\r
49//\r
50SMBIOS_FILTER_TABLE mSmbiosFilterType1BlackList[] = {\r
51 {0x01, OFFSET_OF(SMBIOS_TABLE_TYPE1, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE1, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
52 {0x01, OFFSET_OF(SMBIOS_TABLE_TYPE1, Uuid), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE1, Uuid), 0},\r
53 {0x01, OFFSET_OF(SMBIOS_TABLE_TYPE1, WakeUpType), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE1, WakeUpType), 0},\r
54};\r
55SMBIOS_FILTER_TABLE mSmbiosFilterType2BlackList[] = {\r
56 {0x02, OFFSET_OF(SMBIOS_TABLE_TYPE2, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE2, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
57 {0x02, OFFSET_OF(SMBIOS_TABLE_TYPE2, LocationInChassis), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE2, LocationInChassis), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
58};\r
59SMBIOS_FILTER_TABLE mSmbiosFilterType3BlackList[] = {\r
60 {0x03, OFFSET_OF(SMBIOS_TABLE_TYPE3, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE3, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
61 {0x03, OFFSET_OF(SMBIOS_TABLE_TYPE3, AssetTag), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE3, AssetTag), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
62};\r
63SMBIOS_FILTER_TABLE mSmbiosFilterType4BlackList[] = {\r
64 {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
65 {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, AssetTag), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, AssetTag), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
66 {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, PartNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, PartNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
67 {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, CoreCount), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, CoreCount), 0},\r
68 {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, EnabledCoreCount), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, EnabledCoreCount), 0},\r
69 {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, ThreadCount), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, ThreadCount), 0},\r
70 {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, CoreCount2), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, CoreCount2), 0},\r
71 {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, EnabledCoreCount2), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, EnabledCoreCount2), 0},\r
72 {0x04, OFFSET_OF(SMBIOS_TABLE_TYPE4, ThreadCount2), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE4, ThreadCount2), 0},\r
73};\r
74SMBIOS_FILTER_TABLE mSmbiosFilterType17BlackList[] = {\r
75 {0x11, OFFSET_OF(SMBIOS_TABLE_TYPE17, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE17, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
76 {0x11, OFFSET_OF(SMBIOS_TABLE_TYPE17, AssetTag), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE17, AssetTag), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
77 {0x11, OFFSET_OF(SMBIOS_TABLE_TYPE17, PartNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE17, PartNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
78};\r
79SMBIOS_FILTER_TABLE mSmbiosFilterType22BlackList[] = {\r
80 {0x16, OFFSET_OF(SMBIOS_TABLE_TYPE22, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE22, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
81 {0x16, OFFSET_OF(SMBIOS_TABLE_TYPE22, SBDSSerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE22, SBDSSerialNumber), 0},\r
82 {0x16, OFFSET_OF(SMBIOS_TABLE_TYPE22, SBDSManufactureDate), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE22, SBDSManufactureDate), 0},\r
83};\r
84SMBIOS_FILTER_TABLE mSmbiosFilterType23BlackList[] = {\r
85 {0x17, OFFSET_OF(SMBIOS_TABLE_TYPE23, ResetCount), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE23, ResetCount), 0},\r
86};\r
87SMBIOS_FILTER_TABLE mSmbiosFilterType39BlackList[] = {\r
88 {0x27, OFFSET_OF(SMBIOS_TABLE_TYPE39, SerialNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE39, SerialNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
89 {0x27, OFFSET_OF(SMBIOS_TABLE_TYPE39, AssetTagNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE39, AssetTagNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
90 {0x27, OFFSET_OF(SMBIOS_TABLE_TYPE39, ModelPartNumber), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE39, ModelPartNumber), SMBIOS_FILTER_TABLE_FLAG_IS_STRING},\r
91};\r
92\r
93SMBIOS_FILTER_STRUCT mSmbiosFilterStandardTableBlackList[] = {\r
94 {0x01, mSmbiosFilterType1BlackList, sizeof(mSmbiosFilterType1BlackList)/sizeof(mSmbiosFilterType1BlackList[0])},\r
95 {0x02, mSmbiosFilterType2BlackList, sizeof(mSmbiosFilterType2BlackList)/sizeof(mSmbiosFilterType2BlackList[0])},\r
96 {0x03, mSmbiosFilterType3BlackList, sizeof(mSmbiosFilterType3BlackList)/sizeof(mSmbiosFilterType3BlackList[0])},\r
97 {0x04, mSmbiosFilterType4BlackList, sizeof(mSmbiosFilterType4BlackList)/sizeof(mSmbiosFilterType4BlackList[0])},\r
98 {0x0B, NULL, 0},\r
99 {0x0F, NULL, 0},\r
100 {0x11, mSmbiosFilterType17BlackList, sizeof(mSmbiosFilterType17BlackList)/sizeof(mSmbiosFilterType17BlackList[0])},\r
101 {0x12, NULL, 0},\r
102 {0x16, mSmbiosFilterType22BlackList, sizeof(mSmbiosFilterType22BlackList)/sizeof(mSmbiosFilterType22BlackList[0])},\r
103 {0x17, mSmbiosFilterType23BlackList, sizeof(mSmbiosFilterType23BlackList)/sizeof(mSmbiosFilterType23BlackList[0])},\r
104 {0x1F, NULL, 0},\r
105 {0x21, NULL, 0},\r
106 {0x27, mSmbiosFilterType39BlackList, sizeof(mSmbiosFilterType39BlackList)/sizeof(mSmbiosFilterType39BlackList[0])},\r
107};\r
108\r
109EFI_SMBIOS_PROTOCOL *mSmbios;\r
110UINTN mMaxLen;\r
111\r
112/**\r
113\r
114 This function dump raw data.\r
115\r
116 @param Data raw data\r
117 @param Size raw data size\r
118\r
119**/\r
120VOID\r
121InternalDumpData (\r
122 IN UINT8 *Data,\r
123 IN UINTN Size\r
124 )\r
125{\r
126 UINTN Index;\r
127 for (Index = 0; Index < Size; Index++) {\r
e293bc24 128 DEBUG ((EFI_D_VERBOSE, "%02x", (UINTN)Data[Index]));\r
c00a0c87
JY
129 }\r
130}\r
131\r
132/**\r
133\r
134 This function dump raw data with colume format.\r
135\r
136 @param Data raw data\r
137 @param Size raw data size\r
138\r
139**/\r
140VOID\r
141InternalDumpHex (\r
142 IN UINT8 *Data,\r
143 IN UINTN Size\r
144 )\r
145{\r
146 UINTN Index;\r
147 UINTN Count;\r
148 UINTN Left;\r
149\r
150#define COLUME_SIZE (16 * 2)\r
151\r
152 Count = Size / COLUME_SIZE;\r
153 Left = Size % COLUME_SIZE;\r
154 for (Index = 0; Index < Count; Index++) {\r
e293bc24 155 DEBUG ((EFI_D_VERBOSE, "%04x: ", Index * COLUME_SIZE));\r
c00a0c87 156 InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE);\r
e293bc24 157 DEBUG ((EFI_D_VERBOSE, "\n"));\r
c00a0c87
JY
158 }\r
159\r
160 if (Left != 0) {\r
e293bc24 161 DEBUG ((EFI_D_VERBOSE, "%04x: ", Index * COLUME_SIZE));\r
c00a0c87 162 InternalDumpData (Data + Index * COLUME_SIZE, Left);\r
e293bc24 163 DEBUG ((EFI_D_VERBOSE, "\n"));\r
c00a0c87
JY
164 }\r
165}\r
166\r
167\r
168/**\r
169\r
170 This function get filter structure by SMBIOS type.\r
171\r
172 @param Type SMBIOS type\r
173\r
174**/\r
175SMBIOS_FILTER_STRUCT *\r
176GetFilterStructByType (\r
177 IN UINT8 Type\r
178 )\r
179{\r
180 UINTN Index;\r
181 for (Index = 0; Index < sizeof(mSmbiosFilterStandardTableBlackList)/sizeof(mSmbiosFilterStandardTableBlackList[0]); Index++) {\r
182 if (mSmbiosFilterStandardTableBlackList[Index].Type == Type) {\r
183 return &mSmbiosFilterStandardTableBlackList[Index];\r
184 }\r
185 }\r
186 return NULL;\r
187}\r
188\r
189/**\r
190\r
191 This function get SMBIOS string in SMBIOS table.\r
192\r
193 @param Head SMBIOS table head\r
194 @param StringId SMBIOS string ID\r
195 @param StringLen length of SMBIOS string\r
196\r
197 @return SMBIOS string data\r
198**/\r
199CHAR8 *\r
200GetSmbiosStringById (\r
201 IN EFI_SMBIOS_TABLE_HEADER *Head,\r
202 IN SMBIOS_TABLE_STRING StringId,\r
203 OUT UINTN *StringLen\r
204 )\r
205{\r
206 UINTN Size;\r
207 UINTN StrLen;\r
208 CHAR8 *CharInStr;\r
209 UINTN StringsNumber;\r
210 CHAR8 *String;\r
211\r
212 CharInStr = (CHAR8 *)Head + Head->Length;\r
213 Size = Head->Length;\r
214 StringsNumber = 0;\r
215 StrLen = 0;\r
216 //\r
217 // look for the two consecutive zeros, check the string limit by the way.\r
218 //\r
219 String = NULL;\r
14c218b3 220 while (*CharInStr != 0 || *(CharInStr+1) != 0) {\r
c00a0c87
JY
221 if (*CharInStr == 0) {\r
222 Size += 1;\r
223 CharInStr++;\r
224 }\r
225 String = CharInStr;\r
226\r
227 for (StrLen = 0 ; StrLen < mMaxLen; StrLen++) {\r
228 if (*(CharInStr+StrLen) == 0) {\r
229 break;\r
230 }\r
231 }\r
232 *StringLen = StrLen;\r
233\r
234 if (StrLen == mMaxLen) {\r
235 return NULL;\r
236 }\r
237\r
238 //\r
239 // forward the pointer\r
240 //\r
241 CharInStr += StrLen;\r
242 Size += StrLen;\r
243 StringsNumber += 1;\r
244 if (StringsNumber == StringId) {\r
245 break;\r
246 }\r
247 }\r
248\r
249 return String;\r
250}\r
251\r
252/**\r
253\r
254 This function update SMBIOS table based on policy.\r
255\r
256 @param TableEntry SMBIOS table\r
257 @param TableEntrySize SMBIOS table size\r
258\r
259**/\r
260VOID\r
261FilterSmbiosEntry (\r
262 IN OUT VOID *TableEntry,\r
263 IN UINTN TableEntrySize\r
264 )\r
265{\r
266 SMBIOS_FILTER_STRUCT *FilterStruct;\r
267 SMBIOS_FILTER_TABLE *Filter;\r
268 UINTN Index;\r
269 SMBIOS_TABLE_STRING StringId;\r
270 CHAR8 *String;\r
271 UINTN StringLen;\r
272\r
273 DEBUG ((EFI_D_INFO, "Smbios Table (Type - %d):\n", ((SMBIOS_STRUCTURE *)TableEntry)->Type));\r
e293bc24 274 DEBUG_CODE (InternalDumpHex (TableEntry, TableEntrySize););\r
c00a0c87
JY
275\r
276 FilterStruct = GetFilterStructByType (((SMBIOS_STRUCTURE *)TableEntry)->Type);\r
277 if (FilterStruct != NULL) {\r
278 if (FilterStruct->Filter == NULL || FilterStruct->FilterCount == 0) {\r
279 // zero all table entries, except header\r
280 ZeroMem ((UINT8 *)TableEntry + sizeof(SMBIOS_STRUCTURE), TableEntrySize - sizeof(SMBIOS_STRUCTURE));\r
281 } else {\r
282 Filter = FilterStruct->Filter;\r
283 for (Index = 0; Index < FilterStruct->FilterCount; Index++) {\r
284 if ((Filter[Index].Flags & SMBIOS_FILTER_TABLE_FLAG_IS_STRING) != 0) {\r
285 CopyMem (&StringId, (UINT8 *)TableEntry + Filter[Index].Offset, sizeof(StringId));\r
286 if (StringId != 0) {\r
287 // set ' ' for string field\r
288 String = GetSmbiosStringById (TableEntry, StringId, &StringLen);\r
8aa6ebe8 289 ASSERT (String != NULL);\r
c00a0c87
JY
290 //DEBUG ((EFI_D_INFO,"StrId(0x%x)-%a(%d)\n", StringId, String, StringLen));\r
291 SetMem (String, StringLen, ' ');\r
292 }\r
293 }\r
294 // zero non-string field\r
295 ZeroMem ((UINT8 *)TableEntry + Filter[Index].Offset, Filter[Index].Size);\r
296 }\r
297 }\r
298 }\r
299\r
300 DEBUG ((EFI_D_INFO, "Filter Smbios Table (Type - %d):\n", ((SMBIOS_STRUCTURE *)TableEntry)->Type));\r
e293bc24 301 DEBUG_CODE (InternalDumpHex (TableEntry, TableEntrySize););\r
c00a0c87
JY
302}\r
303\r
304/**\r
305\r
306 Get the full size of SMBIOS structure including optional strings that follow the formatted structure.\r
307\r
308 @param Head Pointer to the beginning of SMBIOS structure.\r
309 @param NumberOfStrings The returned number of optional strings that follow the formatted structure.\r
14c218b3 310\r
c00a0c87
JY
311 @return Size The returned size.\r
312**/\r
313UINTN\r
314GetSmbiosStructureSize (\r
315 IN EFI_SMBIOS_TABLE_HEADER *Head,\r
316 OUT UINTN *NumberOfStrings\r
317 )\r
318{\r
319 UINTN Size;\r
320 UINTN StrLen;\r
321 CHAR8 *CharInStr;\r
322 UINTN StringsNumber;\r
323\r
324 CharInStr = (CHAR8 *)Head + Head->Length;\r
325 Size = Head->Length;\r
326 StringsNumber = 0;\r
327 StrLen = 0;\r
328 //\r
329 // look for the two consecutive zeros, check the string limit by the way.\r
330 //\r
14c218b3 331 while (*CharInStr != 0 || *(CharInStr+1) != 0) {\r
c00a0c87
JY
332 if (*CharInStr == 0) {\r
333 Size += 1;\r
334 CharInStr++;\r
335 }\r
336\r
337 for (StrLen = 0 ; StrLen < mMaxLen; StrLen++) {\r
338 if (*(CharInStr+StrLen) == 0) {\r
339 break;\r
340 }\r
341 }\r
342\r
343 if (StrLen == mMaxLen) {\r
344 return 0;\r
345 }\r
346\r
347 //\r
348 // forward the pointer\r
349 //\r
350 CharInStr += StrLen;\r
351 Size += StrLen;\r
352 StringsNumber += 1;\r
353 }\r
354\r
355 //\r
356 // count ending two zeros.\r
357 //\r
358 Size += 2;\r
359\r
360 if (NumberOfStrings != NULL) {\r
361 *NumberOfStrings = StringsNumber;\r
362 }\r
363 return Size;\r
364}\r
365\r
366/**\r
367\r
368 This function returns full SMBIOS table length.\r
369\r
370 @param TableAddress SMBIOS table based address\r
371 @param TableMaximumSize Maximum size of SMBIOS table\r
372\r
373 @return SMBIOS table length\r
374\r
375**/\r
376UINTN\r
377GetSmbiosTableLength (\r
378 IN VOID *TableAddress,\r
379 IN UINTN TableMaximumSize\r
380 )\r
381{\r
382 VOID *TableEntry;\r
383 VOID *TableAddressEnd;\r
384 UINTN TableEntryLength;\r
385\r
386 TableAddressEnd = (VOID *)((UINTN)TableAddress + TableMaximumSize);\r
387 TableEntry = TableAddress;\r
388 while (TableEntry < TableAddressEnd) {\r
389 TableEntryLength = GetSmbiosStructureSize (TableEntry, NULL);\r
390 if (TableEntryLength == 0) {\r
391 break;\r
392 }\r
393 if (((SMBIOS_STRUCTURE *)TableEntry)->Type == 127) {\r
394 TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength);\r
395 break;\r
396 }\r
397 TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength);\r
398 }\r
399\r
400 return ((UINTN)TableEntry - (UINTN)TableAddress);\r
401}\r
402\r
403/**\r
404\r
405 This function updatess full SMBIOS table length.\r
406\r
407 @param TableAddress SMBIOS table based address\r
408 @param TableLength SMBIOS table length\r
409\r
410**/\r
411VOID\r
412FilterSmbiosTable (\r
413 IN OUT VOID *TableAddress,\r
414 IN UINTN TableLength\r
415 )\r
416{\r
417 VOID *TableAddressEnd;\r
418 VOID *TableEntry;\r
419 UINTN TableEntryLength;\r
420\r
421 TableEntry = TableAddress;\r
422 TableAddressEnd = (VOID *)((UINTN)TableAddress + TableLength);\r
423 while ((UINTN)TableEntry < (UINTN)TableAddressEnd) {\r
424 TableEntryLength = GetSmbiosStructureSize (TableEntry, NULL);\r
425 if (TableEntryLength == 0) {\r
426 break;\r
427 }\r
428\r
429 FilterSmbiosEntry (TableEntry, TableEntryLength);\r
430\r
431 TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength);\r
432 }\r
433}\r
434\r
435/**\r
35a19d48
SZ
436 Measure SMBIOS with EV_EFI_HANDOFF_TABLES to PCR[1].\r
437\r
438 @param[in] Event Event whose notification function is being invoked.\r
439 @param[in] Context Pointer to the notification function's context.\r
440\r
c00a0c87
JY
441**/\r
442VOID\r
443EFIAPI\r
444MeasureSmbiosTable (\r
445 IN EFI_EVENT Event,\r
446 IN VOID *Context\r
447 )\r
448{\r
449 EFI_STATUS Status;\r
450 EFI_HANDOFF_TABLE_POINTERS HandoffTables;\r
451 SMBIOS_TABLE_ENTRY_POINT *SmbiosTable;\r
452 SMBIOS_TABLE_3_0_ENTRY_POINT *Smbios3Table;\r
453 VOID *SmbiosTableAddress;\r
454 VOID *TableAddress;\r
455 UINTN TableLength;\r
456\r
457 SmbiosTable = NULL;\r
458 Smbios3Table = NULL;\r
459 SmbiosTableAddress = NULL;\r
460 TableLength = 0;\r
461\r
462 if (mSmbios->MajorVersion >= 3) {\r
463 Status = EfiGetSystemConfigurationTable (\r
464 &gEfiSmbios3TableGuid,\r
465 (VOID **) &Smbios3Table\r
466 );\r
467 if (!EFI_ERROR (Status)) {\r
468 DEBUG ((EFI_D_INFO, "Smbios3Table:\n"));\r
469 DEBUG ((EFI_D_INFO, " AnchorString - '%c%c%c%c%c'\n",\r
470 Smbios3Table->AnchorString[0],\r
471 Smbios3Table->AnchorString[1],\r
472 Smbios3Table->AnchorString[2],\r
473 Smbios3Table->AnchorString[3],\r
474 Smbios3Table->AnchorString[4]\r
475 ));\r
476 DEBUG ((EFI_D_INFO, " EntryPointStructureChecksum - 0x%02x\n", Smbios3Table->EntryPointStructureChecksum));\r
477 DEBUG ((EFI_D_INFO, " EntryPointLength - 0x%02x\n", Smbios3Table->EntryPointLength));\r
478 DEBUG ((EFI_D_INFO, " MajorVersion - 0x%02x\n", Smbios3Table->MajorVersion));\r
479 DEBUG ((EFI_D_INFO, " MinorVersion - 0x%02x\n", Smbios3Table->MinorVersion));\r
480 DEBUG ((EFI_D_INFO, " DocRev - 0x%02x\n", Smbios3Table->DocRev));\r
481 DEBUG ((EFI_D_INFO, " EntryPointRevision - 0x%02x\n", Smbios3Table->EntryPointRevision));\r
482 DEBUG ((EFI_D_INFO, " TableMaximumSize - 0x%08x\n", Smbios3Table->TableMaximumSize));\r
483 DEBUG ((EFI_D_INFO, " TableAddress - 0x%016lx\n", Smbios3Table->TableAddress));\r
484 }\r
485 }\r
3c394a67
SZ
486\r
487 if (Smbios3Table == NULL) {\r
c00a0c87
JY
488 Status = EfiGetSystemConfigurationTable (\r
489 &gEfiSmbiosTableGuid,\r
490 (VOID **) &SmbiosTable\r
491 );\r
492 if (!EFI_ERROR (Status)) {\r
493 DEBUG ((EFI_D_INFO, "SmbiosTable:\n"));\r
494 DEBUG ((EFI_D_INFO, " AnchorString - '%c%c%c%c'\n",\r
3c394a67
SZ
495 SmbiosTable->AnchorString[0],\r
496 SmbiosTable->AnchorString[1],\r
497 SmbiosTable->AnchorString[2],\r
498 SmbiosTable->AnchorString[3]\r
c00a0c87
JY
499 ));\r
500 DEBUG ((EFI_D_INFO, " EntryPointStructureChecksum - 0x%02x\n", SmbiosTable->EntryPointStructureChecksum));\r
501 DEBUG ((EFI_D_INFO, " EntryPointLength - 0x%02x\n", SmbiosTable->EntryPointLength));\r
502 DEBUG ((EFI_D_INFO, " MajorVersion - 0x%02x\n", SmbiosTable->MajorVersion));\r
503 DEBUG ((EFI_D_INFO, " MinorVersion - 0x%02x\n", SmbiosTable->MinorVersion));\r
504 DEBUG ((EFI_D_INFO, " MaxStructureSize - 0x%08x\n", SmbiosTable->MaxStructureSize));\r
505 DEBUG ((EFI_D_INFO, " EntryPointRevision - 0x%02x\n", SmbiosTable->EntryPointRevision));\r
506 DEBUG ((EFI_D_INFO, " FormattedArea - '%c%c%c%c%c'\n",\r
507 SmbiosTable->FormattedArea[0],\r
508 SmbiosTable->FormattedArea[1],\r
509 SmbiosTable->FormattedArea[2],\r
510 SmbiosTable->FormattedArea[3],\r
511 SmbiosTable->FormattedArea[4]\r
512 ));\r
513 DEBUG ((EFI_D_INFO, " IntermediateAnchorString - '%c%c%c%c%c'\n",\r
514 SmbiosTable->IntermediateAnchorString[0],\r
515 SmbiosTable->IntermediateAnchorString[1],\r
516 SmbiosTable->IntermediateAnchorString[2],\r
517 SmbiosTable->IntermediateAnchorString[3],\r
518 SmbiosTable->IntermediateAnchorString[4]\r
519 ));\r
520 DEBUG ((EFI_D_INFO, " IntermediateChecksum - 0x%02x\n", SmbiosTable->IntermediateChecksum));\r
521 DEBUG ((EFI_D_INFO, " TableLength - 0x%04x\n", SmbiosTable->TableLength));\r
522 DEBUG ((EFI_D_INFO, " TableAddress - 0x%08x\n", SmbiosTable->TableAddress));\r
523 DEBUG ((EFI_D_INFO, " NumberOfSmbiosStructures - 0x%04x\n", SmbiosTable->NumberOfSmbiosStructures));\r
524 DEBUG ((EFI_D_INFO, " SmbiosBcdRevision - 0x%02x\n", SmbiosTable->SmbiosBcdRevision));\r
525 }\r
3c394a67 526 }\r
c00a0c87
JY
527\r
528 if (Smbios3Table != NULL) {\r
529 SmbiosTableAddress = (VOID *)(UINTN)Smbios3Table->TableAddress;\r
530 TableLength = GetSmbiosTableLength (SmbiosTableAddress, Smbios3Table->TableMaximumSize);\r
531 } else if (SmbiosTable != NULL) {\r
532 SmbiosTableAddress = (VOID *)(UINTN)SmbiosTable->TableAddress;\r
533 TableLength = SmbiosTable->TableLength;\r
534 }\r
535\r
536 if (SmbiosTableAddress != NULL) {\r
537 DEBUG ((DEBUG_INFO, "The Smbios Table starts at: 0x%x\n", SmbiosTableAddress));\r
538 DEBUG ((DEBUG_INFO, "The Smbios Table size: 0x%x\n", TableLength));\r
e293bc24 539 DEBUG_CODE (InternalDumpHex ((UINT8 *)(UINTN)SmbiosTableAddress, TableLength););\r
c00a0c87
JY
540\r
541 TableAddress = AllocateCopyPool ((UINTN)TableLength, (VOID *)(UINTN)SmbiosTableAddress);\r
542 if (TableAddress == NULL) {\r
543 return ;\r
544 }\r
545\r
546 FilterSmbiosTable (TableAddress, TableLength);\r
547\r
548 DEBUG ((DEBUG_INFO, "The final Smbios Table starts at: 0x%x\n", TableAddress));\r
549 DEBUG ((DEBUG_INFO, "The final Smbios Table size: 0x%x\n", TableLength));\r
e293bc24 550 DEBUG_CODE (InternalDumpHex (TableAddress, TableLength););\r
c00a0c87
JY
551\r
552 HandoffTables.NumberOfTables = 1;\r
3c394a67
SZ
553 if (Smbios3Table != NULL) {\r
554 CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), &gEfiSmbios3TableGuid);\r
555 HandoffTables.TableEntry[0].VendorTable = Smbios3Table;\r
556 } else {\r
557 CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), &gEfiSmbiosTableGuid);\r
558 HandoffTables.TableEntry[0].VendorTable = SmbiosTable;\r
559 }\r
c00a0c87
JY
560 Status = TpmMeasureAndLogData (\r
561 1, // PCRIndex\r
562 EV_EFI_HANDOFF_TABLES, // EventType\r
563 &HandoffTables, // EventLog\r
564 sizeof (HandoffTables), // LogLen\r
565 TableAddress, // HashData\r
566 TableLength // HashDataLen\r
567 );\r
568 if (EFI_ERROR (Status)) {\r
569 return ;\r
570 }\r
571 }\r
572\r
573 return ;\r
574}\r
575\r
576/**\r
577\r
14c218b3 578 Driver to produce Smbios measurement.\r
c00a0c87
JY
579\r
580 @param ImageHandle Module's image handle\r
581 @param SystemTable Pointer of EFI_SYSTEM_TABLE\r
582\r
35a19d48 583 @return Status returned from EfiCreateEventReadyToBootEx().\r
c00a0c87
JY
584\r
585**/\r
586EFI_STATUS\r
587EFIAPI\r
588SmbiosMeasurementDriverEntryPoint (\r
589 IN EFI_HANDLE ImageHandle,\r
590 IN EFI_SYSTEM_TABLE *SystemTable\r
591 )\r
592{\r
593 EFI_STATUS Status;\r
594 EFI_EVENT Event;\r
595\r
8c1d8735 596 Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **) &mSmbios);\r
c00a0c87
JY
597 ASSERT_EFI_ERROR (Status);\r
598 DEBUG ((DEBUG_INFO, "The Smbios Table Version: %x.%x\n", mSmbios->MajorVersion, mSmbios->MinorVersion));\r
14c218b3 599\r
c00a0c87
JY
600 if (mSmbios->MajorVersion < 2 || (mSmbios->MajorVersion == 2 && mSmbios->MinorVersion < 7)){\r
601 mMaxLen = SMBIOS_STRING_MAX_LENGTH;\r
602 } else if (mSmbios->MajorVersion < 3) {\r
603 //\r
604 // Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string.\r
605 // However, the length of the entire structure table (including all strings) must be reported\r
606 // in the Structure Table Length field of the SMBIOS Structure Table Entry Point,\r
607 // which is a WORD field limited to 65,535 bytes.\r
608 //\r
609 mMaxLen = SMBIOS_TABLE_MAX_LENGTH;\r
610 } else {\r
611 //\r
612 // SMBIOS 3.0 defines the Structure table maximum size as DWORD field limited to 0xFFFFFFFF bytes.\r
613 // Locate the end of string as long as possible.\r
614 //\r
615 mMaxLen = SMBIOS_3_0_TABLE_MAX_LENGTH;\r
616 }\r
617\r
618 //\r
619 // Measure Smbios tables\r
620 //\r
621 Status = EfiCreateEventReadyToBootEx (\r
622 TPL_CALLBACK,\r
623 MeasureSmbiosTable,\r
624 NULL,\r
625 &Event\r
626 );\r
627\r
628 return Status;\r
629}\r