]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Core / PiSmmCore / SmiHandlerProfile.c
CommitLineData
ca41f3f4
JY
1/** @file\r
2 SMI handler profile support.\r
3\r
4Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
ca41f3f4
JY
6\r
7**/\r
8\r
9#include <PiSmm.h>\r
10#include <Library/BaseLib.h>\r
11#include <Library/BaseMemoryLib.h>\r
12#include <Library/MemoryAllocationLib.h>\r
13#include <Library/UefiBootServicesTableLib.h>\r
14#include <Library/SmmServicesTableLib.h>\r
15#include <Library/DebugLib.h>\r
16#include <Library/PrintLib.h>\r
17#include <Library/UefiLib.h>\r
18#include <Library/DevicePathLib.h>\r
19#include <Library/PeCoffGetEntryPointLib.h>\r
ca41f3f4
JY
20#include <Protocol/LoadedImage.h>\r
21#include <Protocol/SmmAccess2.h>\r
22#include <Protocol/SmmReadyToLock.h>\r
23#include <Protocol/SmmEndOfDxe.h>\r
24\r
25#include <Guid/SmiHandlerProfile.h>\r
26\r
27#include "PiSmmCore.h"\r
28\r
f2485395
SZ
29#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \\r
30 ((ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1)))\r
31\r
ca41f3f4 32typedef struct {\r
f2485395
SZ
33 EFI_GUID FileGuid;\r
34 PHYSICAL_ADDRESS EntryPoint;\r
35 PHYSICAL_ADDRESS ImageBase;\r
36 UINT64 ImageSize;\r
37 UINT32 ImageRef;\r
38 UINT16 PdbStringSize;\r
39 CHAR8 *PdbString;\r
ca41f3f4
JY
40} IMAGE_STRUCT;\r
41\r
42/**\r
43 Register SMI handler profile handler.\r
44**/\r
45VOID\r
1436aea4 46RegisterSmiHandlerProfileHandler (\r
ca41f3f4
JY
47 VOID\r
48 );\r
49\r
50/**\r
51 Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded\r
52 into system memory with the PE/COFF Loader Library functions.\r
53\r
54 Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry\r
55 point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then\r
56 return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS.\r
57 If Pe32Data is NULL, then ASSERT().\r
58 If EntryPoint is NULL, then ASSERT().\r
59\r
60 @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.\r
61 @param EntryPoint The pointer to entry point to the PE/COFF image to return.\r
62\r
63 @retval RETURN_SUCCESS EntryPoint was returned.\r
64 @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image.\r
65\r
66**/\r
67RETURN_STATUS\r
68InternalPeCoffGetEntryPoint (\r
69 IN VOID *Pe32Data,\r
70 OUT VOID **EntryPoint\r
71 );\r
72\r
73extern LIST_ENTRY mSmiEntryList;\r
74extern LIST_ENTRY mHardwareSmiEntryList;\r
75extern SMI_ENTRY mRootSmiEntry;\r
76\r
77extern SMI_HANDLER_PROFILE_PROTOCOL mSmiHandlerProfile;\r
78\r
1436aea4 79GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY mHardwareSmiEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mHardwareSmiEntryList);\r
ca41f3f4 80\r
1436aea4 81GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY mRootSmiEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mRootSmiEntryList);\r
ca41f3f4 82\r
1436aea4
MK
83GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY *mSmmCoreRootSmiEntryList = &mRootSmiEntryList;\r
84GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY *mSmmCoreSmiEntryList = &mSmiEntryList;\r
85GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY *mSmmCoreHardwareSmiEntryList = &mHardwareSmiEntryList;\r
ca41f3f4
JY
86\r
87GLOBAL_REMOVE_IF_UNREFERENCED IMAGE_STRUCT *mImageStruct;\r
f2485395
SZ
88GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mImageStructCountMax;\r
89GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mImageStructCount;\r
ca41f3f4
JY
90\r
91GLOBAL_REMOVE_IF_UNREFERENCED VOID *mSmiHandlerProfileDatabase;\r
92GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmiHandlerProfileDatabaseSize;\r
93\r
94GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmmImageDatabaseSize;\r
95GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmmRootSmiDatabaseSize;\r
96GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmmSmiDatabaseSize;\r
97GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmmHardwareSmiDatabaseSize;\r
98\r
99GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mSmiHandlerProfileRecordingStatus;\r
100\r
101GLOBAL_REMOVE_IF_UNREFERENCED SMI_HANDLER_PROFILE_PROTOCOL mSmiHandlerProfile = {\r
102 SmiHandlerProfileRegisterHandler,\r
103 SmiHandlerProfileUnregisterHandler,\r
104};\r
105\r
106/**\r
107 This function dump raw data.\r
108\r
109 @param Data raw data\r
110 @param Size raw data size\r
111**/\r
112VOID\r
113InternalDumpData (\r
114 IN UINT8 *Data,\r
115 IN UINTN Size\r
116 )\r
117{\r
118 UINTN Index;\r
1436aea4 119\r
ca41f3f4
JY
120 for (Index = 0; Index < Size; Index++) {\r
121 DEBUG ((DEBUG_INFO, "%02x ", (UINTN)Data[Index]));\r
122 }\r
123}\r
124\r
125/**\r
126 Get GUID name for an image.\r
127\r
128 @param[in] LoadedImage LoadedImage protocol.\r
129 @param[out] Guid Guid of the FFS\r
130**/\r
131VOID\r
132GetDriverGuid (\r
133 IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,\r
134 OUT EFI_GUID *Guid\r
135 )\r
136{\r
1436aea4 137 EFI_GUID *FileName;\r
ca41f3f4
JY
138\r
139 FileName = NULL;\r
1436aea4
MK
140 if ((DevicePathType (LoadedImage->FilePath) == MEDIA_DEVICE_PATH) &&\r
141 (DevicePathSubType (LoadedImage->FilePath) == MEDIA_PIWG_FW_FILE_DP))\r
142 {\r
ca41f3f4
JY
143 FileName = &((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)LoadedImage->FilePath)->FvFileName;\r
144 }\r
1436aea4 145\r
ca41f3f4 146 if (FileName != NULL) {\r
1436aea4 147 CopyGuid (Guid, FileName);\r
ca41f3f4 148 } else {\r
1436aea4 149 ZeroMem (Guid, sizeof (EFI_GUID));\r
ca41f3f4
JY
150 }\r
151}\r
152\r
153/**\r
154 Add image structure.\r
155\r
156 @param ImageBase image base\r
157 @param ImageSize image size\r
158 @param EntryPoint image entry point\r
159 @param Guid FFS GUID of the image\r
160 @param PdbString image PDB string\r
161**/\r
162VOID\r
1436aea4
MK
163AddImageStruct (\r
164 IN PHYSICAL_ADDRESS ImageBase,\r
165 IN UINT64 ImageSize,\r
166 IN PHYSICAL_ADDRESS EntryPoint,\r
167 IN EFI_GUID *Guid,\r
168 IN CHAR8 *PdbString\r
ca41f3f4
JY
169 )\r
170{\r
171 UINTN PdbStringSize;\r
172\r
173 if (mImageStructCount >= mImageStructCountMax) {\r
1436aea4 174 ASSERT (FALSE);\r
ca41f3f4
JY
175 return;\r
176 }\r
177\r
1436aea4
MK
178 CopyGuid (&mImageStruct[mImageStructCount].FileGuid, Guid);\r
179 mImageStruct[mImageStructCount].ImageRef = mImageStructCount;\r
180 mImageStruct[mImageStructCount].ImageBase = ImageBase;\r
181 mImageStruct[mImageStructCount].ImageSize = ImageSize;\r
ca41f3f4
JY
182 mImageStruct[mImageStructCount].EntryPoint = EntryPoint;\r
183 if (PdbString != NULL) {\r
1436aea4 184 PdbStringSize = AsciiStrSize (PdbString);\r
ca41f3f4
JY
185 mImageStruct[mImageStructCount].PdbString = AllocateCopyPool (PdbStringSize, PdbString);\r
186 if (mImageStruct[mImageStructCount].PdbString != NULL) {\r
1436aea4 187 mImageStruct[mImageStructCount].PdbStringSize = (UINT16)PdbStringSize;\r
ca41f3f4
JY
188 }\r
189 }\r
190\r
191 mImageStructCount++;\r
192}\r
193\r
194/**\r
195 return an image structure based upon image address.\r
196\r
197 @param Address image address\r
198\r
199 @return image structure\r
200**/\r
201IMAGE_STRUCT *\r
1436aea4 202AddressToImageStruct (\r
ca41f3f4
JY
203 IN UINTN Address\r
204 )\r
205{\r
206 UINTN Index;\r
207\r
208 for (Index = 0; Index < mImageStructCount; Index++) {\r
209 if ((Address >= mImageStruct[Index].ImageBase) &&\r
1436aea4
MK
210 (Address < mImageStruct[Index].ImageBase + mImageStruct[Index].ImageSize))\r
211 {\r
ca41f3f4
JY
212 return &mImageStruct[Index];\r
213 }\r
214 }\r
1436aea4 215\r
ca41f3f4
JY
216 return NULL;\r
217}\r
218\r
219/**\r
220 return an image reference index based upon image address.\r
221\r
222 @param Address image address\r
223\r
224 @return image reference index\r
225**/\r
f2485395 226UINT32\r
1436aea4 227AddressToImageRef (\r
ca41f3f4
JY
228 IN UINTN Address\r
229 )\r
230{\r
1436aea4 231 IMAGE_STRUCT *ImageStruct;\r
ca41f3f4 232\r
1436aea4 233 ImageStruct = AddressToImageStruct (Address);\r
ca41f3f4
JY
234 if (ImageStruct != NULL) {\r
235 return ImageStruct->ImageRef;\r
236 }\r
1436aea4 237\r
f2485395 238 return (UINT32)-1;\r
ca41f3f4
JY
239}\r
240\r
241/**\r
242 Collect SMM image information based upon loaded image protocol.\r
243**/\r
244VOID\r
1436aea4 245GetSmmLoadedImage (\r
ca41f3f4
JY
246 VOID\r
247 )\r
248{\r
249 EFI_STATUS Status;\r
250 UINTN NoHandles;\r
251 UINTN HandleBufferSize;\r
252 EFI_HANDLE *HandleBuffer;\r
253 UINTN Index;\r
254 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
255 CHAR16 *PathStr;\r
256 EFI_SMM_DRIVER_ENTRY *LoadedImagePrivate;\r
f2485395 257 PHYSICAL_ADDRESS EntryPoint;\r
ca41f3f4
JY
258 VOID *EntryPointInImage;\r
259 EFI_GUID Guid;\r
260 CHAR8 *PdbString;\r
f2485395 261 PHYSICAL_ADDRESS RealImageBase;\r
ca41f3f4
JY
262\r
263 HandleBufferSize = 0;\r
1436aea4
MK
264 HandleBuffer = NULL;\r
265 Status = gSmst->SmmLocateHandle (\r
266 ByProtocol,\r
267 &gEfiLoadedImageProtocolGuid,\r
268 NULL,\r
269 &HandleBufferSize,\r
270 HandleBuffer\r
271 );\r
ca41f3f4
JY
272 if (Status != EFI_BUFFER_TOO_SMALL) {\r
273 return;\r
274 }\r
1436aea4 275\r
ca41f3f4
JY
276 HandleBuffer = AllocateZeroPool (HandleBufferSize);\r
277 if (HandleBuffer == NULL) {\r
278 return;\r
279 }\r
1436aea4
MK
280\r
281 Status = gSmst->SmmLocateHandle (\r
ca41f3f4
JY
282 ByProtocol,\r
283 &gEfiLoadedImageProtocolGuid,\r
284 NULL,\r
285 &HandleBufferSize,\r
286 HandleBuffer\r
287 );\r
1436aea4 288 if (EFI_ERROR (Status)) {\r
ca41f3f4
JY
289 return;\r
290 }\r
291\r
1436aea4
MK
292 NoHandles = HandleBufferSize/sizeof (EFI_HANDLE);\r
293 mImageStructCountMax = (UINT32)NoHandles;\r
294 mImageStruct = AllocateZeroPool (mImageStructCountMax * sizeof (IMAGE_STRUCT));\r
ca41f3f4
JY
295 if (mImageStruct == NULL) {\r
296 goto Done;\r
297 }\r
298\r
299 for (Index = 0; Index < NoHandles; Index++) {\r
1436aea4 300 Status = gSmst->SmmHandleProtocol (\r
ca41f3f4
JY
301 HandleBuffer[Index],\r
302 &gEfiLoadedImageProtocolGuid,\r
303 (VOID **)&LoadedImage\r
304 );\r
1436aea4 305 if (EFI_ERROR (Status)) {\r
ca41f3f4
JY
306 continue;\r
307 }\r
1436aea4
MK
308\r
309 PathStr = ConvertDevicePathToText (LoadedImage->FilePath, TRUE, TRUE);\r
310 GetDriverGuid (LoadedImage, &Guid);\r
ca41f3f4
JY
311 DEBUG ((DEBUG_INFO, "Image: %g ", &Guid));\r
312\r
1436aea4
MK
313 EntryPoint = 0;\r
314 LoadedImagePrivate = BASE_CR (LoadedImage, EFI_SMM_DRIVER_ENTRY, SmmLoadedImage);\r
315 RealImageBase = (UINTN)LoadedImage->ImageBase;\r
ca41f3f4 316 if (LoadedImagePrivate->Signature == EFI_SMM_DRIVER_ENTRY_SIGNATURE) {\r
f2485395
SZ
317 EntryPoint = LoadedImagePrivate->ImageEntryPoint;\r
318 if ((EntryPoint != 0) && ((EntryPoint < (UINTN)LoadedImage->ImageBase) || (EntryPoint >= ((UINTN)LoadedImage->ImageBase + LoadedImage->ImageSize)))) {\r
ca41f3f4
JY
319 //\r
320 // If the EntryPoint is not in the range of image buffer, it should come from emulation environment.\r
321 // So patch ImageBuffer here to align the EntryPoint.\r
322 //\r
1436aea4
MK
323 Status = InternalPeCoffGetEntryPoint (LoadedImage->ImageBase, &EntryPointInImage);\r
324 ASSERT_EFI_ERROR (Status);\r
ca41f3f4
JY
325 RealImageBase = (UINTN)LoadedImage->ImageBase + EntryPoint - (UINTN)EntryPointInImage;\r
326 }\r
327 }\r
1436aea4 328\r
f2485395 329 DEBUG ((DEBUG_INFO, "(0x%lx - 0x%lx", RealImageBase, LoadedImage->ImageSize));\r
ca41f3f4 330 if (EntryPoint != 0) {\r
f2485395 331 DEBUG ((DEBUG_INFO, ", EntryPoint:0x%lx", EntryPoint));\r
ca41f3f4 332 }\r
1436aea4 333\r
ca41f3f4
JY
334 DEBUG ((DEBUG_INFO, ")\n"));\r
335\r
336 if (RealImageBase != 0) {\r
1436aea4 337 PdbString = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)RealImageBase);\r
ca41f3f4
JY
338 DEBUG ((DEBUG_INFO, " pdb - %a\n", PdbString));\r
339 } else {\r
340 PdbString = NULL;\r
341 }\r
1436aea4 342\r
ca41f3f4
JY
343 DEBUG ((DEBUG_INFO, " (%s)\n", PathStr));\r
344\r
1436aea4 345 AddImageStruct (RealImageBase, LoadedImage->ImageSize, EntryPoint, &Guid, PdbString);\r
ca41f3f4
JY
346 }\r
347\r
348Done:\r
1436aea4 349 FreePool (HandleBuffer);\r
ca41f3f4
JY
350 return;\r
351}\r
352\r
353/**\r
354 Dump SMI child context.\r
355\r
356 @param HandlerType the handler type\r
357 @param Context the handler context\r
358 @param ContextSize the handler context size\r
359**/\r
360VOID\r
361DumpSmiChildContext (\r
1436aea4
MK
362 IN EFI_GUID *HandlerType,\r
363 IN VOID *Context,\r
364 IN UINTN ContextSize\r
ca41f3f4
JY
365 )\r
366{\r
1436aea4 367 CHAR16 *Str;\r
fb1c81a1 368\r
ca41f3f4 369 if (CompareGuid (HandlerType, &gEfiSmmSwDispatch2ProtocolGuid)) {\r
f2485395 370 DEBUG ((DEBUG_INFO, " SwSmi - 0x%lx\n", ((SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT *)Context)->SwSmiInputValue));\r
ca41f3f4
JY
371 } else if (CompareGuid (HandlerType, &gEfiSmmSxDispatch2ProtocolGuid)) {\r
372 DEBUG ((DEBUG_INFO, " SxType - 0x%x\n", ((EFI_SMM_SX_REGISTER_CONTEXT *)Context)->Type));\r
373 DEBUG ((DEBUG_INFO, " SxPhase - 0x%x\n", ((EFI_SMM_SX_REGISTER_CONTEXT *)Context)->Phase));\r
374 } else if (CompareGuid (HandlerType, &gEfiSmmPowerButtonDispatch2ProtocolGuid)) {\r
375 DEBUG ((DEBUG_INFO, " PowerButtonPhase - 0x%x\n", ((EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT *)Context)->Phase));\r
376 } else if (CompareGuid (HandlerType, &gEfiSmmStandbyButtonDispatch2ProtocolGuid)) {\r
377 DEBUG ((DEBUG_INFO, " StandbyButtonPhase - 0x%x\n", ((EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT *)Context)->Phase));\r
378 } else if (CompareGuid (HandlerType, &gEfiSmmPeriodicTimerDispatch2ProtocolGuid)) {\r
379 DEBUG ((DEBUG_INFO, " PeriodicTimerPeriod - %ld\n", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *)Context)->Period));\r
380 DEBUG ((DEBUG_INFO, " PeriodicTimerSmiTickInterval - %ld\n", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *)Context)->SmiTickInterval));\r
381 } else if (CompareGuid (HandlerType, &gEfiSmmGpiDispatch2ProtocolGuid)) {\r
382 DEBUG ((DEBUG_INFO, " GpiNum - 0x%lx\n", ((EFI_SMM_GPI_REGISTER_CONTEXT *)Context)->GpiNum));\r
383 } else if (CompareGuid (HandlerType, &gEfiSmmIoTrapDispatch2ProtocolGuid)) {\r
384 DEBUG ((DEBUG_INFO, " IoTrapAddress - 0x%x\n", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Address));\r
385 DEBUG ((DEBUG_INFO, " IoTrapLength - 0x%x\n", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Length));\r
386 DEBUG ((DEBUG_INFO, " IoTrapType - 0x%x\n", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Type));\r
387 } else if (CompareGuid (HandlerType, &gEfiSmmUsbDispatch2ProtocolGuid)) {\r
388 DEBUG ((DEBUG_INFO, " UsbType - 0x%x\n", ((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *)Context)->Type));\r
1436aea4 389 Str = ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTOCOL *)(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *)Context) + 1), TRUE, TRUE);\r
fb1c81a1
SZ
390 DEBUG ((DEBUG_INFO, " UsbDevicePath - %s\n", Str));\r
391 if (Str != NULL) {\r
392 FreePool (Str);\r
393 }\r
ca41f3f4
JY
394 } else {\r
395 DEBUG ((DEBUG_INFO, " Context - "));\r
396 InternalDumpData (Context, ContextSize);\r
397 DEBUG ((DEBUG_INFO, "\n"));\r
398 }\r
399}\r
400\r
401/**\r
402 Dump all SMI handlers associated with SmiEntry.\r
403\r
404 @param SmiEntry SMI entry.\r
405**/\r
406VOID\r
1436aea4
MK
407DumpSmiHandlerOnSmiEntry (\r
408 IN SMI_ENTRY *SmiEntry\r
ca41f3f4
JY
409 )\r
410{\r
1436aea4
MK
411 LIST_ENTRY *ListEntry;\r
412 SMI_HANDLER *SmiHandler;\r
413 IMAGE_STRUCT *ImageStruct;\r
ca41f3f4
JY
414\r
415 ListEntry = &SmiEntry->SmiHandlers;\r
416 for (ListEntry = ListEntry->ForwardLink;\r
417 ListEntry != &SmiEntry->SmiHandlers;\r
1436aea4
MK
418 ListEntry = ListEntry->ForwardLink)\r
419 {\r
420 SmiHandler = CR (ListEntry, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE);\r
421 ImageStruct = AddressToImageStruct ((UINTN)SmiHandler->Handler);\r
ca41f3f4
JY
422 if (ImageStruct != NULL) {\r
423 DEBUG ((DEBUG_INFO, " Module - %g", &ImageStruct->FileGuid));\r
424 }\r
1436aea4 425\r
ca41f3f4
JY
426 if ((ImageStruct != NULL) && (ImageStruct->PdbString[0] != 0)) {\r
427 DEBUG ((DEBUG_INFO, " (Pdb - %a)", ImageStruct->PdbString));\r
428 }\r
1436aea4 429\r
ca41f3f4
JY
430 DEBUG ((DEBUG_INFO, "\n"));\r
431 if (SmiHandler->ContextSize != 0) {\r
432 DumpSmiChildContext (&SmiEntry->HandlerType, SmiHandler->Context, SmiHandler->ContextSize);\r
433 }\r
1436aea4 434\r
ca41f3f4
JY
435 DEBUG ((DEBUG_INFO, " Handler - 0x%x", SmiHandler->Handler));\r
436 if (ImageStruct != NULL) {\r
1436aea4 437 DEBUG ((DEBUG_INFO, " <== RVA - 0x%x", (UINTN)SmiHandler->Handler - (UINTN)ImageStruct->ImageBase));\r
ca41f3f4 438 }\r
1436aea4 439\r
ca41f3f4
JY
440 DEBUG ((DEBUG_INFO, "\n"));\r
441 DEBUG ((DEBUG_INFO, " CallerAddr - 0x%x", SmiHandler->CallerAddr));\r
442 if (ImageStruct != NULL) {\r
1436aea4 443 DEBUG ((DEBUG_INFO, " <== RVA - 0x%x", SmiHandler->CallerAddr - (UINTN)ImageStruct->ImageBase));\r
ca41f3f4 444 }\r
1436aea4 445\r
ca41f3f4
JY
446 DEBUG ((DEBUG_INFO, "\n"));\r
447 }\r
448\r
449 return;\r
450}\r
451\r
452/**\r
453 Dump all SMI entry on the list.\r
454\r
455 @param SmiEntryList a list of SMI entry.\r
456**/\r
457VOID\r
1436aea4
MK
458DumpSmiEntryList (\r
459 IN LIST_ENTRY *SmiEntryList\r
ca41f3f4
JY
460 )\r
461{\r
1436aea4
MK
462 LIST_ENTRY *ListEntry;\r
463 SMI_ENTRY *SmiEntry;\r
ca41f3f4
JY
464\r
465 ListEntry = SmiEntryList;\r
466 for (ListEntry = ListEntry->ForwardLink;\r
467 ListEntry != SmiEntryList;\r
1436aea4
MK
468 ListEntry = ListEntry->ForwardLink)\r
469 {\r
470 SmiEntry = CR (ListEntry, SMI_ENTRY, AllEntries, SMI_ENTRY_SIGNATURE);\r
ca41f3f4 471 DEBUG ((DEBUG_INFO, "SmiEntry - %g\n", &SmiEntry->HandlerType));\r
1436aea4 472 DumpSmiHandlerOnSmiEntry (SmiEntry);\r
ca41f3f4
JY
473 }\r
474\r
475 return;\r
476}\r
477\r
478/**\r
479 SMM Ready To Lock event notification handler.\r
480\r
481 This function collects all SMM image information and build SmiHandleProfile database,\r
482 and register SmiHandlerProfile SMI handler.\r
483\r
484 @param[in] Protocol Points to the protocol's unique identifier.\r
485 @param[in] Interface Points to the interface instance.\r
486 @param[in] Handle The handle on which the interface was installed.\r
487\r
488 @retval EFI_SUCCESS Notification handler runs successfully.\r
489**/\r
490EFI_STATUS\r
491EFIAPI\r
492SmmReadyToLockInSmiHandlerProfile (\r
493 IN CONST EFI_GUID *Protocol,\r
494 IN VOID *Interface,\r
495 IN EFI_HANDLE Handle\r
496 )\r
497{\r
498 //\r
499 // Dump all image\r
500 //\r
501 DEBUG ((DEBUG_INFO, "##################\n"));\r
502 DEBUG ((DEBUG_INFO, "# IMAGE DATABASE #\n"));\r
503 DEBUG ((DEBUG_INFO, "##################\n"));\r
504 GetSmmLoadedImage ();\r
505 DEBUG ((DEBUG_INFO, "\n"));\r
506\r
507 //\r
508 // Dump SMI Handler\r
509 //\r
510 DEBUG ((DEBUG_INFO, "########################\n"));\r
511 DEBUG ((DEBUG_INFO, "# SMI Handler DATABASE #\n"));\r
512 DEBUG ((DEBUG_INFO, "########################\n"));\r
513\r
514 DEBUG ((DEBUG_INFO, "# 1. ROOT SMI Handler #\n"));\r
515 DEBUG_CODE (\r
1436aea4
MK
516 DumpSmiEntryList (mSmmCoreRootSmiEntryList);\r
517 );\r
ca41f3f4
JY
518\r
519 DEBUG ((DEBUG_INFO, "# 2. GUID SMI Handler #\n"));\r
520 DEBUG_CODE (\r
1436aea4
MK
521 DumpSmiEntryList (mSmmCoreSmiEntryList);\r
522 );\r
ca41f3f4
JY
523\r
524 DEBUG ((DEBUG_INFO, "# 3. Hardware SMI Handler #\n"));\r
525 DEBUG_CODE (\r
1436aea4
MK
526 DumpSmiEntryList (mSmmCoreHardwareSmiEntryList);\r
527 );\r
ca41f3f4
JY
528\r
529 DEBUG ((DEBUG_INFO, "\n"));\r
530\r
1436aea4 531 RegisterSmiHandlerProfileHandler ();\r
ca41f3f4
JY
532\r
533 if (mImageStruct != NULL) {\r
1436aea4 534 FreePool (mImageStruct);\r
ca41f3f4
JY
535 }\r
536\r
537 return EFI_SUCCESS;\r
538}\r
539\r
540/**\r
541 returns SMM image data base size.\r
542\r
543 @return SMM image data base size.\r
544**/\r
545UINTN\r
1436aea4 546GetSmmImageDatabaseSize (\r
ca41f3f4
JY
547 VOID\r
548 )\r
549{\r
1436aea4
MK
550 UINTN Size;\r
551 UINT32 Index;\r
ca41f3f4 552\r
f2485395 553 Size = 0;\r
ca41f3f4 554 for (Index = 0; Index < mImageStructCount; Index++) {\r
1436aea4 555 Size += sizeof (SMM_CORE_IMAGE_DATABASE_STRUCTURE) + GET_OCCUPIED_SIZE (mImageStruct[Index].PdbStringSize, sizeof (UINT64));\r
ca41f3f4 556 }\r
1436aea4 557\r
ca41f3f4
JY
558 return Size;\r
559}\r
560\r
561/**\r
562 returns all SMI handlers' size associated with SmiEntry.\r
563\r
564 @param SmiEntry SMI entry.\r
565\r
566 @return all SMI handlers' size associated with SmiEntry.\r
567**/\r
568UINTN\r
1436aea4
MK
569GetSmmSmiHandlerSizeOnSmiEntry (\r
570 IN SMI_ENTRY *SmiEntry\r
ca41f3f4
JY
571 )\r
572{\r
1436aea4
MK
573 LIST_ENTRY *ListEntry;\r
574 SMI_HANDLER *SmiHandler;\r
575 UINTN Size;\r
ca41f3f4 576\r
1436aea4 577 Size = 0;\r
ca41f3f4
JY
578 ListEntry = &SmiEntry->SmiHandlers;\r
579 for (ListEntry = ListEntry->ForwardLink;\r
580 ListEntry != &SmiEntry->SmiHandlers;\r
1436aea4
MK
581 ListEntry = ListEntry->ForwardLink)\r
582 {\r
583 SmiHandler = CR (ListEntry, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE);\r
584 Size += sizeof (SMM_CORE_SMI_HANDLER_STRUCTURE) + GET_OCCUPIED_SIZE (SmiHandler->ContextSize, sizeof (UINT64));\r
ca41f3f4
JY
585 }\r
586\r
587 return Size;\r
588}\r
589\r
590/**\r
591 return all SMI handler database size on the SMI entry list.\r
592\r
593 @param SmiEntryList a list of SMI entry.\r
594\r
595 @return all SMI handler database size on the SMI entry list.\r
596**/\r
597UINTN\r
1436aea4
MK
598GetSmmSmiDatabaseSize (\r
599 IN LIST_ENTRY *SmiEntryList\r
ca41f3f4
JY
600 )\r
601{\r
1436aea4
MK
602 LIST_ENTRY *ListEntry;\r
603 SMI_ENTRY *SmiEntry;\r
604 UINTN Size;\r
ca41f3f4 605\r
1436aea4 606 Size = 0;\r
ca41f3f4
JY
607 ListEntry = SmiEntryList;\r
608 for (ListEntry = ListEntry->ForwardLink;\r
609 ListEntry != SmiEntryList;\r
1436aea4
MK
610 ListEntry = ListEntry->ForwardLink)\r
611 {\r
612 SmiEntry = CR (ListEntry, SMI_ENTRY, AllEntries, SMI_ENTRY_SIGNATURE);\r
613 Size += sizeof (SMM_CORE_SMI_DATABASE_STRUCTURE);\r
614 Size += GetSmmSmiHandlerSizeOnSmiEntry (SmiEntry);\r
ca41f3f4 615 }\r
1436aea4 616\r
ca41f3f4
JY
617 return Size;\r
618}\r
619\r
620/**\r
621 return SMI handler profile database size.\r
622\r
623 @return SMI handler profile database size.\r
624**/\r
625UINTN\r
626GetSmiHandlerProfileDatabaseSize (\r
627 VOID\r
628 )\r
629{\r
1436aea4
MK
630 mSmmImageDatabaseSize = GetSmmImageDatabaseSize ();\r
631 mSmmRootSmiDatabaseSize = GetSmmSmiDatabaseSize (mSmmCoreRootSmiEntryList);\r
632 mSmmSmiDatabaseSize = GetSmmSmiDatabaseSize (mSmmCoreSmiEntryList);\r
633 mSmmHardwareSmiDatabaseSize = GetSmmSmiDatabaseSize (mSmmCoreHardwareSmiEntryList);\r
ca41f3f4
JY
634\r
635 return mSmmImageDatabaseSize + mSmmSmiDatabaseSize + mSmmRootSmiDatabaseSize + mSmmHardwareSmiDatabaseSize;\r
636}\r
637\r
638/**\r
639 get SMM image database.\r
640\r
641 @param Data The buffer to hold SMM image database\r
642 @param ExpectedSize The expected size of the SMM image database\r
643\r
644 @return SMM image data base size.\r
645**/\r
646UINTN\r
647GetSmmImageDatabaseData (\r
1436aea4
MK
648 IN OUT VOID *Data,\r
649 IN UINTN ExpectedSize\r
ca41f3f4
JY
650 )\r
651{\r
1436aea4
MK
652 SMM_CORE_IMAGE_DATABASE_STRUCTURE *ImageStruct;\r
653 UINTN Size;\r
654 UINTN Index;\r
ca41f3f4
JY
655\r
656 ImageStruct = Data;\r
1436aea4 657 Size = 0;\r
ca41f3f4
JY
658 for (Index = 0; Index < mImageStructCount; Index++) {\r
659 if (Size >= ExpectedSize) {\r
660 return 0;\r
661 }\r
1436aea4
MK
662\r
663 if (sizeof (SMM_CORE_IMAGE_DATABASE_STRUCTURE) + GET_OCCUPIED_SIZE (mImageStruct[Index].PdbStringSize, sizeof (UINT64)) > ExpectedSize - Size) {\r
ca41f3f4
JY
664 return 0;\r
665 }\r
1436aea4 666\r
ca41f3f4 667 ImageStruct->Header.Signature = SMM_CORE_IMAGE_DATABASE_SIGNATURE;\r
1436aea4
MK
668 ImageStruct->Header.Length = (UINT32)(sizeof (SMM_CORE_IMAGE_DATABASE_STRUCTURE) + GET_OCCUPIED_SIZE (mImageStruct[Index].PdbStringSize, sizeof (UINT64)));\r
669 ImageStruct->Header.Revision = SMM_CORE_IMAGE_DATABASE_REVISION;\r
670 CopyGuid (&ImageStruct->FileGuid, &mImageStruct[Index].FileGuid);\r
671 ImageStruct->ImageRef = mImageStruct[Index].ImageRef;\r
ca41f3f4 672 ImageStruct->EntryPoint = mImageStruct[Index].EntryPoint;\r
1436aea4
MK
673 ImageStruct->ImageBase = mImageStruct[Index].ImageBase;\r
674 ImageStruct->ImageSize = mImageStruct[Index].ImageSize;\r
8ced192d 675 if (mImageStruct[Index].PdbStringSize != 0) {\r
1436aea4 676 ImageStruct->PdbStringOffset = sizeof (SMM_CORE_IMAGE_DATABASE_STRUCTURE);\r
8ced192d
SZ
677 CopyMem ((VOID *)((UINTN)ImageStruct + ImageStruct->PdbStringOffset), mImageStruct[Index].PdbString, mImageStruct[Index].PdbStringSize);\r
678 } else {\r
679 ImageStruct->PdbStringOffset = 0;\r
680 }\r
1436aea4 681\r
ca41f3f4 682 ImageStruct = (SMM_CORE_IMAGE_DATABASE_STRUCTURE *)((UINTN)ImageStruct + ImageStruct->Header.Length);\r
1436aea4 683 Size += sizeof (SMM_CORE_IMAGE_DATABASE_STRUCTURE) + GET_OCCUPIED_SIZE (mImageStruct[Index].PdbStringSize, sizeof (UINT64));\r
ca41f3f4
JY
684 }\r
685\r
686 if (ExpectedSize != Size) {\r
687 return 0;\r
688 }\r
1436aea4 689\r
ca41f3f4
JY
690 return Size;\r
691}\r
692\r
693/**\r
694 get all SMI handler data associated with SmiEntry.\r
695\r
696 @param SmiEntry SMI entry.\r
697 @param Data The buffer to hold all SMI handler data\r
698 @param MaxSize The max size of the SMM image database\r
699 @param Count The count of the SMI handler.\r
700\r
701 @return SMM image data base size.\r
702**/\r
703UINTN\r
1436aea4
MK
704GetSmmSmiHandlerDataOnSmiEntry (\r
705 IN SMI_ENTRY *SmiEntry,\r
706 IN OUT VOID *Data,\r
707 IN UINTN MaxSize,\r
708 OUT UINT32 *Count\r
ca41f3f4
JY
709 )\r
710{\r
1436aea4
MK
711 SMM_CORE_SMI_HANDLER_STRUCTURE *SmiHandlerStruct;\r
712 LIST_ENTRY *ListEntry;\r
713 SMI_HANDLER *SmiHandler;\r
714 UINTN Size;\r
ca41f3f4
JY
715\r
716 SmiHandlerStruct = Data;\r
1436aea4
MK
717 Size = 0;\r
718 *Count = 0;\r
719 ListEntry = &SmiEntry->SmiHandlers;\r
ca41f3f4
JY
720 for (ListEntry = ListEntry->ForwardLink;\r
721 ListEntry != &SmiEntry->SmiHandlers;\r
1436aea4
MK
722 ListEntry = ListEntry->ForwardLink)\r
723 {\r
724 SmiHandler = CR (ListEntry, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE);\r
ca41f3f4
JY
725 if (Size >= MaxSize) {\r
726 *Count = 0;\r
727 return 0;\r
728 }\r
1436aea4
MK
729\r
730 if (sizeof (SMM_CORE_SMI_HANDLER_STRUCTURE) + GET_OCCUPIED_SIZE (SmiHandler->ContextSize, sizeof (UINT64)) > MaxSize - Size) {\r
ca41f3f4
JY
731 *Count = 0;\r
732 return 0;\r
733 }\r
1436aea4
MK
734\r
735 SmiHandlerStruct->Length = (UINT32)(sizeof (SMM_CORE_SMI_HANDLER_STRUCTURE) + GET_OCCUPIED_SIZE (SmiHandler->ContextSize, sizeof (UINT64)));\r
736 SmiHandlerStruct->CallerAddr = (UINTN)SmiHandler->CallerAddr;\r
737 SmiHandlerStruct->Handler = (UINTN)SmiHandler->Handler;\r
738 SmiHandlerStruct->ImageRef = AddressToImageRef ((UINTN)SmiHandler->Handler);\r
ca41f3f4
JY
739 SmiHandlerStruct->ContextBufferSize = (UINT32)SmiHandler->ContextSize;\r
740 if (SmiHandler->ContextSize != 0) {\r
1436aea4 741 SmiHandlerStruct->ContextBufferOffset = sizeof (SMM_CORE_SMI_HANDLER_STRUCTURE);\r
ca41f3f4
JY
742 CopyMem ((UINT8 *)SmiHandlerStruct + SmiHandlerStruct->ContextBufferOffset, SmiHandler->Context, SmiHandler->ContextSize);\r
743 } else {\r
744 SmiHandlerStruct->ContextBufferOffset = 0;\r
745 }\r
1436aea4
MK
746\r
747 Size += sizeof (SMM_CORE_SMI_HANDLER_STRUCTURE) + GET_OCCUPIED_SIZE (SmiHandler->ContextSize, sizeof (UINT64));\r
ca41f3f4 748 SmiHandlerStruct = (SMM_CORE_SMI_HANDLER_STRUCTURE *)((UINTN)SmiHandlerStruct + SmiHandlerStruct->Length);\r
1436aea4 749 *Count = *Count + 1;\r
ca41f3f4
JY
750 }\r
751\r
752 return Size;\r
753}\r
754\r
755/**\r
756 get all SMI handler database on the SMI entry list.\r
757\r
758 @param SmiEntryList a list of SMI entry.\r
759 @param HandlerCategory The handler category\r
760 @param Data The buffer to hold all SMI handler database\r
761 @param ExpectedSize The expected size of the SMM image database\r
762\r
763 @return all SMI database size on the SMI entry list.\r
764**/\r
765UINTN\r
1436aea4
MK
766GetSmmSmiDatabaseData (\r
767 IN LIST_ENTRY *SmiEntryList,\r
768 IN UINT32 HandlerCategory,\r
769 IN OUT VOID *Data,\r
770 IN UINTN ExpectedSize\r
ca41f3f4
JY
771 )\r
772{\r
1436aea4
MK
773 SMM_CORE_SMI_DATABASE_STRUCTURE *SmiStruct;\r
774 LIST_ENTRY *ListEntry;\r
775 SMI_ENTRY *SmiEntry;\r
776 UINTN Size;\r
777 UINTN SmiHandlerSize;\r
778 UINT32 SmiHandlerCount;\r
ca41f3f4
JY
779\r
780 SmiStruct = Data;\r
1436aea4 781 Size = 0;\r
ca41f3f4
JY
782 ListEntry = SmiEntryList;\r
783 for (ListEntry = ListEntry->ForwardLink;\r
784 ListEntry != SmiEntryList;\r
1436aea4
MK
785 ListEntry = ListEntry->ForwardLink)\r
786 {\r
787 SmiEntry = CR (ListEntry, SMI_ENTRY, AllEntries, SMI_ENTRY_SIGNATURE);\r
ca41f3f4
JY
788 if (Size >= ExpectedSize) {\r
789 return 0;\r
790 }\r
1436aea4
MK
791\r
792 if (sizeof (SMM_CORE_SMI_DATABASE_STRUCTURE) > ExpectedSize - Size) {\r
ca41f3f4
JY
793 return 0;\r
794 }\r
795\r
796 SmiStruct->Header.Signature = SMM_CORE_SMI_DATABASE_SIGNATURE;\r
1436aea4
MK
797 SmiStruct->Header.Length = sizeof (SMM_CORE_SMI_DATABASE_STRUCTURE);\r
798 SmiStruct->Header.Revision = SMM_CORE_SMI_DATABASE_REVISION;\r
799 SmiStruct->HandlerCategory = HandlerCategory;\r
800 CopyGuid (&SmiStruct->HandlerType, &SmiEntry->HandlerType);\r
801 Size += sizeof (SMM_CORE_SMI_DATABASE_STRUCTURE);\r
802 SmiHandlerSize = GetSmmSmiHandlerDataOnSmiEntry (SmiEntry, (UINT8 *)SmiStruct + SmiStruct->Header.Length, ExpectedSize - Size, &SmiHandlerCount);\r
803 SmiStruct->HandlerCount = SmiHandlerCount;\r
804 Size += SmiHandlerSize;\r
ca41f3f4 805 SmiStruct->Header.Length += (UINT32)SmiHandlerSize;\r
1436aea4 806 SmiStruct = (VOID *)((UINTN)SmiStruct + SmiStruct->Header.Length);\r
ca41f3f4 807 }\r
1436aea4 808\r
ca41f3f4
JY
809 if (ExpectedSize != Size) {\r
810 return 0;\r
811 }\r
1436aea4 812\r
ca41f3f4
JY
813 return Size;\r
814}\r
815\r
816/**\r
817 Get SMI handler profile database.\r
818\r
819 @param Data the buffer to hold SMI handler profile database\r
820\r
821 @retval EFI_SUCCESS the database is got.\r
822 @retval EFI_INVALID_PARAMETER the database size mismatch.\r
823**/\r
824EFI_STATUS\r
1436aea4
MK
825GetSmiHandlerProfileDatabaseData (\r
826 IN OUT VOID *Data\r
ca41f3f4
JY
827 )\r
828{\r
829 UINTN SmmImageDatabaseSize;\r
830 UINTN SmmSmiDatabaseSize;\r
831 UINTN SmmRootSmiDatabaseSize;\r
832 UINTN SmmHardwareSmiDatabaseSize;\r
833\r
1436aea4
MK
834 DEBUG ((DEBUG_VERBOSE, "GetSmiHandlerProfileDatabaseData\n"));\r
835 SmmImageDatabaseSize = GetSmmImageDatabaseData (Data, mSmmImageDatabaseSize);\r
ca41f3f4 836 if (SmmImageDatabaseSize != mSmmImageDatabaseSize) {\r
1436aea4 837 DEBUG ((DEBUG_ERROR, "GetSmiHandlerProfileDatabaseData - SmmImageDatabaseSize mismatch!\n"));\r
ca41f3f4
JY
838 return EFI_INVALID_PARAMETER;\r
839 }\r
1436aea4
MK
840\r
841 SmmRootSmiDatabaseSize = GetSmmSmiDatabaseData (mSmmCoreRootSmiEntryList, SmmCoreSmiHandlerCategoryRootHandler, (UINT8 *)Data + SmmImageDatabaseSize, mSmmRootSmiDatabaseSize);\r
ca41f3f4 842 if (SmmRootSmiDatabaseSize != mSmmRootSmiDatabaseSize) {\r
1436aea4 843 DEBUG ((DEBUG_ERROR, "GetSmiHandlerProfileDatabaseData - SmmRootSmiDatabaseSize mismatch!\n"));\r
ca41f3f4
JY
844 return EFI_INVALID_PARAMETER;\r
845 }\r
1436aea4
MK
846\r
847 SmmSmiDatabaseSize = GetSmmSmiDatabaseData (mSmmCoreSmiEntryList, SmmCoreSmiHandlerCategoryGuidHandler, (UINT8 *)Data + SmmImageDatabaseSize + mSmmRootSmiDatabaseSize, mSmmSmiDatabaseSize);\r
ca41f3f4 848 if (SmmSmiDatabaseSize != mSmmSmiDatabaseSize) {\r
1436aea4 849 DEBUG ((DEBUG_ERROR, "GetSmiHandlerProfileDatabaseData - SmmSmiDatabaseSize mismatch!\n"));\r
ca41f3f4
JY
850 return EFI_INVALID_PARAMETER;\r
851 }\r
1436aea4
MK
852\r
853 SmmHardwareSmiDatabaseSize = GetSmmSmiDatabaseData (mSmmCoreHardwareSmiEntryList, SmmCoreSmiHandlerCategoryHardwareHandler, (UINT8 *)Data + SmmImageDatabaseSize + SmmRootSmiDatabaseSize + SmmSmiDatabaseSize, mSmmHardwareSmiDatabaseSize);\r
ca41f3f4 854 if (SmmHardwareSmiDatabaseSize != mSmmHardwareSmiDatabaseSize) {\r
1436aea4 855 DEBUG ((DEBUG_ERROR, "GetSmiHandlerProfileDatabaseData - SmmHardwareSmiDatabaseSize mismatch!\n"));\r
ca41f3f4
JY
856 return EFI_INVALID_PARAMETER;\r
857 }\r
858\r
859 return EFI_SUCCESS;\r
860}\r
861\r
862/**\r
863 build SMI handler profile database.\r
864**/\r
865VOID\r
1436aea4 866BuildSmiHandlerProfileDatabase (\r
ca41f3f4
JY
867 VOID\r
868 )\r
869{\r
870 EFI_STATUS Status;\r
1436aea4
MK
871\r
872 mSmiHandlerProfileDatabaseSize = GetSmiHandlerProfileDatabaseSize ();\r
873 mSmiHandlerProfileDatabase = AllocatePool (mSmiHandlerProfileDatabaseSize);\r
ca41f3f4
JY
874 if (mSmiHandlerProfileDatabase == NULL) {\r
875 return;\r
876 }\r
1436aea4
MK
877\r
878 Status = GetSmiHandlerProfileDatabaseData (mSmiHandlerProfileDatabase);\r
879 if (EFI_ERROR (Status)) {\r
880 FreePool (mSmiHandlerProfileDatabase);\r
ca41f3f4
JY
881 mSmiHandlerProfileDatabase = NULL;\r
882 }\r
883}\r
884\r
885/**\r
886 Copy SMI handler profile data.\r
887\r
888 @param DataBuffer The buffer to hold SMI handler profile data.\r
889 @param DataSize On input, data buffer size.\r
890 On output, actual data buffer size copied.\r
891 @param DataOffset On input, data buffer offset to copy.\r
892 On output, next time data buffer offset to copy.\r
893\r
894**/\r
895VOID\r
1436aea4
MK
896SmiHandlerProfileCopyData (\r
897 OUT VOID *DataBuffer,\r
898 IN OUT UINT64 *DataSize,\r
899 IN OUT UINT64 *DataOffset\r
ca41f3f4
JY
900 )\r
901{\r
902 if (*DataOffset >= mSmiHandlerProfileDatabaseSize) {\r
903 *DataOffset = mSmiHandlerProfileDatabaseSize;\r
904 return;\r
905 }\r
1436aea4 906\r
ca41f3f4
JY
907 if (mSmiHandlerProfileDatabaseSize - *DataOffset < *DataSize) {\r
908 *DataSize = mSmiHandlerProfileDatabaseSize - *DataOffset;\r
909 }\r
910\r
1436aea4 911 CopyMem (\r
ca41f3f4
JY
912 DataBuffer,\r
913 (UINT8 *)mSmiHandlerProfileDatabase + *DataOffset,\r
914 (UINTN)*DataSize\r
915 );\r
916 *DataOffset = *DataOffset + *DataSize;\r
917}\r
918\r
919/**\r
920 SMI handler profile handler to get info.\r
921\r
922 @param SmiHandlerProfileParameterGetInfo The parameter of SMI handler profile get info.\r
923\r
924**/\r
925VOID\r
1436aea4
MK
926SmiHandlerProfileHandlerGetInfo (\r
927 IN SMI_HANDLER_PROFILE_PARAMETER_GET_INFO *SmiHandlerProfileParameterGetInfo\r
ca41f3f4
JY
928 )\r
929{\r
1436aea4 930 BOOLEAN SmiHandlerProfileRecordingStatus;\r
ca41f3f4 931\r
1436aea4 932 SmiHandlerProfileRecordingStatus = mSmiHandlerProfileRecordingStatus;\r
ca41f3f4
JY
933 mSmiHandlerProfileRecordingStatus = FALSE;\r
934\r
1436aea4 935 SmiHandlerProfileParameterGetInfo->DataSize = mSmiHandlerProfileDatabaseSize;\r
ca41f3f4
JY
936 SmiHandlerProfileParameterGetInfo->Header.ReturnStatus = 0;\r
937\r
938 mSmiHandlerProfileRecordingStatus = SmiHandlerProfileRecordingStatus;\r
939}\r
940\r
941/**\r
942 SMI handler profile handler to get data by offset.\r
943\r
944 @param SmiHandlerProfileParameterGetDataByOffset The parameter of SMI handler profile get data by offset.\r
945\r
946**/\r
947VOID\r
1436aea4
MK
948SmiHandlerProfileHandlerGetDataByOffset (\r
949 IN SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET *SmiHandlerProfileParameterGetDataByOffset\r
ca41f3f4
JY
950 )\r
951{\r
1436aea4
MK
952 SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET SmiHandlerProfileGetDataByOffset;\r
953 BOOLEAN SmiHandlerProfileRecordingStatus;\r
ca41f3f4 954\r
1436aea4 955 SmiHandlerProfileRecordingStatus = mSmiHandlerProfileRecordingStatus;\r
ca41f3f4
JY
956 mSmiHandlerProfileRecordingStatus = FALSE;\r
957\r
1436aea4 958 CopyMem (&SmiHandlerProfileGetDataByOffset, SmiHandlerProfileParameterGetDataByOffset, sizeof (SmiHandlerProfileGetDataByOffset));\r
ca41f3f4
JY
959\r
960 //\r
961 // Sanity check\r
962 //\r
1436aea4
MK
963 if (!SmmIsBufferOutsideSmmValid ((UINTN)SmiHandlerProfileGetDataByOffset.DataBuffer, (UINTN)SmiHandlerProfileGetDataByOffset.DataSize)) {\r
964 DEBUG ((DEBUG_ERROR, "SmiHandlerProfileHandlerGetDataByOffset: SMI handler profile get data in SMRAM or overflow!\n"));\r
ca41f3f4
JY
965 SmiHandlerProfileParameterGetDataByOffset->Header.ReturnStatus = (UINT64)(INT64)(INTN)EFI_ACCESS_DENIED;\r
966 goto Done;\r
967 }\r
968\r
1436aea4
MK
969 SmiHandlerProfileCopyData ((VOID *)(UINTN)SmiHandlerProfileGetDataByOffset.DataBuffer, &SmiHandlerProfileGetDataByOffset.DataSize, &SmiHandlerProfileGetDataByOffset.DataOffset);\r
970 CopyMem (SmiHandlerProfileParameterGetDataByOffset, &SmiHandlerProfileGetDataByOffset, sizeof (SmiHandlerProfileGetDataByOffset));\r
ca41f3f4
JY
971 SmiHandlerProfileParameterGetDataByOffset->Header.ReturnStatus = 0;\r
972\r
973Done:\r
974 mSmiHandlerProfileRecordingStatus = SmiHandlerProfileRecordingStatus;\r
975}\r
976\r
977/**\r
978 Dispatch function for a Software SMI handler.\r
979\r
980 Caution: This function may receive untrusted input.\r
981 Communicate buffer and buffer size are external input, so this function will do basic validation.\r
982\r
983 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
984 @param Context Points to an optional handler context which was specified when the\r
985 handler was registered.\r
986 @param CommBuffer A pointer to a collection of data in memory that will\r
987 be conveyed from a non-SMM environment into an SMM environment.\r
988 @param CommBufferSize The size of the CommBuffer.\r
989\r
990 @retval EFI_SUCCESS Command is handled successfully.\r
991**/\r
992EFI_STATUS\r
993EFIAPI\r
1436aea4 994SmiHandlerProfileHandler (\r
ca41f3f4
JY
995 IN EFI_HANDLE DispatchHandle,\r
996 IN CONST VOID *Context OPTIONAL,\r
997 IN OUT VOID *CommBuffer OPTIONAL,\r
998 IN OUT UINTN *CommBufferSize OPTIONAL\r
999 )\r
1000{\r
1436aea4
MK
1001 SMI_HANDLER_PROFILE_PARAMETER_HEADER *SmiHandlerProfileParameterHeader;\r
1002 UINTN TempCommBufferSize;\r
ca41f3f4 1003\r
1436aea4 1004 DEBUG ((DEBUG_ERROR, "SmiHandlerProfileHandler Enter\n"));\r
ca41f3f4
JY
1005\r
1006 if (mSmiHandlerProfileDatabase == NULL) {\r
1007 return EFI_SUCCESS;\r
1008 }\r
1009\r
1010 //\r
1011 // If input is invalid, stop processing this SMI\r
1012 //\r
1436aea4 1013 if ((CommBuffer == NULL) || (CommBufferSize == NULL)) {\r
ca41f3f4
JY
1014 return EFI_SUCCESS;\r
1015 }\r
1016\r
1017 TempCommBufferSize = *CommBufferSize;\r
1018\r
1436aea4
MK
1019 if (TempCommBufferSize < sizeof (SMI_HANDLER_PROFILE_PARAMETER_HEADER)) {\r
1020 DEBUG ((DEBUG_ERROR, "SmiHandlerProfileHandler: SMM communication buffer size invalid!\n"));\r
ca41f3f4
JY
1021 return EFI_SUCCESS;\r
1022 }\r
1023\r
1436aea4
MK
1024 if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {\r
1025 DEBUG ((DEBUG_ERROR, "SmiHandlerProfileHandler: SMM communication buffer in SMRAM or overflow!\n"));\r
ca41f3f4
JY
1026 return EFI_SUCCESS;\r
1027 }\r
1028\r
1436aea4 1029 SmiHandlerProfileParameterHeader = (SMI_HANDLER_PROFILE_PARAMETER_HEADER *)((UINTN)CommBuffer);\r
ca41f3f4
JY
1030 SmiHandlerProfileParameterHeader->ReturnStatus = (UINT64)-1;\r
1031\r
1032 switch (SmiHandlerProfileParameterHeader->Command) {\r
1436aea4
MK
1033 case SMI_HANDLER_PROFILE_COMMAND_GET_INFO:\r
1034 DEBUG ((DEBUG_ERROR, "SmiHandlerProfileHandlerGetInfo\n"));\r
1035 if (TempCommBufferSize != sizeof (SMI_HANDLER_PROFILE_PARAMETER_GET_INFO)) {\r
1036 DEBUG ((DEBUG_ERROR, "SmiHandlerProfileHandler: SMM communication buffer size invalid!\n"));\r
1037 return EFI_SUCCESS;\r
1038 }\r
1039\r
1040 SmiHandlerProfileHandlerGetInfo ((SMI_HANDLER_PROFILE_PARAMETER_GET_INFO *)(UINTN)CommBuffer);\r
1041 break;\r
1042 case SMI_HANDLER_PROFILE_COMMAND_GET_DATA_BY_OFFSET:\r
1043 DEBUG ((DEBUG_ERROR, "SmiHandlerProfileHandlerGetDataByOffset\n"));\r
1044 if (TempCommBufferSize != sizeof (SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET)) {\r
1045 DEBUG ((DEBUG_ERROR, "SmiHandlerProfileHandler: SMM communication buffer size invalid!\n"));\r
1046 return EFI_SUCCESS;\r
1047 }\r
1048\r
1049 SmiHandlerProfileHandlerGetDataByOffset ((SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET *)(UINTN)CommBuffer);\r
1050 break;\r
1051 default:\r
1052 break;\r
ca41f3f4
JY
1053 }\r
1054\r
1436aea4 1055 DEBUG ((DEBUG_ERROR, "SmiHandlerProfileHandler Exit\n"));\r
ca41f3f4
JY
1056\r
1057 return EFI_SUCCESS;\r
1058}\r
1059\r
1060/**\r
1061 Register SMI handler profile handler.\r
1062**/\r
1063VOID\r
1064RegisterSmiHandlerProfileHandler (\r
1065 VOID\r
1066 )\r
1067{\r
1436aea4
MK
1068 EFI_STATUS Status;\r
1069 EFI_HANDLE DispatchHandle;\r
ca41f3f4
JY
1070\r
1071 Status = gSmst->SmiHandlerRegister (\r
1072 SmiHandlerProfileHandler,\r
1073 &gSmiHandlerProfileGuid,\r
1074 &DispatchHandle\r
1075 );\r
1076 ASSERT_EFI_ERROR (Status);\r
1077\r
1436aea4 1078 BuildSmiHandlerProfileDatabase ();\r
ca41f3f4
JY
1079}\r
1080\r
1081/**\r
1082 Finds the SMI entry for the requested handler type.\r
1083\r
1084 @param HandlerType The type of the interrupt\r
1085 @param Create Create a new entry if not found\r
1086\r
1087 @return SMI entry\r
1088**/\r
1089SMI_ENTRY *\r
1090SmmCoreFindHardwareSmiEntry (\r
1091 IN EFI_GUID *HandlerType,\r
1092 IN BOOLEAN Create\r
1093 )\r
1094{\r
1095 LIST_ENTRY *Link;\r
1096 SMI_ENTRY *Item;\r
1097 SMI_ENTRY *SmiEntry;\r
1098\r
1099 //\r
1100 // Search the SMI entry list for the matching GUID\r
1101 //\r
1102 SmiEntry = NULL;\r
1103 for (Link = mHardwareSmiEntryList.ForwardLink;\r
1104 Link != &mHardwareSmiEntryList;\r
1436aea4
MK
1105 Link = Link->ForwardLink)\r
1106 {\r
ca41f3f4
JY
1107 Item = CR (Link, SMI_ENTRY, AllEntries, SMI_ENTRY_SIGNATURE);\r
1108 if (CompareGuid (&Item->HandlerType, HandlerType)) {\r
1109 //\r
1110 // This is the SMI entry\r
1111 //\r
1112 SmiEntry = Item;\r
1113 break;\r
1114 }\r
1115 }\r
1116\r
1117 //\r
1118 // If the protocol entry was not found and Create is TRUE, then\r
1119 // allocate a new entry\r
1120 //\r
1121 if ((SmiEntry == NULL) && Create) {\r
1436aea4 1122 SmiEntry = AllocatePool (sizeof (SMI_ENTRY));\r
ca41f3f4
JY
1123 if (SmiEntry != NULL) {\r
1124 //\r
1125 // Initialize new SMI entry structure\r
1126 //\r
1127 SmiEntry->Signature = SMI_ENTRY_SIGNATURE;\r
1128 CopyGuid ((VOID *)&SmiEntry->HandlerType, HandlerType);\r
1129 InitializeListHead (&SmiEntry->SmiHandlers);\r
1130\r
1131 //\r
1132 // Add it to SMI entry list\r
1133 //\r
1134 InsertTailList (&mHardwareSmiEntryList, &SmiEntry->AllEntries);\r
1135 }\r
1136 }\r
1436aea4 1137\r
ca41f3f4
JY
1138 return SmiEntry;\r
1139}\r
1140\r
1c3ac4b9
JY
1141/**\r
1142 Convert EFI_SMM_USB_REGISTER_CONTEXT to SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT.\r
1143\r
1144 @param UsbContext A pointer to EFI_SMM_USB_REGISTER_CONTEXT\r
1145 @param UsbContextSize The size of EFI_SMM_USB_REGISTER_CONTEXT in bytes\r
1146 @param SmiHandlerUsbContextSize The size of SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT in bytes\r
1147\r
1148 @return SmiHandlerUsbContext A pointer to SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT\r
1149**/\r
1150SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *\r
1151ConvertSmiHandlerUsbContext (\r
1436aea4
MK
1152 IN EFI_SMM_USB_REGISTER_CONTEXT *UsbContext,\r
1153 IN UINTN UsbContextSize,\r
1154 OUT UINTN *SmiHandlerUsbContextSize\r
1c3ac4b9
JY
1155 )\r
1156{\r
1157 UINTN DevicePathSize;\r
1158 SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *SmiHandlerUsbContext;\r
1159\r
1436aea4 1160 ASSERT (UsbContextSize == sizeof (EFI_SMM_USB_REGISTER_CONTEXT));\r
1c3ac4b9 1161\r
1436aea4 1162 DevicePathSize = GetDevicePathSize (UsbContext->Device);\r
1c3ac4b9
JY
1163 SmiHandlerUsbContext = AllocatePool (sizeof (SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT) + DevicePathSize);\r
1164 if (SmiHandlerUsbContext == NULL) {\r
1165 *SmiHandlerUsbContextSize = 0;\r
1166 return NULL;\r
1167 }\r
1436aea4
MK
1168\r
1169 SmiHandlerUsbContext->Type = UsbContext->Type;\r
1c3ac4b9
JY
1170 SmiHandlerUsbContext->DevicePathSize = (UINT32)DevicePathSize;\r
1171 CopyMem (SmiHandlerUsbContext + 1, UsbContext->Device, DevicePathSize);\r
1172 *SmiHandlerUsbContextSize = sizeof (SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT) + DevicePathSize;\r
1173 return SmiHandlerUsbContext;\r
1174}\r
1175\r
f2485395
SZ
1176/**\r
1177 Convert EFI_SMM_SW_REGISTER_CONTEXT to SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT.\r
1178\r
1179 @param SwContext A pointer to EFI_SMM_SW_REGISTER_CONTEXT\r
1180 @param SwContextSize The size of EFI_SMM_SW_REGISTER_CONTEXT in bytes\r
1181 @param SmiHandlerSwContextSize The size of SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT in bytes\r
1182\r
1183 @return SmiHandlerSwContext A pointer to SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT\r
1184**/\r
1185SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT *\r
1186ConvertSmiHandlerSwContext (\r
1436aea4
MK
1187 IN EFI_SMM_SW_REGISTER_CONTEXT *SwContext,\r
1188 IN UINTN SwContextSize,\r
1189 OUT UINTN *SmiHandlerSwContextSize\r
f2485395
SZ
1190 )\r
1191{\r
1192 SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT *SmiHandlerSwContext;\r
1193\r
1436aea4 1194 ASSERT (SwContextSize == sizeof (EFI_SMM_SW_REGISTER_CONTEXT));\r
f2485395
SZ
1195\r
1196 SmiHandlerSwContext = AllocatePool (sizeof (SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT));\r
1197 if (SmiHandlerSwContext == NULL) {\r
1198 *SmiHandlerSwContextSize = 0;\r
1199 return NULL;\r
1200 }\r
1436aea4 1201\r
f2485395 1202 SmiHandlerSwContext->SwSmiInputValue = SwContext->SwSmiInputValue;\r
1436aea4 1203 *SmiHandlerSwContextSize = sizeof (SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT);\r
f2485395
SZ
1204 return SmiHandlerSwContext;\r
1205}\r
1206\r
ca41f3f4
JY
1207/**\r
1208 This function is called by SmmChildDispatcher module to report\r
1209 a new SMI handler is registered, to SmmCore.\r
1210\r
1211 @param This The protocol instance\r
1212 @param HandlerGuid The GUID to identify the type of the handler.\r
1213 For the SmmChildDispatch protocol, the HandlerGuid\r
1214 must be the GUID of SmmChildDispatch protocol.\r
1215 @param Handler The SMI handler.\r
1216 @param CallerAddress The address of the module who registers the SMI handler.\r
1217 @param Context The context of the SMI handler.\r
1218 For the SmmChildDispatch protocol, the Context\r
1219 must match the one defined for SmmChildDispatch protocol.\r
1220 @param ContextSize The size of the context in bytes.\r
1221 For the SmmChildDispatch protocol, the Context\r
1222 must match the one defined for SmmChildDispatch protocol.\r
1223\r
1224 @retval EFI_SUCCESS The information is recorded.\r
1225 @retval EFI_OUT_OF_RESOURCES There is no enough resource to record the information.\r
1226**/\r
1227EFI_STATUS\r
1228EFIAPI\r
1229SmiHandlerProfileRegisterHandler (\r
1436aea4
MK
1230 IN SMI_HANDLER_PROFILE_PROTOCOL *This,\r
1231 IN EFI_GUID *HandlerGuid,\r
1232 IN EFI_SMM_HANDLER_ENTRY_POINT2 Handler,\r
1233 IN PHYSICAL_ADDRESS CallerAddress,\r
1234 IN VOID *Context OPTIONAL,\r
1235 IN UINTN ContextSize OPTIONAL\r
ca41f3f4
JY
1236 )\r
1237{\r
1238 SMI_HANDLER *SmiHandler;\r
1239 SMI_ENTRY *SmiEntry;\r
1240 LIST_ENTRY *List;\r
1241\r
1c3ac4b9 1242 if (((ContextSize == 0) && (Context != NULL)) ||\r
1436aea4
MK
1243 ((ContextSize != 0) && (Context == NULL)))\r
1244 {\r
1c3ac4b9
JY
1245 return EFI_INVALID_PARAMETER;\r
1246 }\r
1247\r
ca41f3f4
JY
1248 SmiHandler = AllocateZeroPool (sizeof (SMI_HANDLER));\r
1249 if (SmiHandler == NULL) {\r
1250 return EFI_OUT_OF_RESOURCES;\r
1251 }\r
1252\r
1436aea4
MK
1253 SmiHandler->Signature = SMI_HANDLER_SIGNATURE;\r
1254 SmiHandler->Handler = Handler;\r
1255 SmiHandler->CallerAddr = (UINTN)CallerAddress;\r
1256 SmiHandler->Context = Context;\r
1c3ac4b9
JY
1257 SmiHandler->ContextSize = ContextSize;\r
1258\r
1259 if (Context != NULL) {\r
ca41f3f4 1260 if (CompareGuid (HandlerGuid, &gEfiSmmUsbDispatch2ProtocolGuid)) {\r
1c3ac4b9 1261 SmiHandler->Context = ConvertSmiHandlerUsbContext (Context, ContextSize, &SmiHandler->ContextSize);\r
f2485395
SZ
1262 } else if (CompareGuid (HandlerGuid, &gEfiSmmSwDispatch2ProtocolGuid)) {\r
1263 SmiHandler->Context = ConvertSmiHandlerSwContext (Context, ContextSize, &SmiHandler->ContextSize);\r
ca41f3f4
JY
1264 } else {\r
1265 SmiHandler->Context = AllocateCopyPool (ContextSize, Context);\r
1266 }\r
1267 }\r
1436aea4 1268\r
1c3ac4b9
JY
1269 if (SmiHandler->Context == NULL) {\r
1270 SmiHandler->ContextSize = 0;\r
ca41f3f4
JY
1271 }\r
1272\r
1273 SmiEntry = SmmCoreFindHardwareSmiEntry (HandlerGuid, TRUE);\r
1274 if (SmiEntry == NULL) {\r
251779fc
JY
1275 if (SmiHandler->Context != NULL) {\r
1276 FreePool (SmiHandler->Context);\r
1277 }\r
1436aea4 1278\r
1c3ac4b9 1279 FreePool (SmiHandler);\r
ca41f3f4
JY
1280 return EFI_OUT_OF_RESOURCES;\r
1281 }\r
1282\r
1283 List = &SmiEntry->SmiHandlers;\r
1284\r
1285 SmiHandler->SmiEntry = SmiEntry;\r
1286 InsertTailList (List, &SmiHandler->Link);\r
1287\r
1288 return EFI_SUCCESS;\r
1289}\r
1290\r
1291/**\r
1292 This function is called by SmmChildDispatcher module to report\r
1293 an existing SMI handler is unregistered, to SmmCore.\r
1294\r
1295 @param This The protocol instance\r
1296 @param HandlerGuid The GUID to identify the type of the handler.\r
1297 For the SmmChildDispatch protocol, the HandlerGuid\r
1298 must be the GUID of SmmChildDispatch protocol.\r
1299 @param Handler The SMI handler.\r
1c3ac4b9
JY
1300 @param Context The context of the SMI handler.\r
1301 If it is NOT NULL, it will be used to check what is registered.\r
1302 @param ContextSize The size of the context in bytes.\r
1303 If Context is NOT NULL, it will be used to check what is registered.\r
ca41f3f4
JY
1304\r
1305 @retval EFI_SUCCESS The original record is removed.\r
1306 @retval EFI_NOT_FOUND There is no record for the HandlerGuid and handler.\r
1307**/\r
1308EFI_STATUS\r
1309EFIAPI\r
1310SmiHandlerProfileUnregisterHandler (\r
1436aea4
MK
1311 IN SMI_HANDLER_PROFILE_PROTOCOL *This,\r
1312 IN EFI_GUID *HandlerGuid,\r
1313 IN EFI_SMM_HANDLER_ENTRY_POINT2 Handler,\r
1314 IN VOID *Context OPTIONAL,\r
1315 IN UINTN ContextSize OPTIONAL\r
ca41f3f4
JY
1316 )\r
1317{\r
1318 LIST_ENTRY *Link;\r
1319 LIST_ENTRY *Head;\r
1320 SMI_HANDLER *SmiHandler;\r
1321 SMI_ENTRY *SmiEntry;\r
1322 SMI_HANDLER *TargetSmiHandler;\r
1c3ac4b9
JY
1323 VOID *SearchContext;\r
1324 UINTN SearchContextSize;\r
1325\r
1326 if (((ContextSize == 0) && (Context != NULL)) ||\r
1436aea4
MK
1327 ((ContextSize != 0) && (Context == NULL)))\r
1328 {\r
1c3ac4b9
JY
1329 return EFI_INVALID_PARAMETER;\r
1330 }\r
ca41f3f4
JY
1331\r
1332 SmiEntry = SmmCoreFindHardwareSmiEntry (HandlerGuid, FALSE);\r
1333 if (SmiEntry == NULL) {\r
1334 return EFI_NOT_FOUND;\r
1335 }\r
1336\r
1436aea4 1337 SearchContext = Context;\r
1c3ac4b9
JY
1338 SearchContextSize = ContextSize;\r
1339 if (Context != NULL) {\r
1340 if (CompareGuid (HandlerGuid, &gEfiSmmUsbDispatch2ProtocolGuid)) {\r
1341 SearchContext = ConvertSmiHandlerUsbContext (Context, ContextSize, &SearchContextSize);\r
f2485395
SZ
1342 } else if (CompareGuid (HandlerGuid, &gEfiSmmSwDispatch2ProtocolGuid)) {\r
1343 SearchContext = ConvertSmiHandlerSwContext (Context, ContextSize, &SearchContextSize);\r
1c3ac4b9
JY
1344 }\r
1345 }\r
1346\r
ca41f3f4 1347 TargetSmiHandler = NULL;\r
1436aea4 1348 Head = &SmiEntry->SmiHandlers;\r
ca41f3f4
JY
1349 for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
1350 SmiHandler = CR (Link, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE);\r
1351 if (SmiHandler->Handler == Handler) {\r
1c3ac4b9 1352 if ((SearchContext == NULL) ||\r
1436aea4
MK
1353 ((SearchContextSize == SmiHandler->ContextSize) && (CompareMem (SearchContext, SmiHandler->Context, SearchContextSize) == 0)))\r
1354 {\r
1c3ac4b9
JY
1355 TargetSmiHandler = SmiHandler;\r
1356 break;\r
1357 }\r
1358 }\r
1359 }\r
1360\r
1361 if (SearchContext != NULL) {\r
1362 if (CompareGuid (HandlerGuid, &gEfiSmmUsbDispatch2ProtocolGuid)) {\r
1363 FreePool (SearchContext);\r
ca41f3f4
JY
1364 }\r
1365 }\r
1c3ac4b9 1366\r
ca41f3f4
JY
1367 if (TargetSmiHandler == NULL) {\r
1368 return EFI_NOT_FOUND;\r
1369 }\r
1436aea4 1370\r
ca41f3f4
JY
1371 SmiHandler = TargetSmiHandler;\r
1372\r
1373 RemoveEntryList (&SmiHandler->Link);\r
251779fc
JY
1374 if (SmiHandler->Context != NULL) {\r
1375 FreePool (SmiHandler->Context);\r
1376 }\r
1436aea4 1377\r
ca41f3f4
JY
1378 FreePool (SmiHandler);\r
1379\r
1380 if (IsListEmpty (&SmiEntry->SmiHandlers)) {\r
1381 RemoveEntryList (&SmiEntry->AllEntries);\r
1382 FreePool (SmiEntry);\r
1383 }\r
1384\r
1385 return EFI_SUCCESS;\r
1386}\r
1387\r
1388/**\r
1389 Initialize SmiHandler profile feature.\r
1390**/\r
1391VOID\r
1392SmmCoreInitializeSmiHandlerProfile (\r
1393 VOID\r
1394 )\r
1395{\r
1396 EFI_STATUS Status;\r
1397 VOID *Registration;\r
1398 EFI_HANDLE Handle;\r
1399\r
1400 if ((PcdGet8 (PcdSmiHandlerProfilePropertyMask) & 0x1) != 0) {\r
1401 InsertTailList (&mRootSmiEntryList, &mRootSmiEntry.AllEntries);\r
1402\r
1403 Status = gSmst->SmmRegisterProtocolNotify (\r
1404 &gEfiSmmReadyToLockProtocolGuid,\r
1405 SmmReadyToLockInSmiHandlerProfile,\r
1406 &Registration\r
1407 );\r
1408 ASSERT_EFI_ERROR (Status);\r
1409\r
1410 Handle = NULL;\r
1411 Status = gSmst->SmmInstallProtocolInterface (\r
1412 &Handle,\r
1413 &gSmiHandlerProfileGuid,\r
1414 EFI_NATIVE_INTERFACE,\r
1415 &mSmiHandlerProfile\r
1416 );\r
1417 ASSERT_EFI_ERROR (Status);\r
1418 }\r
1419}\r