]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Bhyve/PlatformPei/Platform.c
NetworkPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / Bhyve / PlatformPei / Platform.c
CommitLineData
656419f9
RC
1/**@file\r
2 Platform PEI driver\r
3\r
4 Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
5 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
6 Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>\r
7\r
8 SPDX-License-Identifier: BSD-2-Clause-Patent\r
9\r
10**/\r
11\r
12//\r
13// The package level header files this module uses\r
14//\r
15#include <PiPei.h>\r
16\r
17//\r
18// The Library classes this module consumes\r
19//\r
20#include <Library/BaseLib.h>\r
21#include <Library/DebugLib.h>\r
22#include <Library/HobLib.h>\r
23#include <Library/IoLib.h>\r
9fb629ed 24#include <Library/LocalApicLib.h>\r
656419f9
RC
25#include <Library/MemoryAllocationLib.h>\r
26#include <Library/PcdLib.h>\r
27#include <Library/PciLib.h>\r
28#include <Library/PeimEntryPoint.h>\r
29#include <Library/PeiServicesLib.h>\r
30#include <Library/ResourcePublicationLib.h>\r
656419f9
RC
31#include <Guid/MemoryTypeInformation.h>\r
32#include <Ppi/MasterBootMode.h>\r
33#include <IndustryStandard/Pci22.h>\r
34#include <OvmfPlatforms.h>\r
35\r
36#include "Platform.h"\r
37#include "Cmos.h"\r
38\r
39EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {\r
40 { EfiACPIMemoryNVS, 0x004 },\r
41 { EfiACPIReclaimMemory, 0x008 },\r
42 { EfiReservedMemoryType, 0x004 },\r
43 { EfiRuntimeServicesData, 0x024 },\r
44 { EfiRuntimeServicesCode, 0x030 },\r
45 { EfiBootServicesCode, 0x180 },\r
46 { EfiBootServicesData, 0xF00 },\r
47 { EfiMaxMemoryType, 0x000 }\r
48};\r
49\r
50\r
51EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = {\r
52 {\r
53 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
54 &gEfiPeiMasterBootModePpiGuid,\r
55 NULL\r
56 }\r
57};\r
58\r
59\r
60UINT16 mHostBridgeDevId;\r
61\r
62EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION;\r
63\r
64BOOLEAN mS3Supported = FALSE;\r
65\r
66UINT32 mMaxCpuCount;\r
67\r
68VOID\r
69AddIoMemoryBaseSizeHob (\r
70 EFI_PHYSICAL_ADDRESS MemoryBase,\r
71 UINT64 MemorySize\r
72 )\r
73{\r
74 BuildResourceDescriptorHob (\r
75 EFI_RESOURCE_MEMORY_MAPPED_IO,\r
76 EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
77 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
78 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
79 EFI_RESOURCE_ATTRIBUTE_TESTED,\r
80 MemoryBase,\r
81 MemorySize\r
82 );\r
83}\r
84\r
85VOID\r
86AddReservedMemoryBaseSizeHob (\r
87 EFI_PHYSICAL_ADDRESS MemoryBase,\r
88 UINT64 MemorySize,\r
89 BOOLEAN Cacheable\r
90 )\r
91{\r
92 BuildResourceDescriptorHob (\r
93 EFI_RESOURCE_MEMORY_RESERVED,\r
94 EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
95 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
96 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
97 (Cacheable ?\r
98 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
99 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
100 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE :\r
101 0\r
102 ) |\r
103 EFI_RESOURCE_ATTRIBUTE_TESTED,\r
104 MemoryBase,\r
105 MemorySize\r
106 );\r
107}\r
108\r
109VOID\r
110AddIoMemoryRangeHob (\r
111 EFI_PHYSICAL_ADDRESS MemoryBase,\r
112 EFI_PHYSICAL_ADDRESS MemoryLimit\r
113 )\r
114{\r
115 AddIoMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));\r
116}\r
117\r
118\r
119VOID\r
120AddMemoryBaseSizeHob (\r
121 EFI_PHYSICAL_ADDRESS MemoryBase,\r
122 UINT64 MemorySize\r
123 )\r
124{\r
125 BuildResourceDescriptorHob (\r
126 EFI_RESOURCE_SYSTEM_MEMORY,\r
127 EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
128 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
129 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
130 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
131 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
132 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |\r
133 EFI_RESOURCE_ATTRIBUTE_TESTED,\r
134 MemoryBase,\r
135 MemorySize\r
136 );\r
137}\r
138\r
139\r
140VOID\r
141AddMemoryRangeHob (\r
142 EFI_PHYSICAL_ADDRESS MemoryBase,\r
143 EFI_PHYSICAL_ADDRESS MemoryLimit\r
144 )\r
145{\r
146 AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));\r
147}\r
148\r
149\r
150VOID\r
151MemMapInitialization (\r
152 VOID\r
153 )\r
154{\r
155 UINT64 PciIoBase;\r
156 UINT64 PciIoSize;\r
157 RETURN_STATUS PcdStatus;\r
158\r
159 PciIoBase = 0xC000;\r
160 PciIoSize = 0x4000;\r
161\r
162 //\r
163 // Create Memory Type Information HOB\r
164 //\r
165 BuildGuidDataHob (\r
166 &gEfiMemoryTypeInformationGuid,\r
167 mDefaultMemoryTypeInformation,\r
168 sizeof(mDefaultMemoryTypeInformation)\r
169 );\r
170\r
171 //\r
172 // Video memory + Legacy BIOS region\r
173 //\r
174 AddIoMemoryRangeHob (0x0A0000, BASE_1MB);\r
175\r
176 if (TRUE) {\r
177 UINT32 TopOfLowRam;\r
178 UINT64 PciExBarBase;\r
179 UINT32 PciBase;\r
180 UINT32 PciSize;\r
181\r
182 TopOfLowRam = GetSystemMemorySizeBelow4gb ();\r
183 PciExBarBase = 0;\r
184 if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {\r
185 //\r
186 // The MMCONFIG area is expected to fall between the top of low RAM and\r
187 // the base of the 32-bit PCI host aperture.\r
188 //\r
189 PciExBarBase = FixedPcdGet64 (PcdPciExpressBaseAddress);\r
190 ASSERT (TopOfLowRam <= PciExBarBase);\r
191 ASSERT (PciExBarBase <= MAX_UINT32 - SIZE_256MB);\r
192 PciBase = (UINT32)(PciExBarBase + SIZE_256MB);\r
193 } else {\r
4c495e5e 194 PciBase = (UINT32)PcdGet64 (PcdPciMmio32Base);\r
44ced037
CK
195 if (PciBase == 0)\r
196 PciBase = (TopOfLowRam < BASE_2GB) ? BASE_2GB : TopOfLowRam;\r
656419f9
RC
197 }\r
198\r
199 //\r
200 // address purpose size\r
201 // ------------ -------- -------------------------\r
202 // max(top, 2g) PCI MMIO 0xFC000000 - max(top, 2g)\r
203 // 0xFC000000 gap 44 MB\r
204 // 0xFEC00000 IO-APIC 4 KB\r
205 // 0xFEC01000 gap 1020 KB\r
206 // 0xFED00000 HPET 1 KB\r
207 // 0xFED00400 gap 111 KB\r
208 // 0xFED1C000 gap (PIIX4) / RCRB (ICH9) 16 KB\r
209 // 0xFED20000 gap 896 KB\r
210 // 0xFEE00000 LAPIC 1 MB\r
211 //\r
212 PciSize = 0xFC000000 - PciBase;\r
213 AddIoMemoryBaseSizeHob (PciBase, PciSize);\r
214 PcdStatus = PcdSet64S (PcdPciMmio32Base, PciBase);\r
215 ASSERT_RETURN_ERROR (PcdStatus);\r
216 PcdStatus = PcdSet64S (PcdPciMmio32Size, PciSize);\r
217 ASSERT_RETURN_ERROR (PcdStatus);\r
218\r
219 AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);\r
220 AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);\r
221 if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {\r
222 AddIoMemoryBaseSizeHob (ICH9_ROOT_COMPLEX_BASE, SIZE_16KB);\r
223 //\r
224 // Note: there should be an\r
225 //\r
226 // AddIoMemoryBaseSizeHob (PciExBarBase, SIZE_256MB);\r
227 //\r
228 // call below, just like the one above for RCBA. However, Linux insists\r
229 // that the MMCONFIG area be marked in the E820 or UEFI memory map as\r
230 // "reserved memory" -- Linux does not content itself with a simple gap\r
231 // in the memory map wherever the MCFG ACPI table points to.\r
232 //\r
233 // This appears to be a safety measure. The PCI Firmware Specification\r
234 // (rev 3.1) says in 4.1.2. "MCFG Table Description": "The resources can\r
235 // *optionally* be returned in [...] EFIGetMemoryMap as reserved memory\r
236 // [...]". (Emphasis added here.)\r
237 //\r
238 // Normally we add memory resource descriptor HOBs in\r
239 // QemuInitializeRam(), and pre-allocate from those with memory\r
240 // allocation HOBs in InitializeRamRegions(). However, the MMCONFIG area\r
241 // is most definitely not RAM; so, as an exception, cover it with\r
242 // uncacheable reserved memory right here.\r
243 //\r
244 AddReservedMemoryBaseSizeHob (PciExBarBase, SIZE_256MB, FALSE);\r
245 BuildMemoryAllocationHob (PciExBarBase, SIZE_256MB,\r
246 EfiReservedMemoryType);\r
247 }\r
248 AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress), SIZE_1MB);\r
249\r
250 //\r
251 // On Q35, the IO Port space is available for PCI resource allocations from\r
252 // 0x6000 up.\r
253 //\r
254 if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {\r
255 PciIoBase = 0x6000;\r
256 PciIoSize = 0xA000;\r
257 ASSERT ((ICH9_PMBASE_VALUE & 0xF000) < PciIoBase);\r
258 }\r
259 }\r
260\r
261 //\r
262 // Add PCI IO Port space available for PCI resource allocations.\r
263 //\r
264 BuildResourceDescriptorHob (\r
265 EFI_RESOURCE_IO,\r
266 EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
267 EFI_RESOURCE_ATTRIBUTE_INITIALIZED,\r
268 PciIoBase,\r
269 PciIoSize\r
270 );\r
271 PcdStatus = PcdSet64S (PcdPciIoBase, PciIoBase);\r
272 ASSERT_RETURN_ERROR (PcdStatus);\r
273 PcdStatus = PcdSet64S (PcdPciIoSize, PciIoSize);\r
274 ASSERT_RETURN_ERROR (PcdStatus);\r
275}\r
276\r
277VOID\r
278NoexecDxeInitialization (\r
279 VOID\r
280 )\r
281{\r
282}\r
283\r
284VOID\r
285PciExBarInitialization (\r
286 VOID\r
287 )\r
288{\r
289 union {\r
290 UINT64 Uint64;\r
291 UINT32 Uint32[2];\r
292 } PciExBarBase;\r
293\r
294 //\r
295 // We only support the 256MB size for the MMCONFIG area:\r
296 // 256 buses * 32 devices * 8 functions * 4096 bytes config space.\r
297 //\r
298 // The masks used below enforce the Q35 requirements that the MMCONFIG area\r
299 // be (a) correctly aligned -- here at 256 MB --, (b) located under 64 GB.\r
300 //\r
301 // Note that (b) also ensures that the minimum address width we have\r
302 // determined in AddressWidthInitialization(), i.e., 36 bits, will suffice\r
303 // for DXE's page tables to cover the MMCONFIG area.\r
304 //\r
305 PciExBarBase.Uint64 = FixedPcdGet64 (PcdPciExpressBaseAddress);\r
306 ASSERT ((PciExBarBase.Uint32[1] & MCH_PCIEXBAR_HIGHMASK) == 0);\r
307 ASSERT ((PciExBarBase.Uint32[0] & MCH_PCIEXBAR_LOWMASK) == 0);\r
308\r
309 //\r
310 // Clear the PCIEXBAREN bit first, before programming the high register.\r
311 //\r
312 PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW), 0);\r
313\r
314 //\r
315 // Program the high register. Then program the low register, setting the\r
316 // MMCONFIG area size and enabling decoding at once.\r
317 //\r
318 PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_HIGH), PciExBarBase.Uint32[1]);\r
319 PciWrite32 (\r
320 DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW),\r
321 PciExBarBase.Uint32[0] | MCH_PCIEXBAR_BUS_FF | MCH_PCIEXBAR_EN\r
322 );\r
323}\r
324\r
325VOID\r
326MiscInitialization (\r
327 VOID\r
328 )\r
329{\r
330 UINTN PmCmd;\r
331 UINTN Pmba;\r
332 UINT32 PmbaAndVal;\r
333 UINT32 PmbaOrVal;\r
334 UINTN AcpiCtlReg;\r
335 UINT8 AcpiEnBit;\r
336 RETURN_STATUS PcdStatus;\r
337\r
338 //\r
339 // Disable A20 Mask\r
340 //\r
341 IoOr8 (0x92, BIT1);\r
342\r
343 //\r
344 // Build the CPU HOB with guest RAM size dependent address width and 16-bits\r
345 // of IO space. (Side note: unlike other HOBs, the CPU HOB is needed during\r
346 // S3 resume as well, so we build it unconditionally.)\r
347 //\r
348 BuildCpuHob (mPhysMemAddressWidth, 16);\r
349\r
350 //\r
351 // Determine platform type and save Host Bridge DID to PCD\r
352 //\r
353 switch (mHostBridgeDevId) {\r
02967794
RC
354 case 0x7432: // BHYVE (AMD hostbridge)\r
355 case 0x1275: // BHYVE (Intel hostbridge)\r
656419f9
RC
356 case INTEL_82441_DEVICE_ID:\r
357 PmCmd = POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET);\r
358 Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);\r
359 PmbaAndVal = ~(UINT32)PIIX4_PMBA_MASK;\r
360 PmbaOrVal = PIIX4_PMBA_VALUE;\r
361 AcpiCtlReg = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC);\r
362 AcpiEnBit = PIIX4_PMREGMISC_PMIOSE;\r
363 break;\r
364 case INTEL_Q35_MCH_DEVICE_ID:\r
365 PmCmd = POWER_MGMT_REGISTER_Q35 (PCI_COMMAND_OFFSET);\r
366 Pmba = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);\r
367 PmbaAndVal = ~(UINT32)ICH9_PMBASE_MASK;\r
368 PmbaOrVal = ICH9_PMBASE_VALUE;\r
369 AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL);\r
370 AcpiEnBit = ICH9_ACPI_CNTL_ACPI_EN;\r
371 break;\r
372 default:\r
373 DEBUG ((DEBUG_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",\r
374 __FUNCTION__, mHostBridgeDevId));\r
375 ASSERT (FALSE);\r
376 return;\r
377 }\r
378 PcdStatus = PcdSet16S (PcdOvmfHostBridgePciDevId, mHostBridgeDevId);\r
379 ASSERT_RETURN_ERROR (PcdStatus);\r
380\r
381 //\r
382 // If the appropriate IOspace enable bit is set, assume the ACPI PMBA\r
383 // has been configured (e.g., by Xen) and skip the setup here.\r
384 // This matches the logic in AcpiTimerLibConstructor ().\r
385 //\r
386 if ((PciRead8 (AcpiCtlReg) & AcpiEnBit) == 0) {\r
387 //\r
388 // The PEI phase should be exited with fully accessibe ACPI PM IO space:\r
389 // 1. set PMBA\r
390 //\r
391 PciAndThenOr32 (Pmba, PmbaAndVal, PmbaOrVal);\r
392\r
393 //\r
394 // 2. set PCICMD/IOSE\r
395 //\r
396 PciOr8 (PmCmd, EFI_PCI_COMMAND_IO_SPACE);\r
397\r
398 //\r
399 // 3. set ACPI PM IO enable bit (PMREGMISC:PMIOSE or ACPI_CNTL:ACPI_EN)\r
400 //\r
401 PciOr8 (AcpiCtlReg, AcpiEnBit);\r
402 }\r
403\r
404 if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {\r
405 //\r
406 // Set Root Complex Register Block BAR\r
407 //\r
408 PciWrite32 (\r
409 POWER_MGMT_REGISTER_Q35 (ICH9_RCBA),\r
410 ICH9_ROOT_COMPLEX_BASE | ICH9_RCBA_EN\r
411 );\r
412\r
413 //\r
414 // Set PCI Express Register Range Base Address\r
415 //\r
416 PciExBarInitialization ();\r
417 }\r
418}\r
419\r
420\r
421VOID\r
422BootModeInitialization (\r
423 VOID\r
424 )\r
425{\r
426 EFI_STATUS Status;\r
427\r
428 if (CmosRead8 (0xF) == 0xFE) {\r
429 mBootMode = BOOT_ON_S3_RESUME;\r
430 }\r
431 CmosWrite8 (0xF, 0x00);\r
432\r
433 Status = PeiServicesSetBootMode (mBootMode);\r
434 ASSERT_EFI_ERROR (Status);\r
435\r
436 Status = PeiServicesInstallPpi (mPpiBootMode);\r
437 ASSERT_EFI_ERROR (Status);\r
438}\r
439\r
440\r
441VOID\r
442ReserveEmuVariableNvStore (\r
443 )\r
444{\r
445 EFI_PHYSICAL_ADDRESS VariableStore;\r
446 RETURN_STATUS PcdStatus;\r
447\r
448 //\r
449 // Allocate storage for NV variables early on so it will be\r
450 // at a consistent address. Since VM memory is preserved\r
451 // across reboots, this allows the NV variable storage to survive\r
452 // a VM reboot.\r
453 //\r
454 VariableStore =\r
455 (EFI_PHYSICAL_ADDRESS)(UINTN)\r
456 AllocateRuntimePages (\r
457 EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize))\r
458 );\r
459 DEBUG ((DEBUG_INFO,\r
460 "Reserved variable store memory: 0x%lX; size: %dkb\n",\r
461 VariableStore,\r
462 (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / 1024\r
463 ));\r
464 PcdStatus = PcdSet64S (PcdEmuVariableNvStoreReserved, VariableStore);\r
465 ASSERT_RETURN_ERROR (PcdStatus);\r
466}\r
467\r
468\r
469VOID\r
470DebugDumpCmos (\r
471 VOID\r
472 )\r
473{\r
474 UINT32 Loop;\r
475\r
476 DEBUG ((DEBUG_INFO, "CMOS:\n"));\r
477\r
478 for (Loop = 0; Loop < 0x80; Loop++) {\r
479 if ((Loop % 0x10) == 0) {\r
480 DEBUG ((DEBUG_INFO, "%02x:", Loop));\r
481 }\r
482 DEBUG ((DEBUG_INFO, " %02x", CmosRead8 (Loop)));\r
483 if ((Loop % 0x10) == 0xf) {\r
484 DEBUG ((DEBUG_INFO, "\n"));\r
485 }\r
486 }\r
487}\r
488\r
489\r
490VOID\r
491S3Verification (\r
492 VOID\r
493 )\r
494{\r
495#if defined (MDE_CPU_X64)\r
496 if (FeaturePcdGet (PcdSmmSmramRequire) && mS3Supported) {\r
497 DEBUG ((DEBUG_ERROR,\r
498 "%a: S3Resume2Pei doesn't support X64 PEI + SMM yet.\n", __FUNCTION__));\r
499 DEBUG ((DEBUG_ERROR,\r
500 "%a: Please disable S3 on the QEMU command line (see the README),\n",\r
501 __FUNCTION__));\r
502 DEBUG ((DEBUG_ERROR,\r
503 "%a: or build OVMF with \"OvmfPkgIa32X64.dsc\".\n", __FUNCTION__));\r
504 ASSERT (FALSE);\r
505 CpuDeadLoop ();\r
506 }\r
507#endif\r
508}\r
509\r
510\r
511/**\r
512 Fetch the number of boot CPUs from QEMU and expose it to UefiCpuPkg modules.\r
513 Set the mMaxCpuCount variable.\r
514**/\r
515VOID\r
516MaxCpuCountInitialization (\r
517 VOID\r
518 )\r
519{\r
520 UINT16 ProcessorCount = 0;\r
521 RETURN_STATUS PcdStatus;\r
522\r
523 //\r
524 // If the fw_cfg key or fw_cfg entirely is unavailable, load mMaxCpuCount\r
525 // from the PCD default. No change to PCDs.\r
526 //\r
527 if (ProcessorCount == 0) {\r
528 mMaxCpuCount = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);\r
529 return;\r
530 }\r
531 //\r
532 // Otherwise, set mMaxCpuCount to the value reported by QEMU.\r
533 //\r
534 mMaxCpuCount = ProcessorCount;\r
535 //\r
536 // Additionally, tell UefiCpuPkg modules (a) the exact number of VCPUs, (b)\r
537 // to wait, in the initial AP bringup, exactly as long as it takes for all of\r
538 // the APs to report in. For this, we set the longest representable timeout\r
539 // (approx. 71 minutes).\r
540 //\r
541 PcdStatus = PcdSet32S (PcdCpuMaxLogicalProcessorNumber, ProcessorCount);\r
542 ASSERT_RETURN_ERROR (PcdStatus);\r
543 PcdStatus = PcdSet32S (PcdCpuApInitTimeOutInMicroSeconds, MAX_UINT32);\r
544 ASSERT_RETURN_ERROR (PcdStatus);\r
545 DEBUG ((DEBUG_INFO, "%a: QEMU reports %d processor(s)\n", __FUNCTION__,\r
546 ProcessorCount));\r
547}\r
548\r
549\r
550/**\r
551 Perform Platform PEI initialization.\r
552\r
553 @param FileHandle Handle of the file being invoked.\r
554 @param PeiServices Describes the list of possible PEI Services.\r
555\r
556 @return EFI_SUCCESS The PEIM initialized successfully.\r
557\r
558**/\r
559EFI_STATUS\r
560EFIAPI\r
561InitializePlatform (\r
562 IN EFI_PEI_FILE_HANDLE FileHandle,\r
563 IN CONST EFI_PEI_SERVICES **PeiServices\r
564 )\r
565{\r
566 DEBUG ((DEBUG_INFO, "Platform PEIM Loaded\n"));\r
567\r
568 //\r
569 // Initialize Local APIC Timer hardware and disable Local APIC Timer\r
570 // interrupts before initializing the Debug Agent and the debug timer is\r
571 // enabled.\r
572 //\r
573 InitializeApicTimer (0, MAX_UINT32, TRUE, 5);\r
574 DisableApicTimerInterrupt ();\r
575\r
576 DebugDumpCmos ();\r
577\r
578 BootModeInitialization ();\r
579 AddressWidthInitialization ();\r
580 MaxCpuCountInitialization ();\r
581\r
582 //\r
583 // Query Host Bridge DID\r
584 //\r
585 mHostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);\r
586\r
587 if (FeaturePcdGet (PcdSmmSmramRequire)) {\r
588 Q35TsegMbytesInitialization ();\r
589 }\r
590\r
591 PublishPeiMemory ();\r
592\r
593 InitializeRamRegions ();\r
594\r
595 if (mBootMode != BOOT_ON_S3_RESUME) {\r
596 if (!FeaturePcdGet (PcdSmmSmramRequire)) {\r
597 ReserveEmuVariableNvStore ();\r
598 }\r
599 PeiFvInitialization ();\r
600 MemMapInitialization ();\r
601 NoexecDxeInitialization ();\r
602 }\r
603\r
604 InstallClearCacheCallback ();\r
605 AmdSevInitialize ();\r
606 MiscInitialization ();\r
607 InstallFeatureControlCallback ();\r
608\r
609 return EFI_SUCCESS;\r
610}\r