4 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
12 // The package level header files this module uses
17 // The Library classes this module consumes
19 #include <Library/BaseMemoryLib.h>
20 #include <Library/BaseLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/HobLib.h>
23 #include <Library/IoLib.h>
24 #include <Library/MemoryAllocationLib.h>
25 #include <Library/PcdLib.h>
26 #include <Library/PciLib.h>
27 #include <Library/PeimEntryPoint.h>
28 #include <Library/PeiServicesLib.h>
29 #include <Library/QemuFwCfgLib.h>
30 #include <Library/QemuFwCfgS3Lib.h>
31 #include <Library/QemuFwCfgSimpleParserLib.h>
32 #include <Library/ResourcePublicationLib.h>
33 #include <Ppi/MasterBootMode.h>
34 #include <IndustryStandard/I440FxPiix4.h>
35 #include <IndustryStandard/Microvm.h>
36 #include <IndustryStandard/Pci22.h>
37 #include <IndustryStandard/Q35MchIch9.h>
38 #include <IndustryStandard/QemuCpuHotplug.h>
39 #include <Library/MemEncryptSevLib.h>
40 #include <OvmfPlatforms.h>
44 EFI_HOB_PLATFORM_INFO mPlatformInfoHob
= { 0 };
46 EFI_PEI_PPI_DESCRIPTOR mPpiBootMode
[] = {
48 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
49 &gEfiPeiMasterBootModePpiGuid
,
55 MemMapInitialization (
56 IN OUT EFI_HOB_PLATFORM_INFO
*PlatformInfoHob
59 RETURN_STATUS PcdStatus
;
61 PlatformMemMapInitialization (PlatformInfoHob
);
63 if (PlatformInfoHob
->HostBridgeDevId
== 0xffff /* microvm */) {
67 PcdStatus
= PcdSet64S (PcdPciMmio32Base
, PlatformInfoHob
->PcdPciMmio32Base
);
68 ASSERT_RETURN_ERROR (PcdStatus
);
69 PcdStatus
= PcdSet64S (PcdPciMmio32Size
, PlatformInfoHob
->PcdPciMmio32Size
);
70 ASSERT_RETURN_ERROR (PcdStatus
);
72 PcdStatus
= PcdSet64S (PcdPciIoBase
, PlatformInfoHob
->PcdPciIoBase
);
73 ASSERT_RETURN_ERROR (PcdStatus
);
74 PcdStatus
= PcdSet64S (PcdPciIoSize
, PlatformInfoHob
->PcdPciIoSize
);
75 ASSERT_RETURN_ERROR (PcdStatus
);
79 NoexecDxeInitialization (
85 Status
= PlatformNoexecDxeInitialization (&mPlatformInfoHob
);
86 if (!RETURN_ERROR (Status
)) {
87 Status
= PcdSetBoolS (PcdSetNxForStack
, mPlatformInfoHob
.PcdSetNxForStack
);
88 ASSERT_RETURN_ERROR (Status
);
92 static const UINT8 EmptyFdt
[] = {
93 0xd0, 0x0d, 0xfe, 0xed, 0x00, 0x00, 0x00, 0x48,
94 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x48,
95 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x11,
96 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09,
105 MicrovmInitialization (
109 FIRMWARE_CONFIG_ITEM FdtItem
;
116 Status
= QemuFwCfgFindFile ("etc/fdt", &FdtItem
, &FdtSize
);
117 if (EFI_ERROR (Status
)) {
118 DEBUG ((DEBUG_INFO
, "%a: no etc/fdt found in fw_cfg, using dummy\n", __FUNCTION__
));
120 FdtSize
= sizeof (EmptyFdt
);
123 FdtPages
= EFI_SIZE_TO_PAGES (FdtSize
);
124 NewBase
= AllocatePages (FdtPages
);
125 if (NewBase
== NULL
) {
126 DEBUG ((DEBUG_INFO
, "%a: AllocatePages failed\n", __FUNCTION__
));
131 QemuFwCfgSelectItem (FdtItem
);
132 QemuFwCfgReadBytes (FdtSize
, NewBase
);
134 CopyMem (NewBase
, EmptyFdt
, FdtSize
);
137 FdtHobData
= BuildGuidHob (&gFdtHobGuid
, sizeof (*FdtHobData
));
138 if (FdtHobData
== NULL
) {
139 DEBUG ((DEBUG_INFO
, "%a: BuildGuidHob failed\n", __FUNCTION__
));
145 "%a: fdt at 0x%x (size %d)\n",
150 *FdtHobData
= (UINTN
)NewBase
;
154 MiscInitializationForMicrovm (
155 IN EFI_HOB_PLATFORM_INFO
*PlatformInfoHob
158 RETURN_STATUS PcdStatus
;
160 ASSERT (PlatformInfoHob
->HostBridgeDevId
== 0xffff);
162 DEBUG ((DEBUG_INFO
, "%a: microvm\n", __FUNCTION__
));
169 // Build the CPU HOB with guest RAM size dependent address width and 16-bits
170 // of IO space. (Side note: unlike other HOBs, the CPU HOB is needed during
171 // S3 resume as well, so we build it unconditionally.)
173 BuildCpuHob (PlatformInfoHob
->PhysMemAddressWidth
, 16);
175 MicrovmInitialization ();
176 PcdStatus
= PcdSet16S (
177 PcdOvmfHostBridgePciDevId
,
178 MICROVM_PSEUDO_DEVICE_ID
180 ASSERT_RETURN_ERROR (PcdStatus
);
185 IN EFI_HOB_PLATFORM_INFO
*PlatformInfoHob
188 RETURN_STATUS PcdStatus
;
190 PlatformMiscInitialization (PlatformInfoHob
);
192 PcdStatus
= PcdSet16S (PcdOvmfHostBridgePciDevId
, PlatformInfoHob
->HostBridgeDevId
);
193 ASSERT_RETURN_ERROR (PcdStatus
);
197 BootModeInitialization (
198 IN OUT EFI_HOB_PLATFORM_INFO
*PlatformInfoHob
203 if (PlatformCmosRead8 (0xF) == 0xFE) {
204 PlatformInfoHob
->BootMode
= BOOT_ON_S3_RESUME
;
207 PlatformCmosWrite8 (0xF, 0x00);
209 Status
= PeiServicesSetBootMode (PlatformInfoHob
->BootMode
);
210 ASSERT_EFI_ERROR (Status
);
212 Status
= PeiServicesInstallPpi (mPpiBootMode
);
213 ASSERT_EFI_ERROR (Status
);
217 ReserveEmuVariableNvStore (
220 EFI_PHYSICAL_ADDRESS VariableStore
;
221 RETURN_STATUS PcdStatus
;
223 VariableStore
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)PlatformReserveEmuVariableNvStore ();
224 PcdStatus
= PcdSet64S (PcdEmuVariableNvStoreReserved
, VariableStore
);
226 #ifdef SECURE_BOOT_FEATURE_ENABLED
227 PlatformInitEmuVariableNvStore ((VOID
*)(UINTN
)VariableStore
);
230 ASSERT_RETURN_ERROR (PcdStatus
);
238 #if defined (MDE_CPU_X64)
239 if (mPlatformInfoHob
.SmmSmramRequire
&& mPlatformInfoHob
.S3Supported
) {
242 "%a: S3Resume2Pei doesn't support X64 PEI + SMM yet.\n",
247 "%a: Please disable S3 on the QEMU command line (see the README),\n",
252 "%a: or build OVMF with \"OvmfPkgIa32X64.dsc\".\n",
263 Q35BoardVerification (
267 if (mPlatformInfoHob
.HostBridgeDevId
== INTEL_Q35_MCH_DEVICE_ID
) {
273 "%a: no TSEG (SMRAM) on host bridge DID=0x%04x; "
274 "only DID=0x%04x (Q35) is supported\n",
276 mPlatformInfoHob
.HostBridgeDevId
,
277 INTEL_Q35_MCH_DEVICE_ID
284 Fetch the boot CPU count and the possible CPU count from QEMU, and expose
285 them to UefiCpuPkg modules. Set the MaxCpuCount field in PlatformInfoHob.
288 MaxCpuCountInitialization (
289 IN OUT EFI_HOB_PLATFORM_INFO
*PlatformInfoHob
292 RETURN_STATUS PcdStatus
;
294 PlatformMaxCpuCountInitialization (PlatformInfoHob
);
296 PcdStatus
= PcdSet32S (PcdCpuBootLogicalProcessorNumber
, PlatformInfoHob
->PcdCpuBootLogicalProcessorNumber
);
297 ASSERT_RETURN_ERROR (PcdStatus
);
298 PcdStatus
= PcdSet32S (PcdCpuMaxLogicalProcessorNumber
, PlatformInfoHob
->PcdCpuMaxLogicalProcessorNumber
);
299 ASSERT_RETURN_ERROR (PcdStatus
);
303 * @brief Builds PlatformInfo Hob
306 BuildPlatformInfoHob (
310 BuildGuidDataHob (&gUefiOvmfPkgPlatformInfoGuid
, &mPlatformInfoHob
, sizeof (EFI_HOB_PLATFORM_INFO
));
314 Perform Platform PEI initialization.
316 @param FileHandle Handle of the file being invoked.
317 @param PeiServices Describes the list of possible PEI Services.
319 @return EFI_SUCCESS The PEIM initialized successfully.
325 IN EFI_PEI_FILE_HANDLE FileHandle
,
326 IN CONST EFI_PEI_SERVICES
**PeiServices
331 DEBUG ((DEBUG_INFO
, "Platform PEIM Loaded\n"));
333 mPlatformInfoHob
.SmmSmramRequire
= FeaturePcdGet (PcdSmmSmramRequire
);
334 mPlatformInfoHob
.SevEsIsEnabled
= MemEncryptSevEsIsEnabled ();
335 mPlatformInfoHob
.PcdPciMmio64Size
= PcdGet64 (PcdPciMmio64Size
);
336 mPlatformInfoHob
.DefaultMaxCpuNumber
= PcdGet32 (PcdCpuMaxLogicalProcessorNumber
);
338 PlatformDebugDumpCmos ();
340 if (QemuFwCfgS3Enabled ()) {
341 DEBUG ((DEBUG_INFO
, "S3 support was detected on QEMU\n"));
342 mPlatformInfoHob
.S3Supported
= TRUE
;
343 Status
= PcdSetBoolS (PcdAcpiS3Enable
, TRUE
);
344 ASSERT_EFI_ERROR (Status
);
348 BootModeInitialization (&mPlatformInfoHob
);
351 // Query Host Bridge DID
353 mPlatformInfoHob
.HostBridgeDevId
= PciRead16 (OVMF_HOSTBRIDGE_DID
);
354 AddressWidthInitialization (&mPlatformInfoHob
);
356 MaxCpuCountInitialization (&mPlatformInfoHob
);
358 if (mPlatformInfoHob
.SmmSmramRequire
) {
359 Q35BoardVerification ();
360 Q35TsegMbytesInitialization ();
361 Q35SmramAtDefaultSmbaseInitialization ();
366 PlatformQemuUc32BaseInitialization (&mPlatformInfoHob
);
368 InitializeRamRegions (&mPlatformInfoHob
);
370 if (mPlatformInfoHob
.BootMode
!= BOOT_ON_S3_RESUME
) {
371 if (!mPlatformInfoHob
.SmmSmramRequire
) {
372 ReserveEmuVariableNvStore ();
375 PeiFvInitialization ();
376 MemTypeInfoInitialization ();
377 MemMapInitialization (&mPlatformInfoHob
);
378 NoexecDxeInitialization ();
381 InstallClearCacheCallback ();
382 AmdSevInitialize (&mPlatformInfoHob
);
383 if (mPlatformInfoHob
.HostBridgeDevId
== 0xffff) {
384 MiscInitializationForMicrovm (&mPlatformInfoHob
);
386 MiscInitialization (&mPlatformInfoHob
);
389 IntelTdxInitialize ();
390 InstallFeatureControlCallback ();
391 BuildPlatformInfoHob ();