]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
MdeModulePkg/DxeCore: Install UEFI mem attrib table at EndOfDxe.
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Misc / MemoryAttributesTable.c
index c84146a8e8edec4f1296829823e6bd47f26c2f41..60557faa1ca1d2f9fc378a22df40f95339542509 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   UEFI MemoryAttributesTable support\r
 \r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2016 - 2018, 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
@@ -62,7 +62,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-CoreGetMemoryMapPropertiesTable (\r
+CoreGetMemoryMapWithSeparatedImageSection (\r
   IN OUT UINTN                  *MemoryMapSize,\r
   IN OUT EFI_MEMORY_DESCRIPTOR  *MemoryMap,\r
   OUT UINTN                     *MapKey,\r
@@ -71,20 +71,16 @@ CoreGetMemoryMapPropertiesTable (
   );\r
 \r
 extern EFI_PROPERTIES_TABLE  mPropertiesTable;\r
-\r
-BOOLEAN         mIsConstructingMemoryAttributesTable = FALSE;\r
+EFI_MEMORY_ATTRIBUTES_TABLE  *mMemoryAttributesTable = NULL;\r
+BOOLEAN                      mMemoryAttributesTableReadyToBoot = FALSE;\r
 \r
 /**\r
   Install MemoryAttributesTable.\r
 \r
-  @param[in]  Event     The Event this notify function registered to.\r
-  @param[in]  Context   Pointer to the context data registered to the Event.\r
 **/\r
 VOID\r
-EFIAPI\r
 InstallMemoryAttributesTable (\r
-  EFI_EVENT                               Event,\r
-  VOID                                    *Context\r
+  VOID\r
   )\r
 {\r
   UINTN                          MemoryMapSize;\r
@@ -99,17 +95,32 @@ InstallMemoryAttributesTable (
   EFI_MEMORY_ATTRIBUTES_TABLE    *MemoryAttributesTable;\r
   EFI_MEMORY_DESCRIPTOR          *MemoryAttributesEntry;\r
 \r
+  if (gMemoryMapTerminated) {\r
+    //\r
+    // Directly return after MemoryMap terminated.\r
+    //\r
+    return;\r
+  }\r
+\r
   if ((mPropertiesTable.MemoryProtectionAttribute & EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) {\r
     DEBUG ((EFI_D_VERBOSE, "MemoryProtectionAttribute NON_EXECUTABLE_PE_DATA is not set, "));\r
-    DEBUG ((EFI_D_VERBOSE, "because Runtime Driver Section Alignment is not %dK.\n", EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT >> 10));\r
+    DEBUG ((EFI_D_VERBOSE, "because Runtime Driver Section Alignment is not %dK.\n", RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10));\r
     return ;\r
   }\r
 \r
-  mIsConstructingMemoryAttributesTable = TRUE;\r
+  if (mMemoryAttributesTable == NULL) {\r
+    //\r
+    // InstallConfigurationTable here to occupy one entry for MemoryAttributesTable\r
+    // before GetMemoryMap below, as InstallConfigurationTable may allocate runtime\r
+    // memory for the new entry.\r
+    //\r
+    Status = gBS->InstallConfigurationTable (&gEfiMemoryAttributesTableGuid, (VOID *) (UINTN) MAX_ADDRESS);\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
 \r
   MemoryMapSize = 0;\r
   MemoryMap = NULL;\r
-  Status = CoreGetMemoryMapPropertiesTable (\r
+  Status = CoreGetMemoryMapWithSeparatedImageSection (\r
              &MemoryMapSize,\r
              MemoryMap,\r
              &MapKey,\r
@@ -122,7 +133,7 @@ InstallMemoryAttributesTable (
     MemoryMap = AllocatePool (MemoryMapSize);\r
     ASSERT (MemoryMap != NULL);\r
 \r
-    Status = CoreGetMemoryMapPropertiesTable (\r
+    Status = CoreGetMemoryMapWithSeparatedImageSection (\r
                &MemoryMapSize,\r
                MemoryMap,\r
                &MapKey,\r
@@ -178,11 +189,72 @@ InstallMemoryAttributesTable (
     }\r
     MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, DescriptorSize);\r
   }\r
+  MemoryMap = MemoryMapStart;\r
+  FreePool (MemoryMap);\r
 \r
+  //\r
+  // Update configuratoin table for MemoryAttributesTable.\r
+  //\r
   Status = gBS->InstallConfigurationTable (&gEfiMemoryAttributesTableGuid, MemoryAttributesTable);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  mIsConstructingMemoryAttributesTable = FALSE;\r
+  if (mMemoryAttributesTable != NULL) {\r
+    FreePool (mMemoryAttributesTable);\r
+  }\r
+  mMemoryAttributesTable = MemoryAttributesTable;\r
+}\r
+\r
+/**\r
+  Install MemoryAttributesTable on memory allocation.\r
+\r
+  @param[in] MemoryType EFI memory type.\r
+**/\r
+VOID\r
+InstallMemoryAttributesTableOnMemoryAllocation (\r
+  IN EFI_MEMORY_TYPE    MemoryType\r
+  )\r
+{\r
+  //\r
+  // Install MemoryAttributesTable after ReadyToBoot on runtime memory allocation.\r
+  //\r
+  if (mMemoryAttributesTableReadyToBoot &&\r
+      ((MemoryType == EfiRuntimeServicesCode) || (MemoryType == EfiRuntimeServicesData))) {\r
+    InstallMemoryAttributesTable ();\r
+  }\r
+}\r
+\r
+/**\r
+  Install MemoryAttributesTable on ReadyToBoot.\r
+\r
+  @param[in] Event      The Event this notify function registered to.\r
+  @param[in] Context    Pointer to the context data registered to the Event.\r
+**/\r
+VOID\r
+EFIAPI\r
+InstallMemoryAttributesTableOnReadyToBoot (\r
+  IN EFI_EVENT          Event,\r
+  IN VOID               *Context\r
+  )\r
+{\r
+  InstallMemoryAttributesTable ();\r
+  mMemoryAttributesTableReadyToBoot = TRUE;\r
+}\r
+\r
+/**\r
+  Install initial MemoryAttributesTable on EndOfDxe.\r
+  Then SMM can consume this information.\r
+\r
+  @param[in] Event      The Event this notify function registered to.\r
+  @param[in] Context    Pointer to the context data registered to the Event.\r
+**/\r
+VOID\r
+EFIAPI\r
+InstallMemoryAttributesTableOnEndOfDxe (\r
+  IN EFI_EVENT          Event,\r
+  IN VOID               *Context\r
+  )\r
+{\r
+  InstallMemoryAttributesTable ();\r
 }\r
 \r
 /**\r
@@ -196,19 +268,35 @@ CoreInitializeMemoryAttributesTable (
 {\r
   EFI_STATUS  Status;\r
   EFI_EVENT   ReadyToBootEvent;\r
+  EFI_EVENT   EndOfDxeEvent;\r
 \r
   //\r
-  // Construct the table at ReadyToBoot, because this should be\r
-  // last point to allocate RuntimeCode/RuntimeData.\r
+  // Construct the table at ReadyToBoot.\r
   //\r
-  Status = gBS->CreateEventEx (\r
-                  EVT_NOTIFY_SIGNAL,\r
-                  TPL_NOTIFY,\r
-                  InstallMemoryAttributesTable,\r
-                  NULL,\r
-                  &gEfiEventReadyToBootGuid,\r
-                  &ReadyToBootEvent\r
-                  );\r
+  Status = CoreCreateEventInternal (\r
+             EVT_NOTIFY_SIGNAL,\r
+             TPL_CALLBACK,\r
+             InstallMemoryAttributesTableOnReadyToBoot,\r
+             NULL,\r
+             &gEfiEventReadyToBootGuid,\r
+             &ReadyToBootEvent\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Construct the initial table at EndOfDxe,\r
+  // then SMM can consume this information.\r
+  // Use TPL_NOTIFY here, as such SMM code (TPL_CALLBACK)\r
+  // can run after it.\r
+  //\r
+  Status = CoreCreateEventInternal (\r
+             EVT_NOTIFY_SIGNAL,\r
+             TPL_NOTIFY,\r
+             InstallMemoryAttributesTableOnEndOfDxe,\r
+             NULL,\r
+             &gEfiEndOfDxeEventGroupGuid,\r
+             &EndOfDxeEvent\r
+             );\r
   ASSERT_EFI_ERROR (Status);\r
   return ;\r
 }\r