]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Bhyve/PlatformPei/Platform.c
OvmfPkg: 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
ac0a286f 39EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {\r
656419f9
RC
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
ac0a286f 50EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = {\r
656419f9
RC
51 {\r
52 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
53 &gEfiPeiMasterBootModePpiGuid,\r
54 NULL\r
55 }\r
56};\r
57\r
ac0a286f 58UINT16 mHostBridgeDevId;\r
656419f9 59\r
ac0a286f 60EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION;\r
656419f9 61\r
ac0a286f 62BOOLEAN mS3Supported = FALSE;\r
656419f9 63\r
ac0a286f 64UINT32 mMaxCpuCount;\r
656419f9
RC
65\r
66VOID\r
67AddIoMemoryBaseSizeHob (\r
ac0a286f
MK
68 EFI_PHYSICAL_ADDRESS MemoryBase,\r
69 UINT64 MemorySize\r
656419f9
RC
70 )\r
71{\r
72 BuildResourceDescriptorHob (\r
73 EFI_RESOURCE_MEMORY_MAPPED_IO,\r
ac0a286f
MK
74 EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
75 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
76 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
77 EFI_RESOURCE_ATTRIBUTE_TESTED,\r
656419f9
RC
78 MemoryBase,\r
79 MemorySize\r
80 );\r
81}\r
82\r
83VOID\r
84AddReservedMemoryBaseSizeHob (\r
ac0a286f
MK
85 EFI_PHYSICAL_ADDRESS MemoryBase,\r
86 UINT64 MemorySize,\r
87 BOOLEAN Cacheable\r
656419f9
RC
88 )\r
89{\r
90 BuildResourceDescriptorHob (\r
91 EFI_RESOURCE_MEMORY_RESERVED,\r
ac0a286f
MK
92 EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
93 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
94 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
95 (Cacheable ?\r
96 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
97 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
98 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE :\r
99 0\r
100 ) |\r
101 EFI_RESOURCE_ATTRIBUTE_TESTED,\r
656419f9
RC
102 MemoryBase,\r
103 MemorySize\r
104 );\r
105}\r
106\r
107VOID\r
108AddIoMemoryRangeHob (\r
ac0a286f
MK
109 EFI_PHYSICAL_ADDRESS MemoryBase,\r
110 EFI_PHYSICAL_ADDRESS MemoryLimit\r
656419f9
RC
111 )\r
112{\r
113 AddIoMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));\r
114}\r
115\r
656419f9
RC
116VOID\r
117AddMemoryBaseSizeHob (\r
ac0a286f
MK
118 EFI_PHYSICAL_ADDRESS MemoryBase,\r
119 UINT64 MemorySize\r
656419f9
RC
120 )\r
121{\r
122 BuildResourceDescriptorHob (\r
123 EFI_RESOURCE_SYSTEM_MEMORY,\r
ac0a286f
MK
124 EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
125 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
126 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
127 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
128 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
129 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |\r
130 EFI_RESOURCE_ATTRIBUTE_TESTED,\r
656419f9
RC
131 MemoryBase,\r
132 MemorySize\r
133 );\r
134}\r
135\r
656419f9
RC
136VOID\r
137AddMemoryRangeHob (\r
ac0a286f
MK
138 EFI_PHYSICAL_ADDRESS MemoryBase,\r
139 EFI_PHYSICAL_ADDRESS MemoryLimit\r
656419f9
RC
140 )\r
141{\r
142 AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));\r
143}\r
144\r
656419f9
RC
145VOID\r
146MemMapInitialization (\r
147 VOID\r
148 )\r
149{\r
ac0a286f
MK
150 UINT64 PciIoBase;\r
151 UINT64 PciIoSize;\r
152 RETURN_STATUS PcdStatus;\r
656419f9
RC
153\r
154 PciIoBase = 0xC000;\r
155 PciIoSize = 0x4000;\r
156\r
157 //\r
158 // Create Memory Type Information HOB\r
159 //\r
160 BuildGuidDataHob (\r
161 &gEfiMemoryTypeInformationGuid,\r
162 mDefaultMemoryTypeInformation,\r
ac0a286f 163 sizeof (mDefaultMemoryTypeInformation)\r
656419f9
RC
164 );\r
165\r
166 //\r
167 // Video memory + Legacy BIOS region\r
168 //\r
169 AddIoMemoryRangeHob (0x0A0000, BASE_1MB);\r
170\r
171 if (TRUE) {\r
172 UINT32 TopOfLowRam;\r
173 UINT64 PciExBarBase;\r
174 UINT32 PciBase;\r
175 UINT32 PciSize;\r
176\r
ac0a286f 177 TopOfLowRam = GetSystemMemorySizeBelow4gb ();\r
656419f9
RC
178 PciExBarBase = 0;\r
179 if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {\r
180 //\r
181 // The MMCONFIG area is expected to fall between the top of low RAM and\r
182 // the base of the 32-bit PCI host aperture.\r
183 //\r
184 PciExBarBase = FixedPcdGet64 (PcdPciExpressBaseAddress);\r
185 ASSERT (TopOfLowRam <= PciExBarBase);\r
186 ASSERT (PciExBarBase <= MAX_UINT32 - SIZE_256MB);\r
187 PciBase = (UINT32)(PciExBarBase + SIZE_256MB);\r
188 } else {\r
4c495e5e 189 PciBase = (UINT32)PcdGet64 (PcdPciMmio32Base);\r
ac0a286f 190 if (PciBase == 0) {\r
44ced037 191 PciBase = (TopOfLowRam < BASE_2GB) ? BASE_2GB : TopOfLowRam;\r
ac0a286f 192 }\r
656419f9
RC
193 }\r
194\r
195 //\r
196 // address purpose size\r
197 // ------------ -------- -------------------------\r
198 // max(top, 2g) PCI MMIO 0xFC000000 - max(top, 2g)\r
199 // 0xFC000000 gap 44 MB\r
200 // 0xFEC00000 IO-APIC 4 KB\r
201 // 0xFEC01000 gap 1020 KB\r
202 // 0xFED00000 HPET 1 KB\r
203 // 0xFED00400 gap 111 KB\r
204 // 0xFED1C000 gap (PIIX4) / RCRB (ICH9) 16 KB\r
205 // 0xFED20000 gap 896 KB\r
206 // 0xFEE00000 LAPIC 1 MB\r
207 //\r
208 PciSize = 0xFC000000 - PciBase;\r
209 AddIoMemoryBaseSizeHob (PciBase, PciSize);\r
210 PcdStatus = PcdSet64S (PcdPciMmio32Base, PciBase);\r
211 ASSERT_RETURN_ERROR (PcdStatus);\r
212 PcdStatus = PcdSet64S (PcdPciMmio32Size, PciSize);\r
213 ASSERT_RETURN_ERROR (PcdStatus);\r
214\r
215 AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);\r
216 AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);\r
217 if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {\r
218 AddIoMemoryBaseSizeHob (ICH9_ROOT_COMPLEX_BASE, SIZE_16KB);\r
219 //\r
220 // Note: there should be an\r
221 //\r
222 // AddIoMemoryBaseSizeHob (PciExBarBase, SIZE_256MB);\r
223 //\r
224 // call below, just like the one above for RCBA. However, Linux insists\r
225 // that the MMCONFIG area be marked in the E820 or UEFI memory map as\r
226 // "reserved memory" -- Linux does not content itself with a simple gap\r
227 // in the memory map wherever the MCFG ACPI table points to.\r
228 //\r
229 // This appears to be a safety measure. The PCI Firmware Specification\r
230 // (rev 3.1) says in 4.1.2. "MCFG Table Description": "The resources can\r
231 // *optionally* be returned in [...] EFIGetMemoryMap as reserved memory\r
232 // [...]". (Emphasis added here.)\r
233 //\r
234 // Normally we add memory resource descriptor HOBs in\r
235 // QemuInitializeRam(), and pre-allocate from those with memory\r
236 // allocation HOBs in InitializeRamRegions(). However, the MMCONFIG area\r
237 // is most definitely not RAM; so, as an exception, cover it with\r
238 // uncacheable reserved memory right here.\r
239 //\r
240 AddReservedMemoryBaseSizeHob (PciExBarBase, SIZE_256MB, FALSE);\r
ac0a286f
MK
241 BuildMemoryAllocationHob (\r
242 PciExBarBase,\r
243 SIZE_256MB,\r
244 EfiReservedMemoryType\r
245 );\r
656419f9 246 }\r
ac0a286f
MK
247\r
248 AddIoMemoryBaseSizeHob (PcdGet32 (PcdCpuLocalApicBaseAddress), SIZE_1MB);\r
656419f9
RC
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
ac0a286f
MK
290 UINT64 Uint64;\r
291 UINT32 Uint32[2];\r
656419f9
RC
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
ac0a286f
MK
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
656419f9
RC
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
ac0a286f
MK
373 DEBUG ((\r
374 DEBUG_ERROR,\r
375 "%a: Unknown Host Bridge Device ID: 0x%04x\n",\r
376 __FUNCTION__,\r
377 mHostBridgeDevId\r
378 ));\r
656419f9
RC
379 ASSERT (FALSE);\r
380 return;\r
381 }\r
ac0a286f 382\r
656419f9
RC
383 PcdStatus = PcdSet16S (PcdOvmfHostBridgePciDevId, mHostBridgeDevId);\r
384 ASSERT_RETURN_ERROR (PcdStatus);\r
385\r
386 //\r
387 // If the appropriate IOspace enable bit is set, assume the ACPI PMBA\r
388 // has been configured (e.g., by Xen) and skip the setup here.\r
389 // This matches the logic in AcpiTimerLibConstructor ().\r
390 //\r
391 if ((PciRead8 (AcpiCtlReg) & AcpiEnBit) == 0) {\r
392 //\r
393 // The PEI phase should be exited with fully accessibe ACPI PM IO space:\r
394 // 1. set PMBA\r
395 //\r
396 PciAndThenOr32 (Pmba, PmbaAndVal, PmbaOrVal);\r
397\r
398 //\r
399 // 2. set PCICMD/IOSE\r
400 //\r
401 PciOr8 (PmCmd, EFI_PCI_COMMAND_IO_SPACE);\r
402\r
403 //\r
404 // 3. set ACPI PM IO enable bit (PMREGMISC:PMIOSE or ACPI_CNTL:ACPI_EN)\r
405 //\r
406 PciOr8 (AcpiCtlReg, AcpiEnBit);\r
407 }\r
408\r
409 if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {\r
410 //\r
411 // Set Root Complex Register Block BAR\r
412 //\r
413 PciWrite32 (\r
414 POWER_MGMT_REGISTER_Q35 (ICH9_RCBA),\r
415 ICH9_ROOT_COMPLEX_BASE | ICH9_RCBA_EN\r
416 );\r
417\r
418 //\r
419 // Set PCI Express Register Range Base Address\r
420 //\r
421 PciExBarInitialization ();\r
422 }\r
423}\r
424\r
656419f9
RC
425VOID\r
426BootModeInitialization (\r
427 VOID\r
428 )\r
429{\r
ac0a286f 430 EFI_STATUS Status;\r
656419f9
RC
431\r
432 if (CmosRead8 (0xF) == 0xFE) {\r
433 mBootMode = BOOT_ON_S3_RESUME;\r
434 }\r
ac0a286f 435\r
656419f9
RC
436 CmosWrite8 (0xF, 0x00);\r
437\r
438 Status = PeiServicesSetBootMode (mBootMode);\r
439 ASSERT_EFI_ERROR (Status);\r
440\r
441 Status = PeiServicesInstallPpi (mPpiBootMode);\r
442 ASSERT_EFI_ERROR (Status);\r
443}\r
444\r
656419f9
RC
445VOID\r
446ReserveEmuVariableNvStore (\r
447 )\r
448{\r
ac0a286f
MK
449 EFI_PHYSICAL_ADDRESS VariableStore;\r
450 RETURN_STATUS PcdStatus;\r
656419f9
RC
451\r
452 //\r
453 // Allocate storage for NV variables early on so it will be\r
454 // at a consistent address. Since VM memory is preserved\r
455 // across reboots, this allows the NV variable storage to survive\r
456 // a VM reboot.\r
457 //\r
458 VariableStore =\r
459 (EFI_PHYSICAL_ADDRESS)(UINTN)\r
ac0a286f
MK
460 AllocateRuntimePages (\r
461 EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize))\r
462 );\r
463 DEBUG ((\r
464 DEBUG_INFO,\r
465 "Reserved variable store memory: 0x%lX; size: %dkb\n",\r
466 VariableStore,\r
467 (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / 1024\r
468 ));\r
656419f9
RC
469 PcdStatus = PcdSet64S (PcdEmuVariableNvStoreReserved, VariableStore);\r
470 ASSERT_RETURN_ERROR (PcdStatus);\r
471}\r
472\r
656419f9
RC
473VOID\r
474DebugDumpCmos (\r
475 VOID\r
476 )\r
477{\r
ac0a286f 478 UINT32 Loop;\r
656419f9
RC
479\r
480 DEBUG ((DEBUG_INFO, "CMOS:\n"));\r
481\r
482 for (Loop = 0; Loop < 0x80; Loop++) {\r
483 if ((Loop % 0x10) == 0) {\r
484 DEBUG ((DEBUG_INFO, "%02x:", Loop));\r
485 }\r
ac0a286f 486\r
656419f9
RC
487 DEBUG ((DEBUG_INFO, " %02x", CmosRead8 (Loop)));\r
488 if ((Loop % 0x10) == 0xf) {\r
489 DEBUG ((DEBUG_INFO, "\n"));\r
490 }\r
491 }\r
492}\r
493\r
656419f9
RC
494VOID\r
495S3Verification (\r
496 VOID\r
497 )\r
498{\r
ac0a286f 499 #if defined (MDE_CPU_X64)\r
656419f9 500 if (FeaturePcdGet (PcdSmmSmramRequire) && mS3Supported) {\r
ac0a286f
MK
501 DEBUG ((\r
502 DEBUG_ERROR,\r
503 "%a: S3Resume2Pei doesn't support X64 PEI + SMM yet.\n",\r
504 __FUNCTION__\r
505 ));\r
506 DEBUG ((\r
507 DEBUG_ERROR,\r
656419f9 508 "%a: Please disable S3 on the QEMU command line (see the README),\n",\r
ac0a286f
MK
509 __FUNCTION__\r
510 ));\r
511 DEBUG ((\r
512 DEBUG_ERROR,\r
513 "%a: or build OVMF with \"OvmfPkgIa32X64.dsc\".\n",\r
514 __FUNCTION__\r
515 ));\r
656419f9
RC
516 ASSERT (FALSE);\r
517 CpuDeadLoop ();\r
518 }\r
656419f9 519\r
ac0a286f
MK
520 #endif\r
521}\r
656419f9
RC
522\r
523/**\r
524 Fetch the number of boot CPUs from QEMU and expose it to UefiCpuPkg modules.\r
525 Set the mMaxCpuCount variable.\r
526**/\r
527VOID\r
528MaxCpuCountInitialization (\r
529 VOID\r
530 )\r
531{\r
ac0a286f
MK
532 UINT16 ProcessorCount = 0;\r
533 RETURN_STATUS PcdStatus;\r
656419f9
RC
534\r
535 //\r
536 // If the fw_cfg key or fw_cfg entirely is unavailable, load mMaxCpuCount\r
537 // from the PCD default. No change to PCDs.\r
538 //\r
539 if (ProcessorCount == 0) {\r
540 mMaxCpuCount = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);\r
541 return;\r
542 }\r
ac0a286f 543\r
656419f9
RC
544 //\r
545 // Otherwise, set mMaxCpuCount to the value reported by QEMU.\r
546 //\r
547 mMaxCpuCount = ProcessorCount;\r
548 //\r
549 // Additionally, tell UefiCpuPkg modules (a) the exact number of VCPUs, (b)\r
550 // to wait, in the initial AP bringup, exactly as long as it takes for all of\r
551 // the APs to report in. For this, we set the longest representable timeout\r
552 // (approx. 71 minutes).\r
553 //\r
554 PcdStatus = PcdSet32S (PcdCpuMaxLogicalProcessorNumber, ProcessorCount);\r
555 ASSERT_RETURN_ERROR (PcdStatus);\r
556 PcdStatus = PcdSet32S (PcdCpuApInitTimeOutInMicroSeconds, MAX_UINT32);\r
557 ASSERT_RETURN_ERROR (PcdStatus);\r
ac0a286f
MK
558 DEBUG ((\r
559 DEBUG_INFO,\r
560 "%a: QEMU reports %d processor(s)\n",\r
561 __FUNCTION__,\r
562 ProcessorCount\r
563 ));\r
656419f9
RC
564}\r
565\r
656419f9
RC
566/**\r
567 Perform Platform PEI initialization.\r
568\r
569 @param FileHandle Handle of the file being invoked.\r
570 @param PeiServices Describes the list of possible PEI Services.\r
571\r
572 @return EFI_SUCCESS The PEIM initialized successfully.\r
573\r
574**/\r
575EFI_STATUS\r
576EFIAPI\r
577InitializePlatform (\r
578 IN EFI_PEI_FILE_HANDLE FileHandle,\r
579 IN CONST EFI_PEI_SERVICES **PeiServices\r
580 )\r
581{\r
582 DEBUG ((DEBUG_INFO, "Platform PEIM Loaded\n"));\r
583\r
584 //\r
585 // Initialize Local APIC Timer hardware and disable Local APIC Timer\r
586 // interrupts before initializing the Debug Agent and the debug timer is\r
587 // enabled.\r
588 //\r
589 InitializeApicTimer (0, MAX_UINT32, TRUE, 5);\r
590 DisableApicTimerInterrupt ();\r
591\r
592 DebugDumpCmos ();\r
593\r
594 BootModeInitialization ();\r
595 AddressWidthInitialization ();\r
596 MaxCpuCountInitialization ();\r
597\r
598 //\r
599 // Query Host Bridge DID\r
600 //\r
601 mHostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);\r
602\r
603 if (FeaturePcdGet (PcdSmmSmramRequire)) {\r
604 Q35TsegMbytesInitialization ();\r
605 }\r
606\r
607 PublishPeiMemory ();\r
608\r
609 InitializeRamRegions ();\r
610\r
611 if (mBootMode != BOOT_ON_S3_RESUME) {\r
612 if (!FeaturePcdGet (PcdSmmSmramRequire)) {\r
613 ReserveEmuVariableNvStore ();\r
614 }\r
ac0a286f 615\r
656419f9
RC
616 PeiFvInitialization ();\r
617 MemMapInitialization ();\r
618 NoexecDxeInitialization ();\r
619 }\r
620\r
621 InstallClearCacheCallback ();\r
622 AmdSevInitialize ();\r
623 MiscInitialization ();\r
624 InstallFeatureControlCallback ();\r
625\r
626 return EFI_SUCCESS;\r
627}\r