]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c
Move Smbios measurement from TCG driver to Smbios driver.
[mirror_edk2.git] / MdeModulePkg / Universal / SmbiosMeasurementDxe / SmbiosMeasurementDxe.c
CommitLineData
c00a0c87
JY
1/** @file\r
2 This driver measures SMBIOS table to TPM.\r
3 \r
4Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
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
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
128 DEBUG ((EFI_D_INFO, "%02x", (UINTN)Data[Index]));\r
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
155 DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE));\r
156 InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE);\r
157 DEBUG ((EFI_D_INFO, "\n"));\r
158 }\r
159\r
160 if (Left != 0) {\r
161 DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE));\r
162 InternalDumpData (Data + Index * COLUME_SIZE, Left);\r
163 DEBUG ((EFI_D_INFO, "\n"));\r
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
220 while (*CharInStr != 0 || *(CharInStr+1) != 0) { \r
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
274 InternalDumpHex (TableEntry, TableEntrySize);\r
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
289 //DEBUG ((EFI_D_INFO,"StrId(0x%x)-%a(%d)\n", StringId, String, StringLen));\r
290 SetMem (String, StringLen, ' ');\r
291 }\r
292 }\r
293 // zero non-string field\r
294 ZeroMem ((UINT8 *)TableEntry + Filter[Index].Offset, Filter[Index].Size);\r
295 }\r
296 }\r
297 }\r
298\r
299 DEBUG ((EFI_D_INFO, "Filter Smbios Table (Type - %d):\n", ((SMBIOS_STRUCTURE *)TableEntry)->Type));\r
300 InternalDumpHex (TableEntry, TableEntrySize);\r
301}\r
302\r
303/**\r
304\r
305 Get the full size of SMBIOS structure including optional strings that follow the formatted structure.\r
306\r
307 @param Head Pointer to the beginning of SMBIOS structure.\r
308 @param NumberOfStrings The returned number of optional strings that follow the formatted structure.\r
309 \r
310 @return Size The returned size.\r
311**/\r
312UINTN\r
313GetSmbiosStructureSize (\r
314 IN EFI_SMBIOS_TABLE_HEADER *Head,\r
315 OUT UINTN *NumberOfStrings\r
316 )\r
317{\r
318 UINTN Size;\r
319 UINTN StrLen;\r
320 CHAR8 *CharInStr;\r
321 UINTN StringsNumber;\r
322\r
323 CharInStr = (CHAR8 *)Head + Head->Length;\r
324 Size = Head->Length;\r
325 StringsNumber = 0;\r
326 StrLen = 0;\r
327 //\r
328 // look for the two consecutive zeros, check the string limit by the way.\r
329 //\r
330 while (*CharInStr != 0 || *(CharInStr+1) != 0) { \r
331 if (*CharInStr == 0) {\r
332 Size += 1;\r
333 CharInStr++;\r
334 }\r
335\r
336 for (StrLen = 0 ; StrLen < mMaxLen; StrLen++) {\r
337 if (*(CharInStr+StrLen) == 0) {\r
338 break;\r
339 }\r
340 }\r
341\r
342 if (StrLen == mMaxLen) {\r
343 return 0;\r
344 }\r
345\r
346 //\r
347 // forward the pointer\r
348 //\r
349 CharInStr += StrLen;\r
350 Size += StrLen;\r
351 StringsNumber += 1;\r
352 }\r
353\r
354 //\r
355 // count ending two zeros.\r
356 //\r
357 Size += 2;\r
358\r
359 if (NumberOfStrings != NULL) {\r
360 *NumberOfStrings = StringsNumber;\r
361 }\r
362 return Size;\r
363}\r
364\r
365/**\r
366\r
367 This function returns full SMBIOS table length.\r
368\r
369 @param TableAddress SMBIOS table based address\r
370 @param TableMaximumSize Maximum size of SMBIOS table\r
371\r
372 @return SMBIOS table length\r
373\r
374**/\r
375UINTN\r
376GetSmbiosTableLength (\r
377 IN VOID *TableAddress,\r
378 IN UINTN TableMaximumSize\r
379 )\r
380{\r
381 VOID *TableEntry;\r
382 VOID *TableAddressEnd;\r
383 UINTN TableEntryLength;\r
384\r
385 TableAddressEnd = (VOID *)((UINTN)TableAddress + TableMaximumSize);\r
386 TableEntry = TableAddress;\r
387 while (TableEntry < TableAddressEnd) {\r
388 TableEntryLength = GetSmbiosStructureSize (TableEntry, NULL);\r
389 if (TableEntryLength == 0) {\r
390 break;\r
391 }\r
392 if (((SMBIOS_STRUCTURE *)TableEntry)->Type == 127) {\r
393 TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength);\r
394 break;\r
395 }\r
396 TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength);\r
397 }\r
398\r
399 return ((UINTN)TableEntry - (UINTN)TableAddress);\r
400}\r
401\r
402/**\r
403\r
404 This function updatess full SMBIOS table length.\r
405\r
406 @param TableAddress SMBIOS table based address\r
407 @param TableLength SMBIOS table length\r
408\r
409**/\r
410VOID\r
411FilterSmbiosTable (\r
412 IN OUT VOID *TableAddress,\r
413 IN UINTN TableLength\r
414 )\r
415{\r
416 VOID *TableAddressEnd;\r
417 VOID *TableEntry;\r
418 UINTN TableEntryLength;\r
419\r
420 TableEntry = TableAddress;\r
421 TableAddressEnd = (VOID *)((UINTN)TableAddress + TableLength);\r
422 while ((UINTN)TableEntry < (UINTN)TableAddressEnd) {\r
423 TableEntryLength = GetSmbiosStructureSize (TableEntry, NULL);\r
424 if (TableEntryLength == 0) {\r
425 break;\r
426 }\r
427\r
428 FilterSmbiosEntry (TableEntry, TableEntryLength);\r
429\r
430 TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength);\r
431 }\r
432}\r
433\r
434/**\r
435 Measure SMBIOS with EV_EFI_HANDOFF_TABLES to PCR[1]\r
436**/\r
437VOID\r
438EFIAPI\r
439MeasureSmbiosTable (\r
440 IN EFI_EVENT Event,\r
441 IN VOID *Context\r
442 )\r
443{\r
444 EFI_STATUS Status;\r
445 EFI_HANDOFF_TABLE_POINTERS HandoffTables;\r
446 SMBIOS_TABLE_ENTRY_POINT *SmbiosTable;\r
447 SMBIOS_TABLE_3_0_ENTRY_POINT *Smbios3Table;\r
448 VOID *SmbiosTableAddress;\r
449 VOID *TableAddress;\r
450 UINTN TableLength;\r
451\r
452 SmbiosTable = NULL;\r
453 Smbios3Table = NULL;\r
454 SmbiosTableAddress = NULL;\r
455 TableLength = 0;\r
456\r
457 if (mSmbios->MajorVersion >= 3) {\r
458 Status = EfiGetSystemConfigurationTable (\r
459 &gEfiSmbios3TableGuid,\r
460 (VOID **) &Smbios3Table\r
461 );\r
462 if (!EFI_ERROR (Status)) {\r
463 DEBUG ((EFI_D_INFO, "Smbios3Table:\n"));\r
464 DEBUG ((EFI_D_INFO, " AnchorString - '%c%c%c%c%c'\n",\r
465 Smbios3Table->AnchorString[0],\r
466 Smbios3Table->AnchorString[1],\r
467 Smbios3Table->AnchorString[2],\r
468 Smbios3Table->AnchorString[3],\r
469 Smbios3Table->AnchorString[4]\r
470 ));\r
471 DEBUG ((EFI_D_INFO, " EntryPointStructureChecksum - 0x%02x\n", Smbios3Table->EntryPointStructureChecksum));\r
472 DEBUG ((EFI_D_INFO, " EntryPointLength - 0x%02x\n", Smbios3Table->EntryPointLength));\r
473 DEBUG ((EFI_D_INFO, " MajorVersion - 0x%02x\n", Smbios3Table->MajorVersion));\r
474 DEBUG ((EFI_D_INFO, " MinorVersion - 0x%02x\n", Smbios3Table->MinorVersion));\r
475 DEBUG ((EFI_D_INFO, " DocRev - 0x%02x\n", Smbios3Table->DocRev));\r
476 DEBUG ((EFI_D_INFO, " EntryPointRevision - 0x%02x\n", Smbios3Table->EntryPointRevision));\r
477 DEBUG ((EFI_D_INFO, " TableMaximumSize - 0x%08x\n", Smbios3Table->TableMaximumSize));\r
478 DEBUG ((EFI_D_INFO, " TableAddress - 0x%016lx\n", Smbios3Table->TableAddress));\r
479 }\r
480 }\r
481 Status = EfiGetSystemConfigurationTable (\r
482 &gEfiSmbiosTableGuid,\r
483 (VOID **) &SmbiosTable\r
484 );\r
485 if (!EFI_ERROR (Status)) {\r
486 DEBUG ((EFI_D_INFO, "SmbiosTable:\n"));\r
487 DEBUG ((EFI_D_INFO, " AnchorString - '%c%c%c%c'\n",\r
488 Smbios3Table->AnchorString[0],\r
489 Smbios3Table->AnchorString[1],\r
490 Smbios3Table->AnchorString[2],\r
491 Smbios3Table->AnchorString[3]\r
492 ));\r
493 DEBUG ((EFI_D_INFO, " EntryPointStructureChecksum - 0x%02x\n", SmbiosTable->EntryPointStructureChecksum));\r
494 DEBUG ((EFI_D_INFO, " EntryPointLength - 0x%02x\n", SmbiosTable->EntryPointLength));\r
495 DEBUG ((EFI_D_INFO, " MajorVersion - 0x%02x\n", SmbiosTable->MajorVersion));\r
496 DEBUG ((EFI_D_INFO, " MinorVersion - 0x%02x\n", SmbiosTable->MinorVersion));\r
497 DEBUG ((EFI_D_INFO, " MaxStructureSize - 0x%08x\n", SmbiosTable->MaxStructureSize));\r
498 DEBUG ((EFI_D_INFO, " EntryPointRevision - 0x%02x\n", SmbiosTable->EntryPointRevision));\r
499 DEBUG ((EFI_D_INFO, " FormattedArea - '%c%c%c%c%c'\n",\r
500 SmbiosTable->FormattedArea[0],\r
501 SmbiosTable->FormattedArea[1],\r
502 SmbiosTable->FormattedArea[2],\r
503 SmbiosTable->FormattedArea[3],\r
504 SmbiosTable->FormattedArea[4]\r
505 ));\r
506 DEBUG ((EFI_D_INFO, " IntermediateAnchorString - '%c%c%c%c%c'\n",\r
507 SmbiosTable->IntermediateAnchorString[0],\r
508 SmbiosTable->IntermediateAnchorString[1],\r
509 SmbiosTable->IntermediateAnchorString[2],\r
510 SmbiosTable->IntermediateAnchorString[3],\r
511 SmbiosTable->IntermediateAnchorString[4]\r
512 ));\r
513 DEBUG ((EFI_D_INFO, " IntermediateChecksum - 0x%02x\n", SmbiosTable->IntermediateChecksum));\r
514 DEBUG ((EFI_D_INFO, " TableLength - 0x%04x\n", SmbiosTable->TableLength));\r
515 DEBUG ((EFI_D_INFO, " TableAddress - 0x%08x\n", SmbiosTable->TableAddress));\r
516 DEBUG ((EFI_D_INFO, " NumberOfSmbiosStructures - 0x%04x\n", SmbiosTable->NumberOfSmbiosStructures));\r
517 DEBUG ((EFI_D_INFO, " SmbiosBcdRevision - 0x%02x\n", SmbiosTable->SmbiosBcdRevision));\r
518 }\r
519\r
520 if (Smbios3Table != NULL) {\r
521 SmbiosTableAddress = (VOID *)(UINTN)Smbios3Table->TableAddress;\r
522 TableLength = GetSmbiosTableLength (SmbiosTableAddress, Smbios3Table->TableMaximumSize);\r
523 } else if (SmbiosTable != NULL) {\r
524 SmbiosTableAddress = (VOID *)(UINTN)SmbiosTable->TableAddress;\r
525 TableLength = SmbiosTable->TableLength;\r
526 }\r
527\r
528 if (SmbiosTableAddress != NULL) {\r
529 DEBUG ((DEBUG_INFO, "The Smbios Table starts at: 0x%x\n", SmbiosTableAddress));\r
530 DEBUG ((DEBUG_INFO, "The Smbios Table size: 0x%x\n", TableLength));\r
531 InternalDumpHex ((UINT8 *)(UINTN)SmbiosTableAddress, TableLength);\r
532\r
533 TableAddress = AllocateCopyPool ((UINTN)TableLength, (VOID *)(UINTN)SmbiosTableAddress);\r
534 if (TableAddress == NULL) {\r
535 return ;\r
536 }\r
537\r
538 FilterSmbiosTable (TableAddress, TableLength);\r
539\r
540 DEBUG ((DEBUG_INFO, "The final Smbios Table starts at: 0x%x\n", TableAddress));\r
541 DEBUG ((DEBUG_INFO, "The final Smbios Table size: 0x%x\n", TableLength));\r
542 InternalDumpHex (TableAddress, TableLength);\r
543\r
544 HandoffTables.NumberOfTables = 1;\r
545 HandoffTables.TableEntry[0].VendorGuid = gEfiSmbiosTableGuid;\r
546 HandoffTables.TableEntry[0].VendorTable = SmbiosTable;\r
547 Status = TpmMeasureAndLogData (\r
548 1, // PCRIndex\r
549 EV_EFI_HANDOFF_TABLES, // EventType\r
550 &HandoffTables, // EventLog\r
551 sizeof (HandoffTables), // LogLen\r
552 TableAddress, // HashData\r
553 TableLength // HashDataLen\r
554 );\r
555 if (EFI_ERROR (Status)) {\r
556 return ;\r
557 }\r
558 }\r
559\r
560 return ;\r
561}\r
562\r
563/**\r
564\r
565 Driver to produce Smbios measurement. \r
566\r
567 @param ImageHandle Module's image handle\r
568 @param SystemTable Pointer of EFI_SYSTEM_TABLE\r
569\r
570 @retval EFI_SUCCESS Smbios protocol installed\r
571 @retval Other No protocol installed, unload driver.\r
572\r
573**/\r
574EFI_STATUS\r
575EFIAPI\r
576SmbiosMeasurementDriverEntryPoint (\r
577 IN EFI_HANDLE ImageHandle,\r
578 IN EFI_SYSTEM_TABLE *SystemTable\r
579 )\r
580{\r
581 EFI_STATUS Status;\r
582 EFI_EVENT Event;\r
583\r
584 Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &mSmbios);\r
585 ASSERT_EFI_ERROR (Status);\r
586 DEBUG ((DEBUG_INFO, "The Smbios Table Version: %x.%x\n", mSmbios->MajorVersion, mSmbios->MinorVersion));\r
587 \r
588 if (mSmbios->MajorVersion < 2 || (mSmbios->MajorVersion == 2 && mSmbios->MinorVersion < 7)){\r
589 mMaxLen = SMBIOS_STRING_MAX_LENGTH;\r
590 } else if (mSmbios->MajorVersion < 3) {\r
591 //\r
592 // Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string.\r
593 // However, the length of the entire structure table (including all strings) must be reported\r
594 // in the Structure Table Length field of the SMBIOS Structure Table Entry Point,\r
595 // which is a WORD field limited to 65,535 bytes.\r
596 //\r
597 mMaxLen = SMBIOS_TABLE_MAX_LENGTH;\r
598 } else {\r
599 //\r
600 // SMBIOS 3.0 defines the Structure table maximum size as DWORD field limited to 0xFFFFFFFF bytes.\r
601 // Locate the end of string as long as possible.\r
602 //\r
603 mMaxLen = SMBIOS_3_0_TABLE_MAX_LENGTH;\r
604 }\r
605\r
606 //\r
607 // Measure Smbios tables\r
608 //\r
609 Status = EfiCreateEventReadyToBootEx (\r
610 TPL_CALLBACK,\r
611 MeasureSmbiosTable,\r
612 NULL,\r
613 &Event\r
614 );\r
615\r
616 return Status;\r
617}\r