From nobody Sat Feb 7 04:57:04 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+86786+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+86786+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1645271897892968.904836179561; Sat, 19 Feb 2022 03:58:17 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id zdCwYY1788612x8mIH0SwOOY; Sat, 19 Feb 2022 03:58:19 -0800 X-Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by mx.groups.io with SMTP id smtpd.web08.9091.1645271832752102625 for ; Sat, 19 Feb 2022 03:58:18 -0800 X-IronPort-AV: E=McAfee;i="6200,9189,10262"; a="231915467" X-IronPort-AV: E=Sophos;i="5.88,381,1635231600"; d="scan'208";a="231915467" X-Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Feb 2022 03:58:18 -0800 X-IronPort-AV: E=Sophos;i="5.88,381,1635231600"; d="scan'208";a="546691263" X-Received: from mxu9-mobl1.ccr.corp.intel.com ([10.249.175.253]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Feb 2022 03:58:15 -0800 From: "Min Xu" To: devel@edk2.groups.io Cc: Min Xu , Ard Biesheuvel , Jordan Justen , Brijesh Singh , Erdem Aktas , James Bottomley , Jiewen Yao , Tom Lendacky , Gerd Hoffmann Subject: [edk2-devel] [PATCH V6 23/42] OvmfPkg/PlatformInitLib: Add platform functions Date: Sat, 19 Feb 2022 19:56:36 +0800 Message-Id: <68d58784e06e9e53a424bf412aa61cd8ef8736ab.1645261990.git.min.m.xu@intel.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,min.m.xu@intel.com X-Gm-Message-State: tbbNHi8dkRnmvr6R5bdx9FD5x1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1645271899; bh=gdcmzIii+L8+yvLD1qgdLDVld5RhJ+VCFpCZ+BzU4EA=; h=Cc:Date:From:Reply-To:Subject:To; b=c8JQAqRA1zSqdT162Cx8z4Yi75Wlul5y4HNfePxHKt73uIYh0XlOxuG8EHA3R/gQq9d g7ORtITsKEr1R79qnOK1WXhWC2Dd9X8ZFpGialFzuhvSAD9cdZ9lKLffCHyIv/pJz2Vy7 fJLfsBnGctQSyQcfoMcHoBU4LJp0t6KIi98= X-ZohoMail-DKIM: fail (Signature date is -2 seconds in the future.) X-ZM-MESSAGEID: 1645271899991100018 Content-Type: text/plain; charset="utf-8" RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3429 Below platform functions are introducted in PlatformInitLib: - PlatformMaxCpuCountInitialization - PlatformMemMapInitialization - PlatformNoexecDxeInitialization - PlatformMiscInitialization They correspond to the below functions in OvmfPkg/PlatformPei: - MaxCpuCountInitialization - MemMapInitialization - MiscInitialization - NoexecDxeInitialization QueryHostBridgeDid is a newly added function. Cc: Ard Biesheuvel Cc: Jordan Justen Cc: Brijesh Singh Cc: Erdem Aktas Cc: James Bottomley Cc: Jiewen Yao Cc: Tom Lendacky Cc: Gerd Hoffmann Signed-off-by: Min Xu --- OvmfPkg/Include/Library/PlatformInitLib.h | 75 +++ OvmfPkg/Library/PlatformInitLib/Platform.c | 491 ++++++++++++++++++ .../PlatformInitLib/PlatformInitLib.inf | 29 ++ 3 files changed, 595 insertions(+) diff --git a/OvmfPkg/Include/Library/PlatformInitLib.h b/OvmfPkg/Include/Li= brary/PlatformInitLib.h index df2646880909..dd108b3a4339 100644 --- a/OvmfPkg/Include/Library/PlatformInitLib.h +++ b/OvmfPkg/Include/Library/PlatformInitLib.h @@ -118,6 +118,81 @@ PlatformQemuUc32BaseInitialization ( IN UINT32 LowerMemorySize ); =20 +/** + * Query Host Bridge Dev Id. + * + * @return Host Bridge Dev Id. + */ +UINT16 +EFIAPI +PlatformQueryHostBridgeDid ( + VOID + ); + +/** + Fetch the boot CPU count and the possible CPU count from QEMU. + + @param HostBridgeDevId The Host bridge Dev Id. + @param DefaultMaxCpuCount The default max cpu count. + @param MaxCpuCount The pointer to the returned max cpu count. + @param BootCpuCount The pointer to the returned boot cpu count. +**/ +VOID +EFIAPI +PlatformMaxCpuCountInitialization ( + IN UINT16 HostBridgeDevId, + IN UINT32 DefaultMaxCpuCount, + OUT UINT32 *MaxCpuCount, + OUT UINT16 *BootCpuCount + ); + +/** + * Initialize the Memory Map IO hobs. + * + * @param HostBridgeDevId The host bridge Dev Id. + * @param Uc32Base The Qemu Uc32Base address. + * @param PciBase The pointer to the Pci base address. + * @param PciSize The pointer to the Pci base size. + * @param PciIoBase The pointer to the Pci Io base address. + * @param PciIoSize The pointer to the Pci Io size. + */ +VOID +EFIAPI +PlatformMemMapInitialization ( + IN UINT16 HostBridgeDevId, + IN UINT32 Uc32Base, + OUT UINT32 *PciBase, + OUT UINT32 *PciSize, + OUT UINT64 *PciIoBase, + OUT UINT64 *PciIoSize + ); + +/** + * Fetch "opt/ovmf/PcdSetNxForStack" from QEMU + * + * @param Setting The pointer to the setting of "/opt/ovmf/PcdSetNxFor= Stack". + * @return EFI_SUCCESS Successfully fetch the settings. + */ +EFI_STATUS +EFIAPI +PlatformNoexecDxeInitialization ( + OUT BOOLEAN *Setting + ); + +/** + * Misc initialization, such as Disable A20 Mask, Build CPU Hob, + * PM settings, Set PCI Express Register Range Base Address. + * + * @param HostBridgeDevId The host bridge Dev id. + * @param PhysMemAddressWidth The physical memory address width. + */ +VOID +EFIAPI +PlatformMiscInitialization ( + IN UINT16 HostBridgeDevId, + IN UINT8 PhysMemAddressWidth + ); + /** Publish system RAM and reserve memory regions. =20 diff --git a/OvmfPkg/Library/PlatformInitLib/Platform.c b/OvmfPkg/Library/P= latformInitLib/Platform.c index e41f230ff563..308a64f6558b 100644 --- a/OvmfPkg/Library/PlatformInitLib/Platform.c +++ b/OvmfPkg/Library/PlatformInitLib/Platform.c @@ -19,6 +19,21 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include =20 VOID @@ -104,3 +119,479 @@ PlatformAddMemoryRangeHob ( { PlatformAddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryB= ase)); } + +/** + * Initialize the Memory Map IO hobs. + * + * @param HostBridgeDevId The host bridge Dev Id. + * @param Uc32Base The Qemu Uc32Base address. + * @param PciBase The pointer to the Pci base address. + * @param PciSize The pointer to the Pci base size. + * @param PciIoBase The pointer to the Pci Io base address. + * @param PciIoSize The pointer to the Pci Io size. + */ +VOID +EFIAPI +PlatformMemMapInitialization ( + UINT16 HostBridgeDevId, + UINT32 Uc32Base, + UINT32 *PciBase, + UINT32 *PciSize, + UINT64 *PciIoBase, + UINT64 *PciIoSize + ) +{ + UINT32 TopOfLowRam; + UINT64 PciExBarBase; + + *PciIoBase =3D 0xC000; + *PciIoSize =3D 0x4000; + *PciBase =3D 0; + *PciSize =3D 0; + + // + // Video memory + Legacy BIOS region + // + PlatformAddIoMemoryRangeHob (0x0A0000, BASE_1MB); + + if (HostBridgeDevId =3D=3D 0xffff /* microvm */) { + PlatformAddIoMemoryBaseSizeHob (MICROVM_GED_MMIO_BASE, SIZE_4KB); + PlatformAddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB); /* ioapic #1 */ + PlatformAddIoMemoryBaseSizeHob (0xFEC10000, SIZE_4KB); /* ioapic #2 */ + return; + } + + TopOfLowRam =3D PlatformGetSystemMemorySizeBelow4gb (); + PciExBarBase =3D 0; + if (HostBridgeDevId =3D=3D INTEL_Q35_MCH_DEVICE_ID) { + // + // The MMCONFIG area is expected to fall between the top of low RAM and + // the base of the 32-bit PCI host aperture. + // + PciExBarBase =3D FixedPcdGet64 (PcdPciExpressBaseAddress); + ASSERT (TopOfLowRam <=3D PciExBarBase); + ASSERT (PciExBarBase <=3D MAX_UINT32 - SIZE_256MB); + *PciBase =3D (UINT32)(PciExBarBase + SIZE_256MB); + } else { + ASSERT (TopOfLowRam <=3D Uc32Base); + *PciBase =3D Uc32Base; + } + + // + // address purpose size + // ------------ -------- ------------------------- + // max(top, 2g) PCI MMIO 0xFC000000 - max(top, 2g) + // 0xFC000000 gap 44 MB + // 0xFEC00000 IO-APIC 4 KB + // 0xFEC01000 gap 1020 KB + // 0xFED00000 HPET 1 KB + // 0xFED00400 gap 111 KB + // 0xFED1C000 gap (PIIX4) / RCRB (ICH9) 16 KB + // 0xFED20000 gap 896 KB + // 0xFEE00000 LAPIC 1 MB + // + *PciSize =3D 0xFC000000 - *PciBase; + PlatformAddIoMemoryBaseSizeHob (*PciBase, *PciSize); + + PlatformAddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB); + PlatformAddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB); + if (HostBridgeDevId =3D=3D INTEL_Q35_MCH_DEVICE_ID) { + PlatformAddIoMemoryBaseSizeHob (ICH9_ROOT_COMPLEX_BASE, SIZE_16KB); + // + // Note: there should be an + // + // AddIoMemoryBaseSizeHob (PciExBarBase, SIZE_256MB); + // + // call below, just like the one above for RCBA. However, Linux insists + // that the MMCONFIG area be marked in the E820 or UEFI memory map as + // "reserved memory" -- Linux does not content itself with a simple gap + // in the memory map wherever the MCFG ACPI table points to. + // + // This appears to be a safety measure. The PCI Firmware Specification + // (rev 3.1) says in 4.1.2. "MCFG Table Description": "The resources c= an + // *optionally* be returned in [...] EFIGetMemoryMap as reserved memory + // [...]". (Emphasis added here.) + // + // Normally we add memory resource descriptor HOBs in + // QemuInitializeRam(), and pre-allocate from those with memory + // allocation HOBs in InitializeRamRegions(). However, the MMCONFIG ar= ea + // is most definitely not RAM; so, as an exception, cover it with + // uncacheable reserved memory right here. + // + PlatformAddReservedMemoryBaseSizeHob (PciExBarBase, SIZE_256MB, FALSE); + BuildMemoryAllocationHob ( + PciExBarBase, + SIZE_256MB, + EfiReservedMemoryType + ); + } + + PlatformAddIoMemoryBaseSizeHob (FixedPcdGet32 (PcdCpuLocalApicBaseAddres= s), SIZE_1MB); + + // + // On Q35, the IO Port space is available for PCI resource allocations f= rom + // 0x6000 up. + // + if (HostBridgeDevId =3D=3D INTEL_Q35_MCH_DEVICE_ID) { + *PciIoBase =3D 0x6000; + *PciIoSize =3D 0xA000; + ASSERT ((ICH9_PMBASE_VALUE & 0xF000) < *PciIoBase); + } + + // + // Add PCI IO Port space available for PCI resource allocations. + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_IO, + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED, + *PciIoBase, + *PciIoSize + ); +} + +/** + * Fetch "opt/ovmf/PcdSetNxForStack" from QEMU + * + * @param Setting The pointer to the setting of "/opt/ovmf/PcdSetNxFor= Stack". + * @return EFI_SUCCESS Successfully fetch the settings. + */ +EFI_STATUS +EFIAPI +PlatformNoexecDxeInitialization ( + OUT BOOLEAN *Setting + ) +{ + return QemuFwCfgParseBool ("opt/ovmf/PcdSetNxForStack", Setting); +} + +VOID +PciExBarInitialization ( + VOID + ) +{ + union { + UINT64 Uint64; + UINT32 Uint32[2]; + } PciExBarBase; + + // + // We only support the 256MB size for the MMCONFIG area: + // 256 buses * 32 devices * 8 functions * 4096 bytes config space. + // + // The masks used below enforce the Q35 requirements that the MMCONFIG a= rea + // be (a) correctly aligned -- here at 256 MB --, (b) located under 64 G= B. + // + // Note that (b) also ensures that the minimum address width we have + // determined in AddressWidthInitialization(), i.e., 36 bits, will suffi= ce + // for DXE's page tables to cover the MMCONFIG area. + // + PciExBarBase.Uint64 =3D FixedPcdGet64 (PcdPciExpressBaseAddress); + ASSERT ((PciExBarBase.Uint32[1] & MCH_PCIEXBAR_HIGHMASK) =3D=3D 0); + ASSERT ((PciExBarBase.Uint32[0] & MCH_PCIEXBAR_LOWMASK) =3D=3D 0); + + // + // Clear the PCIEXBAREN bit first, before programming the high register. + // + PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW), 0); + + // + // Program the high register. Then program the low register, setting the + // MMCONFIG area size and enabling decoding at once. + // + PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_HIGH), PciExBarBase.Uint32[= 1]); + PciWrite32 ( + DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW), + PciExBarBase.Uint32[0] | MCH_PCIEXBAR_BUS_FF | MCH_PCIEXBAR_EN + ); +} + +/** + * Misc initialization, such as Disable A20 Mask, Build CPU Hob, + * PM settings, Set PCI Express Register Range Base Address. + * + * @param HostBridgeDevId The host bridge Dev id. + * @param PhysMemAddressWidth The physical memory address width. + */ +VOID +EFIAPI +PlatformMiscInitialization ( + IN UINT16 HostBridgeDevId, + IN UINT8 PhysMemAddressWidth + ) +{ + UINTN PmCmd; + UINTN Pmba; + UINT32 PmbaAndVal; + UINT32 PmbaOrVal; + UINTN AcpiCtlReg; + UINT8 AcpiEnBit; + + // + // 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 dur= ing + // S3 resume as well, so we build it unconditionally.) + // + BuildCpuHob (PhysMemAddressWidth, 16); + + // + // Determine platform type and save Host Bridge DID to PCD + // + switch (HostBridgeDevId) { + case INTEL_82441_DEVICE_ID: + PmCmd =3D POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET); + Pmba =3D POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA); + PmbaAndVal =3D ~(UINT32)PIIX4_PMBA_MASK; + PmbaOrVal =3D PIIX4_PMBA_VALUE; + AcpiCtlReg =3D POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC); + AcpiEnBit =3D PIIX4_PMREGMISC_PMIOSE; + break; + case INTEL_Q35_MCH_DEVICE_ID: + PmCmd =3D POWER_MGMT_REGISTER_Q35 (PCI_COMMAND_OFFSET); + Pmba =3D POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE); + PmbaAndVal =3D ~(UINT32)ICH9_PMBASE_MASK; + PmbaOrVal =3D ICH9_PMBASE_VALUE; + AcpiCtlReg =3D POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL); + AcpiEnBit =3D ICH9_ACPI_CNTL_ACPI_EN; + break; + default: + DEBUG (( + DEBUG_ERROR, + "%a: Unknown Host Bridge Device ID: 0x%04x\n", + __FUNCTION__, + HostBridgeDevId + )); + ASSERT (FALSE); + return; + } + + // + // If the appropriate IOspace enable bit is set, assume the ACPI PMBA has + // been configured and skip the setup here. This matches the logic in + // AcpiTimerLibConstructor (). + // + if ((PciRead8 (AcpiCtlReg) & AcpiEnBit) =3D=3D 0) { + // + // The PEI phase should be exited with fully accessibe ACPI PM IO spac= e: + // 1. set PMBA + // + PciAndThenOr32 (Pmba, PmbaAndVal, PmbaOrVal); + + // + // 2. set PCICMD/IOSE + // + PciOr8 (PmCmd, EFI_PCI_COMMAND_IO_SPACE); + + // + // 3. set ACPI PM IO enable bit (PMREGMISC:PMIOSE or ACPI_CNTL:ACPI_EN) + // + PciOr8 (AcpiCtlReg, AcpiEnBit); + } + + if (HostBridgeDevId =3D=3D INTEL_Q35_MCH_DEVICE_ID) { + // + // Set Root Complex Register Block BAR + // + PciWrite32 ( + POWER_MGMT_REGISTER_Q35 (ICH9_RCBA), + ICH9_ROOT_COMPLEX_BASE | ICH9_RCBA_EN + ); + + // + // Set PCI Express Register Range Base Address + // + PciExBarInitialization (); + } +} + +/** + Fetch the boot CPU count and the possible CPU count from QEMU. + + @param HostBridgeDevId The Host bridge Dev Id. + @param DefaultMaxCpuCount The default max cpu count. + @param MaxCpuCount The pointer to the returned max cpu count. + @param BootCpuCount The pointer to the returned boot cpu count. +**/ +VOID +EFIAPI +PlatformMaxCpuCountInitialization ( + IN UINT16 HostBridgeDevId, + IN UINT32 DefaultMaxCpuCount, + OUT UINT32 *MaxCpuCount, + OUT UINT16 *BootCpuCount + ) +{ + // + // Try to fetch the boot CPU count. + // + QemuFwCfgSelectItem (QemuFwCfgItemSmpCpuCount); + *BootCpuCount =3D QemuFwCfgRead16 (); + if (*BootCpuCount =3D=3D 0) { + // + // QEMU doesn't report the boot CPU count. (BootCpuCount =3D=3D 0) wil= l let + // MpInitLib count APs up to (PcdCpuMaxLogicalProcessorNumber - 1), or + // until PcdCpuApInitTimeOutInMicroSeconds elapses (whichever is reach= ed + // first). + // + DEBUG ((DEBUG_WARN, "%a: boot CPU count unavailable\n", __FUNCTION__)); + *MaxCpuCount =3D DefaultMaxCpuCount; + } else { + // + // We will expose BootCpuCount to MpInitLib. MpInitLib will count APs = up to + // (BootCpuCount - 1) precisely, regardless of timeout. + // + // Now try to fetch the possible CPU count. + // + UINTN CpuHpBase; + UINT32 CmdData2; + + CpuHpBase =3D ((HostBridgeDevId =3D=3D INTEL_Q35_MCH_DEVICE_ID) ? + ICH9_CPU_HOTPLUG_BASE : PIIX4_CPU_HOTPLUG_BASE); + + // + // If only legacy mode is available in the CPU hotplug register block,= or + // the register block is completely missing, then the writes below are + // no-ops. + // + // 1. Switch the hotplug register block to modern mode. + // + IoWrite32 (CpuHpBase + QEMU_CPUHP_W_CPU_SEL, 0); + // + // 2. Select a valid CPU for deterministic reading of + // QEMU_CPUHP_R_CMD_DATA2. + // + // CPU#0 is always valid; it is the always present and non-removable + // BSP. + // + IoWrite32 (CpuHpBase + QEMU_CPUHP_W_CPU_SEL, 0); + // + // 3. Send a command after which QEMU_CPUHP_R_CMD_DATA2 is specified to + // read as zero, and which does not invalidate the selector. (The + // selector may change, but it must not become invalid.) + // + // Send QEMU_CPUHP_CMD_GET_PENDING, as it will prove useful later. + // + IoWrite8 (CpuHpBase + QEMU_CPUHP_W_CMD, QEMU_CPUHP_CMD_GET_PENDING); + // + // 4. Read QEMU_CPUHP_R_CMD_DATA2. + // + // If the register block is entirely missing, then this is an unass= igned + // IO read, returning all-bits-one. + // + // If only legacy mode is available, then bit#0 stands for CPU#0 in= the + // "CPU present bitmap". CPU#0 is always present. + // + // Otherwise, QEMU_CPUHP_R_CMD_DATA2 is either still reserved (retu= rning + // all-bits-zero), or it is specified to read as zero after the abo= ve + // steps. Both cases confirm modern mode. + // + CmdData2 =3D IoRead32 (CpuHpBase + QEMU_CPUHP_R_CMD_DATA2); + DEBUG ((DEBUG_VERBOSE, "%a: CmdData2=3D0x%x\n", __FUNCTION__, CmdData2= )); + if (CmdData2 !=3D 0) { + // + // QEMU doesn't support the modern CPU hotplug interface. Assume tha= t the + // possible CPU count equals the boot CPU count (precluding hotplug). + // + DEBUG (( + DEBUG_WARN, + "%a: modern CPU hotplug interface unavailable\n", + __FUNCTION__ + )); + *MaxCpuCount =3D *BootCpuCount; + } else { + // + // Grab the possible CPU count from the modern CPU hotplug interface. + // + UINT32 Present, Possible, Selected; + + Present =3D 0; + Possible =3D 0; + + // + // We've sent QEMU_CPUHP_CMD_GET_PENDING last; this ensures + // QEMU_CPUHP_RW_CMD_DATA can now be read usefully. However, + // QEMU_CPUHP_CMD_GET_PENDING may have selected a CPU with actual pe= nding + // hotplug events; therefore, select CPU#0 forcibly. + // + IoWrite32 (CpuHpBase + QEMU_CPUHP_W_CPU_SEL, Possible); + + do { + UINT8 CpuStatus; + + // + // Read the status of the currently selected CPU. This will help w= ith a + // sanity check against "BootCpuCount". + // + CpuStatus =3D IoRead8 (CpuHpBase + QEMU_CPUHP_R_CPU_STAT); + if ((CpuStatus & QEMU_CPUHP_STAT_ENABLED) !=3D 0) { + ++Present; + } + + // + // Attempt to select the next CPU. + // + ++Possible; + IoWrite32 (CpuHpBase + QEMU_CPUHP_W_CPU_SEL, Possible); + // + // If the selection is successful, then the following read will re= turn + // the selector (which we know is positive at this point). Otherwi= se, + // the read will return 0. + // + Selected =3D IoRead32 (CpuHpBase + QEMU_CPUHP_RW_CMD_DATA); + ASSERT (Selected =3D=3D Possible || Selected =3D=3D 0); + } while (Selected > 0); + + // + // Sanity check: fw_cfg and the modern CPU hotplug interface should + // return the same boot CPU count. + // + if (*BootCpuCount !=3D Present) { + DEBUG (( + DEBUG_WARN, + "%a: QEMU v2.7 reset bug: BootCpuCount=3D%d " + "Present=3D%u\n", + __FUNCTION__, + *BootCpuCount, + Present + )); + // + // The handling of QemuFwCfgItemSmpCpuCount, across CPU hotplug pl= us + // platform reset (including S3), was corrected in QEMU commit + // e3cadac073a9 ("pc: fix FW_CFG_NB_CPUS to account for -device ad= ded + // CPUs", 2016-11-16), part of release v2.8.0. + // + *BootCpuCount =3D (UINT16)Present; + } + + *MaxCpuCount =3D Possible; + } + } + + DEBUG (( + DEBUG_INFO, + "%a: BootCpuCount=3D%d MaxCpuCount=3D%u\n", + __FUNCTION__, + *BootCpuCount, + *MaxCpuCount + )); + ASSERT (*BootCpuCount <=3D *MaxCpuCount); +} + +/** + * Query Host Bridge Dev Id. + * + * @return Host Bridge Dev Id. + */ +UINT16 +EFIAPI +PlatformQueryHostBridgeDid ( + VOID + ) +{ + return PciRead16 (OVMF_HOSTBRIDGE_DID); +} diff --git a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf b/OvmfPkg/= Library/PlatformInitLib/PlatformInitLib.inf index 6ba1e59246d1..a42b54805ba6 100644 --- a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf +++ b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf @@ -28,6 +28,7 @@ Platform.c =20 [Packages] + EmbeddedPkg/EmbeddedPkg.dec MdeModulePkg/MdeModulePkg.dec MdePkg/MdePkg.dec OvmfPkg/OvmfPkg.dec @@ -42,6 +43,7 @@ QemuFwCfgSimpleParserLib MtrrLib PcdLib + PciLib =20 [FixedPcd] gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress @@ -50,5 +52,32 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize =20 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidSize + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsSize + + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize + + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize + + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize + + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress + [FeaturePcd] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode --=20 2.29.2.windows.2 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#86786): https://edk2.groups.io/g/devel/message/86786 Mute This Topic: https://groups.io/mt/89252051/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-