]>
Commit | Line | Data |
---|---|---|
c00a0c87 JY |
1 | /** @file\r |
2 | This driver measures SMBIOS table to TPM.\r | |
14c218b3 | 3 | \r |
7f2f96f1 | 4 | Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r |
14c218b3 SZ |
5 | This program and the accompanying materials\r |
6 | are licensed and made available under the terms and conditions of the BSD License\r | |
7 | which accompanies this distribution. The full text of the license may be found at\r | |
8 | http://opensource.org/licenses/bsd-license.php\r | |
9 | \r | |
10 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
11 | WITHOUT 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 | |
33 | typedef 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 | |
41 | typedef 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 | |
50 | SMBIOS_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 | |
55 | SMBIOS_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 | |
59 | SMBIOS_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 | |
63 | SMBIOS_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 | |
74 | SMBIOS_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 | |
79 | SMBIOS_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 | |
84 | SMBIOS_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 |
87 | SMBIOS_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 |
90 | SMBIOS_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 | |
96 | SMBIOS_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 | |
113 | EFI_SMBIOS_PROTOCOL *mSmbios;\r | |
114 | UINTN 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 | |
124 | VOID\r | |
125 | InternalDumpData (\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 | |
144 | VOID\r | |
145 | InternalDumpHex (\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 | |
179 | SMBIOS_FILTER_STRUCT *\r | |
180 | GetFilterStructByType (\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 | |
203 | CHAR8 *\r | |
204 | GetSmbiosStringById (\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 | |
264 | VOID\r | |
265 | FilterSmbiosEntry (\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 | |
330 | UINTN\r | |
331 | GetSmbiosStructureSize (\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 | |
393 | UINTN\r | |
394 | GetSmbiosTableLength (\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 | |
428 | VOID\r | |
429 | FilterSmbiosTable (\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 |
459 | VOID\r | |
460 | EFIAPI\r | |
461 | MeasureSmbiosTable (\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 | |
603 | EFI_STATUS\r | |
604 | EFIAPI\r | |
605 | SmbiosMeasurementDriverEntryPoint (\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 |