]>
Commit | Line | Data |
---|---|---|
1 | /** @file\r | |
2 | This driver measures SMBIOS table to TPM.\r | |
3 | \r | |
4 | Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r | |
5 | SPDX-License-Identifier: BSD-2-Clause-Patent\r | |
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 | |
27 | typedef 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 | |
35 | typedef 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 | |
44 | SMBIOS_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 | |
49 | SMBIOS_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 | |
53 | SMBIOS_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 | |
57 | SMBIOS_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 | |
68 | SMBIOS_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 | |
73 | SMBIOS_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 | |
78 | SMBIOS_FILTER_TABLE mSmbiosFilterType23BlackList[] = {\r | |
79 | {0x17, OFFSET_OF(SMBIOS_TABLE_TYPE23, ResetCount), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE23, ResetCount), 0},\r | |
80 | };\r | |
81 | SMBIOS_FILTER_TABLE mSmbiosFilterType27BlackList[] = {\r | |
82 | {0x1B, OFFSET_OF(SMBIOS_TABLE_TYPE27, NominalSpeed), FIELD_SIZE_OF(SMBIOS_TABLE_TYPE27, NominalSpeed), 0},\r | |
83 | };\r | |
84 | SMBIOS_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 | |
90 | SMBIOS_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 | |
101 | {0x1B, mSmbiosFilterType27BlackList, sizeof(mSmbiosFilterType27BlackList)/sizeof(mSmbiosFilterType27BlackList[0])},\r | |
102 | {0x1F, NULL, 0},\r | |
103 | {0x21, NULL, 0},\r | |
104 | {0x27, mSmbiosFilterType39BlackList, sizeof(mSmbiosFilterType39BlackList)/sizeof(mSmbiosFilterType39BlackList[0])},\r | |
105 | };\r | |
106 | \r | |
107 | EFI_SMBIOS_PROTOCOL *mSmbios;\r | |
108 | UINTN 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 | |
118 | VOID\r | |
119 | InternalDumpData (\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 | |
126 | DEBUG ((EFI_D_VERBOSE, "%02x", (UINTN)Data[Index]));\r | |
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 | |
138 | VOID\r | |
139 | InternalDumpHex (\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 | |
153 | DEBUG ((EFI_D_VERBOSE, "%04x: ", Index * COLUME_SIZE));\r | |
154 | InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE);\r | |
155 | DEBUG ((EFI_D_VERBOSE, "\n"));\r | |
156 | }\r | |
157 | \r | |
158 | if (Left != 0) {\r | |
159 | DEBUG ((EFI_D_VERBOSE, "%04x: ", Index * COLUME_SIZE));\r | |
160 | InternalDumpData (Data + Index * COLUME_SIZE, Left);\r | |
161 | DEBUG ((EFI_D_VERBOSE, "\n"));\r | |
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 | |
173 | SMBIOS_FILTER_STRUCT *\r | |
174 | GetFilterStructByType (\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 | |
197 | CHAR8 *\r | |
198 | GetSmbiosStringById (\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 | |
218 | while (*CharInStr != 0 || *(CharInStr+1) != 0) {\r | |
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 | |
258 | VOID\r | |
259 | FilterSmbiosEntry (\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 | |
272 | DEBUG_CODE (InternalDumpHex (TableEntry, TableEntrySize););\r | |
273 | \r | |
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 | |
302 | }\r | |
303 | // zero non-string field\r | |
304 | ZeroMem ((UINT8 *)TableEntry + Filter[Index].Offset, Filter[Index].Size);\r | |
305 | }\r | |
306 | }\r | |
307 | }\r | |
308 | }\r | |
309 | }\r | |
310 | \r | |
311 | DEBUG ((EFI_D_INFO, "Filter Smbios Table (Type - %d):\n", ((SMBIOS_STRUCTURE *)TableEntry)->Type));\r | |
312 | DEBUG_CODE (InternalDumpHex (TableEntry, TableEntrySize););\r | |
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 | |
321 | \r | |
322 | @return Size The returned size.\r | |
323 | **/\r | |
324 | UINTN\r | |
325 | GetSmbiosStructureSize (\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 | |
342 | while (*CharInStr != 0 || *(CharInStr+1) != 0) {\r | |
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 | |
387 | UINTN\r | |
388 | GetSmbiosTableLength (\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 | |
422 | VOID\r | |
423 | FilterSmbiosTable (\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 | |
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 | |
452 | **/\r | |
453 | VOID\r | |
454 | EFIAPI\r | |
455 | MeasureSmbiosTable (\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 | |
497 | \r | |
498 | if (Smbios3Table == NULL) {\r | |
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 | |
506 | SmbiosTable->AnchorString[0],\r | |
507 | SmbiosTable->AnchorString[1],\r | |
508 | SmbiosTable->AnchorString[2],\r | |
509 | SmbiosTable->AnchorString[3]\r | |
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 | |
537 | }\r | |
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 | |
550 | DEBUG_CODE (InternalDumpHex ((UINT8 *)(UINTN)SmbiosTableAddress, TableLength););\r | |
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 | |
561 | DEBUG_CODE (InternalDumpHex (TableAddress, TableLength););\r | |
562 | \r | |
563 | HandoffTables.NumberOfTables = 1;\r | |
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 | |
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 | |
589 | Driver to produce Smbios measurement.\r | |
590 | \r | |
591 | @param ImageHandle Module's image handle\r | |
592 | @param SystemTable Pointer of EFI_SYSTEM_TABLE\r | |
593 | \r | |
594 | @return Status returned from EfiCreateEventReadyToBootEx().\r | |
595 | \r | |
596 | **/\r | |
597 | EFI_STATUS\r | |
598 | EFIAPI\r | |
599 | SmbiosMeasurementDriverEntryPoint (\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 | |
607 | Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **) &mSmbios);\r | |
608 | ASSERT_EFI_ERROR (Status);\r | |
609 | DEBUG ((DEBUG_INFO, "The Smbios Table Version: %x.%x\n", mSmbios->MajorVersion, mSmbios->MinorVersion));\r | |
610 | \r | |
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 |