]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Enhance PiSmmCoreMemoryAllocationLib Free function implementation to call gSmst or...
authorlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 28 Jul 2010 01:08:13 +0000 (01:08 +0000)
committerlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 28 Jul 2010 01:08:13 +0000 (01:08 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10701 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/MemoryAllocationLib.c
MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf

index 7df6a1a73bf4dafa83a48af90522d9bfce10d371..7435844fb9ad24ac0dffed695dd99c9612bbe6c0 100644 (file)
 \r
 #include <PiSmm.h>\r
 \r
+#include <Protocol/SmmAccess2.h>\r
 #include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/DebugLib.h>\r
 #include "PiSmmCoreMemoryAllocationServices.h"\r
 \r
+EFI_SMRAM_DESCRIPTOR  *mSmramRanges    = NULL;\r
+UINTN                 mSmramRangeCount = 0;\r
+\r
+/**\r
+  This function gets and caches SMRAM ranges that are present in the system.\r
+    \r
+  It will ASSERT() if SMM Access2 Protocol doesn't exist.\r
+  It will ASSERT() if SMRAM ranges can't be got.\r
+  It will ASSERT() if Resource can't be allocated for cache SMRAM range. \r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+GetSmramRanges (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_SMM_ACCESS2_PROTOCOL  *SmmAccess;\r
+  UINTN                     Size;\r
+\r
+  //\r
+  // Locate SMM Access2 Protocol\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiSmmAccess2ProtocolGuid, \r
+                  NULL, \r
+                  (VOID **)&SmmAccess\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Get SMRAM range information\r
+  //\r
+  Size = 0;\r
+  Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);\r
+  ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
+\r
+  mSmramRanges = (EFI_SMRAM_DESCRIPTOR *) AllocatePool (Size);\r
+  ASSERT (mSmramRanges != NULL);\r
+\r
+  Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmramRanges);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);\r
+}\r
+\r
+/**\r
+  Check whether the start address of buffer is within any of the SMRAM ranges.\r
+\r
+  @param[in]  Buffer   The pointer to the buffer to be checked.\r
+\r
+  @retval     TURE     The buffer is in SMRAM ranges.\r
+  @retval     FALSE    The buffer is out of SMRAM ranges.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+BufferInSmram (\r
+  IN VOID *Buffer\r
+  )\r
+{\r
+  UINTN  Index;\r
+\r
+  if (mSmramRanges == NULL) {\r
+    //\r
+    // SMRAM ranges is not got. Try to get them all.\r
+    //\r
+    GetSmramRanges();\r
+  }\r
+\r
+  for (Index = 0; Index < mSmramRangeCount; Index ++) {\r
+    if (((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer >= mSmramRanges[Index].CpuStart) && \r
+        ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer < (mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize))) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
 /**\r
   Allocates one or more 4KB pages of a certain memory type.\r
 \r
@@ -145,7 +227,19 @@ FreePages (
   EFI_STATUS  Status;\r
 \r
   ASSERT (Pages != 0);\r
-  Status = SmmFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);\r
+  if (BufferInSmram (Buffer)) {\r
+    //\r
+    // When Buffer is in SMRAM range, it should be allocated by SmmAllocatePages() service.\r
+    // So, SmmFreePages() service is used to free it.\r
+    //\r
+    Status = SmmFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);\r
+  } else {\r
+    //\r
+    // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.\r
+    // So, gBS->FreePages() service is used to free it.\r
+    //\r
+    Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);\r
+  }\r
   ASSERT_EFI_ERROR (Status);\r
 }\r
 \r
@@ -342,7 +436,19 @@ FreeAlignedPages (
   EFI_STATUS  Status;\r
 \r
   ASSERT (Pages != 0);\r
-  Status = SmmFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);\r
+  if (BufferInSmram (Buffer)) {\r
+    //\r
+    // When Buffer is in SMRAM range, it should be allocated by SmmAllocatePages() service.\r
+    // So, SmmFreePages() service is used to free it.\r
+    //\r
+    Status = SmmFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);\r
+  } else {\r
+    //\r
+    // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.\r
+    // So, gBS->FreePages() service is used to free it.\r
+    //\r
+    Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);\r
+  }\r
   ASSERT_EFI_ERROR (Status);\r
 }\r
 \r
@@ -808,7 +914,19 @@ FreePool (
 {\r
   EFI_STATUS    Status;\r
 \r
-  Status = SmmFreePool (Buffer);\r
+  if (BufferInSmram (Buffer)) {\r
+    //\r
+    // When Buffer is in SMRAM range, it should be allocated by SmmAllocatePool() service.\r
+    // So, SmmFreePool() service is used to free it.\r
+    //\r
+    Status = SmmFreePool (Buffer);\r
+  } else {\r
+    //\r
+    // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePool() service.\r
+    // So, gBS->FreePool() service is used to free it.\r
+    //\r
+    Status = gBS->FreePool (Buffer);\r
+  }\r
   ASSERT_EFI_ERROR (Status);\r
 }\r
 \r
index fb51095bad2ae6995c6072263fd9c430623263b4..8f3e0fc116e7fd764dac02bf8a1b19334b884699 100644 (file)
@@ -40,3 +40,7 @@
 [LibraryClasses]\r
   DebugLib\r
   BaseMemoryLib\r
+  UefiBootServicesTableLib\r
+\r
+[Protocols]\r
+  gEfiSmmAccess2ProtocolGuid    ## CONSUMES  \r