QemuOpenBoardPkg adds a MinPlatform port to QEMU x86_64. This port brings a starting place for understanding the MinPlatform, and board porting.
This patch adds the base for QemuOpenBoardPkg. It also enables MinPlatform stage 1 (debug) functionality which includes serial debug messages. Cc: Leif Lindholm <quic_llind...@quicinc.com> Cc: Michael D Kinney <michael.d.kin...@intel.com> Cc: Isaac Oram <isaac.w.o...@intel.com> Cc: Pedro Falcato <pedro.falc...@gmail.com> Cc: Gerd Hoffmann <kra...@redhat.com> Cc: Stefan Hajnoczi <stefa...@gmail.com> Signed-off-by: Theo Jehl <theojeh...@gmail.com> --- .../QemuOpenBoardPkg/QemuOpenBoardPkg.dec | 33 ++ .../Include/Dsc/Stage1.dsc.inc | 55 ++++ .../QemuOpenBoardPkg/QemuOpenBoardPkg.dsc | 157 ++++++++++ .../QemuOpenBoardPkg/QemuOpenBoardPkg.fdf | 203 +++++++++++++ .../Library/BoardInitLib/BoardInitLib.inf | 29 ++ .../Library/PeiReportFvLib/PeiReportFvLib.inf | 63 ++++ .../Library/PlatformSecLib/PlatformSecLib.inf | 49 +++ .../QemuOpenFwCfgLib/QemuOpenFwCfgLib.inf | 23 ++ .../PlatformInitPei/PlatformInitPei.inf | 59 ++++ .../Include/Library/QemuOpenFwCfgLib.h | 105 +++++++ .../PlatformInitPei/PlatformInit.h | 59 ++++ .../Library/BoardInitLib/BoardInitLib.c | 231 ++++++++++++++ .../Library/PeiReportFvLib/PeiReportFvLib.c | 285 ++++++++++++++++++ .../Library/PlatformSecLib/PlatformSecLib.c | 140 +++++++++ .../QemuOpenFwCfgLib/QemuOpenFwCfgLib.c | 136 +++++++++ .../QemuOpenBoardPkg/PlatformInitPei/Cpu.c | 64 ++++ .../QemuOpenBoardPkg/PlatformInitPei/Memory.c | 254 ++++++++++++++++ .../QemuOpenBoardPkg/PlatformInitPei/Pci.c | 70 +++++ .../QemuOpenBoardPkg/PlatformInitPei/Pcie.c | 106 +++++++ .../PlatformInitPei/PlatformInit.c | 75 +++++ .../Include/Fdf/FlashMap.fdf.inc | 94 ++++++ .../Library/PlatformSecLib/Ia32/SecEntry.nasm | 117 +++++++ Platform/Qemu/QemuOpenBoardPkg/README.md | 53 ++++ 23 files changed, 2460 insertions(+) create mode 100644 Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dec create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage1.dsc.inc create mode 100644 Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dsc create mode 100644 Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.fdf create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.inf create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.inf create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgLib.inf create mode 100644 Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInitPei.inf create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Include/Library/QemuOpenFwCfgLib.h create mode 100644 Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.h create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.c create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.c create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgLib.c create mode 100644 Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Cpu.c create mode 100644 Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Memory.c create mode 100644 Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pci.c create mode 100644 Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pcie.c create mode 100644 Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.c create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Include/Fdf/FlashMap.fdf.inc create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/Ia32/SecEntry.nasm create mode 100644 Platform/Qemu/QemuOpenBoardPkg/README.md diff --git a/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dec b/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dec new file mode 100644 index 000000000000..aa50766172a0 --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dec @@ -0,0 +1,33 @@ +## @file QemuOpenBoardPkg.dec +# Declaration file for QemuOpenBoardPkg. +# +# This package supports a simple QEMU port implemented per the MinPlatform +# Arch specification. +# +# Copyright (c) 2022 Theo Jehl +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# @par Specification Reference: +# -https://tianocore-docs.github.io/edk2-MinimumPlatformSpecification/draft/ 0.7 +## + +[Defines] + DEC_SPECIFICATION = 0x00010005 + PACKAGE_NAME = QemuOpenBoardPkg + PACKAGE_GUID = 3487DE0A-6770-48A2-9833-FB426A42D7B2 + PACKAGE_VERSION = 0.1 + +[LibraryClasses] + QemuOpenFwCfgLib|Include/Library/QemuOpenFwCfgLib.h + +[Includes] + Include + +[Guids] + gQemuOpenBoardPkgTokenSpaceGuid = { 0x221b20c4, 0xa3dc, 0x4b8f, { 0xb6, 0x94, 0x03, 0xc7, 0xf4, 0x76, 0x51, 0x2b } } + +[PcdsFixedAtBuild] + gQemuOpenBoardPkgTokenSpaceGuid.PcdTemporaryRamBase|0|UINT32|0x00000001 + gQemuOpenBoardPkgTokenSpaceGuid.PcdTemporaryRamSize|0|UINT32|0x00000002 + gQemuOpenBoardPkgTokenSpaceGuid.PcdDebugIoPort|0|UINT16|0x00000003 + gQemuOpenBoardPkgTokenSpaceGuid.PcdFdVarBlockSize|0|UINT16|0x00000004 diff --git a/Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage1.dsc.inc b/Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage1.dsc.inc new file mode 100644 index 000000000000..114c4e8193b2 --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage1.dsc.inc @@ -0,0 +1,55 @@ +## @file +# Common DSC content to begin Stage 1 enabling +# +# @copyright +# Copyright (C) 2022 Intel Corporation +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +################################################################################ +# +# Library Class section - list of all Library Classes needed by this Platform. +# +################################################################################ + +[LibraryClasses] + PciSegmentInfoLib | MinPlatformPkg/Pci/Library/PciSegmentInfoLibSimple/PciSegmentInfoLibSimple.inf + BoardInitLib | QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.inf + SetCacheMtrrLib | MinPlatformPkg/Library/SetCacheMtrrLib/SetCacheMtrrLib.inf + ReportCpuHobLib | MinPlatformPkg/PlatformInit/Library/ReportCpuHobLib/ReportCpuHobLib.inf + SiliconPolicyInitLib | MinPlatformPkg/PlatformInit/Library/SiliconPolicyInitLibNull/SiliconPolicyInitLibNull.inf + SiliconPolicyUpdateLib | MinPlatformPkg/PlatformInit/Library/SiliconPolicyUpdateLibNull/SiliconPolicyUpdateLibNull.inf + ReportFvLib | QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf + PciLib | MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf + +[LibraryClasses.Common.SEC] + TestPointCheckLib | MinPlatformPkg/Test/Library/TestPointCheckLib/SecTestPointCheckLib.inf + TimerLib | MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf + +[LibraryClasses.Common.PEI_CORE, LibraryClasses.Common.PEIM] + TestPointCheckLib | MinPlatformPkg/Test/Library/TestPointCheckLib/PeiTestPointCheckLib.inf + TestPointLib | MinPlatformPkg/Test/Library/TestPointLib/PeiTestPointLib.inf + TimerLib | MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf + +[Components.$(PEI_ARCH)] + UefiCpuPkg/SecCore/SecCore.inf + MdeModulePkg/Core/Pei/PeiMain.inf + MdeModulePkg/Universal/Variable/Pei/VariablePei.inf + UefiCpuPkg/CpuIoPei/CpuIoPei.inf + MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.inf + MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf + MdeModulePkg/Universal/PCD/Pei/Pcd.inf { + <LibraryClasses> + PcdLib | MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + } + MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf + MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf + MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPreMem.inf + MinPlatformPkg/PlatformInit/ReportFv/ReportFvPei.inf + MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMem.inf + MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf + QemuOpenBoardPkg/PlatformInitPei/PlatformInitPei.inf + !if $(SMM_REQUIRED) == TRUE + OvmfPkg/SmmAccess/SmmAccessPei.inf + !endif diff --git a/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dsc b/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dsc new file mode 100644 index 000000000000..fc36b9d45ab2 --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dsc @@ -0,0 +1,157 @@ +## @file +# QemuOpenBoardPkg.dsc +# +# Description file for QemuOpenBoardPkg +# +# Copyright (c) 2022 Theo Jehl +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + DSC_SPECIFICATION = 0x0001001C + PLATFORM_GUID = 94797875-D562-40CF-8D55-ADD623C8D46C + PLATFORM_NAME = QemuOpenBoardPkg + PLATFORM_VERSION = 0.1 + SUPPORTED_ARCHITECTURES = IA32 | X64 + FLASH_DEFINITION = $(PLATFORM_NAME)/$(PLATFORM_NAME).fdf + OUTPUT_DIRECTORY = Build/$(PLATFORM_NAME) + BUILD_TARGETS = DEBUG | RELEASE | NOOPT + SKUID_IDENTIFIER = ALL + SMM_REQUIRED = FALSE + +!ifndef $(PEI_ARCH) + !error "PEI_ARCH must be specified to build this feature!" +!endif +!ifndef $(DXE_ARCH) + !error "DXE_ARCH must be specified to build this feature!" +!endif + +[SkuIds] + 0 | DEFAULT + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + MinPlatformPkg/MinPlatformPkg.dec + QemuOpenBoardPkg/QemuOpenBoardPkg.dec + UefiCpuPkg/UefiCpuPkg.dec + OvmfPkg/OvmfPkg.dec + +[PcdsFixedAtBuild] + ###################################### + # Key Boot Stage and FSP configuration + ###################################### + # + # Please select the Boot Stage here. + # Stage 1 - enable debug (system deadloop after debug init) + # Stage 2 - mem init (system deadloop after mem init) + # Stage 3 - boot to shell only + # Stage 4 - boot to OS + # Stage 5 - boot to OS with security boot enabled + # Stage 6 - boot with advanced features enabled + # + gMinPlatformPkgTokenSpaceGuid.PcdBootStage | 1 + +# +# MinPlatform common include for required feature PCD +# These PCD must be set before the core include files, CoreCommonLib, +# CorePeiLib, and CoreDxeLib. +# Optional MinPlatformPkg features should be enabled after this +# +!include MinPlatformPkg/Include/Dsc/MinPlatformFeaturesPcd.dsc.inc + +# +# Commonly used MinPlatform feature configuration logic that maps functionity to stage +# +!include BoardModulePkg/Include/Dsc/CommonStageConfig.dsc.inc + +[PcdsFixedAtBuild] + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel | 0x802A00C7 + gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel | 0x802A00C7 + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask | 0x17 + + # QEMU "memory" is functional even in SEC. For simplicity, we just use that + # "memory" for the temporary RAM + gQemuOpenBoardPkgTokenSpaceGuid.PcdTemporaryRamBase | 0x1000000 + gQemuOpenBoardPkgTokenSpaceGuid.PcdTemporaryRamSize | 0x010000 + + gQemuOpenBoardPkgTokenSpaceGuid.PcdDebugIoPort | 0x402 + gEfiMdePkgTokenSpaceGuid.PcdFSBClock | 100000000 + + # PCIe base address for Q35 machines + # QEMU usable memory below 4G cannot exceed 2.8Gb + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress | 0xB0000000 + + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable | TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange | FALSE + + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMBase | 0x00000000 # Will be updated by build + +[PcdsFeatureFlag] + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress | TRUE + + !if $(DXE_ARCH) == X64 + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode | TRUE + !else + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode | FALSE + !endif + + gMinPlatformPkgTokenSpaceGuid.PcdSerialTerminalEnable | TRUE + + !if $(SMM_REQUIRED) == TRUE + gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire | FALSE + gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugSupport | FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache | FALSE + !endif + +[PcdsDynamicDefault] + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId | 0 + + # Video setup + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution | 640 + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution | 480 + + gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion | 0x0208 + gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev | 0x0 + + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut | 3 + + gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber | 0 + gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber | 0 + + !if $(SMM_REQUIRED) == TRUE + gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes | 8 + gUefiOvmfPkgTokenSpaceGuid.PcdQ35SmramAtDefaultSmbase | FALSE + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode | 0x01 + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout | 100000 + !endif + +# Include Common libraries and then stage specific libraries and components +!include MinPlatformPkg/Include/Dsc/CoreCommonLib.dsc +!include MinPlatformPkg/Include/Dsc/CorePeiLib.dsc +!include MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc +!include QemuOpenBoardPkg/Include/Dsc/Stage1.dsc.inc + +[LibraryClasses.Common] + QemuOpenFwCfgLib | QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgLib.inf + PlatformHookLib | MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf + PlatformSecLib | QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.inf + DebugLib | MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf + PciCf8Lib | MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf + TimerLib | OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf + +[LibraryClasses.Common.DXE_CORE] + TimerLib | OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf + +[LibraryClasses.Common.DXE_DRIVER, LibraryClasses.Common.DXE_RUNTIME_DRIVER, LibraryClasses.Common.DXE_SMM_DRIVER, LibraryClasses.Common.UEFI_DRIVER, LibraryClasses.Common.UEFI_APPLICATION, LibraryClasses.Common.SMM_CORE] + TimerLib | OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf + QemuFwCfgLib | OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf + MemEncryptSevLib | OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf + MemEncryptTdxLib | OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLibNull.inf + Tcg2PhysicalPresenceLib | OvmfPkg/Library/Tcg2PhysicalPresenceLibNull/DxeTcg2PhysicalPresenceLib.inf + ResetSystemLib | OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf + +[LibraryClasses.Common.SEC] + DebugLib | OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf + +[Components.$(DXE_ARCH)] diff --git a/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.fdf b/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.fdf new file mode 100644 index 000000000000..0bfad51cb32e --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.fdf @@ -0,0 +1,203 @@ +## @file +# QemuOpenBoardPkg.fdf +# +# Copyright (c) 2022 Theo Jehl +# SPDX-License-Identifier: BSD-2-Clause-Patent + +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress = 0xFF800000 +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize = 0x800000 + +!include QemuOpenBoardPkg/Include/Fdf/FlashMap.fdf.inc + +[FD.QemuOpenBoardPkgVars] + BaseAddress = 0xFF800000 + Size = 0x80000 + ErasePolarity = 1 + BlockSize = 0x800|gQemuOpenBoardPkgTokenSpaceGuid.PcdFdVarBlockSize + NumBlocks = 0x100 + + # + # Do not modify this block + # These three areas are tightly coupled and should be modified with utmost care. + # The total size must match the size in the EFI_FIRMWARE_VOLUME_HEADER in NvStorage512K.fdf. + # The NvStorageVariableSize must also match the VARIABLE_STORE_HEADER size in NvStorage512K.fdf. + # The EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER in CommonNvStorageFtwWorking.fdf doesn't have size info. + # + gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageVariableOffset | gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + !include WhitleyOpenBoardPkg/Include/Fdf/NvStorage512K.fdf + gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingOffset | gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + !include WhitleyOpenBoardPkg/Include/Fdf/CommonNvStorageFtwWorking.fdf + gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareOffset | gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + DATA = { 0xFF } # Hack to ensure build doesn't treat the next PCD as Base/Size to be written + +[FD.QemuOpenBoardPkg] + BaseAddress = 0xFF880000 + Size = 0x780000 + ErasePolarity = 1 + BlockSize = 0x1000 + NumBlocks = 0x780 + + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize + FV = FvAdvanced + + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize + FV = FvSecurity + + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize + FV = FvOsBoot + + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize + FV = FvUefiBoot + + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspSize + FV = FvBsp + + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize + FV = FvPostMemory + + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize + FV = FvFspS + + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize + FV = FvFspM + + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize + FV = FvFspT + + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemoryOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemorySize + FV = FvBspPreMemory + + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemorySize + FV = FvPreMemory + +########################### +# +# Stage 1 Firmware Volumes +# +########################### + +[FV.FvPreMemory] + !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf + FvNameGuid = BD479C6B-2EFF-401F-A7F1-566347B41D07 + + FILE FV_IMAGE = 618FBA00-2231-41F6-9931-25A89DF501D3 { + SECTION FV_IMAGE = FvSecurityPreMemory + } + + INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf + + INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf + INF MinPlatformPkg/PlatformInit/ReportFv/ReportFvPei.inf + + INF MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf + INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf + + INF UefiCpuPkg/SecCore/SecCore.inf + +[FV.FvSecurityPreMemory] + !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf + FvNameGuid = F626B0FB-D759-44A8-B131-42408BB3533D + +[FV.FvBspPreMemory] + !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf + FvNameGuid = 5CF9C072-385F-44FC-B21B-002074251C08 + + INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf + INF MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPreMem.inf + INF QemuOpenBoardPkg/PlatformInitPei/PlatformInitPei.inf + + FILE FV_IMAGE = 90B948EA-FF73-4689-B90A-A54F86C1FC01 { + SECTION FV_IMAGE = FvAdvancedPreMemory + } + +[FV.FvAdvancedPreMemory] + !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf + FvNameGuid = 43528CE0-812B-4074-B77E-C49E7A2F4FE1 + +[FV.FvFspT] + !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf + FvNameGuid = 958CAF39-0B6C-40F1-B190-EC91C536CFF9 + +[FV.FvFspM] + !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf + FvNameGuid = 03982cf7-246a-4356-b6ba-436a2251595c + + INF MdeModulePkg/Core/Pei/PeiMain.inf + + FILE FV_IMAGE = 83B39C64-BFB9-42EC-A7A3-527854A5C4C3 { + SECTION FV_IMAGE = FvPreMemorySilicon + } + +[FV.FvPreMemorySilicon] + !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf + FvNameGuid = F0205C0E-0AD1-499C-A5F9-96BAF98248A0 + + INF MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMem.inf + + !if $(SMM_REQUIRED) == TRUE + INF OvmfPkg/SmmAccess/SmmAccessPei.inf + !endif + +[FV.FvFspS] + !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf + FvNameGuid = C6786443-AFCA-471B-A8FC-E8C330708F99 + +[FV.FvPostMemorySilicon] + !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf + FvNameGuid = EF76DFDC-2B7D-423D-BFE4-8FD4BB22E770 + +########################### +# +# Stage 2 Firmware Volumes +# +########################### +[FV.FvPostMemory] + !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf + FvNameGuid = 5A1D6978-BABE-42F9-A629-F7B3B6A1E1BD + +[FV.FvBsp] + !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf + FvNameGuid = FCA0BC4A-994D-4EF9-BD56-A8C45872C2A8 + +########################### +# +# Stage 3 Firmware Volumes +# +########################### +[FV.FvUefiBoot] + !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf + FvNameGuid = D0C15ADB-FE38-4331-841C-0E96C1B0FBFA + +########################### +# +# Stage 4 Firmware Volumes +# +########################### +[FV.FvOsBoot] + !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf + FvNameGuid = AE8F0EA0-1614-422D-ABC1-C518596F1678 + +########################### +# +# Stage 5 Firmware Volumes +# +########################### +[FV.FvSecurity] + !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf + FvNameGuid = 1AE6AB90-9431-425B-9A92-ED2708A4E982 + +########################### +# +# Stage 6 Firmware Volumes +# +########################### +[FV.FvAdvanced] + !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf + FvNameGuid = 936D6D65-CB6C-4B87-A51C-70D56511CB55 + +########################### +# +# File Construction Rules +# +########################### +!include MinPlatformPkg/Include/Fdf/RuleInclude.fdf diff --git a/Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.inf b/Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.inf new file mode 100644 index 000000000000..8f75d1277070 --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.inf @@ -0,0 +1,29 @@ +## @file +# QemuOpenBoardPkg BoardInitLib instance +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BoardInitLib + FILE_GUID = 70EE7BD9-08FF-4D0E-AA7B-4320844F939A + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = BoardInitLib + +[Sources] + BoardInitLib.c + +[Packages] + QemuOpenBoardPkg/QemuOpenBoardPkg.dec + MdePkg/MdePkg.dec + MinPlatformPkg/MinPlatformPkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + DebugLib + PcdLib + IoLib + PciCf8Lib diff --git a/Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf b/Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf new file mode 100644 index 000000000000..d416f1c64061 --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf @@ -0,0 +1,63 @@ +### @file +# Component information file for the Report Firmware Volume (FV) library. +# +# Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +### + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = PeiReportFvLib + FILE_GUID = 44328FA5-E4DD-4A15-ABDF-C6584AC363D9 + VERSION_STRING = 1.0 + MODULE_TYPE = PEIM + LIBRARY_CLASS = ReportFvLib + +[LibraryClasses] + BaseMemoryLib + DebugLib + HobLib + PeiServicesLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + MinPlatformPkg/MinPlatformPkg.dec + QemuOpenBoardPkg/QemuOpenBoardPkg.dec + +[Sources] + PeiReportFvLib.c + +[Pcd] + gMinPlatformPkgTokenSpaceGuid.PcdBootStage ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFspWrapperBootMode ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryBase ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemorySize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTBase ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMBase ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSBase ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryBase ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootBase ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootBase ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityBase ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedPreMemoryBase ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedPreMemorySize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedBase ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemorySize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemoryBase ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemoryOffset ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspSize ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspBase ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspOffset ## CONSUMES diff --git a/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.inf b/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.inf new file mode 100644 index 000000000000..d838ad2b0e9d --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.inf @@ -0,0 +1,49 @@ +## @file +# PlatformSecLib for QEMU OpenBoardPkg +# +# Copyright (c) 2022 Theo Jehl +# SPDX-License-Identifier: BSD-2-Clause-Patent + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PlatformSecLib + FILE_GUID = 37b1bddc-5a53-4f2a-af7d-b78d5e80dcbd + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + LIBRARY_CLASS = PlatformSecLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[Sources.IA32] + Ia32/SecEntry.nasm + +[Sources] + PlatformSecLib.c + +[LibraryClasses] + DebugLib + BaseLib + BaseMemoryLib + PciLib + PcdLib + HobLib + MtrrLib + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + QemuOpenBoardPkg/QemuOpenBoardPkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + MinPlatformPkg/MinPlatformPkg.dec + +[Ppis] + gTopOfTemporaryRamPpiGuid + +[Pcd] + gQemuOpenBoardPkgTokenSpaceGuid.PcdTemporaryRamBase + gQemuOpenBoardPkgTokenSpaceGuid.PcdTemporaryRamSize + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMBase diff --git a/Platform/Qemu/QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgLib.inf b/Platform/Qemu/QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgLib.inf new file mode 100644 index 000000000000..195191bd7e2c --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgLib.inf @@ -0,0 +1,23 @@ +## @file +# QemuOpenFwCfgLib.inf +# +# Simple implementation of the QemuFwCfgLib that reads data from the QEMU +# FW_CFG device +# +# Copyright (c) 2022 Theo Jehl +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = QemuFwCfgLib + FILE_GUID = 70EE7BD9-08FF-4D0E-AA7B-4320844F939A + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = QemuOpenFwCfgLib + +[Sources] + QemuOpenFwCfgLib.c + +[LibraryClasses] + IoLib diff --git a/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInitPei.inf b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInitPei.inf new file mode 100644 index 000000000000..43b1e13adfeb --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInitPei.inf @@ -0,0 +1,59 @@ +## @file +# PlatformInitPei +# +# Simple PEIM for QEMU PIIX4/Q35 Memory, SMP and PCI/PCI Express initialization +# +# Copyright (c) 2022 Theo Jehl +# SPDX-License-Identifier: BSD-2-Clause-Patent + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PlatformInitPei + FILE_GUID = 82d851fe-3106-4175-8b6c-87fda1f2d0ac + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = PlatformInit + +[Packages] + OvmfPkg/OvmfPkg.dec + MdePkg/MdePkg.dec + QemuOpenBoardPkg/QemuOpenBoardPkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[Sources] + PlatformInit.h + PlatformInit.c + Memory.c + Pcie.c + Pci.c + Cpu.c + +[LibraryClasses] + PeimEntryPoint + QemuOpenFwCfgLib + HobLib + PcdLib + PciLib + +[Guids] + gUefiOvmfPkgPlatformInfoGuid + +[Pcd] + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress + gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber + gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber + gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase + gUefiOvmfPkgTokenSpaceGuid.PcdPciIoSize + gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Base + gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Size + gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Base + gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress + gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes + +[FeaturePcd] + gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire + +[Depex] + TRUE diff --git a/Platform/Qemu/QemuOpenBoardPkg/Include/Library/QemuOpenFwCfgLib.h b/Platform/Qemu/QemuOpenBoardPkg/Include/Library/QemuOpenFwCfgLib.h new file mode 100644 index 000000000000..8e5f8ccf70e2 --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/Include/Library/QemuOpenFwCfgLib.h @@ -0,0 +1,105 @@ +/** @file QemuOpenFwCfgLib.h + QemuOpenFwCfgLib Headers + + Implements a minimal library to interact with Qemu FW CFG device + + QEMU FW CFG device allow the OS to retrieve files passed by QEMU or the user. + Files can vary from E820 entries to ACPI tables. + + Copyright (c) 2022 Theo Jehl All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + + +#ifndef QEMU_OPEN_BOARD_PKG_QEMU_FW_CFG_LIB_H_ +#define QEMU_OPEN_BOARD_PKG_QEMU_FW_CFG_LIB_H_ + +#include <PiPei.h> +#include <Library/IoLib.h> + +// QEMU fw_cfg registers +#define FW_CFG_PORT_SEL 0x510 +#define FW_CFG_PORT_DATA 0x511 +#define FW_CFG_PORT_DMA 0x514 + +// QEMU Selectors +#define FW_CFG_SIGNATURE 0x0000 +#define FW_CFG_ID 0x0001 +#define FW_CFG_FILE_DIR 0x0019 + +#define FW_CFG_QEMU_SIGNATURE SIGNATURE_32('Q', 'E', 'M', 'U') + +typedef struct { + UINT32 Size; + UINT16 Select; + UINT16 Reserved; + CHAR8 Name[56]; +} QEMU_FW_CFG_FILE; + +/** + Checks for Qemu fw_cfg device by reading "QEMU" using the signature selector + + @return EFI_SUCCESS - The fw_cfg device is present + @return EFI_UNSUPPORTED - The device is absent + */ +EFI_STATUS +EFIAPI +QemuFwCfgIsPresent ( + VOID + ); + +/** + Sets the selector register to the specified value + + @param[in] Selector + + @return EFI_SUCCESS + @return EFI_UNSUPPORTED + */ +EFI_STATUS +EFIAPI +QemuFwCfgSelectItem ( + IN UINT16 Selector + ); + +/** + Reads 8 bits from the data register + + @return UINT8 + */ +UINT8 +EFIAPI +QemuFwCfgRead8 ( + VOID + ); + +/** + Reads N bytes from the data register + + @param Size + @param Buffer + */ +VOID +EFIAPI +QemuFwCfgReadBytes ( + IN UINTN Size, + OUT VOID *Buffer + ); + +/** + Finds a file in fw_cfg by its name + + @param[in] String Pointer to an ASCII string to match in the database + @param[out] FWConfigFile Buffer for the config file + + @return EFI_STATUS Entry was found, FWConfigFile is populated + @return EFI_ERROR Entry was not found + */ +EFI_STATUS +EFIAPI +QemuFwCfgFindFile ( + IN CHAR8 *String, + OUT QEMU_FW_CFG_FILE *FWConfigFile + ); + +#endif // QEMU_OPEN_BOARD_PKG_QEMU_FW_CFG_LIB_H_ diff --git a/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.h b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.h new file mode 100644 index 000000000000..771d2f958c40 --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.h @@ -0,0 +1,59 @@ +/** @file PlatformInit.h + Headers for PlatformInitPei PEIM + + Copyright (c) 2022 Theo Jehl All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef QEMU_OPEN_BOARD_PKG_PLATFORM_INIT_H_ +#define QEMU_OPEN_BOARD_PKG_PLATFORM_INIT_H_ + +#include <PiPei.h> +#include <Uefi.h> + +#define PIIX4_PCI_IO_BASE 0xC000 +#define PIIX4_PCI_IO_SIZE 0x4000 + +#define Q35_PCI_IO_BASE 0x6000 +#define Q35_PCI_IO_SIZE 0xA000 + +#define PCI_MMIO_TOP_ADDRESS 0xFC000000 + +EFI_STATUS +EFIAPI +PlatformInit ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +UINT32 +EFIAPI +GetMemoryBelow4Gb ( + VOID + ); + +EFI_STATUS +EFIAPI +InstallMemory ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +EFI_STATUS +EFIAPI +InitializePcie ( + VOID + ); + +EFI_STATUS +EFIAPI +InitializePciPIIX4 ( + VOID + ); + +EFI_STATUS +EFIAPI +MaxCpuInit ( + VOID + ); + +#endif //QEMU_OPEN_BOARD_PKG_PLATFORM_INIT_H_ diff --git a/Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.c b/Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.c new file mode 100644 index 000000000000..7dedd4a2a561 --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.c @@ -0,0 +1,231 @@ +/** @file + Board initialization library + + Copyright (c) 2022 Theo Jehl All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Library/BoardInitLib.h> +#include <Uefi.h> +#include <Library/IoLib.h> +#include <Library/PcdLib.h> +#include <Library/DebugLib.h> +#include <Library/PciCf8Lib.h> +#include <IndustryStandard/Pci.h> +#include <IndustryStandard/I440FxPiix4.h> +#include <IndustryStandard/Q35MchIch9.h> +#include <Library/HobLib.h> + +#define QEMU_IO_DEBUG_MAGIC 0xE9 + +/** + This board service detects the board type. + + @retval EFI_SUCCESS The board was detected successfully. + @retval EFI_NOT_FOUND The board could not be detected. +**/ +EFI_STATUS +EFIAPI +BoardDetect ( + VOID + ) +{ + UINT16 DeviceID, VendorID; + + DEBUG ((DEBUG_INFO, "BoardDetect()\n")); + + // + // Retrieve chipset device ID and vendor ID + // + DeviceID = PciCf8Read16 (PCI_CF8_LIB_ADDRESS (0, 0, 0, PCI_DEVICE_ID_OFFSET)); + VendorID = PciCf8Read16 (PCI_CF8_LIB_ADDRESS (0, 0, 0, PCI_VENDOR_ID_OFFSET)); + + // + // Qemu can emulate 2 chipsets: + // Intel 440FX with PIIX4 southbridge + // Intel Q35 memory host controller with ICH9 southbridge + // + + switch (DeviceID) { + case INTEL_82441_DEVICE_ID: + DEBUG ((DEBUG_INFO, "Intel 440FX/PIIX4 platform detected!\n")); + return EFI_SUCCESS; + + case INTEL_Q35_MCH_DEVICE_ID: + DEBUG ((DEBUG_INFO, "Intel Q35 MCH/ICH9 platform detected!\n")); + return EFI_SUCCESS; + + default: + DEBUG ((DEBUG_ERROR, "Unable to detect board (Device id %u Vendor ID %u)\n", DeviceID, VendorID)); + return EFI_NOT_FOUND; + } +} + +/** + This board service initializes board-specific debug devices. + + @retval EFI_SUCCESS Board-specific debug initialization was successful. + @retval EFI_NOT_READY The board has not been detected yet. +**/ +EFI_STATUS +EFIAPI +BoardDebugInit ( + VOID + ) +{ + return EFI_SUCCESS; +} + +EFI_BOOT_MODE +EFIAPI +BoardBootModeDetect ( + VOID + ) +{ + DEBUG ((DEBUG_INFO, "BoardBootModeDetect()\n")); + return BOOT_WITH_FULL_CONFIGURATION; +} + +/** + A hook for board-specific initialization prior to memory initialization. + + @retval EFI_SUCCESS The board initialization was successful. + @retval EFI_NOT_READY The board has not been detected yet. +**/ +EFI_STATUS +EFIAPI +BoardInitBeforeMemoryInit ( + VOID + ) +{ + DEBUG ((DEBUG_INFO, "BoardInitBeforeMemoryInit()\n")); + return EFI_SUCCESS; +} + +/** + A hook for board-specific initialization after memory initialization. + + @retval EFI_SUCCESS The board initialization was successful. + @retval EFI_NOT_READY The board has not been detected yet. +**/ +EFI_STATUS +EFIAPI +BoardInitAfterMemoryInit ( + VOID + ) +{ + DEBUG ((DEBUG_INFO, "BoardInitAfterMemoryInit()\n")); + return EFI_SUCCESS; +} + +/** + A hook for board-specific initialization prior to disabling temporary RAM. + + @retval EFI_SUCCESS The board initialization was successful. + @retval EFI_NOT_READY The board has not been detected yet. +**/ +EFI_STATUS +EFIAPI +BoardInitBeforeTempRamExit ( + VOID + ) +{ + DEBUG ((DEBUG_INFO, "BoardInitBeforeTempRamExit()\n")); + return EFI_SUCCESS; +} + +/** + A hook for board-specific initialization after disabling temporary RAM. + + @retval EFI_SUCCESS The board initialization was successful. + @retval EFI_NOT_READY The board has not been detected yet. +**/ +EFI_STATUS +EFIAPI +BoardInitAfterTempRamExit ( + VOID + ) +{ + DEBUG ((DEBUG_INFO, "BoardInitAfterTempRamExit()\n")); + return EFI_SUCCESS; +} + +/** + A hook for board-specific initialization prior to silicon initialization. + + @retval EFI_SUCCESS The board initialization was successful. + @retval EFI_NOT_READY The board has not been detected yet. +**/ +EFI_STATUS +EFIAPI +BoardInitBeforeSiliconInit ( + VOID + ) +{ + DEBUG ((DEBUG_INFO, "BoardInitBeforeSiliconInit()\n")); + return EFI_SUCCESS; +} + +/** + A hook for board-specific initialization after silicon initialization. + + @retval EFI_SUCCESS The board initialization was successful. + @retval EFI_NOT_READY The board has not been detected yet. +**/ +EFI_STATUS +EFIAPI +BoardInitAfterSiliconInit ( + VOID + ) +{ + DEBUG ((DEBUG_INFO, "BoardInitAfterSiliconInit()\n")); + return EFI_SUCCESS; +} + +/** + A hook for board-specific initialization after PCI enumeration. + + @retval EFI_SUCCESS The board initialization was successful. + @retval EFI_NOT_READY The board has not been detected yet. +**/ +EFI_STATUS +EFIAPI +BoardInitAfterPciEnumeration ( + VOID + ) +{ + DEBUG ((DEBUG_INFO, "BoardInitAfterPciEnumeration()\n")); + return EFI_SUCCESS; +} + +/** + A hook for board-specific functionality for the ReadyToBoot event. + + @retval EFI_SUCCESS The board initialization was successful. + @retval EFI_NOT_READY The board has not been detected yet. +**/ +EFI_STATUS +EFIAPI +BoardInitReadyToBoot ( + VOID + ) +{ + DEBUG ((DEBUG_INFO, "BoardInitReadyToBoot()\n")); + return EFI_SUCCESS; +} + +/** + A hook for board-specific functionality for the ExitBootServices event. + + @retval EFI_SUCCESS The board initialization was successful. + @retval EFI_NOT_READY The board has not been detected yet. +**/ +EFI_STATUS +EFIAPI +BoardInitEndOfFirmware ( + VOID + ) +{ + DEBUG ((DEBUG_INFO, "BoardInitEndOfFirmware()\n")); + return EFI_SUCCESS; +} diff --git a/Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c b/Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c new file mode 100644 index 000000000000..809e69ce4381 --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c @@ -0,0 +1,285 @@ +/** @file PeiReportFvLib.c + Source code file for Report Firmware Volume (FV) library + + Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Base.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/HobLib.h> +#include <Library/PeiServicesLib.h> +#include <Library/ReportFvLib.h> +#include <Guid/FirmwareFileSystem2.h> +#include <Ppi/FirmwareVolumeInfo2.h> + +// Use a FV pointer PCD to get a pointer to the FileSystemGuid in the FV header +#define PCD_TO_FV_HEADER_FILE_SYSTEM_GUID(Pcd) (&((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN) PcdGet32 (Pcd))->FileSystemGuid) + +/** + Reports FVs necessary for MinPlarform pre-memory initialization + */ +VOID +ReportPreMemFv ( + VOID + ) +{ + UINTN Index = 0; + EFI_PEI_PPI_DESCRIPTOR *Descriptor = NULL; + EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI *Ppi = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_FIRMWARE_VOLUME_HEADER *FvHeader = NULL; + EFI_BOOT_MODE BootMode = BOOT_WITH_FULL_CONFIGURATION; + + Status = PeiServicesGetBootMode (&BootMode); + ASSERT_EFI_ERROR (Status); + + DEBUG_CODE ( + for (Index = 0; Status == EFI_SUCCESS; Index++) { + Status = PeiServicesLocatePpi (&gEfiPeiFirmwareVolumeInfo2PpiGuid, Index, &Descriptor, (VOID**) &Ppi); + if (!EFI_ERROR (Status)) { + FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) Ppi->FvInfo; + DEBUG ((DEBUG_INFO, "Found FV at 0x%x, size 0x%x\n", FvHeader, FvHeader->FvLength)); + } + } + ); + + // + // FvBspPreMemory and FvPreMemory are required for all stages. + // + + DEBUG ((DEBUG_INFO, "Install FlashFvBspPreMemory - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvBspPreMemoryBase), PcdGet32 (PcdFlashFvBspPreMemorySize))); + PeiServicesInstallFvInfo2Ppi ( + PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvBspPreMemoryBase), + (VOID *)(UINTN)PcdGet32 (PcdFlashFvBspPreMemoryBase), + PcdGet32 (PcdFlashFvBspPreMemorySize), + NULL, + NULL, + 0 + ); + + DEBUG ((DEBUG_INFO, "Install FlashFvPreMemory - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvPreMemoryBase), PcdGet32 (PcdFlashFvPreMemorySize))); + PeiServicesInstallFvInfo2Ppi ( + PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvPreMemoryBase), + (VOID *)(UINTN)PcdGet32 (PcdFlashFvPreMemoryBase), + PcdGet32 (PcdFlashFvPreMemorySize), + NULL, + NULL, + 0 + ); + + // + // In API mode, do not publish FSP FV. + // + if (!PcdGetBool (PcdFspWrapperBootMode)) { + // + // FvFspT may be required for all stages + // + DEBUG ((DEBUG_INFO, "Install FlashFvFspT - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvFspTBase), PcdGet32 (PcdFlashFvFspTSize))); + PeiServicesInstallFvInfo2Ppi ( + PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvFspTBase), + (VOID *)(UINTN)PcdGet32 (PcdFlashFvFspTBase), + PcdGet32 (PcdFlashFvFspTSize), + NULL, + NULL, + 0 + ); + + // + // FvFspM required for stage 2 and above + // + if (PcdGet8 (PcdBootStage) >= 2) { + DEBUG ((DEBUG_INFO, "Install FlashFvFspM - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvFspMBase), PcdGet32 (PcdFlashFvFspMSize))); + PeiServicesInstallFvInfo2Ppi ( + PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvFspMBase), + (VOID *)(UINTN)PcdGet32 (PcdFlashFvFspMBase), + PcdGet32 (PcdFlashFvFspMSize), + NULL, + NULL, + 0 + ); + } + } + + // + // FvAdvanced not needed until stage 6 + // + if (PcdGet8 (PcdBootStage) >= 6) { + DEBUG ((DEBUG_INFO, "Install FlashFvAdvancedPreMemory - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvAdvancedPreMemoryBase), PcdGet32 (PcdFlashFvAdvancedPreMemorySize))); + PeiServicesInstallFvInfo2Ppi ( + PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvAdvancedPreMemoryBase), + (VOID *)(UINTN)PcdGet32 (PcdFlashFvAdvancedPreMemoryBase), + PcdGet32 (PcdFlashFvAdvancedPreMemorySize), + NULL, + NULL, + 0 + ); + } +} +/** + Reports FVs for MinPlarform post-memory initialization + This function also publish FV HOBs to ensure DXE phase is aware of those FVs + */ +VOID +ReportPostMemFv ( + VOID + ) +{ + UINTN Index = 0; + EFI_PEI_PPI_DESCRIPTOR *Descriptor = NULL; + EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI *Ppi = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_FIRMWARE_VOLUME_HEADER *FvHeader = NULL; + + DEBUG_CODE ( + for (Index = 0; Status == EFI_SUCCESS; Index++) { + Status = PeiServicesLocatePpi (&gEfiPeiFirmwareVolumeInfo2PpiGuid, Index, &Descriptor, (VOID**) &Ppi); + if (!EFI_ERROR (Status)) { + FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) Ppi->FvInfo; + DEBUG ((DEBUG_INFO, "Found FV at 0x%x, size 0x%x\n", FvHeader, FvHeader->FvLength)); + } + } + ); + + // + // FvFspS, FvPostMemory, and FvBsp may be required for completing stage 2 + // + if (PcdGet8 (PcdBootStage) >= 2) { + // + // In API mode, do not publish FSP FV. + // + if (!PcdGetBool (PcdFspWrapperBootMode)) { + DEBUG ((DEBUG_INFO, "Install FlashFvFspS - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvFspSBase), PcdGet32 (PcdFlashFvFspSSize))); + PeiServicesInstallFvInfo2Ppi ( + PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvFspSBase), + (VOID *)(UINTN)PcdGet32 (PcdFlashFvFspSBase), + PcdGet32 (PcdFlashFvFspSSize), + NULL, + NULL, + 0 + ); + } + + DEBUG ((DEBUG_INFO, "Install FlashFvPostMemory - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvPostMemoryBase), PcdGet32 (PcdFlashFvPostMemorySize))); + PeiServicesInstallFvInfo2Ppi ( + PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvPostMemoryBase), + (VOID *)(UINTN)PcdGet32 (PcdFlashFvPostMemoryBase), + PcdGet32 (PcdFlashFvPostMemorySize), + NULL, + NULL, + 0 + ); + + DEBUG ((DEBUG_INFO, "%Build FlashFvPostMemory FV Hob at %Lx \n", (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFlashFvPostMemoryBase))); + + BuildFvHob ( + (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFlashFvPostMemoryBase), + PcdGet32 (PcdFlashFvPostMemorySize) + ); + + DEBUG ((DEBUG_INFO, "Install FlashFvBsp - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvBspBase), PcdGet32 (PcdFlashFvBspSize))); + PeiServicesInstallFvInfo2Ppi ( + PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvBspBase), + (VOID *)(UINTN)PcdGet32 (PcdFlashFvBspBase), + PcdGet32 (PcdFlashFvBspSize), + NULL, + NULL, + 0 + ); + } + + // + // FvUefiBoot required for completing stage 3 + // + if (PcdGet8 (PcdBootStage) >= 3) { + DEBUG ((DEBUG_INFO, "Install FlashFvUefiBoot - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvUefiBootBase), PcdGet32 (PcdFlashFvUefiBootSize))); + PeiServicesInstallFvInfo2Ppi ( + PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvUefiBootBase), + (VOID *)(UINTN)PcdGet32 (PcdFlashFvUefiBootBase), + PcdGet32 (PcdFlashFvUefiBootSize), + NULL, + NULL, + 0 + ); + + DEBUG ((DEBUG_INFO, "%Build FlashFvUefiBoot FV Hob at %Lx \n", (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFlashFvUefiBootBase))); + + BuildFvHob ( + (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFlashFvUefiBootBase), + PcdGet32 (PcdFlashFvUefiBootSize) + ); + } + + // + // FvOsBoot required for completing stage 4 + // + if (PcdGet8 (PcdBootStage) >= 4) { + DEBUG ((DEBUG_INFO, "Install FlashFvOsBoot - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvOsBootBase), PcdGet32 (PcdFlashFvOsBootSize))); + PeiServicesInstallFvInfo2Ppi ( + PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvOsBootBase), + (VOID *)(UINTN)PcdGet32 (PcdFlashFvOsBootBase), + PcdGet32 (PcdFlashFvOsBootSize), + NULL, + NULL, + 0 + ); + + DEBUG ((DEBUG_INFO, "%Build FlashFvOsBoot FV Hob at %Lx \n", (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFlashFvUefiBootBase))); + + BuildFvHob ( + (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFlashFvOsBootBase), + PcdGet32 (PcdFlashFvOsBootSize) + ); + } + + // + // FvSecurity required for completing stage 5 + // + if (PcdGet8 (PcdBootStage) >= 5) { + DEBUG ((DEBUG_INFO, "Install FlashFvSecurity - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvSecurityBase), PcdGet32 (PcdFlashFvSecuritySize))); + PeiServicesInstallFvInfo2Ppi ( + PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvSecurityBase), + (VOID *)(UINTN)PcdGet32 (PcdFlashFvSecurityBase), + PcdGet32 (PcdFlashFvSecuritySize), + NULL, + NULL, + 0 + ); + } + + // + // FvAdvanced required for completing stage 6 + // + if (PcdGet8 (PcdBootStage) >= 6) { + DEBUG ((DEBUG_INFO, "Install FlashFvAdvanced - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvAdvancedBase), PcdGet32 (PcdFlashFvAdvancedSize))); + PeiServicesInstallFvInfo2Ppi ( + PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvAdvancedBase), + (VOID *)(UINTN)PcdGet32 (PcdFlashFvAdvancedBase), + PcdGet32 (PcdFlashFvAdvancedSize), + NULL, + NULL, + 0 + ); + } + + // + // Report resource related HOB for flash FV to reserve space in GCD and memory map + // + + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_MAPPED_IO, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + (UINTN)PcdGet32 (PcdFlashAreaBaseAddress), + (UINTN)PcdGet32 (PcdFlashAreaSize) + ); + + BuildMemoryAllocationHob ( + (UINTN)PcdGet32 (PcdFlashAreaBaseAddress), + (UINTN)PcdGet32 (PcdFlashAreaSize), + EfiMemoryMappedIO + ); +} diff --git a/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.c b/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.c new file mode 100644 index 000000000000..5d56df812c3f --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.c @@ -0,0 +1,140 @@ +/** @file + PlatformSecLib library functions + + Copyright (c) 2022 Theo Jehl All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <PiPei.h> +#include <Ppi/SecPlatformInformation.h> +#include <Ppi/TemporaryRamSupport.h> +#include <Library/PcdLib.h> +#include <Ppi/PeiCoreFvLocation.h> +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/HobLib.h> +#include <Library/MtrrLib.h> +#include <Library/PlatformSecLib.h> +#include <Library/PeiServicesLib.h> +#include <Library/IoLib.h> + +#include <Library/LocalApicLib.h> + +EFI_PEI_CORE_FV_LOCATION_PPI gEfiPeiCoreFvLocationPpi = { + (VOID *)FixedPcdGet32 (PcdFlashFvFspMBase) +}; + +STATIC EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformPpi[] = { + // + // This must be the second PPI in the list because it will be patched in SecPlatformMain (); + // + { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gTopOfTemporaryRamPpiGuid, + NULL + } +}; + +EFI_PEI_PPI_DESCRIPTOR gEfiPeiCoreFvLocationDescriptor = { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gEfiPeiCoreFvLocationPpiGuid, + &gEfiPeiCoreFvLocationPpi +}; + +EFI_PEI_PPI_DESCRIPTOR * +EFIAPI +SecPlatformMain ( + IN OUT EFI_SEC_PEI_HAND_OFF *SecCoreData + ) +{ + // Use half of available heap size for PpiList + EFI_PEI_PPI_DESCRIPTOR *PpiList; + + PpiList = (VOID *)((UINTN)SecCoreData->PeiTemporaryRamBase + (UINTN)SecCoreData->PeiTemporaryRamSize / 2); + + CopyMem (PpiList, &gEfiPeiCoreFvLocationDescriptor, sizeof (EFI_PEI_PPI_DESCRIPTOR)); + + CopyMem (&PpiList[1], &mPeiSecPlatformPpi, sizeof (EFI_PEI_PPI_DESCRIPTOR)); + + // Patch the top of RAM PPI + PpiList[1].Ppi = (VOID *)((UINTN)SecCoreData->TemporaryRamBase + SecCoreData->TemporaryRamSize); + DEBUG ((DEBUG_INFO, "SecPlatformMain(): Top of memory %p\n", PpiList[1].Ppi)); + + return PpiList; +} + +/** + This interface conveys state information out of the Security (SEC) phase into PEI. + + @param PeiServices Pointer to the PEI Services Table. + @param StructureSize Pointer to the variable describing size of the input buffer. + @param PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. + +**/ +EFI_STATUS +EFIAPI +SecPlatformInformation ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord + ) +{ + UINT32 TopOfTemporaryRam; + VOID *TopOfRamPpi; + EFI_STATUS Status; + UINT32 Count; + UINT32 *BistStart; + UINT32 Length; + + Status = (*PeiServices)->LocatePpi (PeiServices, &gTopOfTemporaryRamPpiGuid, 0, NULL, &TopOfRamPpi); + if (EFI_ERROR (Status)) { + return Status; + } + + TopOfTemporaryRam = (UINT32)TopOfRamPpi; + + DEBUG ((DEBUG_INFO, "SecPlatformInformation: Top of memory is %p\n", TopOfRamPpi)); + + Count = *(UINT32 *)(TopOfTemporaryRam - sizeof (UINT32)); + Length = Count * sizeof (UINT32); + + BistStart = (UINT32 *)(TopOfTemporaryRam - sizeof (UINT32) - Length); + + DEBUG ((DEBUG_INFO, "SecPlatformInformation: Found %u processors with BISTs starting at %p\n", Count, BistStart)); + + if (*StructureSize < Length) { + *StructureSize = Length; + return EFI_BUFFER_TOO_SMALL; + } + + CopyMem (PlatformInformationRecord, BistStart, Length); + *StructureSize = Length; + + // Mask the PIC to avoid any interruption down the line + IoWrite8 (0x21, 0xff); + IoWrite8 (0xA1, 0xff); + + DEBUG ((DEBUG_INFO, "Initialize APIC Timer \n")); + InitializeApicTimer (0, MAX_UINT32, TRUE, 5); + + DEBUG ((DEBUG_INFO, "Disable APIC Timer interrupt\n")); + DisableApicTimerInterrupt (); + + return EFI_SUCCESS; +} + +/** + This interface disables temporary memory in SEC Phase. +**/ +VOID +EFIAPI +SecPlatformDisableTemporaryMemory ( + VOID + ) +{ + return; +} diff --git a/Platform/Qemu/QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgLib.c b/Platform/Qemu/QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgLib.c new file mode 100644 index 000000000000..4733a2899329 --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgLib.c @@ -0,0 +1,136 @@ +/** @file QemuOpenFwCfgLib.c + QemuOpenFwCfgLib library + + Implements a minimal library to interact with Qemu FW CFG device + + QEMU FW CFG device allow the OS to retrieve files passed by QEMU or the user. + Files can vary from E820 entries to ACPI tables. + + Copyright (c) 2022 Theo Jehl All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Library/QemuOpenFwCfgLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> + +/** + Reads 8 bits from the data register. + + @retval UINT8 +**/ +UINT8 +EFIAPI +QemuFwCfgRead8 ( + VOID + ) +{ + return IoRead8 (FW_CFG_PORT_DATA); +} + +/** + Sets the selector register to the specified value + + @param Selector + + @retval EFI_SUCCESS + @retval EFI_UNSUPPORTED +**/ +EFI_STATUS +EFIAPI +QemuFwCfgSelectItem ( + IN UINT16 Selector + ) +{ + UINT16 WritenSelector; + + WritenSelector = IoWrite16 (FW_CFG_PORT_SEL, Selector); + + if (WritenSelector != Selector) { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + +/** + Reads N bytes from the data register + + @param Size + @param Buffer +**/ +VOID +EFIAPI +QemuFwCfgReadBytes ( + IN UINTN Size, + OUT VOID *Buffer + ) +{ + IoReadFifo8 (FW_CFG_PORT_DATA, Size, Buffer); +} + +/** + Checks for Qemu fw_cfg device by reading "QEMU" using the signature selector + + @retval EFI_SUCCESS - The fw_cfg device is present + @retval EFI_UNSUPPORTED - The device is absent +**/ +EFI_STATUS +EFIAPI +QemuFwCfgIsPresent ( + ) +{ + EFI_STATUS Status; + UINT32 Control; + + Status = QemuFwCfgSelectItem (FW_CFG_SIGNATURE); + if (EFI_ERROR (Status)) { + return Status; + } + + QemuFwCfgReadBytes (4, &Control); + if (Control != FW_CFG_QEMU_SIGNATURE) { + ASSERT (Control == FW_CFG_QEMU_SIGNATURE); + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + +/** + Finds a file in fw_cfg by its name + + @param String Pointer to an ASCII string to match in the database + @param FWConfigFile Buffer for the config file + + @retval EFI_STATUS Entry was found, FWConfigFile is populated + @retval EFI_ERROR Entry was not found +**/ +EFI_STATUS +EFIAPI +QemuFwCfgFindFile ( + IN CHAR8 *String, + OUT QEMU_FW_CFG_FILE *FWConfigFile + ) +{ + QEMU_FW_CFG_FILE FirmwareConfigFile; + UINT32 FilesCount; + UINT32 Idx; + + QemuFwCfgSelectItem (FW_CFG_FILE_DIR); + QemuFwCfgReadBytes (sizeof (UINT32), &FilesCount); + + FilesCount = SwapBytes32 (FilesCount); + + for (Idx = 0; Idx < FilesCount; Idx++) { + QemuFwCfgReadBytes (sizeof (QEMU_FW_CFG_FILE), &FirmwareConfigFile); + if (AsciiStrCmp ((CHAR8 *)&(FirmwareConfigFile.Name), String) == 0) { + FirmwareConfigFile.Select = SwapBytes16 (FirmwareConfigFile.Select); + FirmwareConfigFile.Size = SwapBytes32 (FirmwareConfigFile.Size); + CopyMem (FWConfigFile, &FirmwareConfigFile, sizeof (QEMU_FW_CFG_FILE)); + return EFI_SUCCESS; + } + } + + return EFI_UNSUPPORTED; +} diff --git a/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Cpu.c b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Cpu.c new file mode 100644 index 000000000000..e203b2654226 --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Cpu.c @@ -0,0 +1,64 @@ +/** @file Cpu.c + CPU Count initialization + + Copyright (c) 2022 Theo Jehl All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "PlatformInit.h" +#include <IndustryStandard/Pci.h> +#include <Library/PciCf8Lib.h> +#include <Library/QemuOpenFwCfgLib.h> +#include <IndustryStandard/QemuFwCfg.h> +#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h> +#include <Library/DebugLib.h> +#include <IndustryStandard/Acpi30.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/PcdLib.h> +#include <Library/HobLib.h> + +/** + Probe Qemu FW CFG device for current CPU count and report to MpInitLib. + + @return EFI_SUCCESS Detection was successful. + @retval EFI_UNSUPPORTED QEMU FW CFG device is not present. + */ +EFI_STATUS +EFIAPI +MaxCpuInit ( + VOID + ) +{ + UINT16 BootCpuCount; + EFI_STATUS Status; + + Status = QemuFwCfgIsPresent (); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "QemuFwCfg not present, unable to detect CPU count \n")); + ASSERT_EFI_ERROR (Status); + return EFI_UNSUPPORTED; + } + + // + // Probe Qemu FW CFG device for CPU count + // + + Status = QemuFwCfgSelectItem (QemuFwCfgItemSmpCpuCount); + + if (EFI_ERROR (Status)) { + return Status; + } + + QemuFwCfgReadBytes (sizeof (BootCpuCount), &BootCpuCount); + + // + // Report count to MpInitLib + // + + PcdSet32S (PcdCpuBootLogicalProcessorNumber, BootCpuCount); + + PcdSet32S (PcdCpuMaxLogicalProcessorNumber, 64); + + return EFI_SUCCESS; +} diff --git a/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Memory.c b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Memory.c new file mode 100644 index 000000000000..21705256191b --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Memory.c @@ -0,0 +1,254 @@ +/** @file Memory.c + Memory probing and installation + + Copyright (c) 2022 Theo Jehl All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <PlatformInit.h> +#include <Library/DebugLib.h> +#include <Library/QemuOpenFwCfgLib.h> +#include <Library/PeiServicesTablePointerLib.h> +#include <Library/HobLib.h> +#include <IndustryStandard/E820.h> +#include <Library/PcdLib.h> +#include <Library/BaseMemoryLib.h> + +/** + Return the memory size below 4GB. + + @return Size of memory below 4GB, in bytes. +**/ +UINT32 +EFIAPI +GetMemoryBelow4Gb ( + VOID + ) +{ + EFI_E820_ENTRY64 E820Entry; + QEMU_FW_CFG_FILE FwCfgFile; + UINT32 Processed; + UINT64 Size; + EFI_STATUS Status; + + Status = QemuFwCfgIsPresent (); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = QemuFwCfgFindFile ("etc/e820", &FwCfgFile); + if (EFI_ERROR (Status)) { + return Status; + } + + Size = 0; + QemuFwCfgSelectItem (FwCfgFile.Select); + for (Processed = 0; Processed < FwCfgFile.Size / sizeof (EFI_E820_ENTRY); Processed++) { + QemuFwCfgReadBytes (sizeof (EFI_E820_ENTRY), &E820Entry); + if (E820Entry.Type != EfiAcpiAddressRangeMemory) { + continue; + } + + if (E820Entry.BaseAddr + E820Entry.Length < SIZE_4GB) { + Size += E820Entry.Length; + } else { + ASSERT (Size == (UINT32)Size); + return (UINT32) Size; + } + } + + ASSERT (Size == (UINT32)Size); + return (UINT32) Size; +} + +/** + Reserve an MMIO region. + + @param[in] Start Start of the MMIO region. + @param[in] Length Length of the MMIO region. +**/ +STATIC +VOID +ReserveMmioRegion ( + EFI_PHYSICAL_ADDRESS Start, + UINT64 Length + ) +{ + EFI_RESOURCE_TYPE ResourceType; + EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes; + + ResourceAttributes = EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_TESTED; + ResourceType = EFI_RESOURCE_MEMORY_MAPPED_IO; + + BuildResourceDescriptorHob ( + ResourceType, + ResourceAttributes, + Start, + Length + ); +} + +/** + Install EFI memory by probing QEMU FW CFG devices for valid E820 entries. + It also reserves space for MMIO regions such as VGA, BIOS and APIC. + + @param[in] PeiServices PEI Services pointer. + + @retval EFI_SUCCESS Memory initialization succeded. + @retval EFI_UNSUPPORTED Installation failed (etc/e820 file was not found). + @retval EFI_NOT_FOUND QEMU FW CFG device is not present. +**/ +EFI_STATUS +EFIAPI +InstallMemory ( + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + CONST EFI_PEI_SERVICES **PeiServicesTable; + EFI_E820_ENTRY64 E820Entry; + EFI_E820_ENTRY64 LargestE820Entry; + QEMU_FW_CFG_FILE FwCfgFile; + UINT32 Processed; + BOOLEAN ValidMemory; + EFI_RESOURCE_TYPE ResourceType; + EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes; + UINT32 MemoryBelow4G; + UINT32 RequiredBySmm; + + Status = QemuFwCfgIsPresent (); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "QEMU fw_cfg device is not present\n")); + return EFI_NOT_FOUND; + } else { + DEBUG ((DEBUG_INFO, "QEMU fw_cfg device is present\n")); + } + + Status = QemuFwCfgFindFile ("etc/e820", &FwCfgFile); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "etc/e820 was not found \n")); + return EFI_UNSUPPORTED; + } + + MemoryBelow4G = GetMemoryBelow4Gb (); + + LargestE820Entry.Length = 0; + QemuFwCfgSelectItem (FwCfgFile.Select); + for (Processed = 0; Processed < FwCfgFile.Size / sizeof (EFI_E820_ENTRY); Processed++) { + QemuFwCfgReadBytes (sizeof (EFI_E820_ENTRY), &E820Entry); + + ValidMemory = E820Entry.Type == EfiAcpiAddressRangeMemory; + ResourceType = EFI_RESOURCE_MEMORY_RESERVED; + ResourceAttributes = EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_TESTED; + + if (ValidMemory) { + if (FeaturePcdGet (PcdSmmSmramRequire) && (E820Entry.BaseAddr + E820Entry.Length == MemoryBelow4G)) { + RequiredBySmm = PcdGet16 (PcdQ35TsegMbytes) * SIZE_1MB; + if (E820Entry.Length < RequiredBySmm) { + DEBUG (( + DEBUG_ERROR, + "Error: There's not enough memory below TOLUD for SMM (%lx < %x)\n", + E820Entry.Length, + RequiredBySmm + )); + } + + E820Entry.Length -= RequiredBySmm; + DEBUG (( + DEBUG_INFO, + "SMM is enabled! Stealing [%lx, %lx](%u MiB) for SMRAM...\n", + E820Entry.BaseAddr + E820Entry.Length, + E820Entry.BaseAddr + E820Entry.Length + RequiredBySmm - 1, + PcdGet16 (PcdQ35TsegMbytes) + )); + } + + ResourceType = EFI_RESOURCE_SYSTEM_MEMORY; + ResourceAttributes = EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_TESTED; + + // + // Lets handle the lower 1MB in a special way + // + + if (E820Entry.BaseAddr == 0) { + // + // 0 - 0xa0000 is system memory, everything above that up to 1MB is not + // Note that we check if we actually have 1MB + // + + BuildResourceDescriptorHob ( + ResourceType, + ResourceAttributes, + 0, + MIN (0xa0000, E820Entry.Length) + ); + + E820Entry.BaseAddr += BASE_1MB; + E820Entry.Length -= MIN (BASE_1MB, E820Entry.Length); + } + + // + // Note that we can only check if this is the largest entry after reserving everything we have to reserve + // + + if ((E820Entry.Length > LargestE820Entry.Length) && (E820Entry.BaseAddr + E820Entry.Length <= SIZE_4GB)) { + CopyMem (&LargestE820Entry, &E820Entry, sizeof (EFI_E820_ENTRY64)); + DEBUG (( + DEBUG_INFO, + "New largest entry for PEI: BaseAddress %lx, Size %lx\n", + LargestE820Entry.BaseAddr, + LargestE820Entry.Length + )); + } + } + + BuildResourceDescriptorHob ( + ResourceType, + ResourceAttributes, + E820Entry.BaseAddr, + E820Entry.Length + ); + + DEBUG (( + DEBUG_INFO, + "Processed E820 entry [%lx, %lx] with type %x\n", + E820Entry.BaseAddr, + E820Entry.BaseAddr + E820Entry.Length - 1, + E820Entry.Type + )); + } + + ASSERT (LargestE820Entry.Length != 0); + DEBUG (( + DEBUG_INFO, + "Largest memory chunk found: [%lx, %lx]\n", + LargestE820Entry.BaseAddr, + LargestE820Entry.BaseAddr + LargestE820Entry.Length - 1 + )); + + PeiServicesTable = GetPeiServicesTablePointer (); + + Status = (*PeiServices)->InstallPeiMemory (PeiServicesTable, LargestE820Entry.BaseAddr, LargestE820Entry.Length); + + ASSERT_EFI_ERROR (Status); + + // + // Reserve architectural PC MMIO regions + // VGA space + BIOS shadow mapping + // + + ReserveMmioRegion (0xa0000, 0x100000 - 0xa0000); + + // + // IO APIC and LAPIC space + // + + ReserveMmioRegion (0xfec00000, 0xff000000 - 0xfec00000); + return Status; +} diff --git a/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pci.c b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pci.c new file mode 100644 index 000000000000..4e6b784d9890 --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pci.c @@ -0,0 +1,70 @@ +/** @file Pci.c + PCI Initialization for PIIX4 QEMU + + Copyright (c) 2022 Theo Jehl All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "PlatformInit.h" +#include <IndustryStandard/Pci.h> +#include <Library/PciCf8Lib.h> +#include <Library/QemuOpenFwCfgLib.h> +#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h> +#include <Library/DebugLib.h> +#include <IndustryStandard/Acpi30.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/PcdLib.h> +#include <Library/HobLib.h> + +/** + Initialize PCI support for QEMU PIIX4 machine. + + It also publishes PCI MMIO and IO ranges PCDs for OVMF PciHostBridgeLib. + + @retval EFI_SUCCESS Initialization was a success. + @retval EFI_UNSUPPORTED Initialization failed (Memory below 4Gb probing failed). +**/ +EFI_STATUS +EFIAPI +InitializePciPIIX4 ( + VOID + ) +{ + UINTN PciIoBase; + UINTN PciIoSize; + UINTN PciMmio32Base; + UINTN PciMmio32Size; + + // + // Setup PCI IO ranges for 440FX/PIIX4 platform + // + PciIoBase = PIIX4_PCI_IO_BASE; + PciIoSize = PIIX4_PCI_IO_SIZE; + + PcdSet64S (PcdPciIoBase, PciIoBase); + PcdSet64S (PcdPciIoSize, PciIoSize); + + // + // QEMU only allow a maximum of 2.8Gb of real memory below 4G + // PCI MMIO range below 4Gb starts at the end of real memory below 4G + // + PciMmio32Base = (UINTN)GetMemoryBelow4Gb (); + + if (PciMmio32Base == 0) { + DEBUG ((DEBUG_ERROR, "Unable to detect memory below 4Gb\n")); + ASSERT (PciMmio32Base != 0); + return EFI_UNSUPPORTED; + } + + DEBUG ((DEBUG_ERROR, "Memory below 4Gb: %x \n", PciMmio32Base)); + + // + // Maximum size being PCI_MMIO_TOP_ADDRESS - TopOfLowMem to avoid overlapping with IO-APIC and other hardware mmio ranges + // + PciMmio32Size = PCI_MMIO_TOP_ADDRESS - PciMmio32Base; + + PcdSet64S (PcdPciMmio32Base, PciMmio32Base); + PcdSet64S (PcdPciMmio32Size, PciMmio32Size); + + return EFI_SUCCESS; +} diff --git a/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pcie.c b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pcie.c new file mode 100644 index 000000000000..0a5f0ff398de --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pcie.c @@ -0,0 +1,106 @@ +/** @file Pcie.c + PCI Express initialization for QEMU Q35 + + Copyright (c) 2022 Theo Jehl All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "PlatformInit.h" +#include <IndustryStandard/Pci.h> +#include <Library/PciCf8Lib.h> +#include <IndustryStandard/Q35MchIch9.h> +#include <Library/QemuOpenFwCfgLib.h> +#include <IndustryStandard/QemuFwCfg.h> +#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h> +#include <Library/DebugLib.h> +#include <IndustryStandard/Acpi30.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/PcdLib.h> +#include <Library/HobLib.h> + +/** + Initialize PCI Express support for QEMU Q35 system. + It also publishes PCI MMIO and IO ranges PCDs for OVMF PciHostBridgeLib. + + @retval EFI_SUCCESS Initialization was successful +**/ +EFI_STATUS +EFIAPI +InitializePcie ( + VOID + ) +{ + UINTN PciBase; + UINTN PciSize; + UINTN PciIoBase; + UINTN PciIoSize; + + union { + UINT64 Uint64; + UINT32 Uint32[2]; + } PciExBarBase; + + PciExBarBase.Uint64 = FixedPcdGet64 (PcdPciExpressBaseAddress); + + // + // Build a reserved memory space for PCIE MMIO + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_RESERVED, + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + EFI_RESOURCE_ATTRIBUTE_TESTED, + PciExBarBase.Uint64, + SIZE_256MB + ); + + BuildMemoryAllocationHob ( + PciExBarBase.Uint64, + SIZE_256MB, + EfiReservedMemoryType + ); + + // + // Clear lower 32 bits of register + // + PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW), 0); + + // + // Program PCIE MMIO Base address in MCH PCIEXBAR register + // + PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_HIGH), PciExBarBase.Uint32[1]); + + // + // Enable 256Mb MMIO space + // + PciWrite32 ( + DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW), + PciExBarBase.Uint32[0] | MCH_PCIEXBAR_BUS_FF | MCH_PCIEXBAR_EN + ); + + // + // Disable PCI/PCIe MMIO above 4Gb + // + PcdSet64S (PcdPciMmio64Size, 0); + + // + // Set Pci MMIO space below 4GB + // + PciBase = (UINTN)(PcdGet64 (PcdPciExpressBaseAddress) + SIZE_256MB); + PciSize = PCI_MMIO_TOP_ADDRESS - PciBase; + + PcdSet64S (PcdPciMmio32Base, PciBase); + PcdSet64S (PcdPciMmio32Size, PciSize); + + // + // Set Pci IO port range + // + PciIoBase = Q35_PCI_IO_BASE; + PciIoSize = Q35_PCI_IO_SIZE; + + PcdSet64S (PcdPciIoBase, PciIoBase); + PcdSet64S (PcdPciIoSize, PciIoSize); + + return EFI_SUCCESS; +} diff --git a/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.c b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.c new file mode 100644 index 000000000000..7849298b52d5 --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.c @@ -0,0 +1,75 @@ +/** @file PlarformInit.c + Platform initialization PEIM for QEMU + + Copyright (c) 2022 Theo Jehl All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "PlatformInit.h" +#include <Library/PeimEntryPoint.h> +#include <Library/PeiServicesLib.h> +#include "Library/DebugLib.h" +#include <Library/PlatformInitLib.h> +#include <Library/HobLib.h> +#include <Library/PciCf8Lib.h> +#include <IndustryStandard/Pci.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/PcdLib.h> +#include <IndustryStandard/Q35MchIch9.h> + +EFI_STATUS +EFIAPI +PlatformInit ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + UINT16 DeviceId; + EFI_HOB_PLATFORM_INFO *EfiPlatformInfo; + + // + // Install permanent memory + // + Status = InstallMemory (PeiServices); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Memory installation failed\n")); + return Status; + } else { + DEBUG ((DEBUG_INFO, "Memory installation success\n")); + } + + // + // Report CPU core count to MPInitLib + // + MaxCpuInit (); + + EfiPlatformInfo = AllocateZeroPool (sizeof (EFI_HOB_PLATFORM_INFO)); + if (EfiPlatformInfo == NULL) { + DEBUG ((DEBUG_ERROR, "Failed to allocate pool for EFI_HOB_PLATFORM_INFO\n")); + return EFI_UNSUPPORTED; + } + + // + // Report gUefiOvmfPkgPlatformInfo HOB with only the necessary data for OVMF + // + DeviceId = PciCf8Read16 (PCI_CF8_LIB_ADDRESS (0, 0, 0, PCI_DEVICE_ID_OFFSET)); + DEBUG ((DEBUG_INFO, "Building gUefiOvmfPkgPlatformInfoGuid with Host bridge dev ID %x \n", DeviceId)); + (*EfiPlatformInfo).HostBridgeDevId = DeviceId; + + BuildGuidDataHob (&gUefiOvmfPkgPlatformInfoGuid, EfiPlatformInfo, sizeof (EFI_HOB_PLATFORM_INFO)); + + PcdSet16S (PcdOvmfHostBridgePciDevId, DeviceId); + + // + // Initialize PCI or PCIe based on current emulated system + // + if (DeviceId == INTEL_Q35_MCH_DEVICE_ID) { + DEBUG ((DEBUG_INFO, "Q35: Initialize PCIe\n")); + return InitializePcie (); + } else { + DEBUG ((DEBUG_INFO, "PIIX4: Initialize PCI\n")); + return InitializePciPIIX4 (); + } +} diff --git a/Platform/Qemu/QemuOpenBoardPkg/Include/Fdf/FlashMap.fdf.inc b/Platform/Qemu/QemuOpenBoardPkg/Include/Fdf/FlashMap.fdf.inc new file mode 100644 index 000000000000..6797e223fca4 --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/Include/Fdf/FlashMap.fdf.inc @@ -0,0 +1,94 @@ +## @file +# Flashmap and variable definitions for QemuOpenBoardPkg FVs and FD +# +# @copyright +# Copyright (C) 2022 Theo Jehl +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +# +# These three items are tightly coupled. +# The spare area size must be >= the first two areas. +# The total size must match the size in the EFI_FIRMWARE_VOLUME_HEADER. +# The NvStorageVariableSize must also match the VARIABLE_STORE_HEADER size. +# The EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER doesn't have size info. +# +# There isn't really a benefit to a larger spare area unless the FLASH device +# block size is larger than the size specified. +# +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize = 0x0003C000 +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize = 0x00004000 +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize = gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + +# +# Early FV +# +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemorySize = 0x00081000 +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemorySize = 0x00040000 +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize = 0x00010000 +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize = 0x00040000 +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize = 0x00020000 +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize = 0x00080000 +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspSize = 0x00020000 + +# +# Later FV +# +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize = 0x00400000 +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize = 0x00100000 +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize = 0x00080000 +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize = gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemorySize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspSize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemorySize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize + +# +# Calculate Offsets Once (Do not modify) +# This layout is specified by the EDK II Minimum Platform Archicture specification. +# Each offset is the prior region's offset plus the prior region's size. +# + +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageVariableOffset = 0x00000000 +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingOffset = gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageVariableOffset + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareOffset = gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingOffset + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedOffset = 0x00000000 +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityOffset = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedOffset + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootOffset = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityOffset + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootOffset = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootOffset + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize + +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspOffset = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootOffset + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryOffset = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspOffset + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspSize +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSOffset = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryOffset + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMOffset = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSOffset + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTOffset = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMOffset + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemoryOffset = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTOffset + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryOffset = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemoryOffset + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemorySize + +# +# Calculate base addresses +# QemuOpenBoardPkgVars FD +# + +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase = gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase = gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase = gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase = gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase = gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase = gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + +# +# QemuOpenBoardPkg FD +# + +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedBase = gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityBase = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedBase + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootBase = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityBase + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootBase = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootBase + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize + +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspBase = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootBase + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryBase = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspBase + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspSize +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSBase = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryBase + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMBase = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSBase + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTBase = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMBase + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemoryBase = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTBase + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize +SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryBase = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemoryBase + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemorySize diff --git a/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/Ia32/SecEntry.nasm b/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/Ia32/SecEntry.nasm new file mode 100644 index 000000000000..8ee8809ed0f5 --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/Ia32/SecEntry.nasm @@ -0,0 +1,117 @@ +;------------------------------------------------------------------------------ +; @file SecEntry +; Sec entry implementation +; +; Copyright (c) 2022 Theo Jehl +; SPDX-License-Identifier: BSD-2-Clause-Patent +; +;------------------------------------------------------------------------------ + +CODE_SEG equ CodeSegDescriptor - GDT_START +DATA_SEG equ DataSegDescriptor - GDT_START + +extern ASM_PFX(SecStartup) + +extern ASM_PFX(PcdGet32 (PcdTemporaryRamBase)) +extern ASM_PFX(PcdGet32 (PcdTemporaryRamSize)) + +SECTION .text + +BITS 16 +align 4 +global ASM_PFX(_ModuleEntryPoint) +ASM_PFX(_ModuleEntryPoint): + cli + ; Save the BIST in mm0 + movd mm0, eax + mov esi, GDT_Descriptor + db 66h + lgdt [cs:si] + + mov eax, cr0 + or eax, 1 + mov cr0, eax + + mov ax, DATA_SEG + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + + mov esi, ProtectedModeEntryLinearAddress + + jmp dword far [cs:si] + +BITS 32 +align 4 +ProtectedModeEntry: + PROTECTED_MODE equ $ + + mov ecx, DWORD [ASM_PFX(PcdGet32 (PcdTemporaryRamBase))] + mov edx, DWORD [ASM_PFX(PcdGet32 (PcdTemporaryRamSize))] + + ; Initialize the stack at the end of base + size + mov esp, ecx + add esp, edx + + ; Push 1 CPU, will be probed later with Qemu FW CFG device + push 1 + ; For now, we push the BIST once + movd eax, mm0 + push eax + ; Code in PlatformSecLib will look up this information we've just pushed + ; ================= TOP OF MEMORY ====================== + ; Count of BISTs + ; BISTs[1..n] + ; ================= REST OF MEMORY ===================== + ; Each BIST is always a DWORD in size + + mov edi, 0xFFFFFFFC ;BFV + + push DWORD [edi] ;Passes BFV + + push ecx ;Passes RAM size + + push edx ;Passes RAM base + + call ASM_PFX(SecStartup) + +align 8 +NULL_SEGMENT equ $ - GDT_START +GDT_START: + +NullSegDescriptor: + dd 0x0 + dd 0x0 + + CODE_SEL equ $ - GDT_START + +CodeSegDescriptor: + dw 0xFFFF + dw 0x0 + db 0x0 + db 0x9B + db 0xCF + db 0x0 + + DATA_SEL equ $ - GDT_START + +DataSegDescriptor: + dw 0xFFFF + dw 0x0 + db 0x0 + db 0x93 + db 0xCF + db 0x0 + +GDT_END: + +GDT_Descriptor: + dw GDT_END - GDT_START - 1 + dd GDT_START + +ProtectedModeEntryLinearAddress: +ProtectedModeEntryLinear: + DD ProtectedModeEntry ; Offset of our 32 bit code + DW CODE_SEL diff --git a/Platform/Qemu/QemuOpenBoardPkg/README.md b/Platform/Qemu/QemuOpenBoardPkg/README.md new file mode 100644 index 000000000000..e1238c1f4e3e --- /dev/null +++ b/Platform/Qemu/QemuOpenBoardPkg/README.md @@ -0,0 +1,53 @@ +# QemuOpenBoardPkg + +This project brings UEFI support to QEMU x86_64 following the MinPlatform specification. + +## Capabilities + +- Supports IA-32 and hybrid X64 (IA32 PEI Core and X64 DXE Core) +- Modern QEMU (Tested on 7.0.0) + - PIIX4 and Q35 machines +- Boot UEFI Linux +- Boot UEFI Windows + +## How to build + +### Pre-requesites + +- EDK2 + - How to setup a local tree: https://github.com/tianocore/tianocore.github.io/wiki/Getting-Started-with-EDK-II + +- EDK2 Platforms + - https://github.com/tianocore/edk2-platforms + +- Environnements variables: + - WORKSPACE set to your current workspace + - PACKAGES_PATH should contain path to: + - edk2 + - edk2-platforms + - edk2-platforms/Platform/Intel + - edk2-platforms/Platform/Qemu + - edk2-platforms/Silicon/Intel + +Currently QemuOpenBoardPkg's PEI Core is 32 bits only, DXE supports either 32 bits or 64 bits + +QemuOpenBoardPkg (IA32 PEI - IA32 DXE) + +```build -a IA32 -D PEI_ARCH=IA32 -D DXE_ARCH=IA32``` + +QemuOpenBoardPkg (IA32 PEI - X64 DXE) + +```build -a IA32 -a X64 -D PEI_ARCH=IA32 -D DXE_ARCH=X64``` + +## How to use + +Using qemu-system-x86_64, use + +```-bios <path to QemuOpenBoard FV>``` + +To redirect serial output to the console + +```-serial stdio``` + +## Important notes +- Secure boot is not yet available due to QemuOpenBoardPkg NVRAM storage not being persistent yet. -- 2.37.0 (Apple Git-136) -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#93724): https://edk2.groups.io/g/devel/message/93724 Mute This Topic: https://groups.io/mt/93665758/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-