]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/SmmMemLib/SmmMemLib.c
MdePkg: Clean up source files
[mirror_edk2.git] / MdePkg / Library / SmmMemLib / SmmMemLib.c
CommitLineData
d425764e
JY
1/** @file\r
2 Instance of SMM memory check library.\r
3\r
4 SMM memory check library library implementation. This library consumes SMM_ACCESS2_PROTOCOL\r
5 to get SMRAM information. In order to use this library instance, the platform should produce\r
6 all SMRAM range via SMM_ACCESS2_PROTOCOL, including the range for firmware (like SMM Core\r
7 and SMM driver) and/or specific dedicated hardware.\r
8\r
9095d37b 9 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
d425764e
JY
10 This program and the accompanying materials\r
11 are licensed and made available under the terms and conditions of the BSD License\r
12 which accompanies this distribution. The full text of the license may be found at\r
13 http://opensource.org/licenses/bsd-license.php\r
14\r
15 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
16 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
17\r
18**/\r
19\r
20\r
21#include <PiSmm.h>\r
22\r
23#include <Library/BaseLib.h>\r
24#include <Library/BaseMemoryLib.h>\r
25#include <Library/DebugLib.h>\r
26#include <Library/MemoryAllocationLib.h>\r
27#include <Library/UefiBootServicesTableLib.h>\r
28#include <Library/SmmServicesTableLib.h>\r
29#include <Library/HobLib.h>\r
30#include <Protocol/SmmAccess2.h>\r
91f51fcc
JY
31#include <Protocol/SmmReadyToLock.h>\r
32#include <Protocol/SmmEndOfDxe.h>\r
33\r
34#define NEXT_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \\r
35 ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) + (Size)))\r
d425764e
JY
36\r
37EFI_SMRAM_DESCRIPTOR *mSmmMemLibInternalSmramRanges;\r
38UINTN mSmmMemLibInternalSmramCount;\r
39\r
40//\r
41// Maximum support address used to check input buffer\r
42//\r
43EFI_PHYSICAL_ADDRESS mSmmMemLibInternalMaximumSupportAddress = 0;\r
44\r
91f51fcc
JY
45UINTN mMemoryMapEntryCount;\r
46EFI_MEMORY_DESCRIPTOR *mMemoryMap;\r
47UINTN mDescriptorSize;\r
48\r
49VOID *mRegistrationEndOfDxe;\r
50VOID *mRegistrationReadyToLock;\r
51\r
52BOOLEAN mSmmReadyToLock = FALSE;\r
53\r
d425764e 54/**\r
2a93f2c3 55 Calculate and save the maximum support address.\r
d425764e
JY
56\r
57**/\r
58VOID\r
2a93f2c3 59SmmMemLibInternalCalculateMaximumSupportAddress (\r
d425764e
JY
60 VOID\r
61 )\r
62{\r
63 VOID *Hob;\r
64 UINT32 RegEax;\r
65 UINT8 PhysicalAddressBits;\r
66\r
67 //\r
68 // Get physical address bits supported.\r
69 //\r
70 Hob = GetFirstHob (EFI_HOB_TYPE_CPU);\r
71 if (Hob != NULL) {\r
72 PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;\r
73 } else {\r
74 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
75 if (RegEax >= 0x80000008) {\r
76 AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);\r
77 PhysicalAddressBits = (UINT8) RegEax;\r
78 } else {\r
79 PhysicalAddressBits = 36;\r
80 }\r
81 }\r
82 //\r
83 // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.\r
84 //\r
85 ASSERT (PhysicalAddressBits <= 52);\r
86 if (PhysicalAddressBits > 48) {\r
87 PhysicalAddressBits = 48;\r
88 }\r
9095d37b 89\r
d425764e 90 //\r
9095d37b 91 // Save the maximum support address in one global variable\r
d425764e
JY
92 //\r
93 mSmmMemLibInternalMaximumSupportAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)(LShiftU64 (1, PhysicalAddressBits) - 1);\r
94 DEBUG ((EFI_D_INFO, "mSmmMemLibInternalMaximumSupportAddress = 0x%lx\n", mSmmMemLibInternalMaximumSupportAddress));\r
95}\r
96\r
97/**\r
98 This function check if the buffer is valid per processor architecture and not overlap with SMRAM.\r
99\r
100 @param Buffer The buffer start address to be checked.\r
101 @param Length The buffer length to be checked.\r
102\r
103 @retval TRUE This buffer is valid per processor architecture and not overlap with SMRAM.\r
104 @retval FALSE This buffer is not valid per processor architecture or overlap with SMRAM.\r
105**/\r
106BOOLEAN\r
107EFIAPI\r
108SmmIsBufferOutsideSmmValid (\r
109 IN EFI_PHYSICAL_ADDRESS Buffer,\r
110 IN UINT64 Length\r
111 )\r
112{\r
113 UINTN Index;\r
9095d37b 114\r
d425764e
JY
115 //\r
116 // Check override.\r
117 // NOTE: (B:0->L:4G) is invalid for IA32, but (B:1->L:4G-1)/(B:4G-1->L:1) is valid.\r
118 //\r
119 if ((Length > mSmmMemLibInternalMaximumSupportAddress) ||\r
120 (Buffer > mSmmMemLibInternalMaximumSupportAddress) ||\r
121 ((Length != 0) && (Buffer > (mSmmMemLibInternalMaximumSupportAddress - (Length - 1)))) ) {\r
122 //\r
123 // Overflow happen\r
124 //\r
125 DEBUG ((\r
126 EFI_D_ERROR,\r
127 "SmmIsBufferOutsideSmmValid: Overflow: Buffer (0x%lx) - Length (0x%lx), MaximumSupportAddress (0x%lx)\n",\r
128 Buffer,\r
129 Length,\r
130 mSmmMemLibInternalMaximumSupportAddress\r
131 ));\r
132 return FALSE;\r
133 }\r
9095d37b 134\r
d425764e
JY
135 for (Index = 0; Index < mSmmMemLibInternalSmramCount; Index ++) {\r
136 if (((Buffer >= mSmmMemLibInternalSmramRanges[Index].CpuStart) && (Buffer < mSmmMemLibInternalSmramRanges[Index].CpuStart + mSmmMemLibInternalSmramRanges[Index].PhysicalSize)) ||\r
137 ((mSmmMemLibInternalSmramRanges[Index].CpuStart >= Buffer) && (mSmmMemLibInternalSmramRanges[Index].CpuStart < Buffer + Length))) {\r
138 DEBUG ((\r
139 EFI_D_ERROR,\r
140 "SmmIsBufferOutsideSmmValid: Overlap: Buffer (0x%lx) - Length (0x%lx), ",\r
141 Buffer,\r
142 Length\r
143 ));\r
144 DEBUG ((\r
145 EFI_D_ERROR,\r
146 "CpuStart (0x%lx) - PhysicalSize (0x%lx)\n",\r
147 mSmmMemLibInternalSmramRanges[Index].CpuStart,\r
148 mSmmMemLibInternalSmramRanges[Index].PhysicalSize\r
149 ));\r
150 return FALSE;\r
151 }\r
152 }\r
153\r
91f51fcc
JY
154 //\r
155 // Check override for Valid Communication Region\r
156 //\r
157 if (mSmmReadyToLock) {\r
158 EFI_MEMORY_DESCRIPTOR *MemoryMap;\r
159 BOOLEAN InValidCommunicationRegion;\r
9095d37b 160\r
91f51fcc
JY
161 InValidCommunicationRegion = FALSE;\r
162 MemoryMap = mMemoryMap;\r
163 for (Index = 0; Index < mMemoryMapEntryCount; Index++) {\r
164 if ((Buffer >= MemoryMap->PhysicalStart) &&\r
165 (Buffer + Length <= MemoryMap->PhysicalStart + LShiftU64 (MemoryMap->NumberOfPages, EFI_PAGE_SHIFT))) {\r
166 InValidCommunicationRegion = TRUE;\r
167 }\r
168 MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, mDescriptorSize);\r
169 }\r
170\r
171 if (!InValidCommunicationRegion) {\r
172 DEBUG ((\r
173 EFI_D_ERROR,\r
174 "SmmIsBufferOutsideSmmValid: Not in ValidCommunicationRegion: Buffer (0x%lx) - Length (0x%lx), ",\r
175 Buffer,\r
176 Length\r
177 ));\r
91f51fcc
JY
178 return FALSE;\r
179 }\r
180 }\r
d425764e
JY
181 return TRUE;\r
182}\r
183\r
184/**\r
185 Copies a source buffer (non-SMRAM) to a destination buffer (SMRAM).\r
186\r
187 This function copies a source buffer (non-SMRAM) to a destination buffer (SMRAM).\r
188 It checks if source buffer is valid per processor architecture and not overlap with SMRAM.\r
189 If the check passes, it copies memory and returns EFI_SUCCESS.\r
190 If the check fails, it return EFI_SECURITY_VIOLATION.\r
191 The implementation must be reentrant.\r
192\r
193 @param DestinationBuffer The pointer to the destination buffer of the memory copy.\r
194 @param SourceBuffer The pointer to the source buffer of the memory copy.\r
195 @param Length The number of bytes to copy from SourceBuffer to DestinationBuffer.\r
196\r
197 @retval EFI_SECURITY_VIOLATION The SourceBuffer is invalid per processor architecture or overlap with SMRAM.\r
198 @retval EFI_SUCCESS Memory is copied.\r
199\r
200**/\r
201EFI_STATUS\r
202EFIAPI\r
203SmmCopyMemToSmram (\r
204 OUT VOID *DestinationBuffer,\r
205 IN CONST VOID *SourceBuffer,\r
206 IN UINTN Length\r
207 )\r
208{\r
209 if (!SmmIsBufferOutsideSmmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)SourceBuffer, Length)) {\r
210 DEBUG ((EFI_D_ERROR, "SmmCopyMemToSmram: Security Violation: Source (0x%x), Length (0x%x)\n", SourceBuffer, Length));\r
211 return EFI_SECURITY_VIOLATION;\r
212 }\r
213 CopyMem (DestinationBuffer, SourceBuffer, Length);\r
214 return EFI_SUCCESS;\r
215}\r
216\r
217/**\r
218 Copies a source buffer (SMRAM) to a destination buffer (NON-SMRAM).\r
219\r
220 This function copies a source buffer (non-SMRAM) to a destination buffer (SMRAM).\r
221 It checks if destination buffer is valid per processor architecture and not overlap with SMRAM.\r
222 If the check passes, it copies memory and returns EFI_SUCCESS.\r
223 If the check fails, it returns EFI_SECURITY_VIOLATION.\r
224 The implementation must be reentrant.\r
9095d37b 225\r
d425764e
JY
226 @param DestinationBuffer The pointer to the destination buffer of the memory copy.\r
227 @param SourceBuffer The pointer to the source buffer of the memory copy.\r
228 @param Length The number of bytes to copy from SourceBuffer to DestinationBuffer.\r
229\r
230 @retval EFI_SECURITY_VIOLATION The DesinationBuffer is invalid per processor architecture or overlap with SMRAM.\r
231 @retval EFI_SUCCESS Memory is copied.\r
232\r
233**/\r
234EFI_STATUS\r
235EFIAPI\r
236SmmCopyMemFromSmram (\r
237 OUT VOID *DestinationBuffer,\r
238 IN CONST VOID *SourceBuffer,\r
239 IN UINTN Length\r
240 )\r
241{\r
242 if (!SmmIsBufferOutsideSmmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)DestinationBuffer, Length)) {\r
243 DEBUG ((EFI_D_ERROR, "SmmCopyMemFromSmram: Security Violation: Destination (0x%x), Length (0x%x)\n", DestinationBuffer, Length));\r
244 return EFI_SECURITY_VIOLATION;\r
245 }\r
246 CopyMem (DestinationBuffer, SourceBuffer, Length);\r
247 return EFI_SUCCESS;\r
248}\r
249\r
250/**\r
251 Copies a source buffer (NON-SMRAM) to a destination buffer (NON-SMRAM).\r
252\r
253 This function copies a source buffer (non-SMRAM) to a destination buffer (SMRAM).\r
254 It checks if source buffer and destination buffer are valid per processor architecture and not overlap with SMRAM.\r
255 If the check passes, it copies memory and returns EFI_SUCCESS.\r
256 If the check fails, it returns EFI_SECURITY_VIOLATION.\r
257 The implementation must be reentrant, and it must handle the case where source buffer overlaps destination buffer.\r
9095d37b 258\r
d425764e
JY
259 @param DestinationBuffer The pointer to the destination buffer of the memory copy.\r
260 @param SourceBuffer The pointer to the source buffer of the memory copy.\r
261 @param Length The number of bytes to copy from SourceBuffer to DestinationBuffer.\r
262\r
263 @retval EFI_SECURITY_VIOLATION The DesinationBuffer is invalid per processor architecture or overlap with SMRAM.\r
264 @retval EFI_SECURITY_VIOLATION The SourceBuffer is invalid per processor architecture or overlap with SMRAM.\r
265 @retval EFI_SUCCESS Memory is copied.\r
266\r
267**/\r
268EFI_STATUS\r
269EFIAPI\r
270SmmCopyMem (\r
271 OUT VOID *DestinationBuffer,\r
272 IN CONST VOID *SourceBuffer,\r
273 IN UINTN Length\r
274 )\r
275{\r
276 if (!SmmIsBufferOutsideSmmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)DestinationBuffer, Length)) {\r
277 DEBUG ((EFI_D_ERROR, "SmmCopyMem: Security Violation: Destination (0x%x), Length (0x%x)\n", DestinationBuffer, Length));\r
278 return EFI_SECURITY_VIOLATION;\r
279 }\r
280 if (!SmmIsBufferOutsideSmmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)SourceBuffer, Length)) {\r
281 DEBUG ((EFI_D_ERROR, "SmmCopyMem: Security Violation: Source (0x%x), Length (0x%x)\n", SourceBuffer, Length));\r
282 return EFI_SECURITY_VIOLATION;\r
283 }\r
284 CopyMem (DestinationBuffer, SourceBuffer, Length);\r
285 return EFI_SUCCESS;\r
286}\r
287\r
288/**\r
289 Fills a target buffer (NON-SMRAM) with a byte value.\r
290\r
291 This function fills a target buffer (non-SMRAM) with a byte value.\r
292 It checks if target buffer is valid per processor architecture and not overlap with SMRAM.\r
293 If the check passes, it fills memory and returns EFI_SUCCESS.\r
294 If the check fails, it returns EFI_SECURITY_VIOLATION.\r
9095d37b 295\r
d425764e
JY
296 @param Buffer The memory to set.\r
297 @param Length The number of bytes to set.\r
298 @param Value The value with which to fill Length bytes of Buffer.\r
9095d37b 299\r
d425764e
JY
300 @retval EFI_SECURITY_VIOLATION The Buffer is invalid per processor architecture or overlap with SMRAM.\r
301 @retval EFI_SUCCESS Memory is set.\r
302\r
303**/\r
304EFI_STATUS\r
305EFIAPI\r
306SmmSetMem (\r
307 OUT VOID *Buffer,\r
308 IN UINTN Length,\r
309 IN UINT8 Value\r
310 )\r
311{\r
312 if (!SmmIsBufferOutsideSmmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Length)) {\r
313 DEBUG ((EFI_D_ERROR, "SmmSetMem: Security Violation: Source (0x%x), Length (0x%x)\n", Buffer, Length));\r
314 return EFI_SECURITY_VIOLATION;\r
315 }\r
316 SetMem (Buffer, Length, Value);\r
317 return EFI_SUCCESS;\r
318}\r
319\r
91f51fcc
JY
320/**\r
321 Notification for SMM EndOfDxe protocol.\r
322\r
323 @param[in] Protocol Points to the protocol's unique identifier.\r
324 @param[in] Interface Points to the interface instance.\r
325 @param[in] Handle The handle on which the interface was installed.\r
326\r
327 @retval EFI_SUCCESS Notification runs successfully.\r
328**/\r
329EFI_STATUS\r
330EFIAPI\r
331SmmLibInternalEndOfDxeNotify (\r
332 IN CONST EFI_GUID *Protocol,\r
333 IN VOID *Interface,\r
334 IN EFI_HANDLE Handle\r
335 )\r
336{\r
337 EFI_STATUS Status;\r
338 UINTN MapKey;\r
339 UINTN MemoryMapSize;\r
340 EFI_MEMORY_DESCRIPTOR *MemoryMap;\r
341 EFI_MEMORY_DESCRIPTOR *MemoryMapStart;\r
342 EFI_MEMORY_DESCRIPTOR *SmmMemoryMapStart;\r
343 UINTN MemoryMapEntryCount;\r
344 UINTN DescriptorSize;\r
345 UINT32 DescriptorVersion;\r
346 UINTN Index;\r
347\r
348 MemoryMapSize = 0;\r
349 MemoryMap = NULL;\r
350 Status = gBS->GetMemoryMap (\r
351 &MemoryMapSize,\r
352 MemoryMap,\r
353 &MapKey,\r
354 &DescriptorSize,\r
355 &DescriptorVersion\r
356 );\r
357 ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
358\r
359 do {\r
360 Status = gBS->AllocatePool (EfiBootServicesData, MemoryMapSize, (VOID **)&MemoryMap);\r
361 ASSERT (MemoryMap != NULL);\r
9095d37b 362\r
91f51fcc
JY
363 Status = gBS->GetMemoryMap (\r
364 &MemoryMapSize,\r
365 MemoryMap,\r
366 &MapKey,\r
367 &DescriptorSize,\r
368 &DescriptorVersion\r
369 );\r
370 if (EFI_ERROR (Status)) {\r
371 gBS->FreePool (MemoryMap);\r
372 }\r
373 } while (Status == EFI_BUFFER_TOO_SMALL);\r
374\r
375 //\r
376 // Get Count\r
377 //\r
378 mDescriptorSize = DescriptorSize;\r
379 MemoryMapEntryCount = MemoryMapSize/DescriptorSize;\r
380 MemoryMapStart = MemoryMap;\r
381 mMemoryMapEntryCount = 0;\r
382 for (Index = 0; Index < MemoryMapEntryCount; Index++) {\r
383 switch (MemoryMap->Type) {\r
384 case EfiReservedMemoryType:\r
385 case EfiRuntimeServicesCode:\r
386 case EfiRuntimeServicesData:\r
387 case EfiACPIMemoryNVS:\r
388 mMemoryMapEntryCount++;\r
389 break;\r
390 }\r
391 MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, DescriptorSize);\r
392 }\r
393 MemoryMap = MemoryMapStart;\r
9095d37b 394\r
91f51fcc
JY
395 //\r
396 // Get Data\r
397 //\r
398 mMemoryMap = AllocatePool (mMemoryMapEntryCount*DescriptorSize);\r
399 ASSERT (mMemoryMap != NULL);\r
400 SmmMemoryMapStart = mMemoryMap;\r
401 for (Index = 0; Index < MemoryMapEntryCount; Index++) {\r
402 switch (MemoryMap->Type) {\r
403 case EfiReservedMemoryType:\r
404 case EfiRuntimeServicesCode:\r
405 case EfiRuntimeServicesData:\r
406 case EfiACPIMemoryNVS:\r
407 CopyMem (mMemoryMap, MemoryMap, DescriptorSize);\r
408 mMemoryMap = NEXT_MEMORY_DESCRIPTOR(mMemoryMap, DescriptorSize);\r
409 break;\r
410 }\r
411 MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, DescriptorSize);\r
412 }\r
413 mMemoryMap = SmmMemoryMapStart;\r
414 MemoryMap = MemoryMapStart;\r
9095d37b 415\r
91f51fcc
JY
416 gBS->FreePool (MemoryMap);\r
417\r
418 return EFI_SUCCESS;\r
419}\r
420\r
421\r
422/**\r
423 Notification for SMM ReadyToLock protocol.\r
424\r
425 @param[in] Protocol Points to the protocol's unique identifier.\r
426 @param[in] Interface Points to the interface instance.\r
427 @param[in] Handle The handle on which the interface was installed.\r
428\r
429 @retval EFI_SUCCESS Notification runs successfully.\r
430**/\r
431EFI_STATUS\r
432EFIAPI\r
433SmmLibInternalReadyToLockNotify (\r
434 IN CONST EFI_GUID *Protocol,\r
435 IN VOID *Interface,\r
436 IN EFI_HANDLE Handle\r
437 )\r
438{\r
439 mSmmReadyToLock = TRUE;\r
440 return EFI_SUCCESS;\r
441}\r
d425764e
JY
442/**\r
443 The constructor function initializes the Smm Mem library\r
444\r
445 @param ImageHandle The firmware allocated handle for the EFI image.\r
446 @param SystemTable A pointer to the EFI System Table.\r
447\r
448 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
449\r
450**/\r
451EFI_STATUS\r
452EFIAPI\r
453SmmMemLibConstructor (\r
454 IN EFI_HANDLE ImageHandle,\r
455 IN EFI_SYSTEM_TABLE *SystemTable\r
456 )\r
457{\r
458 EFI_STATUS Status;\r
459 EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;\r
460 UINTN Size;\r
9095d37b 461\r
d425764e
JY
462 //\r
463 // Get SMRAM information\r
464 //\r
465 Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess);\r
466 ASSERT_EFI_ERROR (Status);\r
467\r
468 Size = 0;\r
469 Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);\r
470 ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
471\r
472 mSmmMemLibInternalSmramRanges = AllocatePool (Size);\r
473 ASSERT (mSmmMemLibInternalSmramRanges != NULL);\r
474\r
475 Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmmMemLibInternalSmramRanges);\r
476 ASSERT_EFI_ERROR (Status);\r
477\r
478 mSmmMemLibInternalSmramCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);\r
479\r
480 //\r
2a93f2c3 481 // Calculate and save maximum support address\r
d425764e 482 //\r
2a93f2c3 483 SmmMemLibInternalCalculateMaximumSupportAddress ();\r
d425764e 484\r
91f51fcc
JY
485 //\r
486 // Register EndOfDxe to get UEFI memory map\r
487 //\r
488 Status = gSmst->SmmRegisterProtocolNotify (&gEfiSmmEndOfDxeProtocolGuid, SmmLibInternalEndOfDxeNotify, &mRegistrationEndOfDxe);\r
489 ASSERT_EFI_ERROR (Status);\r
490\r
491 //\r
492 // Register ready to lock so that we can know when to check valid SMRAM region\r
493 //\r
494 Status = gSmst->SmmRegisterProtocolNotify (&gEfiSmmReadyToLockProtocolGuid, SmmLibInternalReadyToLockNotify, &mRegistrationReadyToLock);\r
495 ASSERT_EFI_ERROR (Status);\r
496\r
d425764e
JY
497 return EFI_SUCCESS;\r
498}\r
499\r
500/**\r
501 The destructor function frees resource used in the Smm Mem library\r
502\r
503 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
504 @param[in] SystemTable A pointer to the EFI System Table.\r
505\r
506 @retval EFI_SUCCESS The deconstructor always returns EFI_SUCCESS.\r
507**/\r
508EFI_STATUS\r
509EFIAPI\r
510SmmMemLibDestructor (\r
511 IN EFI_HANDLE ImageHandle,\r
512 IN EFI_SYSTEM_TABLE *SystemTable\r
513 )\r
514{\r
515 FreePool (mSmmMemLibInternalSmramRanges);\r
516\r
91f51fcc
JY
517 gSmst->SmmRegisterProtocolNotify (&gEfiSmmEndOfDxeProtocolGuid, NULL, &mRegistrationEndOfDxe);\r
518 gSmst->SmmRegisterProtocolNotify (&gEfiSmmReadyToLockProtocolGuid, NULL, &mRegistrationReadyToLock);\r
d425764e
JY
519 return EFI_SUCCESS;\r
520}\r