summaryrefslogtreecommitdiffstats
path: root/OvmfPkg/XenPlatformPei
diff options
context:
space:
mode:
Diffstat (limited to 'OvmfPkg/XenPlatformPei')
-rw-r--r--OvmfPkg/XenPlatformPei/MemDetect.c69
-rw-r--r--OvmfPkg/XenPlatformPei/Platform.c11
-rw-r--r--OvmfPkg/XenPlatformPei/Platform.h13
-rw-r--r--OvmfPkg/XenPlatformPei/Xen.c77
4 files changed, 148 insertions, 22 deletions
diff --git a/OvmfPkg/XenPlatformPei/MemDetect.c b/OvmfPkg/XenPlatformPei/MemDetect.c
index cf95f9c474..1f81eee407 100644
--- a/OvmfPkg/XenPlatformPei/MemDetect.c
+++ b/OvmfPkg/XenPlatformPei/MemDetect.c
@@ -96,6 +96,45 @@ Q35TsegMbytesInitialization (
mQ35TsegMbytes = ExtendedTsegMbytes;
}
+STATIC
+UINT64
+GetHighestSystemMemoryAddress (
+ BOOLEAN Below4gb
+ )
+{
+ EFI_E820_ENTRY64 *E820Map;
+ UINT32 E820EntriesCount;
+ EFI_E820_ENTRY64 *Entry;
+ EFI_STATUS Status;
+ UINT32 Loop;
+ UINT64 HighestAddress;
+ UINT64 EntryEnd;
+
+ HighestAddress = 0;
+
+ Status = XenGetE820Map (&E820Map, &E820EntriesCount);
+ ASSERT_EFI_ERROR (Status);
+
+ for (Loop = 0; Loop < E820EntriesCount; Loop++) {
+ Entry = E820Map + Loop;
+ EntryEnd = Entry->BaseAddr + Entry->Length;
+
+ if (Entry->Type == EfiAcpiAddressRangeMemory &&
+ EntryEnd > HighestAddress) {
+
+ if (Below4gb && (EntryEnd <= BASE_4GB)) {
+ HighestAddress = EntryEnd;
+ } else if (!Below4gb && (EntryEnd >= BASE_4GB)) {
+ HighestAddress = EntryEnd;
+ }
+ }
+ }
+
+ //
+ // Round down the end address.
+ //
+ return HighestAddress & ~(UINT64)EFI_PAGE_MASK;
+}
UINT32
GetSystemMemorySizeBelow4gb (
@@ -106,6 +145,19 @@ GetSystemMemorySizeBelow4gb (
UINT8 Cmos0x35;
//
+ // In PVH case, there is no CMOS, we have to calculate the memory size
+ // from parsing the E820
+ //
+ if (XenPvhDetected ()) {
+ UINT64 HighestAddress;
+
+ HighestAddress = GetHighestSystemMemoryAddress (TRUE);
+ ASSERT (HighestAddress > 0 && HighestAddress <= BASE_4GB);
+
+ return HighestAddress;
+ }
+
+ //
// CMOS 0x34/0x35 specifies the system memory above 16 MB.
// * CMOS(0x35) is the high byte
// * CMOS(0x34) is the low byte
@@ -130,6 +182,23 @@ GetSystemMemorySizeAbove4gb (
UINTN CmosIndex;
//
+ // In PVH case, there is no CMOS, we have to calculate the memory size
+ // from parsing the E820
+ //
+ if (XenPvhDetected ()) {
+ UINT64 HighestAddress;
+
+ HighestAddress = GetHighestSystemMemoryAddress (FALSE);
+ ASSERT (HighestAddress == 0 || HighestAddress >= BASE_4GB);
+
+ if (HighestAddress >= BASE_4GB) {
+ HighestAddress -= BASE_4GB;
+ }
+
+ return HighestAddress;
+ }
+
+ //
// CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
// * CMOS(0x5d) is the most significant size byte
// * CMOS(0x5c) is the middle size byte
diff --git a/OvmfPkg/XenPlatformPei/Platform.c b/OvmfPkg/XenPlatformPei/Platform.c
index 6aaafc3ee9..2f42ca6ccd 100644
--- a/OvmfPkg/XenPlatformPei/Platform.c
+++ b/OvmfPkg/XenPlatformPei/Platform.c
@@ -103,6 +103,17 @@ AddReservedMemoryBaseSizeHob (
}
VOID
+AddReservedMemoryRangeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ EFI_PHYSICAL_ADDRESS MemoryLimit,
+ BOOLEAN Cacheable
+ )
+{
+ AddReservedMemoryBaseSizeHob (MemoryBase,
+ (UINT64)(MemoryLimit - MemoryBase), Cacheable);
+}
+
+VOID
AddIoMemoryRangeHob (
EFI_PHYSICAL_ADDRESS MemoryBase,
EFI_PHYSICAL_ADDRESS MemoryLimit
diff --git a/OvmfPkg/XenPlatformPei/Platform.h b/OvmfPkg/XenPlatformPei/Platform.h
index db9a62572f..7661f4a8de 100644
--- a/OvmfPkg/XenPlatformPei/Platform.h
+++ b/OvmfPkg/XenPlatformPei/Platform.h
@@ -45,6 +45,13 @@ AddReservedMemoryBaseSizeHob (
);
VOID
+AddReservedMemoryRangeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ EFI_PHYSICAL_ADDRESS MemoryLimit,
+ BOOLEAN Cacheable
+ );
+
+VOID
AddressWidthInitialization (
VOID
);
@@ -114,6 +121,12 @@ XenPublishRamRegions (
VOID
);
+EFI_STATUS
+XenGetE820Map (
+ EFI_E820_ENTRY64 **Entries,
+ UINT32 *Count
+ );
+
extern EFI_BOOT_MODE mBootMode;
extern UINT8 mPhysMemAddressWidth;
diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
index 72f6f37b46..c4506def9a 100644
--- a/OvmfPkg/XenPlatformPei/Xen.c
+++ b/OvmfPkg/XenPlatformPei/Xen.c
@@ -276,9 +276,14 @@ XenPublishRamRegions (
VOID
)
{
- EFI_E820_ENTRY64 *E820Map;
- UINT32 E820EntriesCount;
- EFI_STATUS Status;
+ EFI_E820_ENTRY64 *E820Map;
+ UINT32 E820EntriesCount;
+ EFI_STATUS Status;
+ EFI_E820_ENTRY64 *Entry;
+ UINTN Index;
+ UINT64 LapicBase;
+ UINT64 LapicEnd;
+
DEBUG ((DEBUG_INFO, "Using memory map provided by Xen\n"));
@@ -287,26 +292,60 @@ XenPublishRamRegions (
//
E820EntriesCount = 0;
Status = XenGetE820Map (&E820Map, &E820EntriesCount);
-
ASSERT_EFI_ERROR (Status);
- if (E820EntriesCount > 0) {
- EFI_E820_ENTRY64 *Entry;
- UINT32 Loop;
-
- for (Loop = 0; Loop < E820EntriesCount; Loop++) {
- Entry = E820Map + Loop;
+ LapicBase = PcdGet32 (PcdCpuLocalApicBaseAddress);
+ LapicEnd = LapicBase + SIZE_1MB;
+ AddIoMemoryRangeHob (LapicBase, LapicEnd);
+
+ for (Index = 0; Index < E820EntriesCount; Index++) {
+ UINT64 Base;
+ UINT64 End;
+ UINT64 ReservedBase;
+ UINT64 ReservedEnd;
+
+ Entry = &E820Map[Index];
+
+ //
+ // Round up the start address, and round down the end address.
+ //
+ Base = ALIGN_VALUE (Entry->BaseAddr, (UINT64)EFI_PAGE_SIZE);
+ End = (Entry->BaseAddr + Entry->Length) & ~(UINT64)EFI_PAGE_MASK;
+
+ switch (Entry->Type) {
+ case EfiAcpiAddressRangeMemory:
+ AddMemoryRangeHob (Base, End);
+ break;
+ case EfiAcpiAddressRangeACPI:
+ AddReservedMemoryRangeHob (Base, End, FALSE);
+ break;
+ case EfiAcpiAddressRangeReserved:
+ //
+ // hvmloader marks a range that overlaps with the local APIC memory
+ // mapped region as reserved, but CpuDxe wants it as mapped IO. We
+ // have already added it as mapped IO, so skip it here.
+ //
//
- // Only care about RAM
+ // add LAPIC predecessor range, if any
//
- if (Entry->Type != EfiAcpiAddressRangeMemory) {
- continue;
+ ReservedBase = Base;
+ ReservedEnd = MIN (End, LapicBase);
+ if (ReservedBase < ReservedEnd) {
+ AddReservedMemoryRangeHob (ReservedBase, ReservedEnd, FALSE);
}
- AddMemoryBaseSizeHob (Entry->BaseAddr, Entry->Length);
-
- MtrrSetMemoryAttribute (Entry->BaseAddr, Entry->Length, CacheWriteBack);
+ //
+ // add LAPIC successor range, if any
+ //
+ ReservedBase = MAX (Base, LapicEnd);
+ ReservedEnd = End;
+ if (ReservedBase < ReservedEnd) {
+ AddReservedMemoryRangeHob (ReservedBase, ReservedEnd, FALSE);
+ }
+ break;
+ default:
+ break;
}
}
}
@@ -326,12 +365,6 @@ InitializeXen (
{
RETURN_STATUS PcdStatus;
- //
- // Reserve away HVMLOADER reserved memory [0xFC000000,0xFD000000).
- // This needs to match HVMLOADER RESERVED_MEMBASE/RESERVED_MEMSIZE.
- //
- AddReservedMemoryBaseSizeHob (0xFC000000, 0x1000000, FALSE);
-
PcdStatus = PcdSetBoolS (PcdPciDisableBusEnumeration, TRUE);
ASSERT_RETURN_ERROR (PcdStatus);