#include <Library/DxeServicesTableLib.h>\r
#include <Library/CacheMaintenanceLib.h>\r
\r
+#include <Protocol/Cpu.h>\r
+\r
+STATIC EFI_CPU_ARCH_PROTOCOL *mCpu;\r
+\r
VOID *\r
UncachedInternalAllocatePages (\r
IN EFI_MEMORY_TYPE MemoryType,\r
\r
Status = gDS->GetMemorySpaceDescriptor (Memory, &Descriptor);\r
if (EFI_ERROR (Status)) {\r
- gBS->FreePages (Memory, Pages);\r
- return Status;\r
+ goto FreePages;\r
}\r
\r
Status = gDS->SetMemorySpaceAttributes (Memory, EFI_PAGES_TO_SIZE (Pages),\r
- EFI_MEMORY_WC | EFI_MEMORY_XP);\r
+ EFI_MEMORY_WC);\r
if (EFI_ERROR (Status)) {\r
- gBS->FreePages (Memory, Pages);\r
- return Status;\r
+ goto FreePages;\r
+ }\r
+\r
+ //\r
+ // EFI_CPU_ARCH_PROTOCOL::SetMemoryAttributes() will preserve the original\r
+ // memory type attribute if no memory type is passed. Permission attributes\r
+ // will be replaced, so EFI_MEMORY_RO will be removed if present (although\r
+ // it would be a bug if that were the case for an AllocatePages() allocation)\r
+ //\r
+ Status = mCpu->SetMemoryAttributes (mCpu, Memory, EFI_PAGES_TO_SIZE (Pages),\r
+ EFI_MEMORY_XP);\r
+ if (EFI_ERROR (Status)) {\r
+ goto FreePages;\r
}\r
\r
InvalidateDataCacheRange ((VOID *)(UINTN)Memory, EFI_PAGES_TO_SIZE (Pages));\r
NewNode = AllocatePool (sizeof (FREE_PAGE_NODE));\r
if (NewNode == NULL) {\r
ASSERT (FALSE);\r
- gBS->FreePages (Memory, Pages);\r
- return EFI_OUT_OF_RESOURCES;\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto FreePages;\r
}\r
\r
NewNode->Base = Memory;\r
\r
*Allocation = NewNode->Allocation;\r
return EFI_SUCCESS;\r
+\r
+FreePages:\r
+ gBS->FreePages (Memory, Pages);\r
+ return Status;\r
}\r
\r
/**\r
* This function is not responsible to free allocated buffer (eg: case of memory leak,\r
* runtime allocation).\r
*/\r
+EFI_STATUS\r
+EFIAPI\r
+UncachedMemoryAllocationLibConstructor (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ return gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&mCpu);\r
+}\r
+\r
EFI_STATUS\r
EFIAPI\r
UncachedMemoryAllocationLibDestructor (\r