public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v2 0/3] ArmPkg: implement EFI memory attributes protocol
@ 2023-02-02 11:27 Ard Biesheuvel
  2023-02-02 11:27 ` [PATCH v2 1/3] MdePkg: Add Memory Attribute Protocol definition Ard Biesheuvel
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Ard Biesheuvel @ 2023-02-02 11:27 UTC (permalink / raw)
  To: devel
  Cc: Ard Biesheuvel, Michael Kinney, Liming Gao, Jiewen Yao,
	Michael Kubacki, Sean Brogan, Rebecca Cran, Leif Lindholm,
	Sami Mujawar, Taylor Beebe

v2:
- drop patch to bump exposed UEFI revision to v2.10
- add missing permitted return values to protocol definition
    
Cc: Michael Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Michael Kubacki <michael.kubacki@microsoft.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Rebecca Cran <quic_rcran@quicinc.com>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Taylor Beebe <t@taylorbeebe.com>

Ard Biesheuvel (3):
  MdePkg: Add Memory Attribute Protocol definition
  ArmPkg/CpuDxe: Unify PageAttributeToGcdAttribute helper
  ArmPkg/CpuDxe: Implement EFI memory attributes protocol

 ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c       |   5 +-
 ArmPkg/Drivers/CpuDxe/Arm/Mmu.c           |  46 ++--
 ArmPkg/Drivers/CpuDxe/CpuDxe.c            |   2 +
 ArmPkg/Drivers/CpuDxe/CpuDxe.h            |   8 +
 ArmPkg/Drivers/CpuDxe/CpuDxe.inf          |   2 +
 ArmPkg/Drivers/CpuDxe/MemoryAttribute.c   | 252 ++++++++++++++++++++
 MdePkg/Include/Protocol/MemoryAttribute.h | 142 +++++++++++
 MdePkg/MdePkg.dec                         |   3 +
 8 files changed, 436 insertions(+), 24 deletions(-)
 create mode 100644 ArmPkg/Drivers/CpuDxe/MemoryAttribute.c
 create mode 100644 MdePkg/Include/Protocol/MemoryAttribute.h

-- 
2.39.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/3] MdePkg: Add Memory Attribute Protocol definition
  2023-02-02 11:27 [PATCH v2 0/3] ArmPkg: implement EFI memory attributes protocol Ard Biesheuvel
@ 2023-02-02 11:27 ` Ard Biesheuvel
  2023-02-03  5:28   ` 回复: [edk2-devel] " gaoliming
  2023-02-02 11:27 ` [PATCH v2 2/3] ArmPkg/CpuDxe: Unify PageAttributeToGcdAttribute helper Ard Biesheuvel
  2023-02-02 11:27 ` [PATCH v2 3/3] ArmPkg/CpuDxe: Implement EFI memory attributes protocol Ard Biesheuvel
  2 siblings, 1 reply; 5+ messages in thread
From: Ard Biesheuvel @ 2023-02-02 11:27 UTC (permalink / raw)
  To: devel
  Cc: Ard Biesheuvel, Michael Kinney, Liming Gao, Jiewen Yao,
	Michael Kubacki, Sean Brogan, Rebecca Cran, Leif Lindholm,
	Sami Mujawar, Taylor Beebe

Add the Memory Attribute Protocol definition, which was adopted and
included in version 2.10 of the UEFI specification.

Link: https://bugzilla.tianocore.org/show_bug.cgi?id=3519
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 MdePkg/Include/Protocol/MemoryAttribute.h | 142 ++++++++++++++++++++
 MdePkg/MdePkg.dec                         |   3 +
 2 files changed, 145 insertions(+)

diff --git a/MdePkg/Include/Protocol/MemoryAttribute.h b/MdePkg/Include/Protocol/MemoryAttribute.h
new file mode 100644
index 000000000000..ff930fb21aa6
--- /dev/null
+++ b/MdePkg/Include/Protocol/MemoryAttribute.h
@@ -0,0 +1,142 @@
+/** @file
+
+  EFI Memory Attribute Protocol provides retrieval and update service
+  for memory attributes in EFI environment.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2023, Google LLC. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EFI_MEMORY_ATTRIBUTE_H__
+#define __EFI_MEMORY_ATTRIBUTE_H__
+
+#define EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID \
+  { \
+    0xf4560cf6, 0x40ec, 0x4b4a, { 0xa1, 0x92, 0xbf, 0x1d, 0x57, 0xd0, 0xb1, 0x89 } \
+  }
+
+typedef struct _EFI_MEMORY_ATTRIBUTE_PROTOCOL EFI_MEMORY_ATTRIBUTE_PROTOCOL;
+
+/**
+  This function set given attributes of the memory region specified by
+  BaseAddress and Length.
+
+  The valid Attributes is EFI_MEMORY_RP, EFI_MEMORY_XP, and EFI_MEMORY_RO.
+
+  @param  This              The EFI_MEMORY_ATTRIBUTE_PROTOCOL instance.
+  @param  BaseAddress       The physical address that is the start address of
+                            a memory region.
+  @param  Length            The size in bytes of the memory region.
+  @param  Attributes        The bit mask of attributes to set for the memory
+                            region.
+
+  @retval EFI_SUCCESS           The attributes were set for the memory region.
+  @retval EFI_INVALID_PARAMETER Length is zero.
+                                Attributes specified an illegal combination of
+                                attributes that cannot be set together.
+  @retval EFI_UNSUPPORTED       The processor does not support one or more
+                                bytes of the memory resource range specified
+                                by BaseAddress and Length.
+                                The bit mask of attributes is not supported for
+                                the memory resource range specified by
+                                BaseAddress and Length.
+  @retval EFI_OUT_OF_RESOURCES  Requested attributes cannot be applied due to
+                                lack of system resources.
+  @retval EFI_ACCESS_DENIED     Attributes for the requested memory region are
+                                controlled by system firmware and cannot be
+                                updated via the protocol.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_MEMORY_ATTRIBUTES)(
+  IN  EFI_MEMORY_ATTRIBUTE_PROTOCOL       *This,
+  IN  EFI_PHYSICAL_ADDRESS                BaseAddress,
+  IN  UINT64                              Length,
+  IN  UINT64                              Attributes
+  );
+
+/**
+  This function clears given attributes of the memory region specified by
+  BaseAddress and Length.
+
+  The valid Attributes is EFI_MEMORY_RP, EFI_MEMORY_XP, and EFI_MEMORY_RO.
+
+  @param  This              The EFI_MEMORY_ATTRIBUTE_PROTOCOL instance.
+  @param  BaseAddress       The physical address that is the start address of
+                            a memory region.
+  @param  Length            The size in bytes of the memory region.
+  @param  Attributes        The bit mask of attributes to clear for the memory
+                            region.
+
+  @retval EFI_SUCCESS           The attributes were cleared for the memory region.
+  @retval EFI_INVALID_PARAMETER Length is zero.
+                                Attributes specified an illegal combination of
+                                attributes that cannot be cleared together.
+  @retval EFI_UNSUPPORTED       The processor does not support one or more
+                                bytes of the memory resource range specified
+                                by BaseAddress and Length.
+                                The bit mask of attributes is not supported for
+                                the memory resource range specified by
+                                BaseAddress and Length.
+  @retval EFI_OUT_OF_RESOURCES  Requested attributes cannot be applied due to
+                                lack of system resources.
+  @retval EFI_ACCESS_DENIED     Attributes for the requested memory region are
+                                controlled by system firmware and cannot be
+                                updated via the protocol.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CLEAR_MEMORY_ATTRIBUTES)(
+  IN  EFI_MEMORY_ATTRIBUTE_PROTOCOL       *This,
+  IN  EFI_PHYSICAL_ADDRESS                BaseAddress,
+  IN  UINT64                              Length,
+  IN  UINT64                              Attributes
+  );
+
+/**
+  This function retrieves the attributes of the memory region specified by
+  BaseAddress and Length. If different attributes are got from different part
+  of the memory region, EFI_NO_MAPPING will be returned.
+
+  @param  This              The EFI_MEMORY_ATTRIBUTE_PROTOCOL instance.
+  @param  BaseAddress       The physical address that is the start address of
+                            a memory region.
+  @param  Length            The size in bytes of the memory region.
+  @param  Attributes        Pointer to attributes returned.
+
+  @retval EFI_SUCCESS           The attributes got for the memory region.
+  @retval EFI_INVALID_PARAMETER Length is zero.
+                                Attributes is NULL.
+  @retval EFI_NO_MAPPING        Attributes are not consistent cross the memory
+                                region.
+  @retval EFI_UNSUPPORTED       The processor does not support one or more
+                                bytes of the memory resource range specified
+                                by BaseAddress and Length.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_MEMORY_ATTRIBUTES)(
+  IN  EFI_MEMORY_ATTRIBUTE_PROTOCOL       *This,
+  IN  EFI_PHYSICAL_ADDRESS                BaseAddress,
+  IN  UINT64                              Length,
+  OUT UINT64                              *Attributes
+  );
+
+///
+/// EFI Memory Attribute Protocol provides services to retrieve or update
+/// attribute of memory in the EFI environment.
+///
+struct _EFI_MEMORY_ATTRIBUTE_PROTOCOL {
+  EFI_GET_MEMORY_ATTRIBUTES      GetMemoryAttributes;
+  EFI_SET_MEMORY_ATTRIBUTES      SetMemoryAttributes;
+  EFI_CLEAR_MEMORY_ATTRIBUTES    ClearMemoryAttributes;
+};
+
+extern EFI_GUID  gEfiMemoryAttributeProtocolGuid;
+
+#endif
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 3d08f20d15b0..a8658403c8fd 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -1915,6 +1915,9 @@ [Protocols]
   ## Include/Protocol/RedfishDiscover.h
   gEfiRedfishDiscoverProtocolGuid      = { 0x5db12509, 0x4550, 0x4347, { 0x96, 0xb3, 0x73, 0xc0, 0xff, 0x6e, 0x86, 0x9f }}
 
+   ## Include/Protocol/MemoryAttribute.h
+  gEfiMemoryAttributeProtocolGuid = { 0xf4560cf6, 0x40ec, 0x4b4a, { 0xa1, 0x92, 0xbf, 0x1d, 0x57, 0xd0, 0xb1, 0x89 }}
+
   #
   # Protocols defined in Shell2.0
   #
-- 
2.39.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/3] ArmPkg/CpuDxe: Unify PageAttributeToGcdAttribute helper
  2023-02-02 11:27 [PATCH v2 0/3] ArmPkg: implement EFI memory attributes protocol Ard Biesheuvel
  2023-02-02 11:27 ` [PATCH v2 1/3] MdePkg: Add Memory Attribute Protocol definition Ard Biesheuvel
