]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
Add fix for the hardcoded Max ACPI table number. With this fix, the number of ACPI...
[mirror_edk2.git] / MdeModulePkg / Core / Pei / Dispatcher / Dispatcher.c
index eed0c1cdc9daf85a77e7670833f9685c660d34f9..d0b7bb072dfbf4a3cb175553c24711e25369d5ee 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
   EFI PEI Core dispatch services\r
   \r
-Copyright (c) 2006 - 2010, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2006 - 2010, 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
 http://opensource.org/licenses/bsd-license.php\r
@@ -240,6 +240,50 @@ ShadowPeiCore(
 // defined in DXE Core.\r
 //\r
 #define MINIMUM_INITIAL_MEMORY_SIZE 0x10000\r
+/**\r
+  This function is to test if the memory range described in resource HOB is available or not. \r
+  \r
+  This function should only be invoked when Loading Module at Fixed Address(LMFA) feature is enabled. Some platform may allocate the \r
+  memory before PeiLoadFixAddressHook in invoked. so this function is to test if the memory range described by the input resource HOB is\r
+  available or not.\r
+\r
+  @param PrivateData         Pointer to the private data passed in from caller\r
+  @param ResourceHob         Pointer to a resource HOB which described the memory range described by the input resource HOB\r
+**/\r
+BOOLEAN\r
+PeiLoadFixAddressIsMemoryRangeAvailable (\r
+  IN PEI_CORE_INSTANCE                  *PrivateData,\r
+  IN EFI_HOB_RESOURCE_DESCRIPTOR        *ResourceHob\r
+  )\r
+{\r
+       EFI_HOB_MEMORY_ALLOCATION          *MemoryHob;\r
+       BOOLEAN                             IsAvailable;\r
+       EFI_PEI_HOB_POINTERS                Hob;\r
+       \r
+  IsAvailable = TRUE;\r
+       if (PrivateData == NULL || ResourceHob == NULL) {\r
+         return FALSE;\r
+       }\r
+       //\r
+  // test if the memory range describe in the HOB is already allocated.\r
+  //\r
+  for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {\r
+    //                                                              \r
+    // See if this is a memory allocation HOB                     \r
+    //\r
+    if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) { \r
+      MemoryHob = Hob.MemoryAllocation;\r
+      if(MemoryHob->AllocDescriptor.MemoryBaseAddress == ResourceHob->PhysicalStart && \r
+         MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength == ResourceHob->PhysicalStart + ResourceHob->ResourceLength) {\r
+         IsAvailable = FALSE;\r
+         break;  \r
+       }\r
+     }\r
+  }\r
+  \r
+  return IsAvailable;\r
+       \r
+}\r
 /**\r
   Hook function for Loading Module at Fixed Address feature\r
   \r
@@ -269,6 +313,7 @@ PeiLoadFixAddressHook(
   EFI_PEI_HOB_POINTERS               NextHob;\r
   EFI_PHYSICAL_ADDRESS               MaxMemoryBaseAddress;\r
   UINT64                             MaxMemoryLength;\r
+  EFI_HOB_MEMORY_ALLOCATION          *MemoryHob;\r
   //\r
   // Initialize Local Variables\r
   //\r
@@ -361,6 +406,61 @@ PeiLoadFixAddressHook(
       }\r
     } \r
   }\r
+  //\r
+  // Some platform is already allocated pages before the HOB re-org. Here to build dedicated resource HOB to describe\r
+  //  the allocated memory range\r
+  //\r
+  for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {\r
+    //                                                              \r
+    // See if this is a memory allocation HOB                     \r
+    //\r
+    if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) {\r
+      MemoryHob = Hob.MemoryAllocation;\r
+      for (NextHob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(NextHob); NextHob.Raw = GET_NEXT_HOB(NextHob)) {\r
+        //\r
+        // See if this is a resource descriptor HOB\r
+        //\r
+        if (GET_HOB_TYPE (NextHob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
+               NextResourceHob = NextHob.ResourceDescriptor;\r
+          //\r
+          // If range described in this hob is not system memory or heigher than MAX_ADDRESS, ignored.\r
+          //\r
+          if (NextResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY && NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength > MAX_ADDRESS) {\r
+            continue;\r
+          }\r
+          //\r
+          // If the range describe in memory allocation HOB  belongs to the memroy range described by the resource hob\r
+          //          \r
+          if (MemoryHob->AllocDescriptor.MemoryBaseAddress >= NextResourceHob->PhysicalStart && \r
+              MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength <= NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength) {\r
+             //\r
+             // Build seperate resource hob for this allocated range\r
+             //                     \r
+             if (MemoryHob->AllocDescriptor.MemoryBaseAddress > NextResourceHob->PhysicalStart) {\r
+               BuildResourceDescriptorHob (\r
+                 EFI_RESOURCE_SYSTEM_MEMORY,                       \r
+                 NextResourceHob->ResourceAttribute,\r
+                 NextResourceHob->PhysicalStart,                             \r
+                 (MemoryHob->AllocDescriptor.MemoryBaseAddress - NextResourceHob->PhysicalStart)      \r
+               );\r
+             }\r
+             if (MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength < NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength) {\r
+               BuildResourceDescriptorHob (\r
+                 EFI_RESOURCE_SYSTEM_MEMORY,                       \r
+                 NextResourceHob->ResourceAttribute,\r
+                 MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength,                            \r
+                 (NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength -(MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength))    \r
+               );\r
+             }\r
+             NextResourceHob->PhysicalStart = MemoryHob->AllocDescriptor.MemoryBaseAddress;\r
+             NextResourceHob->ResourceLength = MemoryHob->AllocDescriptor.MemoryLength;\r
+             break;\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
   //\r
   // Try to find and validate the TOP address.\r
   //  \r
@@ -396,11 +496,12 @@ PeiLoadFixAddressHook(
             // See if Top address specified by user is valid.\r
             //\r
             if (ResourceHob->PhysicalStart + TotalReservedMemorySize < TopLoadingAddress && \r
-                (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - MINIMUM_INITIAL_MEMORY_SIZE) >= TopLoadingAddress) {\r
+                (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - MINIMUM_INITIAL_MEMORY_SIZE) >= TopLoadingAddress && \r
+                PeiLoadFixAddressIsMemoryRangeAvailable(PrivateData, ResourceHob)) {\r
               CurrentResourceHob = ResourceHob; \r
               CurrentHob = Hob;\r
               break;\r
-            }\r
+           }\r
         }\r
       }  \r
     }  \r
@@ -428,7 +529,7 @@ PeiLoadFixAddressHook(
               //\r
               // See if Top address specified by user is valid.\r
               //\r
-              if (ResourceHob->ResourceLength > TotalReservedMemorySize) {\r
+              if (ResourceHob->ResourceLength > TotalReservedMemorySize && PeiLoadFixAddressIsMemoryRangeAvailable(PrivateData, ResourceHob)) {\r
                  DEBUG ((EFI_D_INFO, "(0x%lx, 0x%lx)\n",  \r
                           (ResourceHob->PhysicalStart + TotalReservedMemorySize -MINIMUM_INITIAL_MEMORY_SIZE), \r
                           (ResourceHob->PhysicalStart + ResourceHob->ResourceLength -MINIMUM_INITIAL_MEMORY_SIZE) \r
@@ -440,7 +541,8 @@ PeiLoadFixAddressHook(
       //\r
       // Assert here \r
       //\r
-      ASSERT (FALSE);      \r
+      ASSERT (FALSE);   \r
+      return;   \r
     }     \r
   } else {\r
     //\r
@@ -462,7 +564,7 @@ PeiLoadFixAddressHook(
         //\r
         if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY && \r
             ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MAX_ADDRESS &&\r
-            ResourceHob->ResourceLength > TotalReservedMemorySize) {\r
+            ResourceHob->ResourceLength > TotalReservedMemorySize && PeiLoadFixAddressIsMemoryRangeAvailable(PrivateData, ResourceHob)) {\r
           //\r
           // See if this is the highest largest system memory region below MaxAddress\r
           //\r
@@ -479,7 +581,8 @@ PeiLoadFixAddressHook(
       //\r
       // Assert here \r
       //\r
-      ASSERT (FALSE);      \r
+      ASSERT (FALSE);\r
+      return;  \r
     } else {\r
       TopLoadingAddress = CurrentResourceHob->PhysicalStart + CurrentResourceHob->ResourceLength ; \r
     }         \r
@@ -487,10 +590,10 @@ PeiLoadFixAddressHook(
   \r
   if (CurrentResourceHob != NULL) {\r
     //\r
-    // rebuild hob for PEI memmory and reserved memory\r
+    // rebuild resource HOB for PEI memmory and reserved memory\r
     //\r
     BuildResourceDescriptorHob (\r
-      EFI_RESOURCE_SYSTEM_MEMORY,                       // MemoryType,\r
+      EFI_RESOURCE_SYSTEM_MEMORY,                       \r
       (\r
       EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
       EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
@@ -500,15 +603,15 @@ PeiLoadFixAddressHook(
       EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
       EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
       ),\r
-      (TopLoadingAddress - TotalReservedMemorySize),                             // MemoryBegin\r
-      TotalReservedMemorySize      // MemoryLength\r
+      (TopLoadingAddress - TotalReservedMemorySize),                             \r
+      TotalReservedMemorySize     \r
     );\r
     //\r
-    // rebuild hob for the remain memory if necessary\r
+    // rebuild resource for the remain memory if necessary\r
     //\r
     if (CurrentResourceHob->PhysicalStart < TopLoadingAddress - TotalReservedMemorySize) {\r
       BuildResourceDescriptorHob (\r
-        EFI_RESOURCE_SYSTEM_MEMORY,                       // MemoryType,\r
+        EFI_RESOURCE_SYSTEM_MEMORY,                       \r
         (\r
          EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
          EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
@@ -517,8 +620,8 @@ PeiLoadFixAddressHook(
          EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
          EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
          ),\r
-         CurrentResourceHob->PhysicalStart,                             // MemoryBegin\r
-         (TopLoadingAddress - TotalReservedMemorySize - CurrentResourceHob->PhysicalStart)      // MemoryLength\r
+         CurrentResourceHob->PhysicalStart,                             \r
+         (TopLoadingAddress - TotalReservedMemorySize - CurrentResourceHob->PhysicalStart)      \r
        );\r
     }\r
     if (CurrentResourceHob->PhysicalStart + CurrentResourceHob->ResourceLength  > TopLoadingAddress ) {\r
@@ -796,14 +899,13 @@ PeiDispatcher (
                       ));\r
               DEBUG_CODE_END ();\r
               \r
-              if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) {\r
+              if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
                 //\r
                 // Loading Module at Fixed Address is enabled\r
                 //\r
                 PeiLoadFixAddressHook(Private);\r
                 //\r
-                // if Loading Module at Fixed Address is enabled, This is the first invoke to page\r
-                // allocation for Pei Code range. This memory range should be reserved for loading PEIMs\r
+                // if Loading Module at Fixed Address is enabled, Allocating memory range for Pei code range.\r
                 //\r
                 LoadFixPeiCodeBegin = AllocatePages((UINTN)PcdGet32(PcdLoadFixAddressPeiCodePageNumber));\r
                 DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: PeiCodeBegin = 0x%lX, PeiCodeTop= 0x%lX\n", (UINT64)(UINTN)LoadFixPeiCodeBegin, (UINT64)((UINTN)LoadFixPeiCodeBegin + PcdGet32(PcdLoadFixAddressPeiCodePageNumber) * EFI_PAGE_SIZE)));\r
@@ -946,7 +1048,7 @@ PeiDispatcher (
               //\r
               PrivateInMem->PeimDispatcherReenter  = TRUE;\r
               \r
-              if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) {\r
+              if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (PrivateInMem->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
                 //\r
                 // if Loading Module at Fixed Address is enabled, allocate the PEI code memory range usage bit map array.\r
                 // Every bit in the array indicate the status of the corresponding memory page available or not\r