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