@ 2023-02-02 11:27 ` Ard Biesheuvel
  2023-02-02 11:27 ` [PATCH v2 3/3] ArmPkg/CpuDxe: Implement EFI memory attributes protocol Ard Biesheuvel
  2 siblings, 0 replies; 5+ messages in thread
From: Ard Biesheuvel @ 2023-02-02 11:27 UTC (permalink / raw)
  To: devel
  Cc: Ard Biesheuvel, Michael Kinney, Liming Gao, Jiewen Yao,
	Michael Kubacki, Sean Brogan, Rebecca Cran, Leif Lindholm,
	Sami Mujawar, Taylor Beebe

In preparation for introducing an implementation of the EFI memory
attributes protocol that is shared between ARM and AArch64, unify the
existing code that converts a page table descriptor into a
EFI_MEMORY_xxx bitfield, so it can be called from the generic code.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c |  5 +--
 ArmPkg/Drivers/CpuDxe/Arm/Mmu.c     | 46 +++++++++++---------
 ArmPkg/Drivers/CpuDxe/CpuDxe.h      |  5 +++
 3 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c b/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c
index 8bb33046e707..4ec9fc0a582c 100644
--- a/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c
+++ b/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c
@@ -30,13 +30,12 @@ GetRootTranslationTableInfo (
   *RootTableEntryCount = TT_ENTRY_COUNT >> (T0SZ - MIN_T0SZ) % BITS_PER_LEVEL;
 }
 
