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