--- /dev/null
+/** @file\r
+\r
+ Virtual Memory Management Services to set or clear the memory encryption bit\r
+\r
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
+\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
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Code is derived from MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h\r
+\r
+**/\r
+\r
+#ifndef __VIRTUAL_MEMORY__\r
+#define __VIRTUAL_MEMORY__\r
+\r
+#include <Uefi.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+\r
+#include <Library/CacheMaintenanceLib.h>\r
+#define SYS_CODE64_SEL 0x38\r
+\r
+#pragma pack(1)\r
+\r
+//\r
+// Page-Map Level-4 Offset (PML4) and\r
+// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB\r
+//\r
+\r
+typedef union {\r
+ struct {\r
+ UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory\r
+ UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write\r
+ UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User\r
+ UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching\r
+ UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached\r
+ UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)\r
+ UINT64 Reserved:1; // Reserved\r
+ UINT64 MustBeZero:2; // Must Be Zero\r
+ UINT64 Available:3; // Available for use by system software\r
+ UINT64 PageTableBaseAddress:40; // Page Table Base Address\r
+ UINT64 AvabilableHigh:11; // Available for use by system software\r
+ UINT64 Nx:1; // No Execute bit\r
+ } Bits;\r
+ UINT64 Uint64;\r
+} PAGE_MAP_AND_DIRECTORY_POINTER;\r
+\r
+//\r
+// Page Table Entry 4KB\r
+//\r
+typedef union {\r
+ struct {\r
+ UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory\r
+ UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write\r
+ UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User\r
+ UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching\r
+ UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached\r
+ UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)\r
+ UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page\r
+ UINT64 PAT:1; //\r
+ UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write\r
+ UINT64 Available:3; // Available for use by system software\r
+ UINT64 PageTableBaseAddress:40; // Page Table Base Address\r
+ UINT64 AvabilableHigh:11; // Available for use by system software\r
+ UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution\r
+ } Bits;\r
+ UINT64 Uint64;\r
+} PAGE_TABLE_4K_ENTRY;\r
+\r
+//\r
+// Page Table Entry 2MB\r
+//\r
+typedef union {\r
+ struct {\r
+ UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory\r
+ UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write\r
+ UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User\r
+ UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching\r
+ UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached\r
+ UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)\r
+ UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page\r
+ UINT64 MustBe1:1; // Must be 1\r
+ UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write\r
+ UINT64 Available:3; // Available for use by system software\r
+ UINT64 PAT:1; //\r
+ UINT64 MustBeZero:8; // Must be zero;\r
+ UINT64 PageTableBaseAddress:31; // Page Table Base Address\r
+ UINT64 AvabilableHigh:11; // Available for use by system software\r
+ UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution\r
+ } Bits;\r
+ UINT64 Uint64;\r
+} PAGE_TABLE_ENTRY;\r
+\r
+//\r
+// Page Table Entry 1GB\r
+//\r
+typedef union {\r
+ struct {\r
+ UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory\r
+ UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write\r
+ UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User\r
+ UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching\r
+ UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached\r
+ UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)\r
+ UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page\r
+ UINT64 MustBe1:1; // Must be 1\r
+ UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write\r
+ UINT64 Available:3; // Available for use by system software\r
+ UINT64 PAT:1; //\r
+ UINT64 MustBeZero:17; // Must be zero;\r
+ UINT64 PageTableBaseAddress:22; // Page Table Base Address\r
+ UINT64 AvabilableHigh:11; // Available for use by system software\r
+ UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution\r
+ } Bits;\r
+ UINT64 Uint64;\r
+} PAGE_TABLE_1G_ENTRY;\r
+\r
+#pragma pack()\r
+\r
+#define IA32_PG_P BIT0\r
+#define IA32_PG_RW BIT1\r
+\r
+#define PAGETABLE_ENTRY_MASK ((1UL << 9) - 1)\r
+#define PML4_OFFSET(x) ( (x >> 39) & PAGETABLE_ENTRY_MASK)\r
+#define PDP_OFFSET(x) ( (x >> 30) & PAGETABLE_ENTRY_MASK)\r
+#define PDE_OFFSET(x) ( (x >> 21) & PAGETABLE_ENTRY_MASK)\r
+#define PTE_OFFSET(x) ( (x >> 12) & PAGETABLE_ENTRY_MASK)\r
+#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull\r
+\r
+/**\r
+ This function clears memory encryption bit for the memory region specified by PhysicalAddress\r
+ and length from the current page table context.\r
+\r
+ @param[in] PhysicalAddress The physical address that is the start address of a memory region.\r
+ @param[in] Length The length of memory region\r
+ @param[in] Flush Flush the caches before applying the encryption mask\r
+\r
+ @retval RETURN_SUCCESS The attributes were cleared for the memory region.\r
+ @retval RETURN_INVALID_PARAMETER Number of pages is zero.\r
+ @retval RETURN_UNSUPPORTED Setting the memory encyrption attribute is not supported\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+InternalMemEncryptSevSetMemoryDecrypted (\r
+ IN PHYSICAL_ADDRESS Cr3BaseAddress,\r
+ IN PHYSICAL_ADDRESS PhysicalAddress,\r
+ IN UINT64 Length,\r
+ IN BOOLEAN CacheFlush\r
+ );\r
+\r
+/**\r
+ This function sets memory encryption bit for the memory region specified by\r
+ PhysicalAddress and length from the current page table context.\r
+\r
+ @param[in] PhysicalAddress The physical address that is the start address\r
+ of a memory region.\r
+ @param[in] Length The length of memory region\r
+ @param[in] Flush Flush the caches before applying the\r
+ encryption mask\r
+\r
+ @retval RETURN_SUCCESS The attributes were cleared for the memory region.\r
+ @retval RETURN_INVALID_PARAMETER Number of pages is zero.\r
+ @retval RETURN_UNSUPPORTED Setting the memory encyrption attribute is\r
+ not supported\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+InternalMemEncryptSevSetMemoryEncrypted (\r
+ IN PHYSICAL_ADDRESS Cr3BaseAddress,\r
+ IN PHYSICAL_ADDRESS PhysicalAddress,\r
+ IN UINT64 Length,\r
+ IN BOOLEAN CacheFlush\r
+ );\r
+\r
+#endif\r