Add MemoryAttributesTable generation in DxeCore.
We leverage the information collected by original
PropertiesTable, and publish runtime code/data to
another standalone table. So that this is a
compatible solution to report more PE Code/Data
information.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: "Yao, Jiewen" <jiewen....@intel.com>
Cc: "Gao, Liming" <liming....@intel.com>
---
 MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c | 214 +++++++++++++++++++++
 1 file changed, 214 insertions(+)
 create mode 100644 MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c

diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c 
b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
new file mode 100644
index 0000000..c84146a
--- /dev/null
+++ b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
@@ -0,0 +1,214 @@
+/** @file
+  UEFI MemoryAttributesTable support
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD 
License
+which accompanies this distribution.  The full text of the license may be 
found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+
+#include <Guid/EventGroup.h>
+
+#include <Guid/MemoryAttributesTable.h>
+#include <Guid/PropertiesTable.h>
+
+#include "DxeMain.h"
+
+/**
+  This function for GetMemoryMap() with properties table capability.
+
+  It calls original GetMemoryMap() to get the original memory map information. 
Then
+  plus the additional memory map entries for PE Code/Data seperation.
+
+  @param  MemoryMapSize          A pointer to the size, in bytes, of the
+                                 MemoryMap buffer. On input, this is the size 
of
+                                 the buffer allocated by the caller.  On 
output,
+                                 it is the size of the buffer returned by the
+                                 firmware  if the buffer was large enough, or 
the
+                                 size of the buffer needed  to contain the map 
if
+                                 the buffer was too small.
+  @param  MemoryMap              A pointer to the buffer in which firmware 
places
+                                 the current memory map.
+  @param  MapKey                 A pointer to the location in which firmware
+                                 returns the key for the current memory map.
+  @param  DescriptorSize         A pointer to the location in which firmware
+                                 returns the size, in bytes, of an individual
+                                 EFI_MEMORY_DESCRIPTOR.
+  @param  DescriptorVersion      A pointer to the location in which firmware
+                                 returns the version number associated with the
+                                 EFI_MEMORY_DESCRIPTOR.
+
+  @retval EFI_SUCCESS            The memory map was returned in the MemoryMap
+                                 buffer.
+  @retval EFI_BUFFER_TOO_SMALL   The MemoryMap buffer was too small. The 
current
+                                 buffer size needed to hold the memory map is
+                                 returned in MemoryMapSize.
+  @retval EFI_INVALID_PARAMETER  One of the parameters has an invalid value.
+
+**/
+EFI_STATUS
+EFIAPI
+CoreGetMemoryMapPropertiesTable (
+  IN OUT UINTN                  *MemoryMapSize,
+  IN OUT EFI_MEMORY_DESCRIPTOR  *MemoryMap,
+  OUT UINTN                     *MapKey,
+  OUT UINTN                     *DescriptorSize,
+  OUT UINT32                    *DescriptorVersion
+  );
+
+extern EFI_PROPERTIES_TABLE  mPropertiesTable;
+
+BOOLEAN         mIsConstructingMemoryAttributesTable = FALSE;
+
+/**
+  Install MemoryAttributesTable.
+
+  @param[in]  Event     The Event this notify function registered to.
+  @param[in]  Context   Pointer to the context data registered to the Event.
+**/
+VOID
+EFIAPI
+InstallMemoryAttributesTable (
+  EFI_EVENT                               Event,
+  VOID                                    *Context
+  )
+{
+  UINTN                          MemoryMapSize;
+  EFI_MEMORY_DESCRIPTOR          *MemoryMap;
+  EFI_MEMORY_DESCRIPTOR          *MemoryMapStart;
+  UINTN                          MapKey;
+  UINTN                          DescriptorSize;
+  UINT32                         DescriptorVersion;
+  UINTN                          Index;
+  EFI_STATUS                     Status;
+  UINT32                         RuntimeEntryCount;
+  EFI_MEMORY_ATTRIBUTES_TABLE    *MemoryAttributesTable;
+  EFI_MEMORY_DESCRIPTOR          *MemoryAttributesEntry;
+
+  if ((mPropertiesTable.MemoryProtectionAttribute & 
EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) {
+    DEBUG ((EFI_D_VERBOSE, "MemoryProtectionAttribute NON_EXECUTABLE_PE_DATA 
is not set, "));
+    DEBUG ((EFI_D_VERBOSE, "because Runtime Driver Section Alignment is not 
%dK.\n", EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT >> 10));
+    return ;
+  }
+
+  mIsConstructingMemoryAttributesTable = TRUE;
+
+  MemoryMapSize = 0;
+  MemoryMap = NULL;
+  Status = CoreGetMemoryMapPropertiesTable (
+             &MemoryMapSize,
+             MemoryMap,
+             &MapKey,
+             &DescriptorSize,
+             &DescriptorVersion
+             );
+  ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+
+  do {
+    MemoryMap = AllocatePool (MemoryMapSize);
+    ASSERT (MemoryMap != NULL);
+
+    Status = CoreGetMemoryMapPropertiesTable (
+               &MemoryMapSize,
+               MemoryMap,
+               &MapKey,
+               &DescriptorSize,
+               &DescriptorVersion
+               );
+    if (EFI_ERROR (Status)) {
+      FreePool (MemoryMap);
+    }
+  } while (Status == EFI_BUFFER_TOO_SMALL);
+
+  MemoryMapStart = MemoryMap;
+  RuntimeEntryCount = 0;
+  for (Index = 0; Index < MemoryMapSize/DescriptorSize; Index++) {
+    switch (MemoryMap->Type) {
+    case EfiRuntimeServicesCode:
+    case EfiRuntimeServicesData:
+      RuntimeEntryCount ++;
+      break;
+    }
+    MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, DescriptorSize);
+  }
+
+  //
+  // Allocate MemoryAttributesTable
+  //
+  MemoryAttributesTable = AllocatePool (sizeof(EFI_MEMORY_ATTRIBUTES_TABLE) + 
DescriptorSize * RuntimeEntryCount);
+  ASSERT (MemoryAttributesTable != NULL);
+  MemoryAttributesTable->Version         = EFI_MEMORY_ATTRIBUTES_TABLE_VERSION;
+  MemoryAttributesTable->NumberOfEntries = RuntimeEntryCount;
+  MemoryAttributesTable->DescriptorSize  = (UINT32)DescriptorSize;
+  MemoryAttributesTable->Reserved        = 0;
+  DEBUG ((EFI_D_VERBOSE, "MemoryAttributesTable:\n"));
+  DEBUG ((EFI_D_VERBOSE, "  Version              - 0x%08x\n", 
MemoryAttributesTable->Version));
+  DEBUG ((EFI_D_VERBOSE, "  NumberOfEntries      - 0x%08x\n", 
MemoryAttributesTable->NumberOfEntries));
+  DEBUG ((EFI_D_VERBOSE, "  DescriptorSize       - 0x%08x\n", 
MemoryAttributesTable->DescriptorSize));
+  MemoryAttributesEntry = (EFI_MEMORY_DESCRIPTOR *)(MemoryAttributesTable + 1);
+  MemoryMap = MemoryMapStart;
+  for (Index = 0; Index < MemoryMapSize/DescriptorSize; Index++) {
+    switch (MemoryMap->Type) {
+    case EfiRuntimeServicesCode:
+    case EfiRuntimeServicesData:
+      CopyMem (MemoryAttributesEntry, MemoryMap, DescriptorSize);
+      MemoryAttributesEntry->Attribute &= 
(EFI_MEMORY_RO|EFI_MEMORY_XP|EFI_MEMORY_RUNTIME);
+      DEBUG ((EFI_D_VERBOSE, "Entry (0x%x)\n", MemoryAttributesEntry));
+      DEBUG ((EFI_D_VERBOSE, "  Type              - 0x%x\n", 
MemoryAttributesEntry->Type));
+      DEBUG ((EFI_D_VERBOSE, "  PhysicalStart     - 0x%016lx\n", 
MemoryAttributesEntry->PhysicalStart));
+      DEBUG ((EFI_D_VERBOSE, "  VirtualStart      - 0x%016lx\n", 
MemoryAttributesEntry->VirtualStart));
+      DEBUG ((EFI_D_VERBOSE, "  NumberOfPages     - 0x%016lx\n", 
MemoryAttributesEntry->NumberOfPages));
+      DEBUG ((EFI_D_VERBOSE, "  Attribute         - 0x%016lx\n", 
MemoryAttributesEntry->Attribute));
+      MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR(MemoryAttributesEntry, 
DescriptorSize);
+      break;
+    }
+    MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, DescriptorSize);
+  }
+
+  Status = gBS->InstallConfigurationTable (&gEfiMemoryAttributesTableGuid, 
MemoryAttributesTable);
+  ASSERT_EFI_ERROR (Status);
+
+  mIsConstructingMemoryAttributesTable = FALSE;
+}
+
+/**
+  Initialize MemoryAttrubutesTable support.
+**/
+VOID
+EFIAPI
+CoreInitializeMemoryAttributesTable (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  EFI_EVENT   ReadyToBootEvent;
+
+  //
+  // Construct the table at ReadyToBoot, because this should be
+  // last point to allocate RuntimeCode/RuntimeData.
+  //
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  InstallMemoryAttributesTable,
+                  NULL,
+                  &gEfiEventReadyToBootGuid,
+                  &ReadyToBootEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+  return ;
+}
-- 
1.9.5.msysgit.0

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to