diff --git a/OvmfPkg/XenPlatformPei/Platform.h b/OvmfPkg/XenPlatformPei/Platform.h index 7661f4a8de..e70ca58078 100644 --- a/OvmfPkg/XenPlatformPei/Platform.h +++ b/OvmfPkg/XenPlatformPei/Platform.h @@ -127,6 +127,11 @@ XenGetE820Map ( UINT32 *Count ); +EFI_STATUS +PhysicalAddressIdentityMapping ( + IN EFI_PHYSICAL_ADDRESS AddressToMap + ); + extern EFI_BOOT_MODE mBootMode; extern UINT8 mPhysMemAddressWidth; diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c index c41fecdc48..b2a7d1c21d 100644 --- a/OvmfPkg/XenPlatformPei/Xen.c +++ b/OvmfPkg/XenPlatformPei/Xen.c @@ -17,6 +17,8 @@ // // The Library classes this module consumes // +#include +#include #include #include #include @@ -25,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -386,3 +389,71 @@ InitializeXen ( return EFI_SUCCESS; } + +EFI_STATUS +PhysicalAddressIdentityMapping ( + IN EFI_PHYSICAL_ADDRESS AddressToMap + ) +{ + INTN Index; + PAGE_MAP_AND_DIRECTORY_POINTER *L4, *L3; + PAGE_TABLE_ENTRY *PageTable; + + DEBUG ((DEBUG_INFO, "Mapping 1:1 of address 0x%lx\n", (UINT64)AddressToMap)); + + // L4 / Top level Page Directory Pointers + + L4 = (VOID*)(UINTN)PcdGet32 (PcdOvmfSecPageTablesBase); + Index = PML4_OFFSET (AddressToMap); + + if (!L4[Index].Bits.Present) { + L3 = AllocatePages (1); + if (L3 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem (L3, EFI_PAGE_SIZE); + + L4[Index].Bits.ReadWrite = 1; + L4[Index].Bits.Accessed = 1; + L4[Index].Bits.PageTableBaseAddress = (EFI_PHYSICAL_ADDRESS)L3 >> 12; + L4[Index].Bits.Present = 1; + } + + // L3 / Next level Page Directory Pointers + + L3 = (VOID*)(EFI_PHYSICAL_ADDRESS)(L4[Index].Bits.PageTableBaseAddress << 12); + Index = PDP_OFFSET (AddressToMap); + + if (!L3[Index].Bits.Present) { + PageTable = AllocatePages (1); + if (PageTable == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem (PageTable, EFI_PAGE_SIZE); + + L3[Index].Bits.ReadWrite = 1; + L3[Index].Bits.Accessed = 1; + L3[Index].Bits.PageTableBaseAddress = (EFI_PHYSICAL_ADDRESS)PageTable >> 12; + L3[Index].Bits.Present = 1; + } + + // L2 / Page Table Entries + + PageTable = (VOID*)(EFI_PHYSICAL_ADDRESS)(L3[Index].Bits.PageTableBaseAddress << 12); + Index = PDE_OFFSET (AddressToMap); + + if (!PageTable[Index].Bits.Present) { + PageTable[Index].Bits.ReadWrite = 1; + PageTable[Index].Bits.Accessed = 1; + PageTable[Index].Bits.Dirty = 1; + PageTable[Index].Bits.MustBe1 = 1; + PageTable[Index].Bits.PageTableBaseAddress = AddressToMap >> 21; + PageTable[Index].Bits.Present = 1; + } + + CpuFlushTlb (); + + return EFI_SUCCESS; +} diff --git a/OvmfPkg/XenPlatformPei/XenPlatformPei.inf b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf index 0ef77db92c..8790d907d3 100644 --- a/OvmfPkg/XenPlatformPei/XenPlatformPei.inf +++ b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf @@ -66,6 +66,7 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId