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