-STATIC
 UINT64
 PageAttributeToGcdAttribute (
-  IN UINT64  PageAttributes
+  IN UINTN  PageAttributes
   )
 {
-  UINT64  GcdAttributes;
+  UINTN  GcdAttributes;
 
   switch (PageAttributes & TT_ATTR_INDX_MASK) {
     case TT_ATTR_INDX_DEVICE_MEMORY:
diff --git a/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c b/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c
index 2daf47ba6fe5..9545a1c1d2d3 100644
--- a/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c
+++ b/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c
@@ -77,39 +77,46 @@ SectionToGcdAttributes (
   return EFI_SUCCESS;
 }
 
-EFI_STATUS
-PageToGcdAttributes (
-  IN  UINT32  PageAttributes,
-  OUT UINT64  *GcdAttributes
+UINT64
+PageAttributeToGcdAttribute (
+  IN UINTN  PageAttributes
   )
 {
-  *GcdAttributes = 0;
+  UINT64 GcdAttributes;
 
   // determine cacheability attributes
   switch (PageAttributes & TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK) {
     case TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED:
-      *GcdAttributes |= EFI_MEMORY_UC;
+      GcdAttributes = EFI_MEMORY_UC;
       break;
     case TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE:
-      *GcdAttributes |= EFI_MEMORY_UC;
+      GcdAttributes = EFI_MEMORY_UC;
       break;
     case TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC:
-      *GcdAttributes |= EFI_MEMORY_WT;
+      GcdAttributes = EFI_MEMORY_WT;
       break;
     case TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_NO_ALLOC:
-      *GcdAttributes |= EFI_MEMORY_WB;
+      GcdAttributes = EFI_MEMORY_WB;
       break;
     case TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE:
-      *GcdAttributes |= EFI_MEMORY_WC;
+      GcdAttributes = EFI_MEMORY_WC;
       break;
     case TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC:
-      *GcdAttributes |= EFI_MEMORY_WB;
+      GcdAttributes = EFI_MEMORY_WB;
       break;
     case TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE:
-      *GcdAttributes |= EFI_MEMORY_UC;
+      GcdAttributes = EFI_MEMORY_UC;
       break;
     default:
-      return EFI_UNSUPPORTED;
+      DEBUG ((
+        DEBUG_ERROR,
+        "PageAttributeToGcdAttribute: PageAttributes:0x%X not supported.\n",
+        PageAttributes
+        ));
+      ASSERT (0);
+      // The Global Coherency Domain (GCD) value is defined as a bit set.
+      // Returning 0 means no attribute has been set.
+      GcdAttributes = 0;
   }
 
   // determine protection attributes
@@ -126,7 +133,7 @@ PageToGcdAttributes (
     // read only cases map to write-protect
     case TT_DESCRIPTOR_PAGE_AP_RO_NO:
     case TT_DESCRIPTOR_PAGE_AP_RO_RO:
-      *GcdAttributes |= EFI_MEMORY_RO;
+      GcdAttributes |= EFI_MEMORY_RO;
       break;
 
     default:
@@ -135,10 +142,10 @@ PageToGcdAttributes (
 
   // now process eXectue Never attribute
   if ((PageAttributes & TT_DESCRIPTOR_PAGE_XN_MASK) != 0 ) {
-    *GcdAttributes |= EFI_MEMORY_XP;
+    GcdAttributes |= EFI_MEMORY_XP;
   }
 
-  return EFI_SUCCESS;
+  return GcdAttributes;
 }
 
 EFI_STATUS
@@ -152,7 +159,6 @@ SyncCacheConfigPage (
   IN OUT UINT32                           *NextSectionAttributes
   )
 {
-  EFI_STATUS                     Status;
   UINT32                         i;
   volatile ARM_PAGE_TABLE_ENTRY  *SecondLevelTable;
   UINT32                         NextPageAttributes;
@@ -183,8 +189,7 @@ SyncCacheConfigPage (
         NextPageAttributes = PageAttributes;
       } else if (PageAttributes != NextPageAttributes) {
         // Convert Section Attributes into GCD Attributes
-        Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);
-        ASSERT_EFI_ERROR (Status);
+        GcdAttributes = PageAttributeToGcdAttribute (NextPageAttributes);
 
         // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
         SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);
@@ -196,8 +201,7 @@ SyncCacheConfigPage (
       }
     } else if (NextPageAttributes != 0) {
       // Convert Page Attributes into GCD Attributes
-      Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);
-      ASSERT_EFI_ERROR (Status);
+      GcdAttributes = PageAttributeToGcdAttribute (NextPageAttributes);
 
       // update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
       SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);
diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.h b/ArmPkg/Drivers/CpuDxe/CpuDxe.h
index ff672390ce51..8933fa90c4ed 100644
--- a/ArmPkg/Drivers/CpuDxe/CpuDxe.h
+++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.h
@@ -126,4 +126,9 @@ SetGcdMemorySpaceAttributes (
   IN UINT64                           Attributes
   );
 
+UINT64
+PageAttributeToGcdAttribute (
+  IN UINTN  PageAttributes
+  );
+
 #endif // CPU_DXE_H_
-- 
2.39.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 3/3] ArmPkg/CpuDxe: Implement EFI memory attributes protocol
  2023-02-02 11:27 [PATCH v2 0/3] ArmPkg: implement EFI memory attributes protocol Ard Biesheuvel
  2023-02-02 11:27 ` [PATCH v2 1/3] MdePkg: Add Memory Attribute Protocol definition Ard Biesheuvel
  2023-02-02 11:27 ` [PATCH v2 2/3] ArmPkg/CpuDxe: Unify PageAttributeToGcdAttribute helper Ard Biesheuvel
@ 2023-02-02 11:27 ` Ard Biesheuvel
  2 siblings, 0 replies; 5+ messages in thread
From: Ard Biesheuvel @ 2023-02-02 11:27 UTC (permalink / raw)
  To: devel
  Cc: Ard Biesheuvel, Michael Kinney, Liming Gao, Jiewen Yao,
	Michael Kubacki, Sean Brogan, Rebecca Cran, Leif Lindholm,
	Sami Mujawar, Taylor Beebe

Expose the protocol introduced in v2.10 that permits the caller to
manage mapping permissions in the page tables.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 ArmPkg/Drivers/CpuDxe/CpuDxe.c          |   2 +
 ArmPkg/Drivers/CpuDxe/CpuDxe.h          |   3 +
 ArmPkg/Drivers/CpuDxe/CpuDxe.inf        |   2 +
 ArmPkg/Drivers/CpuDxe/MemoryAttribute.c | 252 ++++++++++++++++++++
 4 files changed, 259 insertions(+)

diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.c b/ArmPkg/Drivers/CpuDxe/CpuDxe.c
index e6742f0a25fc..d04958e79e52 100644
--- a/ArmPkg/Drivers/CpuDxe/CpuDxe.c
+++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.c
@@ -244,6 +244,8 @@ CpuDxeInitialize (
                   &mCpuHandle,
                   &gEfiCpuArchProtocolGuid,
                   &mCpu,
+                  &gEfiMemoryAttributeProtocolGuid,
+                  &mMemoryAttribute,
                   NULL
                   );
 
diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.h b/ArmPkg/Drivers/CpuDxe/CpuDxe.h
index 8933fa90c4ed..f45d2bc101a3 100644
--- a/ArmPkg/Drivers/CpuDxe/CpuDxe.h
+++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.h
@@ -30,9 +30,12 @@
 #include <Protocol/Cpu.h>
 #include <Protocol/DebugSupport.h>
 #include <Protocol/LoadedImage.h>
+#include <Protocol/MemoryAttribute.h>
 
 extern BOOLEAN  mIsFlushingGCD;
 
+extern EFI_MEMORY_ATTRIBUTE_PROTOCOL  mMemoryAttribute;
+
 /**
   This function registers and enables the handler specified by InterruptHandler for a processor
   interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf b/ArmPkg/Drivers/CpuDxe/CpuDxe.inf
index 10792b393fc8..e732e21cb94a 100644
--- a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.inf
@@ -23,6 +23,7 @@ [Sources.Common]
   CpuDxe.h
   CpuMmuCommon.c
   Exception.c
+  MemoryAttribute.c
 
 [Sources.ARM]
   Arm/Mmu.c
@@ -53,6 +54,7 @@ [LibraryClasses]
 
 [Protocols]
   gEfiCpuArchProtocolGuid
+  gEfiMemoryAttributeProtocolGuid
 
 [Guids]
   gEfiDebugImageInfoTableGuid
diff --git a/ArmPkg/Drivers/CpuDxe/MemoryAttribute.c b/ArmPkg/Drivers/CpuDxe/MemoryAttribute.c
new file mode 100644
index 000000000000..827deb94dd99
--- /dev/null
+++ b/ArmPkg/Drivers/CpuDxe/MemoryAttribute.c
@@ -0,0 +1,252 @@
+/** @file
+
+  Copyright (c) 2023, Google LLC. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CpuDxe.h"
+
+/**
+  This function retrieves the attributes of the memory region specified by
+  BaseAddress and Length. If different attributes are got from different part
+  of the memory region, EFI_NO_MAPPING will be returned.
+
+  @param  This              The EFI_MEMORY_ATTRIBUTE_PROTOCOL instance.
+  @param  BaseAddress       The physical address that is the start address of
+                            a memory region.
+  @param  Length            The size in bytes of the memory region.
+  @param  Attributes        Pointer to attributes returned.
+
+  @retval EFI_SUCCESS           The attributes got for the memory region.
+  @retval EFI_INVALID_PARAMETER Length is zero.
+                                Attributes is NULL.
+  @retval EFI_NO_MAPPING        Attributes are not consistent cross the memory
+                                region.
+  @retval EFI_UNSUPPORTED       The processor does not support one or more
+                                bytes of the memory resource range specified
+                                by BaseAddress and Length.
+
+**/
+STATIC
+EFI_STATUS
+GetMemoryAttributes (
+  IN  EFI_MEMORY_ATTRIBUTE_PROTOCOL       *This,
+  IN  EFI_PHYSICAL_ADDRESS                BaseAddress,
+  IN  UINT64                              Length,
+  OUT UINT64                              *Attributes
+  )
+{
+  UINTN       RegionAddress;
+  UINTN       RegionLength;
+  UINTN       RegionAttributes;
+  UINTN       Union;
+  UINTN       Intersection;
+  EFI_STATUS  Status;
+
+  if ((Length == 0) || (Attributes == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  DEBUG ((DEBUG_INFO,
+          "%a: BaseAddress == 0x%lx, Length == 0x%lx\n",
+          __FUNCTION__,
+          (UINTN)BaseAddress,
+          (UINTN)Length
+          ));
+
+  Union         = 0;
+  Intersection  = MAX_UINTN;
+
+  for (RegionAddress = (UINTN)BaseAddress;
+       RegionAddress < (UINTN)(BaseAddress + Length);
+       RegionAddress += RegionLength) {
+
+    Status = GetMemoryRegion (&RegionAddress,
+                              &RegionLength,
+                              &RegionAttributes
+                              );
+
+    DEBUG ((DEBUG_INFO,
+            "%a: RegionAddress == 0x%lx, RegionLength == 0x%lx, RegionAttributes == 0x%lx\n",
+            __FUNCTION__,
+            RegionAddress,
+            RegionLength,
+            RegionAttributes
+            ));
+
+    if (EFI_ERROR (Status)) {
+      return EFI_NO_MAPPING;
+    }
+
+    Union         |= RegionAttributes;
+    Intersection  &= RegionAttributes;
+  }
+
+  DEBUG ((DEBUG_INFO,
+          "%a: Union == %lx, Intersection == %lx\n",
+          __FUNCTION__,
+          Union,
+          Intersection
+          ));
+
+  if (Union != Intersection) {
+    return EFI_NO_MAPPING;
+  }
+
+  *Attributes = PageAttributeToGcdAttribute (Union) & (EFI_MEMORY_RO | EFI_MEMORY_XP);
+  return EFI_SUCCESS;
+}
+
+/**
+  This function set given attributes of the memory region specified by
+  BaseAddress and Length.
+
+  The valid Attributes is EFI_MEMORY_RP, EFI_MEMORY_XP, and EFI_MEMORY_RO.
+
+  @param  This              The EFI_MEMORY_ATTRIBUTE_PROTOCOL instance.
+  @param  BaseAddress       The physical address that is the start address of
+                            a memory region.
+  @param  Length            The size in bytes of the memory region.
+  @param  Attributes        The bit mask of attributes to set for the memory
+                            region.
+
+  @retval EFI_SUCCESS           The attributes were set for the memory region.
+  @retval EFI_INVALID_PARAMETER Length is zero.
+                                Attributes specified an illegal combination of
+                                attributes that cannot be set together.
+  @retval EFI_UNSUPPORTED       The processor does not support one or more
+                                bytes of the memory resource range specified
+                                by BaseAddress and Length.
+                                The bit mask of attributes is not supported for
+                                the memory resource range specified by
+                                BaseAddress and Length.
+  @retval EFI_OUT_OF_RESOURCES  Requested attributes cannot be applied due to
+                                lack of system resources.
+  @retval EFI_ACCESS_DENIED     Attributes for the requested memory region are
+                                controlled by system firmware and cannot be
+                                updated via the protocol.
+
+**/
+STATIC
+EFI_STATUS
+SetMemoryAttributes (
+  IN  EFI_MEMORY_ATTRIBUTE_PROTOCOL       *This,
+  IN  EFI_PHYSICAL_ADDRESS                BaseAddress,
+  IN  UINT64                              Length,
+  IN  UINT64                              Attributes
+  )
+{
+  EFI_STATUS  Status;
+
+  DEBUG ((DEBUG_INFO,
+          "%a: BaseAddress == 0x%lx, Length == 0x%lx, Attributes == 0x%lx\n",
+          __FUNCTION__,
+          (UINTN)BaseAddress,
+          (UINTN)Length,
+          (UINTN)Attributes
+          ));
+
+  if ((Length == 0) ||
+      ((Attributes & ~(EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP)) != 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((Attributes & EFI_MEMORY_RP) != 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if ((Attributes & EFI_MEMORY_RO) != 0) {
+    Status = ArmSetMemoryRegionReadOnly (BaseAddress, Length);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  if ((Attributes & EFI_MEMORY_XP) != 0) {
+    Status = ArmSetMemoryRegionNoExec (BaseAddress, Length);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function clears given attributes of the memory region specified by
+  BaseAddress and Length.
+
+  The valid Attributes is EFI_MEMORY_RP, EFI_MEMORY_XP, and EFI_MEMORY_RO.
+
+  @param  This              The EFI_MEMORY_ATTRIBUTE_PROTOCOL instance.
+  @param  BaseAddress       The physical address that is the start address of
+                            a memory region.
+  @param  Length            The size in bytes of the memory region.
+  @param  Attributes        The bit mask of attributes to clear for the memory
+                            region.
+
+  @retval EFI_SUCCESS           The attributes were cleared for the memory region.
+  @retval EFI_INVALID_PARAMETER Length is zero.
+                                Attributes specified an illegal combination of
+                                attributes that cannot be cleared together.
+  @retval EFI_UNSUPPORTED       The processor does not support one or more
+                                bytes of the memory resource range specified
+                                by BaseAddress and Length.
+                                The bit mask of attributes is not supported for
+                                the memory resource range specified by
+                                BaseAddress and Length.
+  @retval EFI_OUT_OF_RESOURCES  Requested attributes cannot be applied due to
+                                lack of system resources.
+  @retval EFI_ACCESS_DENIED     Attributes for the requested memory region are
+                                controlled by system firmware and cannot be
+                                updated via the protocol.
+
+**/
+STATIC
+EFI_STATUS
+ClearMemoryAttributes (
+  IN  EFI_MEMORY_ATTRIBUTE_PROTOCOL       *This,
+  IN  EFI_PHYSICAL_ADDRESS                BaseAddress,
+  IN  UINT64                              Length,
+  IN  UINT64                              Attributes
+  )
+{
+  EFI_STATUS  Status;
+
+  DEBUG ((DEBUG_INFO,
+          "%a: BaseAddress == 0x%lx, Length == 0x%lx, Attributes == 0x%lx\n",
+          __FUNCTION__,
+          (UINTN)BaseAddress,
+          (UINTN)Length,
+          (UINTN)Attributes
+          ));
+
+  if ((Length == 0) ||
+      ((Attributes & ~(EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP)) != 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((Attributes & EFI_MEMORY_RO) != 0) {
+    Status = ArmClearMemoryRegionReadOnly (BaseAddress, Length);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  if ((Attributes & EFI_MEMORY_XP) != 0) {
+    Status = ArmClearMemoryRegionNoExec (BaseAddress, Length);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_MEMORY_ATTRIBUTE_PROTOCOL  mMemoryAttribute = {
+  GetMemoryAttributes,
+  SetMemoryAttributes,
+  ClearMemoryAttributes
+};
-- 
2.39.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* 回复: [edk2-devel] [PATCH v2 1/3] MdePkg: Add Memory Attribute Protocol definition
  2023-02-02 11:27 ` [PATCH v2 1/3] MdePkg: Add Memory Attribute Protocol definition Ard Biesheuvel
@ 2023-02-03  5:28   ` gaoliming
  0 siblings, 0 replies; 5+ messages in thread
From: gaoliming @ 2023-02-03  5:28 UTC (permalink / raw)
  To: devel, ardb
  Cc: 'Michael Kinney', 'Jiewen Yao',
	'Michael Kubacki', 'Sean Brogan',
	'Rebecca Cran', 'Leif Lindholm',
	'Sami Mujawar', 'Taylor Beebe'

Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>

> -----邮件原件-----
> 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Ard
> Biesheuvel
> 发送时间: 2023年2月2日 19:27
> 收件人: devel@edk2.groups.io
> 抄送: Ard Biesheuvel <ardb@kernel.org>; Michael Kinney
> <michael.d.kinney@intel.com>; Liming Gao <gaoliming@byosoft.com.cn>;
> Jiewen Yao <jiewen.yao@intel.com>; Michael Kubacki
> <michael.kubacki@microsoft.com>; Sean Brogan
> <sean.brogan@microsoft.com>; Rebecca Cran <quic_rcran@quicinc.com>;
> Leif Lindholm <quic_llindhol@quicinc.com>; Sami Mujawar
> <sami.mujawar@arm.com>; Taylor Beebe <t@taylorbeebe.com>
> 主题: [edk2-devel] [PATCH v2 1/3] MdePkg: Add Memory Attribute Protocol
> definition
> 
> Add the Memory Attribute Protocol definition, which was adopted and
> included in version 2.10 of the UEFI specification.
> 
> Link: https://bugzilla.tianocore.org/show_bug.cgi?id=3519
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> ---
>  MdePkg/Include/Protocol/MemoryAttribute.h | 142
> ++++++++++++++++++++
>  MdePkg/MdePkg.dec                         |   3 +
>  2 files changed, 145 insertions(+)
> 
> diff --git a/MdePkg/Include/Protocol/MemoryAttribute.h
> b/MdePkg/Include/Protocol/MemoryAttribute.h
> new file mode 100644
> index 000000000000..ff930fb21aa6
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/MemoryAttribute.h
> @@ -0,0 +1,142 @@
> +/** @file
> 
> +
> 
> +  EFI Memory Attribute Protocol provides retrieval and update service
> 
> +  for memory attributes in EFI environment.
> 
> +
> 
> +  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> 
> +  Copyright (c) 2023, Google LLC. All rights reserved.<BR>
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +
> 
> +**/
> 
> +
> 
> +#ifndef __EFI_MEMORY_ATTRIBUTE_H__
> 
> +#define __EFI_MEMORY_ATTRIBUTE_H__
> 
> +
> 
> +#define EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID \
> 
> +  { \
> 
> +    0xf4560cf6, 0x40ec, 0x4b4a, { 0xa1, 0x92, 0xbf, 0x1d, 0x57, 0xd0,
0xb1,
> 0x89 } \
> 
> +  }
> 
> +
> 
> +typedef struct _EFI_MEMORY_ATTRIBUTE_PROTOCOL
> EFI_MEMORY_ATTRIBUTE_PROTOCOL;
> 
> +
> 
> +/**
> 
> +  This function set given attributes of the memory region specified by
> 
> +  BaseAddress and Length.
> 
> +
> 
> +  The valid Attributes is EFI_MEMORY_RP, EFI_MEMORY_XP, and
> EFI_MEMORY_RO.
> 
> +
> 
> +  @param  This              The
> EFI_MEMORY_ATTRIBUTE_PROTOCOL instance.
> 
> +  @param  BaseAddress       The physical address that is the start
> address of
> 
> +                            a memory region.
> 
> +  @param  Length            The size in bytes of the memory region.
> 
> +  @param  Attributes        The bit mask of attributes to set for the
> memory
> 
> +                            region.
> 
> +
> 
> +  @retval EFI_SUCCESS           The attributes were set for the
> memory region.
> 
> +  @retval EFI_INVALID_PARAMETER Length is zero.
> 
> +                                Attributes specified an illegal
> combination of
> 
> +                                attributes that cannot be set
> together.
> 
> +  @retval EFI_UNSUPPORTED       The processor does not support one
> or more
> 
> +                                bytes of the memory resource range
> specified
> 
> +                                by BaseAddress and Length.
> 
> +                                The bit mask of attributes is not
> supported for
> 
> +                                the memory resource range
> specified by
> 
> +                                BaseAddress and Length.
> 
> +  @retval EFI_OUT_OF_RESOURCES  Requested attributes cannot be
> applied due to
> 
> +                                lack of system resources.
> 
> +  @retval EFI_ACCESS_DENIED     Attributes for the requested memory
> region are
> 
> +                                controlled by system firmware and
> cannot be
> 
> +                                updated via the protocol.
> 
> +
> 
> +**/
> 
> +typedef
> 
> +EFI_STATUS
> 
> +(EFIAPI *EFI_SET_MEMORY_ATTRIBUTES)(
> 
> +  IN  EFI_MEMORY_ATTRIBUTE_PROTOCOL       *This,
> 
> +  IN  EFI_PHYSICAL_ADDRESS                BaseAddress,
> 
> +  IN  UINT64                              Length,
> 
> +  IN  UINT64                              Attributes
> 
> +  );
> 
> +
> 
> +/**
> 
> +  This function clears given attributes of the memory region specified by
> 
> +  BaseAddress and Length.
> 
> +
> 
> +  The valid Attributes is EFI_MEMORY_RP, EFI_MEMORY_XP, and
> EFI_MEMORY_RO.
> 
> +
> 
> +  @param  This              The
> EFI_MEMORY_ATTRIBUTE_PROTOCOL instance.
> 
> +  @param  BaseAddress       The physical address that is the start
> address of
> 
> +                            a memory region.
> 
> +  @param  Length            The size in bytes of the memory region.
> 
> +  @param  Attributes        The bit mask of attributes to clear for the
> memory
> 
> +                            region.
> 
> +
> 
> +  @retval EFI_SUCCESS           The attributes were cleared for the
> memory region.
> 
> +  @retval EFI_INVALID_PARAMETER Length is zero.
> 
> +                                Attributes specified an illegal
> combination of
> 
> +                                attributes that cannot be cleared
> together.
> 
> +  @retval EFI_UNSUPPORTED       The processor does not support one
> or more
> 
> +                                bytes of the memory resource range
> specified
> 
> +                                by BaseAddress and Length.
> 
> +                                The bit mask of attributes is not
> supported for
> 
> +                                the memory resource range
> specified by
> 
> +                                BaseAddress and Length.
> 
> +  @retval EFI_OUT_OF_RESOURCES  Requested attributes cannot be
> applied due to
> 
> +                                lack of system resources.
> 
> +  @retval EFI_ACCESS_DENIED     Attributes for the requested memory
> region are
> 
> +                                controlled by system firmware and
> cannot be
> 
> +                                updated via the protocol.
> 
> +
> 
> +**/
> 
> +typedef
> 
> +EFI_STATUS
> 
> +(EFIAPI *EFI_CLEAR_MEMORY_ATTRIBUTES)(
> 
> +  IN  EFI_MEMORY_ATTRIBUTE_PROTOCOL       *This,
> 
> +  IN  EFI_PHYSICAL_ADDRESS                BaseAddress,
> 
> +  IN  UINT64                              Length,
> 
> +  IN  UINT64                              Attributes
> 
> +  );
> 
> +
> 
> +/**
> 
> +  This function retrieves the attributes of the memory region specified
by
> 
> +  BaseAddress and Length. If different attributes are got from different
part
> 
> +  of the memory region, EFI_NO_MAPPING will be returned.
> 
> +
> 
> +  @param  This              The
> EFI_MEMORY_ATTRIBUTE_PROTOCOL instance.
> 
> +  @param  BaseAddress       The physical address that is the start
> address of
> 
> +                            a memory region.
> 
> +  @param  Length            The size in bytes of the memory region.
> 
> +  @param  Attributes        Pointer to attributes returned.
> 
> +
> 
> +  @retval EFI_SUCCESS           The attributes got for the memory
> region.
> 
> +  @retval EFI_INVALID_PARAMETER Length is zero.
> 
> +                                Attributes is NULL.
> 
> +  @retval EFI_NO_MAPPING        Attributes are not consistent cross
> the memory
> 
> +                                region.
> 
> +  @retval EFI_UNSUPPORTED       The processor does not support one
> or more
> 
> +                                bytes of the memory resource range
> specified
> 
> +                                by BaseAddress and Length.
> 
> +
> 
> +**/
> 
> +typedef
> 
> +EFI_STATUS
> 
> +(EFIAPI *EFI_GET_MEMORY_ATTRIBUTES)(
> 
> +  IN  EFI_MEMORY_ATTRIBUTE_PROTOCOL       *This,
> 
> +  IN  EFI_PHYSICAL_ADDRESS                BaseAddress,
> 
> +  IN  UINT64                              Length,
> 
> +  OUT UINT64                              *Attributes
> 
> +  );
> 
> +
> 
> +///
> 
> +/// EFI Memory Attribute Protocol provides services to retrieve or update
> 
> +/// attribute of memory in the EFI environment.
> 
> +///
> 
> +struct _EFI_MEMORY_ATTRIBUTE_PROTOCOL {
> 
> +  EFI_GET_MEMORY_ATTRIBUTES      GetMemoryAttributes;
> 
> +  EFI_SET_MEMORY_ATTRIBUTES      SetMemoryAttributes;
> 
> +  EFI_CLEAR_MEMORY_ATTRIBUTES    ClearMemoryAttributes;
> 
> +};
> 
> +
> 
> +extern EFI_GUID  gEfiMemoryAttributeProtocolGuid;
> 
> +
> 
> +#endif
> 
> diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
> index 3d08f20d15b0..a8658403c8fd 100644
> --- a/MdePkg/MdePkg.dec
> +++ b/MdePkg/MdePkg.dec
> @@ -1915,6 +1915,9 @@ [Protocols]
>    ## Include/Protocol/RedfishDiscover.h
> 
>    gEfiRedfishDiscoverProtocolGuid      = { 0x5db12509, 0x4550, 0x4347,
> { 0x96, 0xb3, 0x73, 0xc0, 0xff, 0x6e, 0x86, 0x9f }}
> 
> 
> 
> +   ## Include/Protocol/MemoryAttribute.h
> 
> +  gEfiMemoryAttributeProtocolGuid = { 0xf4560cf6, 0x40ec, 0x4b4a, { 0xa1,
> 0x92, 0xbf, 0x1d, 0x57, 0xd0, 0xb1, 0x89 }}
> 
> +
> 
>    #
> 
>    # Protocols defined in Shell2.0
> 
>    #
> 
> --
> 2.39.0
> 
> 
> 
> -=-=-=-=-=-=
> Groups.io Links: You receive all messages sent to this group.
> View/Reply Online (#99466): https://edk2.groups.io/g/devel/message/99466
> Mute This Topic: https://groups.io/mt/96697936/4905953
> Group Owner: devel+owner@edk2.groups.io
> Unsubscribe: https://edk2.groups.io/g/devel/unsub
> [gaoliming@byosoft.com.cn]
> -=-=-=-=-=-=
> 




^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-02-03  5:28 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-02-02 11:27 [PATCH v2 0/3] ArmPkg: implement EFI memory attributes protocol Ard Biesheuvel
2023-02-02 11:27 ` [PATCH v2 1/3] MdePkg: Add Memory Attribute Protocol definition Ard Biesheuvel
2023-02-03  5:28   ` 回复: [edk2-devel] " gaoliming
2023-02-02 11:27 ` [PATCH v2 2/3] ArmPkg/CpuDxe: Unify PageAttributeToGcdAttribute helper Ard Biesheuvel
2023-02-02 11:27 ` [PATCH v2 3/3] ArmPkg/CpuDxe: Implement EFI memory attributes protocol Ard Biesheuvel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox