#include <Library/PeimEntryPoint.h>\r
#include <Library/PeiServicesLib.h>\r
#include <Library/QemuFwCfgLib.h>\r
+#include <Library/QemuFwCfgS3Lib.h>\r
#include <Library/ResourcePublicationLib.h>\r
#include <Guid/MemoryTypeInformation.h>\r
#include <Ppi/MasterBootMode.h>\r
\r
BOOLEAN mS3Supported = FALSE;\r
\r
+UINT32 mMaxCpuCount;\r
\r
VOID\r
AddIoMemoryBaseSizeHob (\r
VOID\r
)\r
{\r
+ UINT64 PciIoBase;\r
+ UINT64 PciIoSize;\r
+ RETURN_STATUS PcdStatus;\r
+\r
+ PciIoBase = 0xC000;\r
+ PciIoSize = 0x4000;\r
+\r
//\r
// Create Memory Type Information HOB\r
//\r
sizeof(mDefaultMemoryTypeInformation)\r
);\r
\r
- //\r
- // Add PCI IO Port space available for PCI resource allocations.\r
- //\r
- BuildResourceDescriptorHob (\r
- EFI_RESOURCE_IO,\r
- EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
- EFI_RESOURCE_ATTRIBUTE_INITIALIZED,\r
- PcdGet64 (PcdPciIoBase),\r
- PcdGet64 (PcdPciIoSize)\r
- );\r
-\r
//\r
// Video memory + Legacy BIOS region\r
//\r
//\r
PciSize = 0xFC000000 - PciBase;\r
AddIoMemoryBaseSizeHob (PciBase, PciSize);\r
- PcdSet64 (PcdPciMmio32Base, PciBase);\r
- PcdSet64 (PcdPciMmio32Size, PciSize);\r
+ PcdStatus = PcdSet64S (PcdPciMmio32Base, PciBase);\r
+ ASSERT_RETURN_ERROR (PcdStatus);\r
+ PcdStatus = PcdSet64S (PcdPciMmio32Size, PciSize);\r
+ ASSERT_RETURN_ERROR (PcdStatus);\r
+\r
AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);\r
AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);\r
if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {\r
EfiReservedMemoryType);\r
}\r
AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress), SIZE_1MB);\r
+\r
+ //\r
+ // On Q35, the IO Port space is available for PCI resource allocations from\r
+ // 0x6000 up.\r
+ //\r
+ if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {\r
+ PciIoBase = 0x6000;\r
+ PciIoSize = 0xA000;\r
+ ASSERT ((ICH9_PMBASE_VALUE & 0xF000) < PciIoBase);\r
+ }\r
}\r
+\r
+ //\r
+ // Add PCI IO Port space available for PCI resource allocations.\r
+ //\r
+ BuildResourceDescriptorHob (\r
+ EFI_RESOURCE_IO,\r
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED,\r
+ PciIoBase,\r
+ PciIoSize\r
+ );\r
+ PcdStatus = PcdSet64S (PcdPciIoBase, PciIoBase);\r
+ ASSERT_RETURN_ERROR (PcdStatus);\r
+ PcdStatus = PcdSet64S (PcdPciIoSize, PciIoSize);\r
+ ASSERT_RETURN_ERROR (PcdStatus);\r
}\r
\r
EFI_STATUS\r
\r
#define UPDATE_BOOLEAN_PCD_FROM_FW_CFG(TokenName) \\r
do { \\r
- BOOLEAN Setting; \\r
+ BOOLEAN Setting; \\r
+ RETURN_STATUS PcdStatus; \\r
\\r
if (!EFI_ERROR (GetNamedFwCfgBoolean ( \\r
"opt/ovmf/" #TokenName, &Setting))) { \\r
- PcdSetBool (TokenName, Setting); \\r
+ PcdStatus = PcdSetBoolS (TokenName, Setting); \\r
+ ASSERT_RETURN_ERROR (PcdStatus); \\r
} \\r
} while (0)\r
\r
VOID\r
)\r
{\r
- UINTN PmCmd;\r
- UINTN Pmba;\r
- UINTN AcpiCtlReg;\r
- UINT8 AcpiEnBit;\r
+ UINTN PmCmd;\r
+ UINTN Pmba;\r
+ UINT32 PmbaAndVal;\r
+ UINT32 PmbaOrVal;\r
+ UINTN AcpiCtlReg;\r
+ UINT8 AcpiEnBit;\r
+ RETURN_STATUS PcdStatus;\r
\r
//\r
// Disable A20 Mask\r
case INTEL_82441_DEVICE_ID:\r
PmCmd = POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET);\r
Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);\r
+ PmbaAndVal = ~(UINT32)PIIX4_PMBA_MASK;\r
+ PmbaOrVal = PIIX4_PMBA_VALUE;\r
AcpiCtlReg = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC);\r
AcpiEnBit = PIIX4_PMREGMISC_PMIOSE;\r
break;\r
case INTEL_Q35_MCH_DEVICE_ID:\r
PmCmd = POWER_MGMT_REGISTER_Q35 (PCI_COMMAND_OFFSET);\r
Pmba = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);\r
+ PmbaAndVal = ~(UINT32)ICH9_PMBASE_MASK;\r
+ PmbaOrVal = ICH9_PMBASE_VALUE;\r
AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL);\r
AcpiEnBit = ICH9_ACPI_CNTL_ACPI_EN;\r
break;\r
ASSERT (FALSE);\r
return;\r
}\r
- PcdSet16 (PcdOvmfHostBridgePciDevId, mHostBridgeDevId);\r
+ PcdStatus = PcdSet16S (PcdOvmfHostBridgePciDevId, mHostBridgeDevId);\r
+ ASSERT_RETURN_ERROR (PcdStatus);\r
\r
//\r
// If the appropriate IOspace enable bit is set, assume the ACPI PMBA\r
// The PEI phase should be exited with fully accessibe ACPI PM IO space:\r
// 1. set PMBA\r
//\r
- PciAndThenOr32 (Pmba, ~(UINT32)PIIX4_PMBA_MASK, PIIX4_PMBA_VALUE);\r
+ PciAndThenOr32 (Pmba, PmbaAndVal, PmbaOrVal);\r
\r
//\r
// 2. set PCICMD/IOSE\r
)\r
{\r
EFI_PHYSICAL_ADDRESS VariableStore;\r
+ RETURN_STATUS PcdStatus;\r
\r
//\r
// Allocate storage for NV variables early on so it will be\r
//\r
VariableStore =\r
(EFI_PHYSICAL_ADDRESS)(UINTN)\r
- AllocateAlignedRuntimePages (\r
- EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)),\r
- PcdGet32 (PcdFlashNvStorageFtwSpareSize)\r
+ AllocateRuntimePages (\r
+ EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize))\r
);\r
DEBUG ((EFI_D_INFO,\r
"Reserved variable store memory: 0x%lX; size: %dkb\n",\r
VariableStore,\r
(2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / 1024\r
));\r
- PcdSet64 (PcdEmuVariableNvStoreReserved, VariableStore);\r
+ PcdStatus = PcdSet64S (PcdEmuVariableNvStoreReserved, VariableStore);\r
+ ASSERT_RETURN_ERROR (PcdStatus);\r
}\r
\r
\r
}\r
\r
\r
+/**\r
+ Fetch the number of boot CPUs from QEMU and expose it to UefiCpuPkg modules.\r
+ Set the mMaxCpuCount variable.\r
+**/\r
+VOID\r
+MaxCpuCountInitialization (\r
+ VOID\r
+ )\r
+{\r
+ UINT16 ProcessorCount;\r
+ RETURN_STATUS PcdStatus;\r
+\r
+ QemuFwCfgSelectItem (QemuFwCfgItemSmpCpuCount);\r
+ ProcessorCount = QemuFwCfgRead16 ();\r
+ //\r
+ // If the fw_cfg key or fw_cfg entirely is unavailable, load mMaxCpuCount\r
+ // from the PCD default. No change to PCDs.\r
+ //\r
+ if (ProcessorCount == 0) {\r
+ mMaxCpuCount = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);\r
+ return;\r
+ }\r
+ //\r
+ // Otherwise, set mMaxCpuCount to the value reported by QEMU.\r
+ //\r
+ mMaxCpuCount = ProcessorCount;\r
+ //\r
+ // Additionally, tell UefiCpuPkg modules (a) the exact number of VCPUs, (b)\r
+ // to wait, in the initial AP bringup, exactly as long as it takes for all of\r
+ // the APs to report in. For this, we set the longest representable timeout\r
+ // (approx. 71 minutes).\r
+ //\r
+ PcdStatus = PcdSet32S (PcdCpuMaxLogicalProcessorNumber, ProcessorCount);\r
+ ASSERT_RETURN_ERROR (PcdStatus);\r
+ PcdStatus = PcdSet32S (PcdCpuApInitTimeOutInMicroSeconds, MAX_UINT32);\r
+ ASSERT_RETURN_ERROR (PcdStatus);\r
+ DEBUG ((DEBUG_INFO, "%a: QEMU reports %d processor(s)\n", __FUNCTION__,\r
+ ProcessorCount));\r
+}\r
+\r
+\r
/**\r
Perform Platform PEI initialization.\r
\r
{\r
EFI_STATUS Status;\r
\r
- DEBUG ((EFI_D_ERROR, "Platform PEIM Loaded\n"));\r
+ DEBUG ((DEBUG_INFO, "Platform PEIM Loaded\n"));\r
\r
DebugDumpCmos ();\r
\r
S3Verification ();\r
BootModeInitialization ();\r
AddressWidthInitialization ();\r
+ MaxCpuCountInitialization ();\r
+\r
+ //\r
+ // Query Host Bridge DID\r
+ //\r
+ mHostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);\r
+\r
+ if (FeaturePcdGet (PcdSmmSmramRequire)) {\r
+ Q35TsegMbytesInitialization ();\r
+ }\r
\r
PublishPeiMemory ();\r
\r
InitializeXen ();\r
}\r
\r
- //\r
- // Query Host Bridge DID\r
- //\r
- mHostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);\r
-\r
if (mBootMode != BOOT_ON_S3_RESUME) {\r
- ReserveEmuVariableNvStore ();\r
+ if (!FeaturePcdGet (PcdSmmSmramRequire)) {\r
+ ReserveEmuVariableNvStore ();\r
+ }\r
PeiFvInitialization ();\r
MemMapInitialization ();\r
NoexecDxeInitialization ();\r
}\r
\r
+ AmdSevInitialize ();\r
MiscInitialization ();\r
+ InstallFeatureControlCallback ();\r
\r
return EFI_SUCCESS;\r
}\r