]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Mem/Page.c
MdeModulePkg/Core: Fix typos in comments
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Mem / Page.c
index abfb0b9c7461a15e4ac5a2aae95b5088d66640ac..bda4f6397e915c65dc57365f72610281e5b22b95 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   UEFI Memory page management functions.\r
 \r
-Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -204,7 +204,7 @@ CoreAddRange (
   // If we are in EFI 1.10 compatability mode no event groups will be\r
   // found and nothing will happen we we call this function. These events\r
   // will get signaled but since a lock is held around the call to this\r
-  // function the notificaiton events will only be called after this funciton\r
+  // function the notificaiton events will only be called after this function\r
   // returns and the lock is released.\r
   //\r
   CoreNotifySignalList (&gEfiEventMemoryMapChangeGuid);\r
@@ -416,7 +416,11 @@ PromoteMemoryResource (
       //\r
       // Update the GCD map\r
       //\r
-      Entry->GcdMemoryType = EfiGcdMemoryTypeSystemMemory;\r
+      if ((Entry->Capabilities & EFI_MEMORY_MORE_RELIABLE) == EFI_MEMORY_MORE_RELIABLE) {\r
+        Entry->GcdMemoryType = EfiGcdMemoryTypeMoreReliable;\r
+      } else {\r
+        Entry->GcdMemoryType = EfiGcdMemoryTypeSystemMemory;\r
+      }\r
       Entry->Capabilities |= EFI_MEMORY_TESTED;\r
       Entry->ImageHandle  = gDxeCoreImageHandle;\r
       Entry->DeviceHandle = NULL;\r
@@ -540,7 +544,7 @@ CoreAddMemoryDescriptor (
     return;\r
   }\r
 \r
-  if (Type >= EfiMaxMemoryType && Type <= 0x7fffffff) {\r
+  if (Type >= EfiMaxMemoryType && Type < MEMORY_TYPE_OEM_RESERVED_MIN) {\r
     return;\r
   }\r
   CoreAcquireMemoryLock ();\r
@@ -721,7 +725,7 @@ CoreConvertPagesEx (
   ASSERT_LOCKED (&gMemoryLock);\r
   ASSERT ( (ChangingType == FALSE) || (ChangingAttributes == FALSE) );\r
 \r
-  if (NumberOfPages == 0 || ((Start & EFI_PAGE_MASK) != 0) || (Start > (Start + NumberOfBytes))) {\r
+  if (NumberOfPages == 0 || ((Start & EFI_PAGE_MASK) != 0) || (Start >= End)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -1047,6 +1051,11 @@ CoreFindFreePagesI (
 \r
     DescEnd = ((DescEnd + 1) & (~(Alignment - 1))) - 1;\r
 \r
+    // Skip if DescEnd is less than DescStart after alignment clipping\r
+    if (DescEnd < DescStart) {\r
+      continue;\r
+    }\r
+\r
     //\r
     // Compute the number of bytes we can used from this\r
     // descriptor, and see it's enough to satisfy the request\r
@@ -1192,6 +1201,8 @@ CoreInternalAllocatePages (
 {\r
   EFI_STATUS      Status;\r
   UINT64          Start;\r
+  UINT64          NumberOfBytes;\r
+  UINT64          End;\r
   UINT64          MaxAddress;\r
   UINTN           Alignment;\r
 \r
@@ -1199,7 +1210,7 @@ CoreInternalAllocatePages (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if ((MemoryType >= EfiMaxMemoryType && MemoryType <= 0x7fffffff) ||\r
+  if ((MemoryType >= EfiMaxMemoryType && MemoryType < MEMORY_TYPE_OEM_RESERVED_MIN) ||\r
        (MemoryType == EfiConventionalMemory) || (MemoryType == EfiPersistentMemory)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -1237,6 +1248,30 @@ CoreInternalAllocatePages (
   //\r
   MaxAddress = MAX_ADDRESS;\r
 \r
+  //\r
+  // Check for Type AllocateAddress,\r
+  // if NumberOfPages is 0 or\r
+  // if (NumberOfPages << EFI_PAGE_SHIFT) is above MAX_ADDRESS or\r
+  // if (Start + NumberOfBytes) rolls over 0 or\r
+  // if Start is above MAX_ADDRESS or\r
+  // if End is above MAX_ADDRESS,\r
+  // return EFI_NOT_FOUND.\r
+  //\r
+  if (Type == AllocateAddress) {\r
+    if ((NumberOfPages == 0) ||\r
+        (NumberOfPages > RShiftU64 (MaxAddress, EFI_PAGE_SHIFT))) {\r
+      return EFI_NOT_FOUND;\r
+    }\r
+    NumberOfBytes = LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT);\r
+    End = Start + NumberOfBytes - 1;\r
+\r
+    if ((Start >= End) ||\r
+        (Start > MaxAddress) || \r
+        (End > MaxAddress)) {\r
+      return EFI_NOT_FOUND;\r
+    }\r
+  }\r
+\r
   if (Type == AllocateMaxAddress) {\r
     MaxAddress = Start;\r
   }\r
@@ -1300,7 +1335,15 @@ CoreAllocatePages (
 \r
   Status = CoreInternalAllocatePages (Type, MemoryType, NumberOfPages, Memory);\r
   if (!EFI_ERROR (Status)) {\r
-    CoreUpdateProfile ((EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), MemoryProfileActionAllocatePages, MemoryType, EFI_PAGES_TO_SIZE (NumberOfPages), (VOID *) (UINTN) *Memory);\r
+    CoreUpdateProfile (\r
+      (EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0),\r
+      MemoryProfileActionAllocatePages,\r
+      MemoryType,\r
+      EFI_PAGES_TO_SIZE (NumberOfPages),\r
+      (VOID *) (UINTN) *Memory,\r
+      NULL\r
+      );\r
+    InstallMemoryAttributesTableOnMemoryAllocation (MemoryType);\r
   }\r
   return Status;\r
 }\r
@@ -1310,6 +1353,7 @@ CoreAllocatePages (
 \r
   @param  Memory                 Base address of memory being freed\r
   @param  NumberOfPages          The number of pages to free\r
+  @param  MemoryType             Pointer to memory type\r
 \r
   @retval EFI_NOT_FOUND          Could not find the entry that covers the range\r
   @retval EFI_INVALID_PARAMETER  Address not aligned\r
@@ -1320,7 +1364,8 @@ EFI_STATUS
 EFIAPI\r
 CoreInternalFreePages (\r
   IN EFI_PHYSICAL_ADDRESS   Memory,\r
-  IN UINTN                  NumberOfPages\r
+  IN UINTN                  NumberOfPages,\r
+  OUT EFI_MEMORY_TYPE       *MemoryType OPTIONAL\r
   )\r
 {\r
   EFI_STATUS      Status;\r
@@ -1368,6 +1413,10 @@ CoreInternalFreePages (
   NumberOfPages += EFI_SIZE_TO_PAGES (Alignment) - 1;\r
   NumberOfPages &= ~(EFI_SIZE_TO_PAGES (Alignment) - 1);\r
 \r
+  if (MemoryType != NULL) {\r
+    *MemoryType = Entry->Type;\r
+  }\r
+\r
   Status = CoreConvertPages (Memory, NumberOfPages, EfiConventionalMemory);\r
 \r
   if (EFI_ERROR (Status)) {\r
@@ -1397,11 +1446,20 @@ CoreFreePages (
   IN UINTN                 NumberOfPages\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
+  EFI_STATUS        Status;\r
+  EFI_MEMORY_TYPE   MemoryType;\r
 \r
-  Status = CoreInternalFreePages (Memory, NumberOfPages);\r
+  Status = CoreInternalFreePages (Memory, NumberOfPages, &MemoryType);\r
   if (!EFI_ERROR (Status)) {\r
-    CoreUpdateProfile ((EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), MemoryProfileActionFreePages, (EFI_MEMORY_TYPE) 0, EFI_PAGES_TO_SIZE (NumberOfPages), (VOID *) (UINTN) Memory);\r
+    CoreUpdateProfile (\r
+      (EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0),\r
+      MemoryProfileActionFreePages,\r
+      MemoryType,\r
+      EFI_PAGES_TO_SIZE (NumberOfPages),\r
+      (VOID *) (UINTN) Memory,\r
+      NULL\r
+      );\r
+    InstallMemoryAttributesTableOnMemoryAllocation (MemoryType);\r
   }\r
   return Status;\r
 }\r
@@ -1534,6 +1592,7 @@ CoreGetMemoryMap (
   LIST_ENTRY                        *Link;\r
   MEMORY_MAP                        *Entry;\r
   EFI_GCD_MAP_ENTRY                 *GcdMapEntry;\r
+  EFI_GCD_MAP_ENTRY                 MergeGcdMapEntry;\r
   EFI_MEMORY_TYPE                   Type;\r
   EFI_MEMORY_DESCRIPTOR             *MemoryMapStart;\r
 \r
@@ -1645,23 +1704,49 @@ CoreGetMemoryMap (
     MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size);\r
   }\r
 \r
-  for (Link = mGcdMemorySpaceMap.ForwardLink; Link != &mGcdMemorySpaceMap; Link = Link->ForwardLink) {\r
-    GcdMapEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);\r
-    if ((GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeReserved) ||\r
-        ((GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) &&\r
-        ((GcdMapEntry->Attributes & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME))) {\r
\r
+  ZeroMem (&MergeGcdMapEntry, sizeof (MergeGcdMapEntry));\r
+  GcdMapEntry = NULL;\r
+  for (Link = mGcdMemorySpaceMap.ForwardLink; ; Link = Link->ForwardLink) {\r
+    if (Link != &mGcdMemorySpaceMap) {\r
+      //\r
+      // Merge adjacent same type and attribute GCD memory range\r
+      //\r
+      GcdMapEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);\r
+  \r
+      if ((MergeGcdMapEntry.Capabilities == GcdMapEntry->Capabilities) && \r
+          (MergeGcdMapEntry.Attributes == GcdMapEntry->Attributes) &&\r
+          (MergeGcdMapEntry.GcdMemoryType == GcdMapEntry->GcdMemoryType) &&\r
+          (MergeGcdMapEntry.GcdIoType == GcdMapEntry->GcdIoType)) {\r
+        MergeGcdMapEntry.EndAddress  = GcdMapEntry->EndAddress;\r
+        continue;\r
+      }\r
+    }\r
+\r
+    if ((MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeReserved) ||\r
+        ((MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) &&\r
+        ((MergeGcdMapEntry.Attributes & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME))) {\r
+      //\r
+      // Page Align GCD range is required. When it is converted to EFI_MEMORY_DESCRIPTOR, \r
+      // it will be recorded as page PhysicalStart and NumberOfPages. \r
+      //\r
+      ASSERT ((MergeGcdMapEntry.BaseAddress & EFI_PAGE_MASK) == 0);\r
+      ASSERT (((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1) & EFI_PAGE_MASK) == 0);\r
+      \r
       // \r
       // Create EFI_MEMORY_DESCRIPTOR for every Reserved and runtime MMIO GCD entries\r
       //\r
-      MemoryMap->PhysicalStart = GcdMapEntry->BaseAddress;\r
+      MemoryMap->PhysicalStart = MergeGcdMapEntry.BaseAddress;\r
       MemoryMap->VirtualStart  = 0;\r
-      MemoryMap->NumberOfPages = RShiftU64 ((GcdMapEntry->EndAddress - GcdMapEntry->BaseAddress + 1), EFI_PAGE_SHIFT);\r
-      MemoryMap->Attribute     = GcdMapEntry->Attributes & ~EFI_MEMORY_PORT_IO;\r
+      MemoryMap->NumberOfPages = RShiftU64 ((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1), EFI_PAGE_SHIFT);\r
+      MemoryMap->Attribute     = (MergeGcdMapEntry.Attributes & ~EFI_MEMORY_PORT_IO) | \r
+                                (MergeGcdMapEntry.Capabilities & (EFI_MEMORY_RP | EFI_MEMORY_WP | EFI_MEMORY_XP | EFI_MEMORY_RO |\r
+                                EFI_MEMORY_UC | EFI_MEMORY_UCE | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB));\r
 \r
-      if (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeReserved) {\r
+      if (MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeReserved) {\r
         MemoryMap->Type = EfiReservedMemoryType;\r
-      } else if (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) {\r
-        if ((GcdMapEntry->Attributes & EFI_MEMORY_PORT_IO) == EFI_MEMORY_PORT_IO) {\r
+      } else if (MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) {\r
+        if ((MergeGcdMapEntry.Attributes & EFI_MEMORY_PORT_IO) == EFI_MEMORY_PORT_IO) {\r
           MemoryMap->Type = EfiMemoryMappedIOPortSpace;\r
         } else {\r
           MemoryMap->Type = EfiMemoryMappedIO;\r
@@ -1675,14 +1760,23 @@ CoreGetMemoryMap (
       MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size);\r
     }\r
     \r
-    if (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypePersistentMemory) {\r
+    if (MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypePersistentMemory) {\r
+      //\r
+      // Page Align GCD range is required. When it is converted to EFI_MEMORY_DESCRIPTOR, \r
+      // it will be recorded as page PhysicalStart and NumberOfPages. \r
+      //\r
+      ASSERT ((MergeGcdMapEntry.BaseAddress & EFI_PAGE_MASK) == 0);\r
+      ASSERT (((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1) & EFI_PAGE_MASK) == 0);\r
+\r
       // \r
       // Create EFI_MEMORY_DESCRIPTOR for every Persistent GCD entries\r
       //\r
-      MemoryMap->PhysicalStart = GcdMapEntry->BaseAddress;\r
+      MemoryMap->PhysicalStart = MergeGcdMapEntry.BaseAddress;\r
       MemoryMap->VirtualStart  = 0;\r
-      MemoryMap->NumberOfPages = RShiftU64 ((GcdMapEntry->EndAddress - GcdMapEntry->BaseAddress + 1), EFI_PAGE_SHIFT);\r
-      MemoryMap->Attribute     = GcdMapEntry->Attributes | EFI_MEMORY_NV;\r
+      MemoryMap->NumberOfPages = RShiftU64 ((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1), EFI_PAGE_SHIFT);\r
+      MemoryMap->Attribute     = MergeGcdMapEntry.Attributes | EFI_MEMORY_NV | \r
+                                (MergeGcdMapEntry.Capabilities & (EFI_MEMORY_RP | EFI_MEMORY_WP | EFI_MEMORY_XP | EFI_MEMORY_RO |\r
+                                EFI_MEMORY_UC | EFI_MEMORY_UCE | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB));\r
       MemoryMap->Type          = EfiPersistentMemory;\r
       \r
       //\r
@@ -1691,6 +1785,18 @@ CoreGetMemoryMap (
       //\r
       MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size);\r
     }\r
+    if (Link == &mGcdMemorySpaceMap) {\r
+      //\r
+      // break loop when arrive at head.\r
+      //\r
+      break;\r
+    }\r
+    if (GcdMapEntry != NULL) {\r
+      //\r
+      // Copy new GCD map entry for the following GCD range merge\r
+      //\r
+      CopyMem (&MergeGcdMapEntry, GcdMapEntry, sizeof (MergeGcdMapEntry));\r
+    }\r
   }\r
 \r
   //\r