// The package level header files this module uses\r
//\r
#include <IndustryStandard/E820.h>\r
+#include <IndustryStandard/I440FxPiix4.h>\r
#include <IndustryStandard/Q35MchIch9.h>\r
#include <PiPei.h>\r
\r
\r
STATIC UINT16 mQ35TsegMbytes;\r
\r
+UINT32 mQemuUc32Base;\r
+\r
VOID\r
Q35TsegMbytesInitialization (\r
VOID\r
}\r
\r
\r
+VOID\r
+QemuUc32BaseInitialization (\r
+ VOID\r
+ )\r
+{\r
+ UINT32 LowerMemorySize;\r
+ UINT32 Uc32Size;\r
+\r
+ if (mXen) {\r
+ return;\r
+ }\r
+\r
+ if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {\r
+ //\r
+ // On q35, the 32-bit area that we'll mark as UC, through variable MTRRs,\r
+ // starts at PcdPciExpressBaseAddress. The platform DSC is responsible for\r
+ // setting PcdPciExpressBaseAddress such that describing the\r
+ // [PcdPciExpressBaseAddress, 4GB) range require a very small number of\r
+ // variable MTRRs (preferably 1 or 2).\r
+ //\r
+ ASSERT (FixedPcdGet64 (PcdPciExpressBaseAddress) <= MAX_UINT32);\r
+ mQemuUc32Base = (UINT32)FixedPcdGet64 (PcdPciExpressBaseAddress);\r
+ return;\r
+ }\r
+\r
+ ASSERT (mHostBridgeDevId == INTEL_82441_DEVICE_ID);\r
+ //\r
+ // On i440fx, start with the [LowerMemorySize, 4GB) range. Make sure one\r
+ // variable MTRR suffices by truncating the size to a whole power of two,\r
+ // while keeping the end affixed to 4GB. This will round the base up.\r
+ //\r
+ LowerMemorySize = GetSystemMemorySizeBelow4gb ();\r
+ Uc32Size = GetPowerOfTwo32 ((UINT32)(SIZE_4GB - LowerMemorySize));\r
+ mQemuUc32Base = (UINT32)(SIZE_4GB - Uc32Size);\r
+ //\r
+ // Assuming that LowerMemorySize is at least 1 byte, Uc32Size is at most 2GB.\r
+ // Therefore mQemuUc32Base is at least 2GB.\r
+ //\r
+ ASSERT (mQemuUc32Base >= BASE_2GB);\r
+\r
+ if (mQemuUc32Base != LowerMemorySize) {\r
+ DEBUG ((DEBUG_VERBOSE, "%a: rounded UC32 base from 0x%x up to 0x%x, for "\r
+ "an UC32 size of 0x%x\n", __FUNCTION__, LowerMemorySize, mQemuUc32Base,\r
+ Uc32Size));\r
+ }\r
+}\r
+\r
+\r
/**\r
Iterate over the RAM entries in QEMU's fw_cfg E820 RAM map that start outside\r
of the 32-bit address range.\r
ASSERT_EFI_ERROR (Status);\r
\r
//\r
- // Set memory range from the "top of lower RAM" (RAM below 4GB) to 4GB as\r
- // uncacheable\r
+ // Set the memory range from the start of the 32-bit MMIO area (32-bit PCI\r
+ // MMIO aperture on i440fx, PCIEXBAR on q35) to 4GB as uncacheable.\r
//\r
- Status = MtrrSetMemoryAttribute (LowerMemorySize,\r
- SIZE_4GB - LowerMemorySize, CacheUncacheable);\r
+ Status = MtrrSetMemoryAttribute (mQemuUc32Base, SIZE_4GB - mQemuUc32Base,\r
+ CacheUncacheable);\r
ASSERT_EFI_ERROR (Status);\r
}\r
}\r