]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Mem/Page.c
Define VERIFY_SIZE_OF macro to verify size of basic UEFI Data types. This should...
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Mem / Page.c
index c55bbe3b921e09a95c80f1ee38bacb1a57fb4b0c..f351a121f35b0eae343c4cf9231f4a03a4206cf8 100644 (file)
@@ -53,24 +53,24 @@ LIST_ENTRY   mFreeMemoryMapEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mFreeMemor
 BOOLEAN      mMemoryTypeInformationInitialized = FALSE;\r
 \r
 EFI_MEMORY_TYPE_STAISTICS mMemoryTypeStatistics[EfiMaxMemoryType + 1] = {\r
-  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE,  FALSE },  // EfiReservedMemoryType\r
-  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiLoaderCode\r
-  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiLoaderData\r
-  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiBootServicesCode\r
-  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiBootServicesData\r
-  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE,  TRUE  },  // EfiRuntimeServicesCode\r
-  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE,  TRUE  },  // EfiRuntimeServicesData\r
-  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiConventionalMemory\r
-  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiUnusableMemory\r
-  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE,  FALSE },  // EfiACPIReclaimMemory\r
-  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE,  FALSE },  // EfiACPIMemoryNVS\r
-  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiMemoryMappedIO\r
-  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiMemoryMappedIOPortSpace\r
-  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE,  TRUE  },  // EfiPalCode\r
-  { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }   // EfiMaxMemoryType\r
+  { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE,  FALSE },  // EfiReservedMemoryType\r
+  { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiLoaderCode\r
+  { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiLoaderData\r
+  { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiBootServicesCode\r
+  { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiBootServicesData\r
+  { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE,  TRUE  },  // EfiRuntimeServicesCode\r
+  { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE,  TRUE  },  // EfiRuntimeServicesData\r
+  { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiConventionalMemory\r
+  { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiUnusableMemory\r
+  { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE,  FALSE },  // EfiACPIReclaimMemory\r
+  { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE,  FALSE },  // EfiACPIMemoryNVS\r
+  { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiMemoryMappedIO\r
+  { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE },  // EfiMemoryMappedIOPortSpace\r
+  { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE,  TRUE  },  // EfiPalCode\r
+  { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }   // EfiMaxMemoryType\r
 };\r
 \r
-EFI_PHYSICAL_ADDRESS mDefaultMaximumAddress = EFI_MAX_ADDRESS;\r
+EFI_PHYSICAL_ADDRESS mDefaultMaximumAddress = MAX_ADDRESS;\r
 \r
 EFI_MEMORY_TYPE_INFORMATION gMemoryTypeInformation[EfiMaxMemoryType + 1] = {\r
   { EfiReservedMemoryType,      0 },\r
@@ -89,7 +89,12 @@ EFI_MEMORY_TYPE_INFORMATION gMemoryTypeInformation[EfiMaxMemoryType + 1] = {
   { EfiPalCode,                 0 },\r
   { EfiMaxMemoryType,           0 }\r
 };\r
-\r
+//\r
+// Only used when load module at fixed address feature is enabled. True means the memory is alreay successfully allocated\r
+// and ready to load the module in to specified address.or else, the memory is not ready and module will be loaded at a \r
+//  address assigned by DXE core.\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED   BOOLEAN       gLoadFixedAddressCodeMemoryReady = FALSE;\r
 \r
 /**\r
   Enter critical section by gaining lock on gMemoryLock.\r
@@ -387,7 +392,7 @@ PromoteMemoryResource (
     Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);\r
 \r
     if (Entry->GcdMemoryType == EfiGcdMemoryTypeReserved &&\r
-        Entry->EndAddress < EFI_MAX_ADDRESS &&\r
+        Entry->EndAddress < MAX_ADDRESS &&\r
         (Entry->Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==\r
           (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED)) {\r
       //\r
@@ -419,7 +424,70 @@ PromoteMemoryResource (
 \r
   return;\r
 }\r
+/**\r
+  This function try to allocate Runtime code & Boot time code memory range. If LMFA enabled, 2 patchable PCD \r
+  PcdLoadFixAddressRuntimeCodePageNumber & PcdLoadFixAddressBootTimeCodePageNumber which are set by tools will record the \r
+  size of boot time and runtime code.\r
 \r
+**/\r
+VOID\r
+CoreLoadingFixedAddressHook (\r
+  VOID\r
+  )\r
+{\r
+   UINT32                     RuntimeCodePageNumber;\r
+   UINT32                     BootTimeCodePageNumber;\r
+   EFI_PHYSICAL_ADDRESS       RuntimeCodeBase;\r
+   EFI_PHYSICAL_ADDRESS       BootTimeCodeBase;\r
+   EFI_STATUS                 Status;\r
+\r
+   //\r
+   // Make sure these 2 areas are not initialzied.\r
+   //\r
+   if (!gLoadFixedAddressCodeMemoryReady) {   \r
+     RuntimeCodePageNumber = PcdGet32(PcdLoadFixAddressRuntimeCodePageNumber);\r
+     BootTimeCodePageNumber= PcdGet32(PcdLoadFixAddressBootTimeCodePageNumber);\r
+     RuntimeCodeBase       = (EFI_PHYSICAL_ADDRESS)(gLoadModuleAtFixAddressConfigurationTable.DxeCodeTopAddress - EFI_PAGES_TO_SIZE (RuntimeCodePageNumber));\r
+     BootTimeCodeBase      = (EFI_PHYSICAL_ADDRESS)(RuntimeCodeBase - EFI_PAGES_TO_SIZE (BootTimeCodePageNumber));\r
+     //\r
+     // Try to allocate runtime memory.\r
+     //\r
+     Status = CoreAllocatePages (\r
+                       AllocateAddress,\r
+                       EfiRuntimeServicesCode,\r
+                       RuntimeCodePageNumber,\r
+                       &RuntimeCodeBase\r
+                       );\r
+     if (EFI_ERROR(Status)) {\r
+       //\r
+       // Runtime memory allocation failed \r
+       //\r
+       return;\r
+     }\r
+     //\r
+     // Try to allocate boot memory.\r
+     //\r
+     Status = CoreAllocatePages (\r
+                       AllocateAddress,\r
+                       EfiBootServicesCode,\r
+                       BootTimeCodePageNumber,\r
+                       &BootTimeCodeBase\r
+                       );\r
+     if (EFI_ERROR(Status)) {\r
+       //\r
+        // boot memory allocation failed. Free Runtime code range and will try the allocation again when \r
+        // new memory range is installed.\r
+        //\r
+        CoreFreePages (\r
+              RuntimeCodeBase,\r
+              RuntimeCodePageNumber\r
+              );\r
+       return;\r
+     }\r
+     gLoadFixedAddressCodeMemoryReady = TRUE;\r
+   } \r
+   return;\r
+}  \r
 \r
 /**\r
   Called to initialize the memory map and add descriptors to\r
@@ -448,7 +516,7 @@ CoreAddMemoryDescriptor (
   EFI_STATUS                  Status;\r
   UINTN                       Index;\r
   UINTN                       FreeIndex;\r
-\r
+  \r
   if ((Start & EFI_PAGE_MASK) != 0) {\r
     return;\r
   }\r
@@ -456,13 +524,19 @@ CoreAddMemoryDescriptor (
   if (Type >= EfiMaxMemoryType && Type <= 0x7fffffff) {\r
     return;\r
   }\r
-\r
   CoreAcquireMemoryLock ();\r
   End = Start + LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT) - 1;\r
   CoreAddRange (Type, Start, End, Attribute);\r
   CoreFreeMemoryMapStack ();\r
   CoreReleaseMemoryLock ();\r
 \r
+  //\r
+  // If Loading Module At Fixed Address feature is enabled. try to allocate memory with Runtime code & Boot time code type\r
+  //\r
+  if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) {\r
+    CoreLoadingFixedAddressHook();\r
+  }\r
+  \r
   //\r
   // Check to see if the statistics for the different memory types have already been established\r
   //\r
@@ -470,6 +544,7 @@ CoreAddMemoryDescriptor (
     return;\r
   }\r
 \r
+  \r
   //\r
   // Loop through each memory type in the order specified by the gMemoryTypeInformation[] array\r
   //\r
@@ -481,7 +556,6 @@ CoreAddMemoryDescriptor (
     if (Type < 0 || Type > EfiMaxMemoryType) {\r
       continue;\r
     }\r
-\r
     if (gMemoryTypeInformation[Index].NumberOfPages != 0) {\r
       //\r
       // Allocate pages for the current memory type from the top of available memory\r
@@ -513,7 +587,7 @@ CoreAddMemoryDescriptor (
               gMemoryTypeInformation[FreeIndex].NumberOfPages\r
               );\r
             mMemoryTypeStatistics[Type].BaseAddress    = 0;\r
-            mMemoryTypeStatistics[Type].MaximumAddress = EFI_MAX_ADDRESS;\r
+            mMemoryTypeStatistics[Type].MaximumAddress = MAX_ADDRESS;\r
           }\r
         }\r
         return;\r
@@ -549,7 +623,6 @@ CoreAddMemoryDescriptor (
     if (Type < 0 || Type > EfiMaxMemoryType) {\r
       continue;\r
     }\r
-\r
     if (gMemoryTypeInformation[Index].NumberOfPages != 0) {\r
       CoreFreePages (\r
         mMemoryTypeStatistics[Type].BaseAddress,\r
@@ -571,7 +644,7 @@ CoreAddMemoryDescriptor (
       }\r
     }\r
     mMemoryTypeStatistics[Type].CurrentNumberOfPages = 0;\r
-    if (mMemoryTypeStatistics[Type].MaximumAddress == EFI_MAX_ADDRESS) {\r
+    if (mMemoryTypeStatistics[Type].MaximumAddress == MAX_ADDRESS) {\r
       mMemoryTypeStatistics[Type].MaximumAddress = mDefaultMaximumAddress;\r
     }\r
   }\r
@@ -651,6 +724,8 @@ CoreConvertPages (
     // if that's all we've got\r
     //\r
     RangeEnd = End;\r
+\r
+    ASSERT (Entry != NULL);\r
     if (Entry->End < End) {\r
       RangeEnd = Entry->End;\r
     }\r
@@ -1019,7 +1094,7 @@ CoreAllocatePages (
   //\r
   // The max address is the max natively addressable address for the processor\r
   //\r
-  MaxAddress = EFI_MAX_ADDRESS;\r
+  MaxAddress = MAX_ADDRESS;\r
 \r
   if (Type == AllocateMaxAddress) {\r
     MaxAddress = Start;\r
@@ -1099,6 +1174,7 @@ CoreFreePages (
 \r
   Alignment = EFI_DEFAULT_PAGE_ALLOCATION_ALIGNMENT;\r
 \r
+  ASSERT (Entry != NULL);\r
   if  (Entry->Type == EfiACPIReclaimMemory   ||\r
        Entry->Type == EfiACPIMemoryNVS       ||\r
        Entry->Type == EfiRuntimeServicesCode ||\r
@@ -1127,7 +1203,7 @@ CoreFreePages (
   //\r
   // Destroy the contents\r
   //\r
-  if (Memory < EFI_MAX_ADDRESS) {\r
+  if (Memory < MAX_ADDRESS) {\r
     DEBUG_CLEAR_MEMORY ((VOID *)(UINTN)Memory, NumberOfPages << EFI_PAGE_SHIFT);\r
   }\r
 \r
@@ -1281,7 +1357,7 @@ CoreGetMemoryMap (
       MemoryMap->Attribute |= EFI_MEMORY_RUNTIME;\r
     }\r
 \r
-    MemoryMap = NextMemoryDescriptor (MemoryMap, Size);\r
+    MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, Size);\r
   }\r
 \r
   for (Link = mGcdMemorySpaceMap.ForwardLink; Link != &mGcdMemorySpaceMap; Link = Link->ForwardLink) {\r
@@ -1308,7 +1384,7 @@ CoreGetMemoryMap (
           }\r
         }\r
 \r
-        MemoryMap = NextMemoryDescriptor (MemoryMap, Size);\r
+        MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, Size);\r
       }\r
     }\r
   }\r
@@ -1357,13 +1433,13 @@ CoreAllocatePoolPages (
   //\r
   // Find the pages to convert\r
   //\r
-  Start = FindFreePages (EFI_MAX_ADDRESS, NumberOfPages, PoolType, Alignment);\r
+  Start = FindFreePages (MAX_ADDRESS, NumberOfPages, PoolType, Alignment);\r
 \r
   //\r
   // Convert it to boot services data\r
   //\r
   if (Start == 0) {\r
-    DEBUG ((DEBUG_ERROR | DEBUG_PAGE, "AllocatePoolPages: failed to allocate %d pages\n", NumberOfPages));\r
+    DEBUG ((DEBUG_ERROR | DEBUG_PAGE, "AllocatePoolPages: failed to allocate %d pages\n", (UINT32)NumberOfPages));\r
   } else {\r
     CoreConvertPages (Start, NumberOfPages, PoolType);\r
   }\r
@@ -1424,18 +1500,18 @@ CoreTerminateMemoryMap (
 \r
     for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {\r
       Entry = CR(Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);\r
-      if (Entry->Attribute & EFI_MEMORY_RUNTIME) {\r
+      if ((Entry->Attribute & EFI_MEMORY_RUNTIME) != 0) {\r
         if (Entry->Type == EfiACPIReclaimMemory || Entry->Type == EfiACPIMemoryNVS) {\r
           DEBUG((DEBUG_ERROR | DEBUG_PAGE, "ExitBootServices: ACPI memory entry has RUNTIME attribute set.\n"));\r
           Status =  EFI_INVALID_PARAMETER;\r
           goto Done;\r
         }\r
-        if (Entry->Start & (EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT - 1)) {\r
+        if ((Entry->Start & (EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT - 1)) != 0) {\r
           DEBUG((DEBUG_ERROR | DEBUG_PAGE, "ExitBootServices: A RUNTIME memory entry is not on a proper alignment.\n"));\r
           Status =  EFI_INVALID_PARAMETER;\r
           goto Done;\r
         }\r
-        if ((Entry->End + 1) & (EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT - 1)) {\r
+        if (((Entry->End + 1) & (EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT - 1)) != 0) {\r
           DEBUG((DEBUG_ERROR | DEBUG_PAGE, "ExitBootServices: A RUNTIME memory entry is not on a proper alignment.\n"));\r
           Status =  EFI_INVALID_PARAMETER;\r
           goto Done;\r