diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c index f26f0e56dd..72f6f37b46 100644 --- a/OvmfPkg/XenPlatformPei/Xen.c +++ b/OvmfPkg/XenPlatformPei/Xen.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "Platform.h" #include "Xen.h" @@ -40,6 +41,8 @@ EFI_XEN_INFO mXenInfo; // Only the E820 table is used by OVMF. // EFI_XEN_OVMF_INFO *mXenHvmloaderInfo; +STATIC EFI_E820_ENTRY64 mE820Entries[128]; +STATIC UINT32 mE820EntriesCount; /** Returns E820 map provided by Xen @@ -55,6 +58,12 @@ XenGetE820Map ( UINT32 *Count ) { + INTN ReturnCode; + xen_memory_map_t Parameters; + UINTN LoopIndex; + UINTN Index; + EFI_E820_ENTRY64 TmpEntry; + // // Get E820 produced by hvmloader // @@ -66,7 +75,42 @@ XenGetE820Map ( return EFI_SUCCESS; } - return EFI_NOT_FOUND; + // + // Otherwise, get the E820 table from the Xen hypervisor + // + + if (mE820EntriesCount > 0) { + *Entries = mE820Entries; + *Count = mE820EntriesCount; + return EFI_SUCCESS; + } + + Parameters.nr_entries = 128; + set_xen_guest_handle (Parameters.buffer, mE820Entries); + + // Returns a errno + ReturnCode = XenHypercallMemoryOp (XENMEM_memory_map, &Parameters); + ASSERT (ReturnCode == 0); + + mE820EntriesCount = Parameters.nr_entries; + + // + // Sort E820 entries + // + for (LoopIndex = 1; LoopIndex < mE820EntriesCount; LoopIndex++) { + for (Index = LoopIndex; Index < mE820EntriesCount; Index++) { + if (mE820Entries[Index - 1].BaseAddr > mE820Entries[Index].BaseAddr) { + TmpEntry = mE820Entries[Index]; + mE820Entries[Index] = mE820Entries[Index - 1]; + mE820Entries[Index - 1] = TmpEntry; + } + } + } + + *Count = mE820EntriesCount; + *Entries = mE820Entries; + + return EFI_SUCCESS; } /**