audk/OvmfPkg/PlatformPei/Platform.c

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

373 lines
9.9 KiB
C
Raw Normal View History

/**@file
Platform PEI driver
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
//
// The package level header files this module uses
//
#include <PiPei.h>
//
// The Library classes this module consumes
//
#include <Library/BaseMemoryLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/IoLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/PciLib.h>
#include <Library/PeimEntryPoint.h>
#include <Library/PeiServicesLib.h>
#include <Library/QemuFwCfgLib.h>
#include <Library/QemuFwCfgS3Lib.h>
#include <Library/QemuFwCfgSimpleParserLib.h>
#include <Library/ResourcePublicationLib.h>
#include <Ppi/MasterBootMode.h>
OvmfPkg/PlatformPei: rewrite MaxCpuCountInitialization() for CPU hotplug MaxCpuCountInitialization() currently handles the following options: (1) QEMU does not report the boot CPU count (FW_CFG_NB_CPUS is 0) In this case, PlatformPei makes MpInitLib enumerate APs up to the default PcdCpuMaxLogicalProcessorNumber value (64) minus 1, or until the default PcdCpuApInitTimeOutInMicroSeconds (50,000) elapses. (Whichever is reached first.) Time-limited AP enumeration had never been reliable on QEMU/KVM, which is why commit 45a70db3c3a5 strated handling case (2) below, in OVMF. (2) QEMU reports the boot CPU count (FW_CFG_NB_CPUS is nonzero) In this case, PlatformPei sets - PcdCpuMaxLogicalProcessorNumber to the reported boot CPU count (FW_CFG_NB_CPUS, which exports "PCMachineState.boot_cpus"), - and PcdCpuApInitTimeOutInMicroSeconds to practically "infinity" (MAX_UINT32, ~71 minutes). That causes MpInitLib to enumerate exactly the present (boot) APs. With CPU hotplug in mind, this method is not good enough. Because, using QEMU terminology, UefiCpuPkg expects PcdCpuMaxLogicalProcessorNumber to provide the "possible CPUs" count ("MachineState.smp.max_cpus"), which includes present and not present CPUs both (with not present CPUs being subject for hot-plugging). FW_CFG_NB_CPUS does not include not present CPUs. Rewrite MaxCpuCountInitialization() for handling the following cases: (1) The behavior of case (1) does not change. (No UefiCpuPkg PCDs are set to values different from the defaults.) (2) QEMU reports the boot CPU count ("PCMachineState.boot_cpus", via FW_CFG_NB_CPUS), but not the possible CPUs count ("MachineState.smp.max_cpus"). In this case, the behavior remains unchanged. The way MpInitLib is instructed to do the same differs however: we now set the new PcdCpuBootLogicalProcessorNumber to the boot CPU count (while continuing to set PcdCpuMaxLogicalProcessorNumber identically). PcdCpuApInitTimeOutInMicroSeconds becomes irrelevant. (3) QEMU reports both the boot CPU count ("PCMachineState.boot_cpus", via FW_CFG_NB_CPUS), and the possible CPUs count ("MachineState.smp.max_cpus"). We tell UefiCpuPkg about the possible CPUs count through PcdCpuMaxLogicalProcessorNumber. We also tell MpInitLib the boot CPU count for precise and quick AP enumeration, via PcdCpuBootLogicalProcessorNumber. PcdCpuApInitTimeOutInMicroSeconds is irrelevant again. This patch is a pre-requisite for enabling CPU hotplug with SMM_REQUIRE. As a side effect, the patch also enables S3 to work with CPU hotplug at once, *without* SMM_REQUIRE. (Without the patch, S3 resume fails, if a CPU is hot-plugged at OS runtime, prior to suspend: the FW_CFG_NB_CPUS increase seen during resume causes PcdCpuMaxLogicalProcessorNumber to increase as well, which is not permitted. With the patch, PcdCpuMaxLogicalProcessorNumber stays the same, namely "MachineState.smp.max_cpus". Therefore, the CPU structures allocated during normal boot can accommodate the CPUs at S3 resume that have been hotplugged prior to S3 suspend.) Cc: Anthony Perard <anthony.perard@citrix.com> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Igor Mammedov <imammedo@redhat.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Julien Grall <julien.grall@arm.com> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1515 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Message-Id: <20191022221554.14963-4-lersek@redhat.com> Acked-by: Anthony PERARD <anthony.perard@citrix.com> Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com> Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2019-10-08 09:15:38 +02:00
#include <IndustryStandard/I440FxPiix4.h>
#include <IndustryStandard/Microvm.h>
OvmfPkg: enable PIIX4 IO space in the PEI phase I. There are at least three locations in OvmfPkg that manipulate the PMBA and related PIIX4 registers. 1. MiscInitialization() [OvmfPkg/PlatformPei/Platform.c] module type: PEIM -- Pre-EFI Initialization Module (a) currently sets the PMBA only: 00.01.3 / 0x40 bits [15:6] 2. AcpiTimerLibConstructor() [OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c] module type: BASE -- probably callable anywhere after PEI (a) sets the PMBA if needed: 00.01.3 / 0x40 bits [15:6] (b) sets PCICMD/IOSE if needed: 00.01.3 / 0x04 bit 0 (c) sets PMREGMISC/PMIOSE: 00.01.3 / 0x80 bit 0 3. AcpiInitialization() [OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c] module type: DXE_DRIVER -- Driver eXecution Environment (a) sets SCI_EN, which depends on correct PMBA setting from earlier ( The relative order of #1 and #3 is dictated minimally by their module types. Said relative order can be verified with the boot log: 27 Loading PEIM at 0x00000822320 EntryPoint=0x00000822580 PlatformPei.efi 28 Platform PEIM Loaded 1259 PlatformBdsInit 1270 PlatformBdsPolicyBehavior Line 28 is printed by InitializePlatform() [OvmfPkg/PlatformPei/Platform.c] which is the entry point of that module. The other two lines are printed by the corresponding functions in "OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c". ) Currently #2 (AcpiTimerLibConstructor()) is called in a random spot (whenever it gets loaded from the firmware image) and masks the insufficient setup in #1. We shouldn't depend on that, PEI should finish with IO space being fully accessibe. In addition, PEI should program the same PMBA value as AcpiTimerLib. II. The PEI change notwithstanding, AcpiTimerLib should stay defensive and ensure proper PM configuration for itself (either by confirming or by doing). III. Considering a possible cleanup/unification of #2 and #3: timer functions relying on AcpiTimerLibConstructor(), - MicroSecondDelay() - NanoSecondDelay() - GetPerformanceCounter() - GetPerformanceCounterProperties() - GetTimeInNanoSecond() may be called before #3 is reached (in Boot Device Selection phase), so we should not move the initialization from #2 to #3. (Again, AcpiTimerLib should contain its own setup.) We should also not move #3 to an earlier phase -- SCI_EN is premature unless we're about to boot real soon ("enable generation of SCI upon assertion of PWRBTN_STS, LID_STS, THRM_STS, or GPI_STS bits"). Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13722 6f19259b-4bc3-4df7-8a09-765794883524
2012-09-12 09:19:16 +02:00
#include <IndustryStandard/Pci22.h>
OvmfPkg/PlatformPei: rewrite MaxCpuCountInitialization() for CPU hotplug MaxCpuCountInitialization() currently handles the following options: (1) QEMU does not report the boot CPU count (FW_CFG_NB_CPUS is 0) In this case, PlatformPei makes MpInitLib enumerate APs up to the default PcdCpuMaxLogicalProcessorNumber value (64) minus 1, or until the default PcdCpuApInitTimeOutInMicroSeconds (50,000) elapses. (Whichever is reached first.) Time-limited AP enumeration had never been reliable on QEMU/KVM, which is why commit 45a70db3c3a5 strated handling case (2) below, in OVMF. (2) QEMU reports the boot CPU count (FW_CFG_NB_CPUS is nonzero) In this case, PlatformPei sets - PcdCpuMaxLogicalProcessorNumber to the reported boot CPU count (FW_CFG_NB_CPUS, which exports "PCMachineState.boot_cpus"), - and PcdCpuApInitTimeOutInMicroSeconds to practically "infinity" (MAX_UINT32, ~71 minutes). That causes MpInitLib to enumerate exactly the present (boot) APs. With CPU hotplug in mind, this method is not good enough. Because, using QEMU terminology, UefiCpuPkg expects PcdCpuMaxLogicalProcessorNumber to provide the "possible CPUs" count ("MachineState.smp.max_cpus"), which includes present and not present CPUs both (with not present CPUs being subject for hot-plugging). FW_CFG_NB_CPUS does not include not present CPUs. Rewrite MaxCpuCountInitialization() for handling the following cases: (1) The behavior of case (1) does not change. (No UefiCpuPkg PCDs are set to values different from the defaults.) (2) QEMU reports the boot CPU count ("PCMachineState.boot_cpus", via FW_CFG_NB_CPUS), but not the possible CPUs count ("MachineState.smp.max_cpus"). In this case, the behavior remains unchanged. The way MpInitLib is instructed to do the same differs however: we now set the new PcdCpuBootLogicalProcessorNumber to the boot CPU count (while continuing to set PcdCpuMaxLogicalProcessorNumber identically). PcdCpuApInitTimeOutInMicroSeconds becomes irrelevant. (3) QEMU reports both the boot CPU count ("PCMachineState.boot_cpus", via FW_CFG_NB_CPUS), and the possible CPUs count ("MachineState.smp.max_cpus"). We tell UefiCpuPkg about the possible CPUs count through PcdCpuMaxLogicalProcessorNumber. We also tell MpInitLib the boot CPU count for precise and quick AP enumeration, via PcdCpuBootLogicalProcessorNumber. PcdCpuApInitTimeOutInMicroSeconds is irrelevant again. This patch is a pre-requisite for enabling CPU hotplug with SMM_REQUIRE. As a side effect, the patch also enables S3 to work with CPU hotplug at once, *without* SMM_REQUIRE. (Without the patch, S3 resume fails, if a CPU is hot-plugged at OS runtime, prior to suspend: the FW_CFG_NB_CPUS increase seen during resume causes PcdCpuMaxLogicalProcessorNumber to increase as well, which is not permitted. With the patch, PcdCpuMaxLogicalProcessorNumber stays the same, namely "MachineState.smp.max_cpus". Therefore, the CPU structures allocated during normal boot can accommodate the CPUs at S3 resume that have been hotplugged prior to S3 suspend.) Cc: Anthony Perard <anthony.perard@citrix.com> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Igor Mammedov <imammedo@redhat.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Julien Grall <julien.grall@arm.com> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1515 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Message-Id: <20191022221554.14963-4-lersek@redhat.com> Acked-by: Anthony PERARD <anthony.perard@citrix.com> Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com> Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2019-10-08 09:15:38 +02:00
#include <IndustryStandard/Q35MchIch9.h>
#include <IndustryStandard/QemuCpuHotplug.h>
OvmfPkg/PlatformPei: Move global variables to PlatformInfoHob BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3863 The intention of PlatformInitLib is to extract the common function used in OvmfPkg/PlatformPei. This lib will be used not only in PEI phase but also in SEC phase. SEC phase cannot use global variables between different functions. So PlatformInfoHob is created to hold the informations shared between functions. For example, HostBridgeDevId corespond to mHostBridgeDevId in PlatformPei. In this patch we will first move below global variables to PlatformInfoHob. - mBootMode - mS3Supported - mPhysMemAddressWidth - mMaxCpuCount - mHostBridgeDevId - mQ35SmramAtDefaultSmbase - mQemuUc32Base - mS3AcpiReservedMemorySize - mS3AcpiReservedMemoryBase PlatformInfoHob also holds other information, for example, PciIoBase / PciIoSize. This is because in SEC phase, PcdSetxxx doesn't work. So we will restruct the functions which set PCDs into two, one for PlatformInfoLib, one for PlatformPei. So in this patch we first move global variables and PCDs to PlatformInfoHob. All the changes are in OvmfPkg/PlatformPei. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Brijesh Singh <brijesh.singh@amd.com> Cc: Erdem Aktas <erdemaktas@google.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Sebastien Boeuf <sebastien.boeuf@intel.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Min Xu <min.m.xu@intel.com>
2022-03-06 03:20:36 +01:00
#include <Library/MemEncryptSevLib.h>
#include <OvmfPlatforms.h>
#include "Platform.h"
EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = {
{
EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
&gEfiPeiMasterBootModePpiGuid,
NULL
}
};
VOID
MemMapInitialization (
IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
)
{
RETURN_STATUS PcdStatus;
PlatformMemMapInitialization (PlatformInfoHob);
if (PlatformInfoHob->HostBridgeDevId == 0xffff /* microvm */) {
return;
}
PcdStatus = PcdSet64S (PcdPciMmio32Base, PlatformInfoHob->PcdPciMmio32Base);
ASSERT_RETURN_ERROR (PcdStatus);
PcdStatus = PcdSet64S (PcdPciMmio32Size, PlatformInfoHob->PcdPciMmio32Size);
ASSERT_RETURN_ERROR (PcdStatus);
PcdStatus = PcdSet64S (PcdPciIoBase, PlatformInfoHob->PcdPciIoBase);
ASSERT_RETURN_ERROR (PcdStatus);
PcdStatus = PcdSet64S (PcdPciIoSize, PlatformInfoHob->PcdPciIoSize);
ASSERT_RETURN_ERROR (PcdStatus);
}
STATIC
VOID
NoexecDxeInitialization (
IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
)
{
RETURN_STATUS Status;
Status = PlatformNoexecDxeInitialization (PlatformInfoHob);
if (!RETURN_ERROR (Status)) {
Status = PcdSetBoolS (PcdSetNxForStack, PlatformInfoHob->PcdSetNxForStack);
ASSERT_RETURN_ERROR (Status);
}
}
static const UINT8 EmptyFdt[] = {
0xd0, 0x0d, 0xfe, 0xed, 0x00, 0x00, 0x00, 0x48,
0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x48,
0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x11,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09,
};
VOID
MicrovmInitialization (
VOID
)
{
FIRMWARE_CONFIG_ITEM FdtItem;
UINTN FdtSize;
UINTN FdtPages;
EFI_STATUS Status;
UINT64 *FdtHobData;
VOID *NewBase;
Status = QemuFwCfgFindFile ("etc/fdt", &FdtItem, &FdtSize);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "%a: no etc/fdt found in fw_cfg, using dummy\n", __func__));
FdtItem = 0;
FdtSize = sizeof (EmptyFdt);
}
FdtPages = EFI_SIZE_TO_PAGES (FdtSize);
NewBase = AllocatePages (FdtPages);
if (NewBase == NULL) {
DEBUG ((DEBUG_INFO, "%a: AllocatePages failed\n", __func__));
return;
}
if (FdtItem) {
QemuFwCfgSelectItem (FdtItem);
QemuFwCfgReadBytes (FdtSize, NewBase);
} else {
CopyMem (NewBase, EmptyFdt, FdtSize);
}
FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof (*FdtHobData));
if (FdtHobData == NULL) {
DEBUG ((DEBUG_INFO, "%a: BuildGuidHob failed\n", __func__));
return;
}
DEBUG ((
DEBUG_INFO,
"%a: fdt at 0x%x (size %d)\n",
__func__,
NewBase,
FdtSize
));
*FdtHobData = (UINTN)NewBase;
}
VOID
MiscInitializationForMicrovm (
IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
)
{
RETURN_STATUS PcdStatus;
ASSERT (PlatformInfoHob->HostBridgeDevId == 0xffff);
DEBUG ((DEBUG_INFO, "%a: microvm\n", __func__));
//
// Disable A20 Mask
//
IoOr8 (0x92, BIT1);
//
// Build the CPU HOB with guest RAM size dependent address width and 16-bits
// of IO space. (Side note: unlike other HOBs, the CPU HOB is needed during
// S3 resume as well, so we build it unconditionally.)
//
BuildCpuHob (PlatformInfoHob->PhysMemAddressWidth, 16);
MicrovmInitialization ();
PcdStatus = PcdSet16S (
PcdOvmfHostBridgePciDevId,
MICROVM_PSEUDO_DEVICE_ID
);
ASSERT_RETURN_ERROR (PcdStatus);
}
VOID
MiscInitialization (
IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
)
{
RETURN_STATUS PcdStatus;
PlatformMiscInitialization (PlatformInfoHob);
PcdStatus = PcdSet16S (PcdOvmfHostBridgePciDevId, PlatformInfoHob->HostBridgeDevId);
ASSERT_RETURN_ERROR (PcdStatus);
}
VOID
BootModeInitialization (
OvmfPkg/PlatformPei: Move global variables to PlatformInfoHob BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3863 The intention of PlatformInitLib is to extract the common function used in OvmfPkg/PlatformPei. This lib will be used not only in PEI phase but also in SEC phase. SEC phase cannot use global variables between different functions. So PlatformInfoHob is created to hold the informations shared between functions. For example, HostBridgeDevId corespond to mHostBridgeDevId in PlatformPei. In this patch we will first move below global variables to PlatformInfoHob. - mBootMode - mS3Supported - mPhysMemAddressWidth - mMaxCpuCount - mHostBridgeDevId - mQ35SmramAtDefaultSmbase - mQemuUc32Base - mS3AcpiReservedMemorySize - mS3AcpiReservedMemoryBase PlatformInfoHob also holds other information, for example, PciIoBase / PciIoSize. This is because in SEC phase, PcdSetxxx doesn't work. So we will restruct the functions which set PCDs into two, one for PlatformInfoLib, one for PlatformPei. So in this patch we first move global variables and PCDs to PlatformInfoHob. All the changes are in OvmfPkg/PlatformPei. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Brijesh Singh <brijesh.singh@amd.com> Cc: Erdem Aktas <erdemaktas@google.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Sebastien Boeuf <sebastien.boeuf@intel.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Min Xu <min.m.xu@intel.com>
2022-03-06 03:20:36 +01:00
IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
)
{
OvmfPkg: PlatformPei: detect S3 Resume in CMOS and set boot mode accordingly Data is transferred between S3 Suspend and S3 Resume as follows: S3 Suspend (DXE): (1) BdsLibBootViaBootOption() EFI_ACPI_S3_SAVE_PROTOCOL [AcpiS3SaveDxe] - saves ACPI S3 Context to LockBox ---------------------+ (including FACS address -- FACS ACPI table | contains OS waking vector) | | - prepares boot script: | EFI_S3_SAVE_STATE_PROTOCOL.Write() [S3SaveStateDxe] | S3BootScriptLib [PiDxeS3BootScriptLib] | - opcodes & arguments are saved in NVS. --+ | | | - issues a notification by installing | | EFI_DXE_SMM_READY_TO_LOCK_PROTOCOL | | | | (2) EFI_S3_SAVE_STATE_PROTOCOL [S3SaveStateDxe] | | S3BootScriptLib [PiDxeS3BootScriptLib] | | - closes script with special opcode <---------+ | - script is available in non-volatile memory | via PcdS3BootScriptTablePrivateDataPtr --+ | | | BootScriptExecutorDxe | | S3BootScriptLib [PiDxeS3BootScriptLib] | | - Knows about boot script location by <----+ | synchronizing with the other library | instance via | PcdS3BootScriptTablePrivateDataPtr. | - Copies relocated image of itself to | reserved memory. --------------------------------+ | - Saved image contains pointer to boot script. ---|--+ | | | | Runtime: | | | | | | (3) OS is booted, writes OS waking vector to FACS, | | | suspends machine | | | | | | S3 Resume (PEI): | | | | | | (4) PlatformPei sets S3 Boot Mode based on CMOS | | | | | | (5) DXE core is skipped and EFI_PEI_S3_RESUME2 is | | | called as last step of PEI | | | | | | (6) S3Resume2Pei retrieves from LockBox: | | | - ACPI S3 Context (path to FACS) <------------------|--|--+ | | | +------------------|--|--+ - Boot Script Executor Image <----------------------+ | | | | (7) BootScriptExecutorDxe | | S3BootScriptLib [PiDxeS3BootScriptLib] | | - executes boot script <-----------------------------+ | | (8) OS waking vector available from ACPI S3 Context / FACS <--+ is called Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> [jordan.l.justen@intel.com: move code into BootModeInitialization] Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jordan Justen <jordan.l.justen@intel.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15290 6f19259b-4bc3-4df7-8a09-765794883524
2014-03-04 09:01:32 +01:00
EFI_STATUS Status;
OvmfPkg: Create initial version of PlatformInitLib BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3863 There are 3 variants of PlatformPei in OvmfPkg: - OvmfPkg/PlatformPei - OvmfPkg/XenPlatformPei - OvmfPkg/Bhyve/PlatformPei/PlatformPei.inf These PlatformPeis can share many common codes, such as Cmos / Hob / Memory / Platform related functions. This commit (and its following several patches) are to create a PlatformInitLib which wraps the common code called in above PlatformPeis. In this initial version of PlatformInitLib, below Cmos related functions are introduced: - PlatformCmosRead8 - PlatformCmosWrite8 - PlatformDebugDumpCmos They correspond to the functions in OvmfPkg/PlatformPei: - CmosRead8 - CmosWrite8 - DebugDumpCmos Considering this PlatformInitLib will be used in SEC phase, global variables and dynamic PCDs are avoided. We use PlatformInfoHob to exchange information between functions. EFI_HOB_PLATFORM_INFO is the data struct which contains the platform information, such as HostBridgeDevId, BootMode, S3Supported, SmmSmramRequire, etc. After PlatformInitLib is created, OvmfPkg/PlatformPei is refactored with this library. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Brijesh Singh <brijesh.singh@amd.com> Cc: Erdem Aktas <erdemaktas@google.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Min Xu <min.m.xu@intel.com>
2022-02-12 07:06:46 +01:00
if (PlatformCmosRead8 (0xF) == 0xFE) {
OvmfPkg/PlatformPei: Move global variables to PlatformInfoHob BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3863 The intention of PlatformInitLib is to extract the common function used in OvmfPkg/PlatformPei. This lib will be used not only in PEI phase but also in SEC phase. SEC phase cannot use global variables between different functions. So PlatformInfoHob is created to hold the informations shared between functions. For example, HostBridgeDevId corespond to mHostBridgeDevId in PlatformPei. In this patch we will first move below global variables to PlatformInfoHob. - mBootMode - mS3Supported - mPhysMemAddressWidth - mMaxCpuCount - mHostBridgeDevId - mQ35SmramAtDefaultSmbase - mQemuUc32Base - mS3AcpiReservedMemorySize - mS3AcpiReservedMemoryBase PlatformInfoHob also holds other information, for example, PciIoBase / PciIoSize. This is because in SEC phase, PcdSetxxx doesn't work. So we will restruct the functions which set PCDs into two, one for PlatformInfoLib, one for PlatformPei. So in this patch we first move global variables and PCDs to PlatformInfoHob. All the changes are in OvmfPkg/PlatformPei. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Brijesh Singh <brijesh.singh@amd.com> Cc: Erdem Aktas <erdemaktas@google.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Sebastien Boeuf <sebastien.boeuf@intel.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Min Xu <min.m.xu@intel.com>
2022-03-06 03:20:36 +01:00
PlatformInfoHob->BootMode = BOOT_ON_S3_RESUME;
OvmfPkg: PlatformPei: detect S3 Resume in CMOS and set boot mode accordingly Data is transferred between S3 Suspend and S3 Resume as follows: S3 Suspend (DXE): (1) BdsLibBootViaBootOption() EFI_ACPI_S3_SAVE_PROTOCOL [AcpiS3SaveDxe] - saves ACPI S3 Context to LockBox ---------------------+ (including FACS address -- FACS ACPI table | contains OS waking vector) | | - prepares boot script: | EFI_S3_SAVE_STATE_PROTOCOL.Write() [S3SaveStateDxe] | S3BootScriptLib [PiDxeS3BootScriptLib] | - opcodes & arguments are saved in NVS. --+ | | | - issues a notification by installing | | EFI_DXE_SMM_READY_TO_LOCK_PROTOCOL | | | | (2) EFI_S3_SAVE_STATE_PROTOCOL [S3SaveStateDxe] | | S3BootScriptLib [PiDxeS3BootScriptLib] | | - closes script with special opcode <---------+ | - script is available in non-volatile memory | via PcdS3BootScriptTablePrivateDataPtr --+ | | | BootScriptExecutorDxe | | S3BootScriptLib [PiDxeS3BootScriptLib] | | - Knows about boot script location by <----+ | synchronizing with the other library | instance via | PcdS3BootScriptTablePrivateDataPtr. | - Copies relocated image of itself to | reserved memory. --------------------------------+ | - Saved image contains pointer to boot script. ---|--+ | | | | Runtime: | | | | | | (3) OS is booted, writes OS waking vector to FACS, | | | suspends machine | | | | | | S3 Resume (PEI): | | | | | | (4) PlatformPei sets S3 Boot Mode based on CMOS | | | | | | (5) DXE core is skipped and EFI_PEI_S3_RESUME2 is | | | called as last step of PEI | | | | | | (6) S3Resume2Pei retrieves from LockBox: | | | - ACPI S3 Context (path to FACS) <------------------|--|--+ | | | +------------------|--|--+ - Boot Script Executor Image <----------------------+ | | | | (7) BootScriptExecutorDxe | | S3BootScriptLib [PiDxeS3BootScriptLib] | | - executes boot script <-----------------------------+ | | (8) OS waking vector available from ACPI S3 Context / FACS <--+ is called Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> [jordan.l.justen@intel.com: move code into BootModeInitialization] Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jordan Justen <jordan.l.justen@intel.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15290 6f19259b-4bc3-4df7-8a09-765794883524
2014-03-04 09:01:32 +01:00
}
OvmfPkg: Create initial version of PlatformInitLib BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3863 There are 3 variants of PlatformPei in OvmfPkg: - OvmfPkg/PlatformPei - OvmfPkg/XenPlatformPei - OvmfPkg/Bhyve/PlatformPei/PlatformPei.inf These PlatformPeis can share many common codes, such as Cmos / Hob / Memory / Platform related functions. This commit (and its following several patches) are to create a PlatformInitLib which wraps the common code called in above PlatformPeis. In this initial version of PlatformInitLib, below Cmos related functions are introduced: - PlatformCmosRead8 - PlatformCmosWrite8 - PlatformDebugDumpCmos They correspond to the functions in OvmfPkg/PlatformPei: - CmosRead8 - CmosWrite8 - DebugDumpCmos Considering this PlatformInitLib will be used in SEC phase, global variables and dynamic PCDs are avoided. We use PlatformInfoHob to exchange information between functions. EFI_HOB_PLATFORM_INFO is the data struct which contains the platform information, such as HostBridgeDevId, BootMode, S3Supported, SmmSmramRequire, etc. After PlatformInitLib is created, OvmfPkg/PlatformPei is refactored with this library. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Brijesh Singh <brijesh.singh@amd.com> Cc: Erdem Aktas <erdemaktas@google.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Min Xu <min.m.xu@intel.com>
2022-02-12 07:06:46 +01:00
PlatformCmosWrite8 (0xF, 0x00);
OvmfPkg/PlatformPei: Move global variables to PlatformInfoHob BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3863 The intention of PlatformInitLib is to extract the common function used in OvmfPkg/PlatformPei. This lib will be used not only in PEI phase but also in SEC phase. SEC phase cannot use global variables between different functions. So PlatformInfoHob is created to hold the informations shared between functions. For example, HostBridgeDevId corespond to mHostBridgeDevId in PlatformPei. In this patch we will first move below global variables to PlatformInfoHob. - mBootMode - mS3Supported - mPhysMemAddressWidth - mMaxCpuCount - mHostBridgeDevId - mQ35SmramAtDefaultSmbase - mQemuUc32Base - mS3AcpiReservedMemorySize - mS3AcpiReservedMemoryBase PlatformInfoHob also holds other information, for example, PciIoBase / PciIoSize. This is because in SEC phase, PcdSetxxx doesn't work. So we will restruct the functions which set PCDs into two, one for PlatformInfoLib, one for PlatformPei. So in this patch we first move global variables and PCDs to PlatformInfoHob. All the changes are in OvmfPkg/PlatformPei. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Brijesh Singh <brijesh.singh@amd.com> Cc: Erdem Aktas <erdemaktas@google.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Sebastien Boeuf <sebastien.boeuf@intel.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Min Xu <min.m.xu@intel.com>
2022-03-06 03:20:36 +01:00
Status = PeiServicesSetBootMode (PlatformInfoHob->BootMode);
ASSERT_EFI_ERROR (Status);
Status = PeiServicesInstallPpi (mPpiBootMode);
ASSERT_EFI_ERROR (Status);
}
VOID
ReserveEmuVariableNvStore (
)
{
EFI_PHYSICAL_ADDRESS VariableStore;
RETURN_STATUS PcdStatus;
VariableStore = (EFI_PHYSICAL_ADDRESS)(UINTN)PlatformReserveEmuVariableNvStore ();
PcdStatus = PcdSet64S (PcdEmuVariableNvStoreReserved, VariableStore);
if (FeaturePcdGet (PcdSecureBootSupported)) {
// restore emulated VarStore from pristine ROM copy
PlatformInitEmuVariableNvStore ((VOID *)(UINTN)VariableStore);
}
ASSERT_RETURN_ERROR (PcdStatus);
}
STATIC
VOID
Q35BoardVerification (
IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob
)
{
if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
return;
}
DEBUG ((
DEBUG_ERROR,
"%a: no TSEG (SMRAM) on host bridge DID=0x%04x; "
"only DID=0x%04x (Q35) is supported\n",
__func__,
PlatformInfoHob->HostBridgeDevId,
INTEL_Q35_MCH_DEVICE_ID
));
ASSERT (FALSE);
CpuDeadLoop ();
}
/**
Fetch the boot CPU count and the possible CPU count from QEMU, and expose
them to UefiCpuPkg modules. Set the MaxCpuCount field in PlatformInfoHob.
**/
VOID
MaxCpuCountInitialization (
IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
)
{
RETURN_STATUS PcdStatus;
PlatformMaxCpuCountInitialization (PlatformInfoHob);
PcdStatus = PcdSet32S (PcdCpuBootLogicalProcessorNumber, PlatformInfoHob->PcdCpuBootLogicalProcessorNumber);
ASSERT_RETURN_ERROR (PcdStatus);
PcdStatus = PcdSet32S (PcdCpuMaxLogicalProcessorNumber, PlatformInfoHob->PcdCpuMaxLogicalProcessorNumber);
ASSERT_RETURN_ERROR (PcdStatus);
}
/**
* @brief Builds PlatformInfo Hob
*/
EFI_HOB_PLATFORM_INFO *
BuildPlatformInfoHob (
VOID
)
{
EFI_HOB_PLATFORM_INFO PlatformInfoHob;
EFI_HOB_GUID_TYPE *GuidHob;
ZeroMem (&PlatformInfoHob, sizeof PlatformInfoHob);
BuildGuidDataHob (&gUefiOvmfPkgPlatformInfoGuid, &PlatformInfoHob, sizeof (EFI_HOB_PLATFORM_INFO));
GuidHob = GetFirstGuidHob (&gUefiOvmfPkgPlatformInfoGuid);
return (EFI_HOB_PLATFORM_INFO *)GET_GUID_HOB_DATA (GuidHob);
}
/**
Perform Platform PEI initialization.
@param FileHandle Handle of the file being invoked.
@param PeiServices Describes the list of possible PEI Services.
@return EFI_SUCCESS The PEIM initialized successfully.
**/
EFI_STATUS
EFIAPI
InitializePlatform (
IN EFI_PEI_FILE_HANDLE FileHandle,
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
EFI_HOB_PLATFORM_INFO *PlatformInfoHob;
EFI_STATUS Status;
DEBUG ((DEBUG_INFO, "Platform PEIM Loaded\n"));
PlatformInfoHob = BuildPlatformInfoHob ();
PlatformInfoHob->SmmSmramRequire = FeaturePcdGet (PcdSmmSmramRequire);
PlatformInfoHob->SevEsIsEnabled = MemEncryptSevEsIsEnabled ();
PlatformInfoHob->PcdPciMmio64Size = PcdGet64 (PcdPciMmio64Size);
PlatformInfoHob->DefaultMaxCpuNumber = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
OvmfPkg/PlatformPei: Move global variables to PlatformInfoHob BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3863 The intention of PlatformInitLib is to extract the common function used in OvmfPkg/PlatformPei. This lib will be used not only in PEI phase but also in SEC phase. SEC phase cannot use global variables between different functions. So PlatformInfoHob is created to hold the informations shared between functions. For example, HostBridgeDevId corespond to mHostBridgeDevId in PlatformPei. In this patch we will first move below global variables to PlatformInfoHob. - mBootMode - mS3Supported - mPhysMemAddressWidth - mMaxCpuCount - mHostBridgeDevId - mQ35SmramAtDefaultSmbase - mQemuUc32Base - mS3AcpiReservedMemorySize - mS3AcpiReservedMemoryBase PlatformInfoHob also holds other information, for example, PciIoBase / PciIoSize. This is because in SEC phase, PcdSetxxx doesn't work. So we will restruct the functions which set PCDs into two, one for PlatformInfoLib, one for PlatformPei. So in this patch we first move global variables and PCDs to PlatformInfoHob. All the changes are in OvmfPkg/PlatformPei. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Brijesh Singh <brijesh.singh@amd.com> Cc: Erdem Aktas <erdemaktas@google.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Sebastien Boeuf <sebastien.boeuf@intel.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Min Xu <min.m.xu@intel.com>
2022-03-06 03:20:36 +01:00
OvmfPkg: Create initial version of PlatformInitLib BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3863 There are 3 variants of PlatformPei in OvmfPkg: - OvmfPkg/PlatformPei - OvmfPkg/XenPlatformPei - OvmfPkg/Bhyve/PlatformPei/PlatformPei.inf These PlatformPeis can share many common codes, such as Cmos / Hob / Memory / Platform related functions. This commit (and its following several patches) are to create a PlatformInitLib which wraps the common code called in above PlatformPeis. In this initial version of PlatformInitLib, below Cmos related functions are introduced: - PlatformCmosRead8 - PlatformCmosWrite8 - PlatformDebugDumpCmos They correspond to the functions in OvmfPkg/PlatformPei: - CmosRead8 - CmosWrite8 - DebugDumpCmos Considering this PlatformInitLib will be used in SEC phase, global variables and dynamic PCDs are avoided. We use PlatformInfoHob to exchange information between functions. EFI_HOB_PLATFORM_INFO is the data struct which contains the platform information, such as HostBridgeDevId, BootMode, S3Supported, SmmSmramRequire, etc. After PlatformInitLib is created, OvmfPkg/PlatformPei is refactored with this library. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Brijesh Singh <brijesh.singh@amd.com> Cc: Erdem Aktas <erdemaktas@google.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Min Xu <min.m.xu@intel.com>
2022-02-12 07:06:46 +01:00
PlatformDebugDumpCmos ();
if (QemuFwCfgS3Enabled ()) {
DEBUG ((DEBUG_INFO, "S3 support was detected on QEMU\n"));
PlatformInfoHob->S3Supported = TRUE;
OvmfPkg/PlatformPei: Move global variables to PlatformInfoHob BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3863 The intention of PlatformInitLib is to extract the common function used in OvmfPkg/PlatformPei. This lib will be used not only in PEI phase but also in SEC phase. SEC phase cannot use global variables between different functions. So PlatformInfoHob is created to hold the informations shared between functions. For example, HostBridgeDevId corespond to mHostBridgeDevId in PlatformPei. In this patch we will first move below global variables to PlatformInfoHob. - mBootMode - mS3Supported - mPhysMemAddressWidth - mMaxCpuCount - mHostBridgeDevId - mQ35SmramAtDefaultSmbase - mQemuUc32Base - mS3AcpiReservedMemorySize - mS3AcpiReservedMemoryBase PlatformInfoHob also holds other information, for example, PciIoBase / PciIoSize. This is because in SEC phase, PcdSetxxx doesn't work. So we will restruct the functions which set PCDs into two, one for PlatformInfoLib, one for PlatformPei. So in this patch we first move global variables and PCDs to PlatformInfoHob. All the changes are in OvmfPkg/PlatformPei. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Brijesh Singh <brijesh.singh@amd.com> Cc: Erdem Aktas <erdemaktas@google.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Sebastien Boeuf <sebastien.boeuf@intel.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Min Xu <min.m.xu@intel.com>
2022-03-06 03:20:36 +01:00
Status = PcdSetBoolS (PcdAcpiS3Enable, TRUE);
ASSERT_EFI_ERROR (Status);
}
BootModeInitialization (PlatformInfoHob);
//
// Query Host Bridge DID
//
PlatformInfoHob->HostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);
AddressWidthInitialization (PlatformInfoHob);
MaxCpuCountInitialization (PlatformInfoHob);
OvmfPkg/PlatformPei: rewrite MaxCpuCountInitialization() for CPU hotplug MaxCpuCountInitialization() currently handles the following options: (1) QEMU does not report the boot CPU count (FW_CFG_NB_CPUS is 0) In this case, PlatformPei makes MpInitLib enumerate APs up to the default PcdCpuMaxLogicalProcessorNumber value (64) minus 1, or until the default PcdCpuApInitTimeOutInMicroSeconds (50,000) elapses. (Whichever is reached first.) Time-limited AP enumeration had never been reliable on QEMU/KVM, which is why commit 45a70db3c3a5 strated handling case (2) below, in OVMF. (2) QEMU reports the boot CPU count (FW_CFG_NB_CPUS is nonzero) In this case, PlatformPei sets - PcdCpuMaxLogicalProcessorNumber to the reported boot CPU count (FW_CFG_NB_CPUS, which exports "PCMachineState.boot_cpus"), - and PcdCpuApInitTimeOutInMicroSeconds to practically "infinity" (MAX_UINT32, ~71 minutes). That causes MpInitLib to enumerate exactly the present (boot) APs. With CPU hotplug in mind, this method is not good enough. Because, using QEMU terminology, UefiCpuPkg expects PcdCpuMaxLogicalProcessorNumber to provide the "possible CPUs" count ("MachineState.smp.max_cpus"), which includes present and not present CPUs both (with not present CPUs being subject for hot-plugging). FW_CFG_NB_CPUS does not include not present CPUs. Rewrite MaxCpuCountInitialization() for handling the following cases: (1) The behavior of case (1) does not change. (No UefiCpuPkg PCDs are set to values different from the defaults.) (2) QEMU reports the boot CPU count ("PCMachineState.boot_cpus", via FW_CFG_NB_CPUS), but not the possible CPUs count ("MachineState.smp.max_cpus"). In this case, the behavior remains unchanged. The way MpInitLib is instructed to do the same differs however: we now set the new PcdCpuBootLogicalProcessorNumber to the boot CPU count (while continuing to set PcdCpuMaxLogicalProcessorNumber identically). PcdCpuApInitTimeOutInMicroSeconds becomes irrelevant. (3) QEMU reports both the boot CPU count ("PCMachineState.boot_cpus", via FW_CFG_NB_CPUS), and the possible CPUs count ("MachineState.smp.max_cpus"). We tell UefiCpuPkg about the possible CPUs count through PcdCpuMaxLogicalProcessorNumber. We also tell MpInitLib the boot CPU count for precise and quick AP enumeration, via PcdCpuBootLogicalProcessorNumber. PcdCpuApInitTimeOutInMicroSeconds is irrelevant again. This patch is a pre-requisite for enabling CPU hotplug with SMM_REQUIRE. As a side effect, the patch also enables S3 to work with CPU hotplug at once, *without* SMM_REQUIRE. (Without the patch, S3 resume fails, if a CPU is hot-plugged at OS runtime, prior to suspend: the FW_CFG_NB_CPUS increase seen during resume causes PcdCpuMaxLogicalProcessorNumber to increase as well, which is not permitted. With the patch, PcdCpuMaxLogicalProcessorNumber stays the same, namely "MachineState.smp.max_cpus". Therefore, the CPU structures allocated during normal boot can accommodate the CPUs at S3 resume that have been hotplugged prior to S3 suspend.) Cc: Anthony Perard <anthony.perard@citrix.com> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Igor Mammedov <imammedo@redhat.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Julien Grall <julien.grall@arm.com> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1515 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Message-Id: <20191022221554.14963-4-lersek@redhat.com> Acked-by: Anthony PERARD <anthony.perard@citrix.com> Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com> Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2019-10-08 09:15:38 +02:00
if (PlatformInfoHob->SmmSmramRequire) {
Q35BoardVerification (PlatformInfoHob);
Q35TsegMbytesInitialization (PlatformInfoHob);
Q35SmramAtDefaultSmbaseInitialization (PlatformInfoHob);
}
PublishPeiMemory (PlatformInfoHob);
PlatformQemuUc32BaseInitialization (PlatformInfoHob);
OvmfPkg/PlatformPei: set 32-bit UC area at PciBase / PciExBarBase (pc/q35) (This is a replacement for commit 39b9a5ffe661 ("OvmfPkg/PlatformPei: fix MTRR for low-RAM sizes that have many bits clear", 2019-05-16).) Reintroduce the same logic as seen in commit 39b9a5ffe661 for the pc (i440fx) board type. For q35, the same approach doesn't work any longer, given that (a) we'd like to keep the PCIEXBAR in the platform DSC a fixed-at-build PCD, and (b) QEMU expects the PCIEXBAR to reside at a lower address than the 32-bit PCI MMIO aperture. Therefore, introduce a helper function for determining the 32-bit "uncacheable" (MMIO) area base address: - On q35, this function behaves statically. Furthermore, the MTRR setup exploits that the range [0xB000_0000, 0xFFFF_FFFF] can be marked UC with just two variable MTRRs (one at 0xB000_0000 (size 256MB), another at 0xC000_0000 (size 1GB)). - On pc (i440fx), the function behaves dynamically, implementing the same logic as commit 39b9a5ffe661 did. The PciBase value is adjusted to the value calculated, similarly to commit 39b9a5ffe661. A further simplification is that we show that the UC32 area size truncation to a whole power of two automatically guarantees a >=2GB base address. Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1859 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com> Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2019-05-29 14:49:55 +02:00
InitializeRamRegions (PlatformInfoHob);
if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
if (!PlatformInfoHob->SmmSmramRequire) {
ReserveEmuVariableNvStore ();
}
PeiFvInitialization (PlatformInfoHob);
MemTypeInfoInitialization (PlatformInfoHob);
MemMapInitialization (PlatformInfoHob);
NoexecDxeInitialization (PlatformInfoHob);
}
InstallClearCacheCallback ();
AmdSevInitialize (PlatformInfoHob);
if (PlatformInfoHob->HostBridgeDevId == 0xffff) {
MiscInitializationForMicrovm (PlatformInfoHob);
} else {
MiscInitialization (PlatformInfoHob);
}
IntelTdxInitialize ();
InstallFeatureControlCallback (PlatformInfoHob);
return EFI_SUCCESS;
}