/** @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
**/\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
);\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
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
MemoryMap = AllocatePool (MemoryMapSize);\r
ASSERT (MemoryMap != NULL);\r
\r
- Status = CoreGetMemoryMapPropertiesTable (\r
+ Status = CoreGetMemoryMapWithSeparatedImageSection (\r
&MemoryMapSize,\r
MemoryMap,\r
&MapKey,\r
}\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
{\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