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