AsmWriteCr0 (AsmReadCr0 () | BIT16);\r
}\r
\r
+RETURN_STATUS\r
+EFIAPI\r
+InternalMemEncryptSevCreateIdentityMap1G (\r
+ IN PHYSICAL_ADDRESS Cr3BaseAddress,\r
+ IN PHYSICAL_ADDRESS PhysicalAddress,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry;\r
+ PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry;\r
+ UINT64 PgTableMask;\r
+ UINT64 AddressEncMask;\r
+ BOOLEAN IsWpEnabled;\r
+ RETURN_STATUS Status;\r
+\r
+ //\r
+ // Set PageMapLevel4Entry to suppress incorrect compiler/analyzer warnings.\r
+ //\r
+ PageMapLevel4Entry = NULL;\r
+\r
+ DEBUG ((\r
+ DEBUG_VERBOSE,\r
+ "%a:%a: Cr3Base=0x%Lx Physical=0x%Lx Length=0x%Lx\n",\r
+ gEfiCallerBaseName,\r
+ __FUNCTION__,\r
+ Cr3BaseAddress,\r
+ PhysicalAddress,\r
+ (UINT64)Length\r
+ ));\r
+\r
+ if (Length == 0) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Check if we have a valid memory encryption mask\r
+ //\r
+ AddressEncMask = InternalGetMemEncryptionAddressMask ();\r
+ if (!AddressEncMask) {\r
+ return RETURN_ACCESS_DENIED;\r
+ }\r
+\r
+ PgTableMask = AddressEncMask | EFI_PAGE_MASK;\r
+\r
+ //\r
+ // Make sure that the page table is changeable.\r
+ //\r
+ IsWpEnabled = IsReadOnlyPageWriteProtected ();\r
+ if (IsWpEnabled) {\r
+ DisableReadOnlyPageWriteProtect ();\r
+ }\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ while (Length) {\r
+ //\r
+ // If Cr3BaseAddress is not specified then read the current CR3\r
+ //\r
+ if (Cr3BaseAddress == 0) {\r
+ Cr3BaseAddress = AsmReadCr3 ();\r
+ }\r
+\r
+ PageMapLevel4Entry = (VOID *)(Cr3BaseAddress & ~PgTableMask);\r
+ PageMapLevel4Entry += PML4_OFFSET (PhysicalAddress);\r
+ if (!PageMapLevel4Entry->Bits.Present) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "%a:%a: bad PML4 for Physical=0x%Lx\n",\r
+ gEfiCallerBaseName,\r
+ __FUNCTION__,\r
+ PhysicalAddress\r
+ ));\r
+ Status = RETURN_NO_MAPPING;\r
+ goto Done;\r
+ }\r
+\r
+ PageDirectory1GEntry = (VOID *)(\r
+ (PageMapLevel4Entry->Bits.PageTableBaseAddress <<\r
+ 12) & ~PgTableMask\r
+ );\r
+ PageDirectory1GEntry += PDP_OFFSET (PhysicalAddress);\r
+ if (!PageDirectory1GEntry->Bits.Present) {\r
+ PageDirectory1GEntry->Bits.Present = 1;\r
+ PageDirectory1GEntry->Bits.MustBe1 = 1;\r
+ PageDirectory1GEntry->Bits.MustBeZero = 0;\r
+ PageDirectory1GEntry->Bits.ReadWrite = 1;\r
+ PageDirectory1GEntry->Uint64 |= (UINT64)PhysicalAddress | AddressEncMask;\r
+ }\r
+\r
+ if (Length <= BIT30) {\r
+ Length = 0;\r
+ } else {\r
+ Length -= BIT30;\r
+ }\r
+\r
+ PhysicalAddress += BIT30;\r
+ }\r
+\r
+ //\r
+ // Flush TLB\r
+ //\r
+ CpuFlushTlb ();\r
+\r
+Done:\r
+ //\r
+ // Restore page table write protection, if any.\r
+ //\r
+ if (IsWpEnabled) {\r
+ EnableReadOnlyPageWriteProtect ();\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
/**\r
This function either sets or clears memory encryption bit for the memory\r
region specified by PhysicalAddress and Length from the current page table\r