mQ35TsegMbytes = ExtendedTsegMbytes;\r
}\r
\r
+STATIC\r
+UINT64\r
+GetHighestSystemMemoryAddress (\r
+ BOOLEAN Below4gb\r
+ )\r
+{\r
+ EFI_E820_ENTRY64 *E820Map;\r
+ UINT32 E820EntriesCount;\r
+ EFI_E820_ENTRY64 *Entry;\r
+ EFI_STATUS Status;\r
+ UINT32 Loop;\r
+ UINT64 HighestAddress;\r
+ UINT64 EntryEnd;\r
+\r
+ HighestAddress = 0;\r
+\r
+ Status = XenGetE820Map (&E820Map, &E820EntriesCount);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ for (Loop = 0; Loop < E820EntriesCount; Loop++) {\r
+ Entry = E820Map + Loop;\r
+ EntryEnd = Entry->BaseAddr + Entry->Length;\r
+\r
+ if (Entry->Type == EfiAcpiAddressRangeMemory &&\r
+ EntryEnd > HighestAddress) {\r
+\r
+ if (Below4gb && (EntryEnd <= BASE_4GB)) {\r
+ HighestAddress = EntryEnd;\r
+ } else if (!Below4gb && (EntryEnd >= BASE_4GB)) {\r
+ HighestAddress = EntryEnd;\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // Round down the end address.\r
+ //\r
+ return HighestAddress & ~(UINT64)EFI_PAGE_MASK;\r
+}\r
\r
UINT32\r
GetSystemMemorySizeBelow4gb (\r
UINT8 Cmos0x34;\r
UINT8 Cmos0x35;\r
\r
+ //\r
+ // In PVH case, there is no CMOS, we have to calculate the memory size\r
+ // from parsing the E820\r
+ //\r
+ if (XenPvhDetected ()) {\r
+ UINT64 HighestAddress;\r
+\r
+ HighestAddress = GetHighestSystemMemoryAddress (TRUE);\r
+ ASSERT (HighestAddress > 0 && HighestAddress <= BASE_4GB);\r
+\r
+ return HighestAddress;\r
+ }\r
+\r
//\r
// CMOS 0x34/0x35 specifies the system memory above 16 MB.\r
// * CMOS(0x35) is the high byte\r
UINT32 Size;\r
UINTN CmosIndex;\r
\r
+ //\r
+ // In PVH case, there is no CMOS, we have to calculate the memory size\r
+ // from parsing the E820\r
+ //\r
+ if (XenPvhDetected ()) {\r
+ UINT64 HighestAddress;\r
+\r
+ HighestAddress = GetHighestSystemMemoryAddress (FALSE);\r
+ ASSERT (HighestAddress == 0 || HighestAddress >= BASE_4GB);\r
+\r
+ if (HighestAddress >= BASE_4GB) {\r
+ HighestAddress -= BASE_4GB;\r
+ }\r
+\r
+ return HighestAddress;\r
+ }\r
+\r
//\r
// CMOS 0x5b-0x5d specifies the system memory above 4GB MB.\r
// * CMOS(0x5d) is the most significant size byte\r
VOID\r
)\r
{\r
- EFI_E820_ENTRY64 *E820Map;\r
- UINT32 E820EntriesCount;\r
- EFI_STATUS Status;\r
+ EFI_E820_ENTRY64 *E820Map;\r
+ UINT32 E820EntriesCount;\r
+ EFI_STATUS Status;\r
+ EFI_E820_ENTRY64 *Entry;\r
+ UINTN Index;\r
+ UINT64 LapicBase;\r
+ UINT64 LapicEnd;\r
+\r
\r
DEBUG ((DEBUG_INFO, "Using memory map provided by Xen\n"));\r
\r
//\r
E820EntriesCount = 0;\r
Status = XenGetE820Map (&E820Map, &E820EntriesCount);\r
-\r
ASSERT_EFI_ERROR (Status);\r
\r
- if (E820EntriesCount > 0) {\r
- EFI_E820_ENTRY64 *Entry;\r
- UINT32 Loop;\r
-\r
- for (Loop = 0; Loop < E820EntriesCount; Loop++) {\r
- Entry = E820Map + Loop;\r
+ LapicBase = PcdGet32 (PcdCpuLocalApicBaseAddress);\r
+ LapicEnd = LapicBase + SIZE_1MB;\r
+ AddIoMemoryRangeHob (LapicBase, LapicEnd);\r
+\r
+ for (Index = 0; Index < E820EntriesCount; Index++) {\r
+ UINT64 Base;\r
+ UINT64 End;\r
+ UINT64 ReservedBase;\r
+ UINT64 ReservedEnd;\r
+\r
+ Entry = &E820Map[Index];\r
+\r
+ //\r
+ // Round up the start address, and round down the end address.\r
+ //\r
+ Base = ALIGN_VALUE (Entry->BaseAddr, (UINT64)EFI_PAGE_SIZE);\r
+ End = (Entry->BaseAddr + Entry->Length) & ~(UINT64)EFI_PAGE_MASK;\r
+\r
+ switch (Entry->Type) {\r
+ case EfiAcpiAddressRangeMemory:\r
+ AddMemoryRangeHob (Base, End);\r
+ break;\r
+ case EfiAcpiAddressRangeACPI:\r
+ AddReservedMemoryRangeHob (Base, End, FALSE);\r
+ break;\r
+ case EfiAcpiAddressRangeReserved:\r
+ //\r
+ // hvmloader marks a range that overlaps with the local APIC memory\r
+ // mapped region as reserved, but CpuDxe wants it as mapped IO. We\r
+ // have already added it as mapped IO, so skip it here.\r
+ //\r
\r
//\r
- // Only care about RAM\r
+ // add LAPIC predecessor range, if any\r
//\r
- if (Entry->Type != EfiAcpiAddressRangeMemory) {\r
- continue;\r
+ ReservedBase = Base;\r
+ ReservedEnd = MIN (End, LapicBase);\r
+ if (ReservedBase < ReservedEnd) {\r
+ AddReservedMemoryRangeHob (ReservedBase, ReservedEnd, FALSE);\r
}\r
\r
- AddMemoryBaseSizeHob (Entry->BaseAddr, Entry->Length);\r
-\r
- MtrrSetMemoryAttribute (Entry->BaseAddr, Entry->Length, CacheWriteBack);\r
+ //\r
+ // add LAPIC successor range, if any\r
+ //\r
+ ReservedBase = MAX (Base, LapicEnd);\r
+ ReservedEnd = End;\r
+ if (ReservedBase < ReservedEnd) {\r
+ AddReservedMemoryRangeHob (ReservedBase, ReservedEnd, FALSE);\r
+ }\r
+ break;\r
+ default:\r
+ break;\r
}\r
}\r
}\r
{\r
RETURN_STATUS PcdStatus;\r
\r
- //\r
- // Reserve away HVMLOADER reserved memory [0xFC000000,0xFD000000).\r
- // This needs to match HVMLOADER RESERVED_MEMBASE/RESERVED_MEMSIZE.\r
- //\r
- AddReservedMemoryBaseSizeHob (0xFC000000, 0x1000000, FALSE);\r
-\r
PcdStatus = PcdSetBoolS (PcdPciDisableBusEnumeration, TRUE);\r
ASSERT_RETURN_ERROR (PcdStatus);\r
\r