* [edk2-platforms PATCH v2 0/7] Add Initial QSP MinPlatform Pkg for SIMICS
@ 2019-08-28 0:40 David Wei
2019-08-28 0:40 ` [edk2-platforms PATCH v2 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58 David Wei
` (6 more replies)
0 siblings, 7 replies; 16+ messages in thread
From: David Wei @ 2019-08-28 0:40 UTC (permalink / raw)
To: devel
Create the SimicsOpenBoardPkg and its silicon Pkg to provide the support
for SIMICS quick start platform. it uses X58/ICH10 and emulated by SIMICS
model.
Different from V1:
Fix coding style and file naming convention issues
Fix dependency issue for DEC file
Change some codes to more intuitive place
Change Board related GUID names
Remove old build bat file to use the python build tool
Use platform Logo Library instead of Logo driver under EDK2
David Wei (7):
SimicsX58SktPkg: Add CPU Pkg for SimicsX58
SimicsICH10Pkg: Add PCH Pkg for SimicsICH10
SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules
SimicsOpenBoardPkg: Add DXE driver for Legacy Sio
SimicsOpenBoardPkg: Add Overrides modules and Logo image for SIMICS
QSP Platform
SimicsOpenBoardPkg/BoardX58Ich10: Add board module for QSP Build tip
Platform/Intel: Add build option for SIMICS QSP Platform
.../Library/BoardInitLib/PeiBoardInitPostMemLib.c | 44 +
.../Library/BoardInitLib/PeiBoardInitPreMemLib.c | 110 ++
.../Library/BoardInitLib/PeiX58Ich10Detect.c | 26 +
.../BoardInitLib/PeiX58Ich10InitPostMemLib.c | 34 +
.../BoardInitLib/PeiX58Ich10InitPreMemLib.c | 111 ++
.../LegacySioDxe/ComponentName.c | 173 +++
.../SimicsOpenBoardPkg/LegacySioDxe/SioChip.c | 272 ++++
.../SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c | 600 ++++++++
.../SimicsOpenBoardPkg/LegacySioDxe/SioService.c | 249 +++
.../SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c | 647 ++++++++
.../Library/LoadLinuxLib/Linux.c | 662 ++++++++
.../Library/LoadLinuxLib/LinuxGdt.c | 175 +++
.../Library/NvVarsFileLib/FsAccess.c | 507 +++++++
.../Library/NvVarsFileLib/NvVarsFileLib.c | 77 +
.../Library/PciHostBridgeLib/PciHostBridgeLib.c | 419 ++++++
.../SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c | 100 ++
.../Library/PeiReportFvLib/PeiReportFvLib.c | 118 ++
.../Library/PlatformBootManagerLib/BdsPlatform.c | 1553 +++++++++++++++++++
.../Library/PlatformBootManagerLib/PlatformData.c | 35 +
.../SerializeVariablesLib/SerializeVariablesLib.c | 869 +++++++++++
.../MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c | 1579 ++++++++++++++++++++
.../MinPlatformPkg/Acpi/AcpiTables/Facs/Facs.c | 84 ++
.../MinPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.c | 359 +++++
.../MinPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.c | 78 +
.../MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c | 46 +
.../Overrides/OvmfPkg/QemuVideoDxe/ComponentName.c | 205 +++
.../Overrides/OvmfPkg/QemuVideoDxe/Driver.c | 1011 +++++++++++++
.../QemuVideoDxe/DriverSupportedEfiVersion.c | 15 +
.../Overrides/OvmfPkg/QemuVideoDxe/Gop.c | 416 ++++++
.../Overrides/OvmfPkg/QemuVideoDxe/Initialize.c | 341 +++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c | 302 ++++
.../SiliconPolicyInitLib/SiliconPolicyInitLib.c | 108 ++
.../SiliconPolicyUpdateLib.c | 70 +
.../Intel/SimicsOpenBoardPkg/SecCore/SecMain.c | 956 ++++++++++++
.../Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c | 865 +++++++++++
.../SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c | 123 ++
Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c | 57 +
.../SimicsOpenBoardPkg/SimicsPei/FeatureControl.c | 114 ++
.../Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c | 568 +++++++
.../Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c | 630 ++++++++
.../SmbiosPlatformDxe/SmbiosPlatformDxe.c | 148 ++
.../Library/ResetSystemLib/ResetSystemLib.c | 137 ++
.../Library/SmmSpiFlashCommonLib/SpiFlashCommon.c | 194 +++
.../SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c | 54 +
.../LibraryPrivate/BasePchSpiCommonLib/SpiCommon.c | 935 ++++++++++++
.../SmmControl/RuntimeDxe/SmmControl2Dxe.c | 410 +++++
Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.c | 175 +++
.../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c | 148 ++
.../SimicsX58SktPkg/Smm/Access/SmmAccessPei.c | 346 +++++
.../SimicsX58SktPkg/Smm/Access/SmramInternal.c | 200 +++
Maintainers.txt | 12 +
.../SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf | 31 +
.../Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl | 821 ++++++++++
.../Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h | 75 +
.../BoardX58Ich10/DecomprScratchEnd.fdf.inc | 66 +
.../BoardInitLib/PeiBoardInitPostMemLib.inf | 36 +
.../Library/BoardInitLib/PeiBoardInitPreMemLib.inf | 39 +
.../Library/BoardInitLib/PeiX58Ich10InitLib.h | 16 +
.../BoardX58Ich10/OpenBoardPkg.dsc | 233 +++
.../BoardX58Ich10/OpenBoardPkg.fdf | 304 ++++
.../BoardX58Ich10/OpenBoardPkg.fdf.inc | 54 +
.../BoardX58Ich10/OpenBoardPkgBuildOption.dsc | 78 +
.../BoardX58Ich10/OpenBoardPkgConfig.dsc | 56 +
.../BoardX58Ich10/OpenBoardPkgPcd.dsc | 281 ++++
.../BoardX58Ich10/VarStore.fdf.inc | 53 +
.../BoardX58Ich10/build_config.cfg | 31 +
.../Include/Guid/SimicsBoardConfig.h | 17 +
.../Include/IndustryStandard/I440FxPiix4.h | 49 +
.../Include/IndustryStandard/LinuxBzImage.h | 158 ++
.../Include/Library/LoadLinuxLib.h | 205 +++
.../Include/Library/SerializeVariablesLib.h | 223 +++
.../SimicsOpenBoardPkg/Include/SimicsPlatforms.h | 55 +
.../LegacySioDxe/ComponentName.h | 87 ++
.../LegacySioDxe/LegacySioDxe.inf | 54 +
.../SimicsOpenBoardPkg/LegacySioDxe/Register.h | 15 +
.../SimicsOpenBoardPkg/LegacySioDxe/SioChip.h | 195 +++
.../SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h | 134 ++
.../SimicsOpenBoardPkg/LegacySioDxe/SioService.h | 143 ++
.../Library/DxeLogoLib/DxeLogoLib.inf | 55 +
.../Library/DxeLogoLib/OEMBadging.h | 83 +
.../Library/LoadLinuxLib/DxeLoadLinuxLib.inf | 42 +
.../Library/LoadLinuxLib/Ia32/JumpToKernel.nasm | 41 +
.../Library/LoadLinuxLib/LoadLinuxLib.h | 52 +
.../Library/LoadLinuxLib/X64/JumpToKernel.nasm | 85 ++
.../Library/NvVarsFileLib/NvVarsFileLib.h | 55 +
.../Library/NvVarsFileLib/NvVarsFileLib.inf | 53 +
.../Library/PciHostBridgeLib/PciHostBridge.h | 68 +
.../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 51 +
.../Library/PeiReportFvLib/PeiReportFvLib.inf | 56 +
.../Library/PlatformBootManagerLib/BdsPlatform.h | 172 +++
.../PlatformBootManagerLib.inf | 72 +
.../SerializeVariablesLib/SerializeVariablesLib.h | 33 +
.../SerializeVariablesLib.inf | 36 +
Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp | Bin 0 -> 141078 bytes
Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec | 152 ++
.../MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h | 45 +
.../Acpi/AcpiTables/AcpiPlatform.inf | 105 ++
.../Overrides/OvmfPkg/QemuVideoDxe/Qemu.h | 507 +++++++
.../OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | 74 +
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm | 279 ++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h | 701 +++++++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh | 79 +
.../SiliconPolicyInitLib/SiliconPolicyInitLib.inf | 38 +
.../SiliconPolicyUpdateLib.inf | 35 +
.../SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm | 45 +
.../Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf | 73 +
.../SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm | 45 +
.../Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h | 37 +
.../SimicsOpenBoardPkg/SimicsDxe/Platform.uni | 31 +
.../SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h | 51 +
.../SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr | 67 +
.../SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf | 65 +
Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h | 50 +
.../Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h | 88 ++
.../SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf | 104 ++
.../SmbiosPlatformDxe/SmbiosPlatformDxe.h | 38 +
.../SmbiosPlatformDxe/SmbiosPlatformDxe.inf | 51 +
Platform/Intel/build.cfg | 2 +
Platform/Intel/build_bios.py | 3 +
Silicon/Intel/SimicsIch10Pkg/Ich10Pkg.dec | 26 +
Silicon/Intel/SimicsIch10Pkg/IchCommonLib.dsc | 12 +
.../Intel/SimicsIch10Pkg/IchPostMemoryInclude.fdf | 9 +
.../Intel/SimicsIch10Pkg/IchPreMemoryInclude.fdf | 9 +
.../Intel/SimicsIch10Pkg/IchUefiBootInclude.fdf | 13 +
.../Include/Library/SpiFlashCommonLib.h | 98 ++
Silicon/Intel/SimicsIch10Pkg/Include/PchAccess.h | 43 +
Silicon/Intel/SimicsIch10Pkg/Include/PchLimits.h | 94 ++
.../SimicsIch10Pkg/Include/PchReservedResources.h | 60 +
.../Intel/SimicsIch10Pkg/Include/Protocol/Spi.h | 295 ++++
.../SimicsIch10Pkg/Include/Register/PchRegsPmc.h | 647 ++++++++
.../SimicsIch10Pkg/Include/Register/PchRegsSpi.h | 304 ++++
.../SimicsIch10Pkg/Include/Register/X58Ich10.h | 113 ++
.../IncludePrivate/Library/PchSpiCommonLib.h | 396 +++++
.../Library/ResetSystemLib/ResetSystemLib.inf | 34 +
.../SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf | 50 +
.../BasePchSpiCommonLib/BasePchSpiCommonLib.inf | 31 +
.../SmmControl/RuntimeDxe/SmmControl2Dxe.inf | 61 +
Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.h | 23 +
Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpiSmm.inf | 44 +
.../Include/Register/X58SmramSaveStateMap.h | 178 +++
Silicon/Intel/SimicsX58SktPkg/SktPkg.dec | 37 +
Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc | 14 +
.../Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf | 9 +
.../Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf | 10 +
Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf | 16 +
.../Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf | 14 +
.../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf | 54 +
.../SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf | 65 +
.../SimicsX58SktPkg/Smm/Access/SmramInternal.h | 81 +
149 files changed, 27535 insertions(+)
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10Detect.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitPostMemLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitPreMemLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/PlatformData.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Facs/Facs.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/ComponentName.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driver.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/DriverSupportedEfiVersion.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Initialize.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/FeatureControl.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.c
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c
create mode 100644 Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/SpiCommon.c
create mode 100644 Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.c
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.c
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/DecomprScratchEnd.fdf.inc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf.inc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgBuildOption.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgConfig.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgPcd.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/VarStore.fdf.inc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/build_config.cfg
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsBoardConfig.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/I440FxPiix4.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/LinuxBzImage.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Library/LoadLinuxLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Library/SerializeVariablesLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/LegacySioDxe.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/DxeLogoLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/OEMBadging.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/DxeLoadLinuxLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.nasm
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel.nasm
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridge.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qemu.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Ich10Pkg.dec
create mode 100644 Silicon/Intel/SimicsIch10Pkg/IchCommonLib.dsc
create mode 100644 Silicon/Intel/SimicsIch10Pkg/IchPostMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/IchPreMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/IchUefiBootInclude.fdf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Library/SpiFlashCommonLib.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/PchAccess.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/PchLimits.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/PchReservedResources.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Protocol/Spi.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsPmc.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsSpi.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Register/X58Ich10.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/IncludePrivate/Library/PchSpiCommonLib.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.inf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePchSpiCommonLib.inf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpiSmm.inf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Include/Register/X58SmramSaveStateMap.h
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPkg.dec
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
--
2.16.2.windows.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [edk2-platforms PATCH v2 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58
2019-08-28 0:40 [edk2-platforms PATCH v2 0/7] Add Initial QSP MinPlatform Pkg for SIMICS David Wei
@ 2019-08-28 0:40 ` David Wei
2019-08-28 22:02 ` Nate DeSimone
2019-08-28 0:40 ` [edk2-platforms PATCH v2 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10 David Wei
` (5 subsequent siblings)
6 siblings, 1 reply; 16+ messages in thread
From: David Wei @ 2019-08-28 0:40 UTC (permalink / raw)
To: devel
Cc: Hao Wu, Liming Gao, Ankit Sinha, Agyeman Prince,
Kubacki Michael A, Nate DeSimone, Michael D Kinney
Add CPU Pkg for SimicsX58. It is added for simics QSP project support
Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c | 148 +++++++++
.../SimicsX58SktPkg/Smm/Access/SmmAccessPei.c | 346 +++++++++++++++++++++
.../SimicsX58SktPkg/Smm/Access/SmramInternal.c | 200 ++++++++++++
.../Include/Register/X58SmramSaveStateMap.h | 178 +++++++++++
Silicon/Intel/SimicsX58SktPkg/SktPkg.dec | 37 +++
Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc | 14 +
.../Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf | 9 +
.../Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf | 10 +
Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf | 16 +
.../Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf | 14 +
.../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf | 54 ++++
.../SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf | 65 ++++
.../SimicsX58SktPkg/Smm/Access/SmramInternal.h | 81 +++++
13 files changed, 1172 insertions(+)
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Include/Register/X58SmramSaveStateMap.h
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPkg.dec
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
new file mode 100644
index 0000000000..771fddb487
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
@@ -0,0 +1,148 @@
+/** @file
+ A DXE_DRIVER providing SMRAM access by producing EFI_SMM_ACCESS2_PROTOCOL.
+
+ X58 TSEG is expected to have been verified and set up by the SmmAccessPei
+ driver.
+
+ Copyright (C) 2013, 2015, Red Hat, Inc.<BR>
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/SmmAccess2.h>
+
+#include "SmramInternal.h"
+
+/**
+ Opens the SMRAM area to be accessible by a boot-service driver.
+
+ This function "opens" SMRAM so that it is visible while not inside of SMM.
+ The function should return EFI_UNSUPPORTED if the hardware does not support
+ hiding of SMRAM. The function should return EFI_DEVICE_ERROR if the SMRAM
+ configuration is locked.
+
+ @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The operation was successful.
+ @retval EFI_UNSUPPORTED The system does not support opening and closing of
+ SMRAM.
+ @retval EFI_DEVICE_ERROR SMRAM cannot be opened, perhaps because it is
+ locked.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeOpen (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ )
+{
+ return SmramAccessOpen (&This->LockState, &This->OpenState);
+}
+
+/**
+ Inhibits access to the SMRAM.
+
+ This function "closes" SMRAM so that it is not visible while outside of SMM.
+ The function should return EFI_UNSUPPORTED if the hardware does not support
+ hiding of SMRAM.
+
+ @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The operation was successful.
+ @retval EFI_UNSUPPORTED The system does not support opening and closing of
+ SMRAM.
+ @retval EFI_DEVICE_ERROR SMRAM cannot be closed.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeClose (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ )
+{
+ return SmramAccessClose (&This->LockState, &This->OpenState);
+}
+
+/**
+ Inhibits access to the SMRAM.
+
+ This function prohibits access to the SMRAM region. This function is usually
+ implemented such that it is a write-once operation.
+
+ @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The device was successfully locked.
+ @retval EFI_UNSUPPORTED The system does not support locking of SMRAM.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeLock (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ )
+{
+ return SmramAccessLock (&This->LockState, &This->OpenState);
+}
+
+/**
+ Queries the memory controller for the possible regions that will support
+ SMRAM.
+
+ @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance.
+ @param[in,out] SmramMapSize A pointer to the size, in bytes, of the
+ SmramMemoryMap buffer.
+ @param[in,out] SmramMap A pointer to the buffer in which firmware
+ places the current memory map.
+
+ @retval EFI_SUCCESS The chipset supported the given resource.
+ @retval EFI_BUFFER_TOO_SMALL The SmramMap parameter was too small. The
+ current buffer size needed to hold the memory
+ map is returned in SmramMapSize.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeGetCapabilities (
+ IN CONST EFI_SMM_ACCESS2_PROTOCOL *This,
+ IN OUT UINTN *SmramMapSize,
+ IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
+ )
+{
+ return SmramAccessGetCapabilities (This->LockState, This->OpenState,
+ SmramMapSize, SmramMap);
+}
+
+//
+// LockState and OpenState will be filled in by the entry point.
+//
+STATIC EFI_SMM_ACCESS2_PROTOCOL mAccess2 = {
+ &SmmAccess2DxeOpen,
+ &SmmAccess2DxeClose,
+ &SmmAccess2DxeLock,
+ &SmmAccess2DxeGetCapabilities
+};
+
+//
+// Entry point of this driver.
+//
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ //
+ // This module should only be included if SMRAM support is required.
+ //
+ ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
+
+ GetStates (&mAccess2.LockState, &mAccess2.OpenState);
+ return gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
+ &gEfiSmmAccess2ProtocolGuid, &mAccess2,
+ NULL);
+}
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
new file mode 100644
index 0000000000..c54026b4d1
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
@@ -0,0 +1,346 @@
+/** @file
+ A PEIM with the following responsibilities:
+
+ - verify & configure the X58 TSEG in the entry point,
+ - provide SMRAM access by producing PEI_SMM_ACCESS_PPI,
+ - set aside the SMM_S3_RESUME_STATE object at the bottom of TSEG, and expose
+ it via the gEfiAcpiVariableGuid GUID HOB.
+
+ This PEIM runs from RAM, so we can write to variables with static storage
+ duration.
+
+ Copyright (C) 2013, 2015, Red Hat, Inc.<BR>
+ Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Guid/AcpiS3Context.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/SmmAccess.h>
+
+#include <Register/X58Ich10.h>
+#include "SmramInternal.h"
+
+//
+// PEI_SMM_ACCESS_PPI implementation.
+//
+
+/**
+ Opens the SMRAM area to be accessible by a PEIM driver.
+
+ This function "opens" SMRAM so that it is visible while not inside of SMM.
+ The function should return EFI_UNSUPPORTED if the hardware does not support
+ hiding of SMRAM. The function should return EFI_DEVICE_ERROR if the SMRAM
+ configuration is locked.
+
+ @param PeiServices General purpose services available to every
+ PEIM.
+ @param This The pointer to the SMM Access Interface.
+ @param DescriptorIndex The region of SMRAM to Open.
+
+ @retval EFI_SUCCESS The region was successfully opened.
+ @retval EFI_DEVICE_ERROR The region could not be opened because locked
+ by chipset.
+ @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccessPeiOpen (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_ACCESS_PPI *This,
+ IN UINTN DescriptorIndex
+ )
+{
+ if (DescriptorIndex >= DescIdxCount) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // According to current practice, DescriptorIndex is not considered at all,
+ // beyond validating it.
+ //
+ return SmramAccessOpen (&This->LockState, &This->OpenState);
+}
+
+/**
+ Inhibits access to the SMRAM.
+
+ This function "closes" SMRAM so that it is not visible while outside of SMM.
+ The function should return EFI_UNSUPPORTED if the hardware does not support
+ hiding of SMRAM.
+
+ @param PeiServices General purpose services available to every
+ PEIM.
+ @param This The pointer to the SMM Access Interface.
+ @param DescriptorIndex The region of SMRAM to Close.
+
+ @retval EFI_SUCCESS The region was successfully closed.
+ @retval EFI_DEVICE_ERROR The region could not be closed because
+ locked by chipset.
+ @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccessPeiClose (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_ACCESS_PPI *This,
+ IN UINTN DescriptorIndex
+ )
+{
+ if (DescriptorIndex >= DescIdxCount) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // According to current practice, DescriptorIndex is not considered at all,
+ // beyond validating it.
+ //
+ return SmramAccessClose (&This->LockState, &This->OpenState);
+}
+
+/**
+ Inhibits access to the SMRAM.
+
+ This function prohibits access to the SMRAM region. This function is usually
+ implemented such that it is a write-once operation.
+
+ @param PeiServices General purpose services available to every
+ PEIM.
+ @param This The pointer to the SMM Access Interface.
+ @param DescriptorIndex The region of SMRAM to Close.
+
+ @retval EFI_SUCCESS The region was successfully locked.
+ @retval EFI_DEVICE_ERROR The region could not be locked because at
+ least one range is still open.
+ @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccessPeiLock (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_ACCESS_PPI *This,
+ IN UINTN DescriptorIndex
+ )
+{
+ if (DescriptorIndex >= DescIdxCount) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // According to current practice, DescriptorIndex is not considered at all,
+ // beyond validating it.
+ //
+ return SmramAccessLock (&This->LockState, &This->OpenState);
+}
+
+/**
+ Queries the memory controller for the possible regions that will support
+ SMRAM.
+
+ @param PeiServices General purpose services available to every
+ PEIM.
+ @param This The pointer to the SmmAccessPpi Interface.
+ @param SmramMapSize The pointer to the variable containing size of
+ the buffer to contain the description
+ information.
+ @param SmramMap The buffer containing the data describing the
+ Smram region descriptors.
+
+ @retval EFI_BUFFER_TOO_SMALL The user did not provide a sufficient buffer.
+ @retval EFI_SUCCESS The user provided a sufficiently-sized buffer.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccessPeiGetCapabilities (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_ACCESS_PPI *This,
+ IN OUT UINTN *SmramMapSize,
+ IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
+ )
+{
+ return SmramAccessGetCapabilities (This->LockState, This->OpenState, SmramMapSize, SmramMap);
+}
+
+//
+// LockState and OpenState will be filled in by the entry point.
+//
+STATIC PEI_SMM_ACCESS_PPI mAccess = {
+ &SmmAccessPeiOpen,
+ &SmmAccessPeiClose,
+ &SmmAccessPeiLock,
+ &SmmAccessPeiGetCapabilities
+};
+
+
+STATIC EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiSmmAccessPpiGuid, &mAccess
+ }
+};
+
+
+//
+// Utility functions.
+//
+STATIC
+UINT8
+CmosRead8 (
+ IN UINT8 Index
+ )
+{
+ IoWrite8 (0x70, Index);
+ return IoRead8 (0x71);
+}
+
+STATIC
+UINT32
+GetSystemMemorySizeBelow4gb (
+ VOID
+ )
+{
+ UINT32 Cmos0x34;
+ UINT32 Cmos0x35;
+
+ Cmos0x34 = CmosRead8 (0x34);
+ Cmos0x35 = CmosRead8 (0x35);
+
+ return ((Cmos0x35 << 8 | Cmos0x34) << 16) + SIZE_16MB;
+}
+
+
+//
+// Entry point of this driver.
+//
+EFI_STATUS
+EFIAPI
+SmmAccessPeiEntryPoint (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ UINT16 HostBridgeDevId;
+ UINT32 EsmramcVal;
+ UINT32 TopOfLowRam, TopOfLowRamMb;
+ EFI_STATUS Status;
+ UINTN SmramMapSize;
+ EFI_SMRAM_DESCRIPTOR SmramMap[DescIdxCount];
+ VOID *GuidHob;
+
+ //
+ // This module should only be included if SMRAM support is required.
+ //
+ ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
+
+ //
+ // Verify if we're running on a X58 machine type.
+ //
+ HostBridgeDevId = PciRead16 (SIMICS_HOSTBRIDGE_DID);
+ if (HostBridgeDevId != INTEL_ICH10_DEVICE_ID) {
+ DEBUG ((EFI_D_ERROR, "%a: no SMRAM with host bridge DID=0x%04x; only "
+ "DID=0x%04x (X58) is supported\n", __FUNCTION__, HostBridgeDevId,
+ INTEL_ICH10_DEVICE_ID));
+ goto WrongConfig;
+ }
+
+ //
+ // Confirm if Simics supports SMRAM.
+ //
+ // With no support for it, the ESMRAMC (Extended System Management RAM
+ // Control) register reads as zero. If there is support, the cache-enable
+ // bits are hard-coded as 1 by Simics.
+ //
+
+ TopOfLowRam = GetSystemMemorySizeBelow4gb ();
+ ASSERT ((TopOfLowRam & (SIZE_1MB - 1)) == 0);
+ TopOfLowRamMb = TopOfLowRam >> 20;
+ DEBUG((EFI_D_INFO, "TopOfLowRam =0x%x; TopOfLowRamMb =0x%x \n", TopOfLowRam, TopOfLowRamMb));
+
+
+ //
+ // Set Top of Low Usable DRAM.
+ //
+ PciWrite32 (DRAMC_REGISTER_X58(MCH_TOLUD), TopOfLowRam);
+ DEBUG((EFI_D_INFO, "MCH_TOLUD =0x%x; \n", PciRead32(DRAMC_REGISTER_X58(MCH_TOLUD))));
+
+ //
+ // Set TSEG Memory Base.
+ //
+ EsmramcVal = (TopOfLowRamMb - FixedPcdGet8(PcdX58TsegMbytes)) << MCH_TSEGMB_MB_SHIFT;
+ //
+ // Set TSEG size, and disable TSEG visibility outside of SMM. Note that the
+ // T_EN bit has inverse meaning; when T_EN is set, then TSEG visibility is
+ // *restricted* to SMM.
+ //
+ EsmramcVal &= ~(UINT32)MCH_ESMRAMC_TSEG_MASK;
+ EsmramcVal |= FixedPcdGet8 (PcdX58TsegMbytes) == 8 ? MCH_ESMRAMC_TSEG_8MB :
+ FixedPcdGet8 (PcdX58TsegMbytes) == 2 ? MCH_ESMRAMC_TSEG_2MB :
+ MCH_ESMRAMC_TSEG_1MB;
+ EsmramcVal |= MCH_ESMRAMC_T_EN;
+ PciWrite32(DRAMC_REGISTER_X58(MCH_TSEGMB), EsmramcVal);
+ DEBUG((EFI_D_INFO, "MCH_TSEGMB =0x%x; \n", PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB))));
+ DEBUG((EFI_D_INFO, "MCH_TSEGMB_1 =0x%x; MCH_TSEGMB_2 =0x%x;\n", ((TopOfLowRamMb - FixedPcdGet8(PcdX58TsegMbytes)) << MCH_TSEGMB_MB_SHIFT), EsmramcVal));
+
+ //
+ // Create the GUID HOB and point it to the first SMRAM range.
+ //
+ GetStates (&mAccess.LockState, &mAccess.OpenState);
+ SmramMapSize = sizeof SmramMap;
+ Status = SmramAccessGetCapabilities (mAccess.LockState, mAccess.OpenState, &SmramMapSize, SmramMap);
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG_CODE_BEGIN ();
+ {
+ UINTN Count;
+ UINTN Idx;
+
+ Count = SmramMapSize / sizeof SmramMap[0];
+ DEBUG ((EFI_D_VERBOSE, "%a: SMRAM map follows, %d entries\n", __FUNCTION__, (INT32)Count));
+ DEBUG ((EFI_D_VERBOSE, "% 20a % 20a % 20a % 20a\n", "PhysicalStart(0x)",
+ "PhysicalSize(0x)", "CpuStart(0x)", "RegionState(0x)"));
+ for (Idx = 0; Idx < Count; ++Idx) {
+ DEBUG ((EFI_D_VERBOSE, "% 20Lx % 20Lx % 20Lx % 20Lx\n",
+ SmramMap[Idx].PhysicalStart, SmramMap[Idx].PhysicalSize,
+ SmramMap[Idx].CpuStart, SmramMap[Idx].RegionState));
+ }
+ }
+ DEBUG_CODE_END ();
+
+ GuidHob = BuildGuidHob (&gEfiAcpiVariableGuid, sizeof SmramMap[DescIdxSmmS3ResumeState]);
+ if (GuidHob == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CopyMem (GuidHob, &SmramMap[DescIdxSmmS3ResumeState], sizeof SmramMap[DescIdxSmmS3ResumeState]);
+
+ //
+ // We're done. The next step should succeed, but even if it fails, we can't
+ // roll back the above BuildGuidHob() allocation, because PEI doesn't support
+ // releasing memory.
+ //
+ return PeiServicesInstallPpi (mPpiList);
+
+WrongConfig:
+ //
+ // We really don't want to continue in this case.
+ //
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ return EFI_UNSUPPORTED;
+}
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
new file mode 100644
index 0000000000..4b5a92f602
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
@@ -0,0 +1,200 @@
+/** @file
+ Functions and types shared by the SMM accessor PEI and DXE modules.
+
+ Copyright (C) 2015, Red Hat, Inc.
+ Copyright (C) 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Guid/AcpiS3Context.h>
+#include <Register/X58Ich10.h>
+#include <Library/DebugLib.h>
+#include <Library/PciLib.h>
+
+#include "SmramInternal.h"
+
+BOOLEAN gLockState;
+BOOLEAN gOpenState;
+
+/**
+ Read the MCH_SMRAM and ESMRAMC registers, and update the LockState and
+ OpenState fields in the PEI_SMM_ACCESS_PPI / EFI_SMM_ACCESS2_PROTOCOL object,
+ from the D_LCK and T_EN bits.
+
+ PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member functions can rely on
+ the LockState and OpenState fields being up-to-date on entry, and they need
+ to restore the same invariant on exit, if they touch the bits in question.
+
+ @param[out] LockState Reflects the D_LCK bit on output; TRUE iff SMRAM is
+ locked.
+ @param[out] OpenState Reflects the inverse of the T_EN bit on output; TRUE
+ iff SMRAM is open.
+**/
+VOID
+GetStates (
+ OUT BOOLEAN *LockState,
+ OUT BOOLEAN *OpenState
+)
+{
+ UINT8 EsmramcVal;
+
+ EsmramcVal = PciRead8(DRAMC_REGISTER_X58(MCH_TSEGMB));
+
+ *OpenState = !(EsmramcVal & MCH_ESMRAMC_T_EN);
+ *LockState = !*OpenState;
+
+ *OpenState = gOpenState;
+ *LockState = gLockState;
+}
+
+//
+// The functions below follow the PEI_SMM_ACCESS_PPI and
+// EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices and This
+// pointers are removed (TSEG doesn't depend on them), and so is the
+// DescriptorIndex parameter (TSEG doesn't support range-wise locking).
+//
+// The LockState and OpenState members that are common to both
+// PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken and updated in
+// isolation from the rest of the (non-shared) members.
+//
+
+EFI_STATUS
+SmramAccessOpen (
+ OUT BOOLEAN *LockState,
+ OUT BOOLEAN *OpenState
+ )
+{
+
+ //
+ // Open TSEG by clearing T_EN.
+ //
+ PciAnd8(DRAMC_REGISTER_X58(MCH_TSEGMB),
+ (UINT8)((~(UINT32)MCH_ESMRAMC_T_EN) & 0xff));
+
+ gOpenState = TRUE;
+ gLockState = !gOpenState;
+
+ GetStates (LockState, OpenState);
+ if (!*OpenState) {
+ return EFI_DEVICE_ERROR;
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SmramAccessClose (
+ OUT BOOLEAN *LockState,
+ OUT BOOLEAN *OpenState
+ )
+{
+ //
+ // Close TSEG by setting T_EN.
+ //
+ PciOr8(DRAMC_REGISTER_X58(MCH_TSEGMB), MCH_ESMRAMC_T_EN);
+
+ gOpenState = FALSE;
+ gLockState = !gOpenState;
+
+ GetStates (LockState, OpenState);
+ if (*OpenState) {
+ return EFI_DEVICE_ERROR;
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SmramAccessLock (
+ OUT BOOLEAN *LockState,
+ IN OUT BOOLEAN *OpenState
+ )
+{
+ if (*OpenState) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Close & lock TSEG by setting T_EN and D_LCK.
+ //
+ PciOr8 (DRAMC_REGISTER_X58(MCH_TSEGMB), MCH_ESMRAMC_T_EN);
+
+ gOpenState = FALSE;
+ gLockState = !gOpenState;
+
+ GetStates (LockState, OpenState);
+ if (*OpenState || !*LockState) {
+ return EFI_DEVICE_ERROR;
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SmramAccessGetCapabilities (
+ IN BOOLEAN LockState,
+ IN BOOLEAN OpenState,
+ IN OUT UINTN *SmramMapSize,
+ IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
+ )
+{
+ UINTN OriginalSize;
+ UINT32 TsegMemoryBaseMb, TsegMemoryBase;
+ UINT64 CommonRegionState;
+ UINT8 TsegSizeBits;
+
+ OriginalSize = *SmramMapSize;
+ *SmramMapSize = DescIdxCount * sizeof *SmramMap;
+ if (OriginalSize < *SmramMapSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ //
+ // Read the TSEG Memory Base register.
+ //
+ TsegMemoryBaseMb = PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB));
+
+ TsegMemoryBaseMb = 0xDF800000;
+
+ TsegMemoryBase = (TsegMemoryBaseMb >> MCH_TSEGMB_MB_SHIFT) << 20;
+
+ //
+ // Precompute the region state bits that will be set for all regions.
+ //
+ CommonRegionState = (OpenState ? EFI_SMRAM_OPEN : EFI_SMRAM_CLOSED) |
+ (LockState ? EFI_SMRAM_LOCKED : 0) |
+ EFI_CACHEABLE;
+
+ //
+ // The first region hosts an SMM_S3_RESUME_STATE object. It is located at the
+ // start of TSEG. We round up the size to whole pages, and we report it as
+ // EFI_ALLOCATED, so that the SMM_CORE stays away from it.
+ //
+ SmramMap[DescIdxSmmS3ResumeState].PhysicalStart = TsegMemoryBase;
+ SmramMap[DescIdxSmmS3ResumeState].CpuStart = TsegMemoryBase;
+ SmramMap[DescIdxSmmS3ResumeState].PhysicalSize =
+ EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (sizeof (SMM_S3_RESUME_STATE)));
+ SmramMap[DescIdxSmmS3ResumeState].RegionState =
+ CommonRegionState | EFI_ALLOCATED;
+
+ //
+ // Get the TSEG size bits from the ESMRAMC register.
+ //
+ TsegSizeBits = PciRead8 (DRAMC_REGISTER_X58(MCH_TSEGMB)) &
+ MCH_ESMRAMC_TSEG_MASK;
+
+ TsegSizeBits = MCH_ESMRAMC_TSEG_8MB;
+
+ //
+ // The second region is the main one, following the first.
+ //
+ SmramMap[DescIdxMain].PhysicalStart =
+ SmramMap[DescIdxSmmS3ResumeState].PhysicalStart +
+ SmramMap[DescIdxSmmS3ResumeState].PhysicalSize;
+ SmramMap[DescIdxMain].CpuStart = SmramMap[DescIdxMain].PhysicalStart;
+ SmramMap[DescIdxMain].PhysicalSize =
+ (TsegSizeBits == MCH_ESMRAMC_TSEG_8MB ? SIZE_8MB :
+ TsegSizeBits == MCH_ESMRAMC_TSEG_2MB ? SIZE_2MB :
+ SIZE_1MB) - SmramMap[DescIdxSmmS3ResumeState].PhysicalSize;
+ SmramMap[DescIdxMain].RegionState = CommonRegionState;
+
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/SimicsX58SktPkg/Include/Register/X58SmramSaveStateMap.h b/Silicon/Intel/SimicsX58SktPkg/Include/Register/X58SmramSaveStateMap.h
new file mode 100644
index 0000000000..db8ee2c37a
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Include/Register/X58SmramSaveStateMap.h
@@ -0,0 +1,178 @@
+/** @file
+SMRAM Save State Map Definitions.
+
+SMRAM Save State Map definitions based on contents of the
+Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+ Volume 3C, Section 34.4 SMRAM
+ Volume 3C, Section 34.5 SMI Handler Execution Environment
+ Volume 3C, Section 34.7 Managing Synchronous and Asynchronous SMIs
+
+and the AMD64 Architecture Programmer's Manual
+ Volume 2, Section 10.2 SMM Resources
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Red Hat, Inc.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __X58_SMRAM_SAVE_STATE_MAP_H__
+#define __X58_SMRAM_SAVE_STATE_MAP_H__
+
+#pragma pack (1)
+
+///
+/// 32-bit SMRAM Save State Map
+///
+typedef struct {
+ UINT8 Reserved0[0x200]; // 7c00h
+ UINT8 Reserved1[0xf8]; // 7e00h
+ UINT32 SMBASE; // 7ef8h
+ UINT32 SMMRevId; // 7efch
+ UINT16 IORestart; // 7f00h
+ UINT16 AutoHALTRestart; // 7f02h
+ UINT8 Reserved2[0x9C]; // 7f08h
+ UINT32 IOMemAddr; // 7fa0h
+ UINT32 IOMisc; // 7fa4h
+ UINT32 _ES; // 7fa8h
+ UINT32 _CS; // 7fach
+ UINT32 _SS; // 7fb0h
+ UINT32 _DS; // 7fb4h
+ UINT32 _FS; // 7fb8h
+ UINT32 _GS; // 7fbch
+ UINT32 Reserved3; // 7fc0h
+ UINT32 _TR; // 7fc4h
+ UINT32 _DR7; // 7fc8h
+ UINT32 _DR6; // 7fcch
+ UINT32 _EAX; // 7fd0h
+ UINT32 _ECX; // 7fd4h
+ UINT32 _EDX; // 7fd8h
+ UINT32 _EBX; // 7fdch
+ UINT32 _ESP; // 7fe0h
+ UINT32 _EBP; // 7fe4h
+ UINT32 _ESI; // 7fe8h
+ UINT32 _EDI; // 7fech
+ UINT32 _EIP; // 7ff0h
+ UINT32 _EFLAGS; // 7ff4h
+ UINT32 _CR3; // 7ff8h
+ UINT32 _CR0; // 7ffch
+} X58_SMRAM_SAVE_STATE_MAP32;
+
+///
+/// 64-bit SMRAM Save State Map
+///
+typedef struct {
+ UINT8 Reserved0[0x200]; // 7c00h
+
+ UINT16 _ES; // 7e00h
+ UINT16 _ESAccessRights; // 7e02h
+ UINT32 _ESLimit; // 7e04h
+ UINT64 _ESBase; // 7e08h
+
+ UINT16 _CS; // 7e10h
+ UINT16 _CSAccessRights; // 7e12h
+ UINT32 _CSLimit; // 7e14h
+ UINT64 _CSBase; // 7e18h
+
+ UINT16 _SS; // 7e20h
+ UINT16 _SSAccessRights; // 7e22h
+ UINT32 _SSLimit; // 7e24h
+ UINT64 _SSBase; // 7e28h
+
+ UINT16 _DS; // 7e30h
+ UINT16 _DSAccessRights; // 7e32h
+ UINT32 _DSLimit; // 7e34h
+ UINT64 _DSBase; // 7e38h
+
+ UINT16 _FS; // 7e40h
+ UINT16 _FSAccessRights; // 7e42h
+ UINT32 _FSLimit; // 7e44h
+ UINT64 _FSBase; // 7e48h
+
+ UINT16 _GS; // 7e50h
+ UINT16 _GSAccessRights; // 7e52h
+ UINT32 _GSLimit; // 7e54h
+ UINT64 _GSBase; // 7e58h
+
+ UINT32 _GDTRReserved1; // 7e60h
+ UINT16 _GDTRLimit; // 7e64h
+ UINT16 _GDTRReserved2; // 7e66h
+ UINT64 _GDTRBase; // 7e68h
+
+ UINT16 _LDTR; // 7e70h
+ UINT16 _LDTRAccessRights; // 7e72h
+ UINT32 _LDTRLimit; // 7e74h
+ UINT64 _LDTRBase; // 7e78h
+
+ UINT32 _IDTRReserved1; // 7e80h
+ UINT16 _IDTRLimit; // 7e84h
+ UINT16 _IDTRReserved2; // 7e86h
+ UINT64 _IDTRBase; // 7e88h
+
+ UINT16 _TR; // 7e90h
+ UINT16 _TRAccessRights; // 7e92h
+ UINT32 _TRLimit; // 7e94h
+ UINT64 _TRBase; // 7e98h
+
+ UINT64 IO_RIP; // 7ea0h
+ UINT64 IO_RCX; // 7ea8h
+ UINT64 IO_RSI; // 7eb0h
+ UINT64 IO_RDI; // 7eb8h
+ UINT32 IO_DWord; // 7ec0h
+ UINT8 Reserved1[0x04]; // 7ec4h
+ UINT8 IORestart; // 7ec8h
+ UINT8 AutoHALTRestart; // 7ec9h
+ UINT8 Reserved2[0x06]; // 7ecah
+
+ UINT64 IA32_EFER; // 7ed0h
+ UINT64 SVM_Guest; // 7ed8h
+ UINT64 SVM_GuestVMCB; // 7ee0h
+ UINT64 SVM_GuestVIntr; // 7ee8h
+ UINT8 Reserved3[0x0c]; // 7ef0h
+
+ UINT32 SMMRevId; // 7efch
+ UINT32 SMBASE; // 7f00h
+
+ UINT8 Reserved4[0x1c]; // 7f04h
+ UINT64 SVM_GuestPAT; // 7f20h
+ UINT64 SVM_HostIA32_EFER; // 7f28h
+ UINT64 SVM_HostCR4; // 7f30h
+ UINT64 SVM_HostCR3; // 7f38h
+ UINT64 SVM_HostCR0; // 7f40h
+
+ UINT64 _CR4; // 7f48h
+ UINT64 _CR3; // 7f50h
+ UINT64 _CR0; // 7f58h
+ UINT64 _DR7; // 7f60h
+ UINT64 _DR6; // 7f68h
+ UINT64 _RFLAGS; // 7f70h
+ UINT64 _RIP; // 7f78h
+ UINT64 _R15; // 7f80h
+ UINT64 _R14; // 7f88h
+ UINT64 _R13; // 7f90h
+ UINT64 _R12; // 7f98h
+ UINT64 _R11; // 7fa0h
+ UINT64 _R10; // 7fa8h
+ UINT64 _R9; // 7fb0h
+ UINT64 _R8; // 7fb8h
+ UINT64 _RDI; // 7fc0h
+ UINT64 _RSI; // 7fc8h
+ UINT64 _RBP; // 7fd0h
+ UINT64 _RSP; // 7fd8h
+ UINT64 _RBX; // 7fe0h
+ UINT64 _RDX; // 7fe8h
+ UINT64 _RCX; // 7ff0h
+ UINT64 _RAX; // 7ff8h
+} X58_SMRAM_SAVE_STATE_MAP64;
+
+///
+/// Union of 32-bit and 64-bit SMRAM Save State Maps
+///
+typedef union {
+ X58_SMRAM_SAVE_STATE_MAP32 x86;
+ X58_SMRAM_SAVE_STATE_MAP64 x64;
+} X58_SMRAM_SAVE_STATE_MAP;
+
+#pragma pack ()
+
+#endif
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPkg.dec b/Silicon/Intel/SimicsX58SktPkg/SktPkg.dec
new file mode 100644
index 0000000000..9fbc546167
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPkg.dec
@@ -0,0 +1,37 @@
+## @file
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = SimicsX58SktPkg
+ PACKAGE_GUID = 070FEC45-BF03-41C1-8D46-8BBE032A7C0C
+ PACKAGE_VERSION = 0.91
+
+[Includes]
+ Include
+
+[Guids]
+ gSimicsX58PkgTokenSpaceGuid = {0x5b276d20, 0x37d0, 0x4af0, {0x8d, 0x04, 0x47, 0x91, 0x2b, 0x7c, 0x1d, 0x44}}
+
+[PcdsFixedAtBuild]
+ ## The following setting controls how many megabytes we configure as TSEG on
+ # X58, for SMRAM purposes. Permitted values are: 1, 2, 8. Other values cause
+ # undefined behavior.
+ #
+ # This PCD is only consulted if PcdSmmSmramRequire is TRUE (see below).
+ gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes|8|UINT8|0x20
+
+[PcdsFeatureFlag]
+ ## This feature flag enables SMM/SMRAM support. Note that it also requires
+ # such support from the underlying QEMU instance; if that support is not
+ # present, the firmware will reject continuing after a certain point.
+ #
+ # The flag also acts as a general "security switch"; when TRUE, many
+ # components will change behavior, with the goal of preventing a malicious
+ # runtime OS from tampering with firmware structures (special memory ranges
+ # used by OVMF, the varstore pflash chip, LockBox etc).
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire|FALSE|BOOLEAN|0x1e
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc b/Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc
new file mode 100644
index 0000000000..af83c380b8
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc
@@ -0,0 +1,14 @@
+## @file
+# Component description file for the X58 SiPkg PEI drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+ #
+ # SEC Phase modules
+ #
+ UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
+ UefiCpuPkg/CpuMpPei/CpuMpPei.inf
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
new file mode 100644
index 0000000000..12e43e86d0
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
@@ -0,0 +1,9 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
new file mode 100644
index 0000000000..5b9cd9ee25
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
@@ -0,0 +1,10 @@
+## @file
+# Component description file for the X58 SiPkg PEI drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+INF UefiCpuPkg/CpuMpPei/CpuMpPei.inf
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
new file mode 100644
index 0000000000..5019e362e3
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
@@ -0,0 +1,16 @@
+## @file
+# Component description file for the X58 SiPkg PEI drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#
+# SEC Phase modules
+#
+# The code in this FV handles the initial firmware startup, and
+# decompresses the PEI and DXE FVs which handles the rest of the boot sequence.
+#
+INF RuleOverride=RESET_VECTOR USE = IA32 UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
new file mode 100644
index 0000000000..b38c3b1108
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
@@ -0,0 +1,14 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+ INF $(SKT_PKG)/Smm/Access/SmmAccess2Dxe.inf
+ INF UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+!endif
+INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
new file mode 100644
index 0000000000..eb8c8f93dd
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
@@ -0,0 +1,54 @@
+## @file
+# A DXE_DRIVER providing SMRAM access by producing EFI_SMM_ACCESS2_PROTOCOL.
+#
+# X58 TSEG is expected to have been verified and set up by the SmmAccessPei
+# driver.
+#
+# Copyright (C) 2013, 2015, Red Hat, Inc.
+# Copyright (C) 2019, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmmAccess2Dxe
+ FILE_GUID = AC95AD3D-4366-44BF-9A62-E4B29D7A2206
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010400
+ ENTRY_POINT = SmmAccess2DxeEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ SmmAccess2Dxe.c
+ SmramInternal.c
+ SmramInternal.h
+
+[Packages]
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ SimicsX58SktPkg/SktPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[LibraryClasses]
+ DebugLib
+ PcdLib
+ PciLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEfiSmmAccess2ProtocolGuid ## PRODUCES
+
+[FeaturePcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
+
+[Depex]
+ TRUE
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
new file mode 100644
index 0000000000..2b6b14f437
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
@@ -0,0 +1,65 @@
+## @file
+# A PEIM with the following responsibilities:
+#
+# - provide SMRAM access by producing PEI_SMM_ACCESS_PPI,
+# - verify & configure the X58 TSEG in the entry point,
+# - set aside the SMM_S3_RESUME_STATE object at the bottom of TSEG, and expose
+# it via the gEfiAcpiVariableGuid GUIDed HOB.
+#
+# Copyright (C) 2013, 2015, Red Hat, Inc.
+# Copyright (C) 2019, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmmAccessPei
+ FILE_GUID = 6C0E75B4-B0B9-44D1-8210-3377D7B4E066
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SmmAccessPeiEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ SmmAccessPei.c
+ SmramInternal.c
+ SmramInternal.h
+
+[Packages]
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ SimicsX58SktPkg/SktPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[Guids]
+ gEfiAcpiVariableGuid
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ HobLib
+ IoLib
+ PcdLib
+ PciLib
+ PeiServicesLib
+ PeimEntryPoint
+
+[FeaturePcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
+
+[FixedPcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes
+
+[Ppis]
+ gPeiSmmAccessPpiGuid ## PRODUCES
+
+[Depex]
+ gEfiPeiMemoryDiscoveredPpiGuid
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
new file mode 100644
index 0000000000..43a79b295f
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
@@ -0,0 +1,81 @@
+/** @file
+ Functions and types shared by the SMM accessor PEI and DXE modules.
+
+ Copyright (C) 2015, Red Hat, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Pi/PiMultiPhase.h>
+
+//
+// We'll have two SMRAM ranges.
+//
+// The first is a tiny one that hosts an SMM_S3_RESUME_STATE object, to be
+// filled in by the CPU SMM driver during normal boot, for the PEI instance of
+// the LockBox library (which will rely on the object during S3 resume).
+//
+// The other SMRAM range is the main one, for the SMM core and the SMM drivers.
+//
+typedef enum {
+ DescIdxSmmS3ResumeState = 0,
+ DescIdxMain = 1,
+ DescIdxCount = 2
+} DESCRIPTOR_INDEX;
+
+/**
+ Read the MCH_SMRAM and ESMRAMC registers, and update the LockState and
+ OpenState fields in the PEI_SMM_ACCESS_PPI / EFI_SMM_ACCESS2_PROTOCOL object,
+ from the D_LCK and T_EN bits.
+
+ PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member functions can rely on
+ the LockState and OpenState fields being up-to-date on entry, and they need
+ to restore the same invariant on exit, if they touch the bits in question.
+
+ @param[out] LockState Reflects the D_LCK bit on output; TRUE iff SMRAM is
+ locked.
+ @param[out] OpenState Reflects the inverse of the T_EN bit on output; TRUE
+ iff SMRAM is open.
+**/
+VOID
+GetStates (
+ OUT BOOLEAN *LockState,
+ OUT BOOLEAN *OpenState
+ );
+
+//
+// The functions below follow the PEI_SMM_ACCESS_PPI and
+// EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices and This
+// pointers are removed (TSEG doesn't depend on them), and so is the
+// DescriptorIndex parameter (TSEG doesn't support range-wise locking).
+//
+// The LockState and OpenState members that are common to both
+// PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken and updated in
+// isolation from the rest of the (non-shared) members.
+//
+
+EFI_STATUS
+SmramAccessOpen (
+ OUT BOOLEAN *LockState,
+ OUT BOOLEAN *OpenState
+ );
+
+EFI_STATUS
+SmramAccessClose (
+ OUT BOOLEAN *LockState,
+ OUT BOOLEAN *OpenState
+ );
+
+EFI_STATUS
+SmramAccessLock (
+ OUT BOOLEAN *LockState,
+ IN OUT BOOLEAN *OpenState
+ );
+
+EFI_STATUS
+SmramAccessGetCapabilities (
+ IN BOOLEAN LockState,
+ IN BOOLEAN OpenState,
+ IN OUT UINTN *SmramMapSize,
+ IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
+ );
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [edk2-platforms PATCH v2 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10
2019-08-28 0:40 [edk2-platforms PATCH v2 0/7] Add Initial QSP MinPlatform Pkg for SIMICS David Wei
2019-08-28 0:40 ` [edk2-platforms PATCH v2 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58 David Wei
@ 2019-08-28 0:40 ` David Wei
2019-08-28 22:02 ` Nate DeSimone
2019-08-28 0:40 ` [edk2-platforms PATCH v2 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules David Wei
` (4 subsequent siblings)
6 siblings, 1 reply; 16+ messages in thread
From: David Wei @ 2019-08-28 0:40 UTC (permalink / raw)
To: devel
Cc: Hao Wu, Liming Gao, Ankit Sinha, Agyeman Prince,
Kubacki Michael A, Nate DeSimone, Michael D Kinney
Add PCH Pkg for SimicsICH10. It is added for simics QSP project support
Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../Library/ResetSystemLib/ResetSystemLib.c | 137 +++
.../Library/SmmSpiFlashCommonLib/SpiFlashCommon.c | 194 +++++
.../SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c | 54 ++
.../LibraryPrivate/BasePchSpiCommonLib/SpiCommon.c | 935 +++++++++++++++++++++
.../SmmControl/RuntimeDxe/SmmControl2Dxe.c | 410 +++++++++
Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.c | 175 ++++
Silicon/Intel/SimicsIch10Pkg/Ich10Pkg.dec | 26 +
Silicon/Intel/SimicsIch10Pkg/IchCommonLib.dsc | 12 +
.../Intel/SimicsIch10Pkg/IchPostMemoryInclude.fdf | 9 +
.../Intel/SimicsIch10Pkg/IchPreMemoryInclude.fdf | 9 +
.../Intel/SimicsIch10Pkg/IchUefiBootInclude.fdf | 13 +
.../Include/Library/SpiFlashCommonLib.h | 98 +++
Silicon/Intel/SimicsIch10Pkg/Include/PchAccess.h | 43 +
Silicon/Intel/SimicsIch10Pkg/Include/PchLimits.h | 94 +++
.../SimicsIch10Pkg/Include/PchReservedResources.h | 60 ++
.../Intel/SimicsIch10Pkg/Include/Protocol/Spi.h | 295 +++++++
.../SimicsIch10Pkg/Include/Register/PchRegsPmc.h | 647 ++++++++++++++
.../SimicsIch10Pkg/Include/Register/PchRegsSpi.h | 304 +++++++
.../SimicsIch10Pkg/Include/Register/X58Ich10.h | 113 +++
.../IncludePrivate/Library/PchSpiCommonLib.h | 396 +++++++++
.../Library/ResetSystemLib/ResetSystemLib.inf | 34 +
.../SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf | 50 ++
.../BasePchSpiCommonLib/BasePchSpiCommonLib.inf | 31 +
.../SmmControl/RuntimeDxe/SmmControl2Dxe.inf | 61 ++
Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.h | 23 +
Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpiSmm.inf | 44 +
26 files changed, 4267 insertions(+)
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.c
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c
create mode 100644 Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/SpiCommon.c
create mode 100644 Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.c
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.c
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Ich10Pkg.dec
create mode 100644 Silicon/Intel/SimicsIch10Pkg/IchCommonLib.dsc
create mode 100644 Silicon/Intel/SimicsIch10Pkg/IchPostMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/IchPreMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/IchUefiBootInclude.fdf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Library/SpiFlashCommonLib.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/PchAccess.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/PchLimits.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/PchReservedResources.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Protocol/Spi.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsPmc.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsSpi.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Register/X58Ich10.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/IncludePrivate/Library/PchSpiCommonLib.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.inf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePchSpiCommonLib.inf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpiSmm.inf
diff --git a/Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.c b/Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.c
new file mode 100644
index 0000000000..ad3e4f455e
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.c
@@ -0,0 +1,137 @@
+/** @file
+ Reset System Library functions for Simics ICH10
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Register/X58Ich10.h>
+
+
+VOID
+AcpiPmControl (
+ UINTN SuspendType
+ )
+{
+ ASSERT (SuspendType < 6);
+ DEBUG((EFI_D_ERROR, "SuspendType = 0x%x\n", SuspendType));
+
+ IoBitFieldWrite16 (ICH10_PMBASE_IO + 4, 10, 13, (UINT16) SuspendType);
+ IoOr16 (ICH10_PMBASE_IO + 0x04, BIT13);
+ CpuDeadLoop ();
+}
+
+/**
+ Calling this function causes a system-wide reset. This sets
+ all circuitry within the system to its initial state. This type of reset
+ is asynchronous to system operation and operates without regard to
+ cycle boundaries.
+
+ System reset should not return, if it returns, it means the system does
+ not support cold reset.
+**/
+VOID
+EFIAPI
+ResetCold (
+ VOID
+ )
+{
+ DEBUG((EFI_D_ERROR, "ResetCold_CF9\n"));
+ IoWrite8 (0xCF9, BIT3 | BIT2 | BIT1); // 1st choice: PIIX3 RCR, RCPU|SRST
+ MicroSecondDelay (50);
+
+ DEBUG((EFI_D_ERROR, "ResetCold_Port64\n"));
+ IoWrite8 (0x64, 0xfe); // 2nd choice: keyboard controller
+ CpuDeadLoop ();
+}
+
+/**
+ Calling this function causes a system-wide initialization. The processors
+ are set to their initial state, and pending cycles are not corrupted.
+
+ System reset should not return, if it returns, it means the system does
+ not support warm reset.
+**/
+VOID
+EFIAPI
+ResetWarm (
+ VOID
+ )
+{
+ DEBUG((EFI_D_ERROR, "ResetWarm\n"));
+ //
+ //BUGBUG workaround for warm reset
+ //
+ IoWrite8(0xCF9, BIT2 | BIT1);
+ MicroSecondDelay(50);
+
+ IoWrite8 (0x64, 0xfe);
+ CpuDeadLoop ();
+}
+
+/**
+ Calling this function causes the system to enter a power state equivalent
+ to the ACPI G2/S5 or G3 states.
+
+ System shutdown should not return, if it returns, it means the system does
+ not support shut down reset.
+**/
+VOID
+EFIAPI
+ResetShutdown (
+ VOID
+ )
+{
+ DEBUG((EFI_D_ERROR, "ResetShutdown\n"));
+ AcpiPmControl (0);
+ ASSERT (FALSE);
+}
+
+
+/**
+ Calling this function causes the system to enter a power state for capsule
+ update.
+
+ Reset update should not return, if it returns, it means the system does
+ not support capsule update.
+
+**/
+VOID
+EFIAPI
+EnterS3WithImmediateWake (
+ VOID
+ )
+{
+ DEBUG((EFI_D_ERROR, "EnterS3WithImmediateWake\n"));
+ AcpiPmControl (1);
+ ASSERT (FALSE);
+}
+
+/**
+ This function causes a systemwide reset. The exact type of the reset is
+ defined by the EFI_GUID that follows the Null-terminated Unicode string passed
+ into ResetData. If the platform does not recognize the EFI_GUID in ResetData
+ the platform must pick a supported reset type to perform.The platform may
+ optionally log the parameters from any non-normal reset that occurs.
+
+ @param[in] DataSize The size, in bytes, of ResetData.
+ @param[in] ResetData The data buffer starts with a Null-terminated string,
+ followed by the EFI_GUID.
+**/
+VOID
+EFIAPI
+ResetPlatformSpecific (
+ IN UINTN DataSize,
+ IN VOID *ResetData
+ )
+{
+ DEBUG((EFI_D_ERROR, "ResetPlatformSpecific\n"));
+ ResetCold ();
+}
diff --git a/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c b/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c
new file mode 100644
index 0000000000..9e3461cbd6
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c
@@ -0,0 +1,194 @@
+/** @file
+ Wrap EFI_SPI_PROTOCOL to provide some library level interfaces
+ for module use.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/SpiFlashCommonLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Protocol/Spi.h>
+
+
+EFI_SPI_PROTOCOL *mSpiProtocol;
+
+//
+// FlashAreaBaseAddress and Size for boottime and runtime usage.
+//
+UINTN mFlashAreaBaseAddress = 0;
+UINTN mFlashAreaSize = 0;
+
+/**
+ Enable block protection on the Serial Flash device.
+
+ @retval EFI_SUCCESS Opertion is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashLock (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ Read NumBytes bytes of data from the address specified by
+ PAddress into Buffer.
+
+ @param[in] Address The starting physical address of the read.
+ @param[in,out] NumBytes On input, the number of bytes to read. On output, the number
+ of bytes actually read.
+ @param[out] Buffer The destination data buffer for the read.
+
+ @retval EFI_SUCCESS Opertion is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashRead (
+ IN UINTN Address,
+ IN OUT UINT32 *NumBytes,
+ OUT UINT8 *Buffer
+ )
+{
+ ASSERT ((NumBytes != NULL) && (Buffer != NULL));
+ if ((NumBytes == NULL) || (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // This function is implemented specifically for those platforms
+ // at which the SPI device is memory mapped for read. So this
+ // function just do a memory copy for Spi Flash Read.
+ //
+ CopyMem (Buffer, (VOID *) Address, *NumBytes);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Write NumBytes bytes of data from Buffer to the address specified by
+ PAddresss.
+
+ @param[in] Address The starting physical address of the write.
+ @param[in,out] NumBytes On input, the number of bytes to write. On output,
+ the actual number of bytes written.
+ @param[in] Buffer The source data buffer for the write.
+
+ @retval EFI_SUCCESS Opertion is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashWrite (
+ IN UINTN Address,
+ IN OUT UINT32 *NumBytes,
+ IN UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN Offset;
+ UINT32 Length;
+ UINT32 RemainingBytes;
+
+ ASSERT ((NumBytes != NULL) && (Buffer != NULL));
+ if ((NumBytes == NULL) || (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ASSERT (Address >= mFlashAreaBaseAddress);
+
+ Offset = Address - mFlashAreaBaseAddress;
+
+ ASSERT ((*NumBytes + Offset) <= mFlashAreaSize);
+
+ Status = EFI_SUCCESS;
+ RemainingBytes = *NumBytes;
+
+
+ while (RemainingBytes > 0) {
+ if (RemainingBytes > SECTOR_SIZE_4KB) {
+ Length = SECTOR_SIZE_4KB;
+ } else {
+ Length = RemainingBytes;
+ }
+ Status = mSpiProtocol->FlashWrite (
+ mSpiProtocol,
+ FlashRegionBios,
+ (UINT32) Offset,
+ Length,
+ Buffer
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ RemainingBytes -= Length;
+ Offset += Length;
+ Buffer += Length;
+ }
+
+ //
+ // Actual number of bytes written
+ //
+ *NumBytes -= RemainingBytes;
+
+ return Status;
+}
+
+/**
+ Erase the block starting at Address.
+
+ @param[in] Address The starting physical address of the block to be erased.
+ This library assume that caller garantee that the PAddress
+ is at the starting address of this block.
+ @param[in] NumBytes On input, the number of bytes of the logical block to be erased.
+ On output, the actual number of bytes erased.
+
+ @retval EFI_SUCCESS. Opertion is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashBlockErase (
+ IN UINTN Address,
+ IN UINTN *NumBytes
+ )
+{
+ EFI_STATUS Status;
+ UINTN Offset;
+ UINTN RemainingBytes;
+
+ ASSERT (NumBytes != NULL);
+ if (NumBytes == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ASSERT (Address >= mFlashAreaBaseAddress);
+
+ Offset = Address - mFlashAreaBaseAddress;
+
+ ASSERT ((*NumBytes % SECTOR_SIZE_4KB) == 0);
+ ASSERT ((*NumBytes + Offset) <= mFlashAreaSize);
+
+ Status = EFI_SUCCESS;
+ RemainingBytes = *NumBytes;
+
+
+ Status = mSpiProtocol->FlashErase (
+ mSpiProtocol,
+ FlashRegionBios,
+ (UINT32) Offset,
+ (UINT32) RemainingBytes
+ );
+ return Status;
+}
+
diff --git a/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c b/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c
new file mode 100644
index 0000000000..984b7733c6
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c
@@ -0,0 +1,54 @@
+/** @file
+ SMM Library instance of SPI Flash Common Library Class
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/SpiFlashCommonLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Protocol/Spi.h>
+
+extern EFI_SPI_PROTOCOL *mSpiProtocol;
+
+extern UINTN mFlashAreaBaseAddress;
+extern UINTN mFlashAreaSize;
+
+/**
+ The library constructuor.
+
+ The function does the necessary initialization work for this library
+ instance.
+
+ @param[in] ImageHandle The firmware allocated handle for the UEFI image.
+ @param[in] SystemTable A pointer to the EFI system table.
+
+ @retval EFI_SUCCESS The function always return EFI_SUCCESS for now.
+ It will ASSERT on error for debug version.
+ @retval EFI_ERROR Please reference LocateProtocol for error code details.
+**/
+EFI_STATUS
+EFIAPI
+SmmSpiFlashCommonLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ mFlashAreaBaseAddress = (UINTN)PcdGet32 (PcdFlashAreaBaseAddress);
+ mFlashAreaSize = (UINTN)PcdGet32 (PcdFlashAreaSize);
+
+ //
+ // Locate the SMM SPI protocol.
+ //
+ Status = gSmst->SmmLocateProtocol (
+ &gEfiSmmSpiProtocolGuid,
+ NULL,
+ (VOID **) &mSpiProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/SpiCommon.c b/Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/SpiCommon.c
new file mode 100644
index 0000000000..bd08b2453b
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/SpiCommon.c
@@ -0,0 +1,935 @@
+/** @file
+ PCH SPI Common Driver implements the SPI Host Controller Compatibility Interface.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <PchAccess.h>
+#include <Protocol/Spi.h>
+#include <IncludePrivate/Library/PchSpiCommonLib.h>
+#include <Register/X58Ich10.h>
+
+/**
+ Initialize an SPI protocol instance.
+
+ @param[in] SpiInstance Pointer to SpiInstance to initialize
+
+ @retval EFI_SUCCESS The protocol instance was properly initialized
+ @exception EFI_UNSUPPORTED The PCH is not supported by this module
+**/
+EFI_STATUS
+SpiProtocolConstructor (
+ IN SPI_INSTANCE *SpiInstance
+ )
+{
+ UINTN PchSpiBar0;
+
+ //
+ // Initialize the SPI protocol instance
+ //
+ SpiInstance->Signature = PCH_SPI_PRIVATE_DATA_SIGNATURE;
+ SpiInstance->Handle = NULL;
+ SpiInstance->SpiProtocol.Revision = PCH_SPI_SERVICES_REVISION;
+ SpiInstance->SpiProtocol.FlashRead = SpiProtocolFlashRead;
+ SpiInstance->SpiProtocol.FlashWrite = SpiProtocolFlashWrite;
+ SpiInstance->SpiProtocol.FlashErase = SpiProtocolFlashErase;
+ SpiInstance->SpiProtocol.FlashReadSfdp = SpiProtocolFlashReadSfdp;
+ SpiInstance->SpiProtocol.FlashReadJedecId = SpiProtocolFlashReadJedecId;
+ SpiInstance->SpiProtocol.FlashWriteStatus = SpiProtocolFlashWriteStatus;
+ SpiInstance->SpiProtocol.FlashReadStatus = SpiProtocolFlashReadStatus;
+ SpiInstance->SpiProtocol.GetRegionAddress = SpiProtocolGetRegionAddress;
+ SpiInstance->SpiProtocol.ReadPchSoftStrap = SpiProtocolReadPchSoftStrap;
+ SpiInstance->SpiProtocol.ReadCpuSoftStrap = SpiProtocolReadCpuSoftStrap;
+
+ SpiInstance->PchAcpiBase = ICH10_PMBASE_IO;
+ ASSERT (SpiInstance->PchAcpiBase != 0);
+
+ PchSpiBar0 = RCRB + SPIBAR;
+
+ if (PchSpiBar0 == 0) {
+ DEBUG ((DEBUG_ERROR, "ERROR : PchSpiBar0 is invalid!\n"));
+ ASSERT (FALSE);
+ }
+
+ if ((MmioRead32 (PchSpiBar0 + R_PCH_SPI_HSFSC) & B_PCH_SPI_HSFSC_FDV) == 0) {
+ DEBUG ((DEBUG_ERROR, "ERROR : SPI Flash Signature invalid, cannot use the Hardware Sequencing registers!\n"));
+ ASSERT (FALSE);
+ }
+ SpiInstance->ReadPermission = 0xffff;
+ SpiInstance->WritePermission = 0xffff;
+ DEBUG ((DEBUG_INFO, "Flash Region Permission: Read- 0x%04x; Write= 0x%04x\n",
+ SpiInstance->ReadPermission,
+ SpiInstance->WritePermission));
+
+ //
+ SpiInstance->TotalFlashSize = PcdGet32(PcdFlashAreaSize);
+ DEBUG ((DEBUG_INFO, "Total Flash Size : %0x\n", SpiInstance->TotalFlashSize));
+ return EFI_SUCCESS;
+}
+
+/**
+ Delay for at least the request number of microseconds for Runtime usage.
+
+ @param[in] ABase Acpi base address
+ @param[in] Microseconds Number of microseconds to delay.
+
+**/
+VOID
+EFIAPI
+PchPmTimerStallRuntimeSafe (
+ IN UINT16 ABase,
+ IN UINTN Microseconds
+ )
+{
+ UINTN Ticks;
+ UINTN Counts;
+ UINTN CurrentTick;
+ UINTN OriginalTick;
+ UINTN RemainingTick;
+
+ if (Microseconds == 0) {
+ return;
+ }
+
+ OriginalTick = IoRead32 ((UINTN) (ABase + R_PCH_ACPI_PM1_TMR)) & B_PCH_ACPI_PM1_TMR_VAL;
+ CurrentTick = OriginalTick;
+
+ //
+ // The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks
+ //
+ Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
+
+ //
+ // The loops needed by timer overflow
+ //
+ Counts = Ticks / V_PCH_ACPI_PM1_TMR_MAX_VAL;
+
+ //
+ // Remaining clocks within one loop
+ //
+ RemainingTick = Ticks % V_PCH_ACPI_PM1_TMR_MAX_VAL;
+
+ //
+ // not intend to use TMROF_STS bit of register PM1_STS, because this adds extra
+ // one I/O operation, and maybe generate SMI
+ //
+ while ((Counts != 0) || (RemainingTick > CurrentTick)) {
+ CurrentTick = IoRead32 ((UINTN) (ABase + R_PCH_ACPI_PM1_TMR)) & B_PCH_ACPI_PM1_TMR_VAL;
+ //
+ // Check if timer overflow
+ //
+ if ((CurrentTick < OriginalTick)) {
+ if (Counts != 0) {
+ Counts--;
+ } else {
+ //
+ // If timer overflow and Counts equ to 0, that means we already stalled more than
+ // RemainingTick, break the loop here
+ //
+ break;
+ }
+ }
+
+ OriginalTick = CurrentTick;
+ }
+}
+
+/**
+ Read data from the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+ @param[out] Buffer The Pointer to caller-allocated buffer containing the dada received.
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashRead (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ OUT UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Sends the command to the SPI interface to execute.
+ //
+ Status = SendSpiCmd (
+ This,
+ FlashRegionType,
+ FlashCycleRead,
+ Address,
+ ByteCount,
+ Buffer
+ );
+ return Status;
+}
+
+/**
+ Write data to the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+ @param[in] Buffer Pointer to caller-allocated buffer containing the data sent during the SPI cycle.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashWrite (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ IN UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Sends the command to the SPI interface to execute.
+ //
+ Status = SendSpiCmd (
+ This,
+ FlashRegionType,
+ FlashCycleWrite,
+ Address,
+ ByteCount,
+ Buffer
+ );
+ return Status;
+}
+
+/**
+ Erase some area on the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashErase (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Sends the command to the SPI interface to execute.
+ //
+ Status = SendSpiCmd (
+ This,
+ FlashRegionType,
+ FlashCycleErase,
+ Address,
+ ByteCount,
+ NULL
+ );
+ return Status;
+}
+
+/**
+ Read SFDP data from the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ComponentNumber The Componen Number for chip select
+ @param[in] Address The starting byte address for SFDP data read.
+ @param[in] ByteCount Number of bytes in SFDP data portion of the SPI cycle
+ @param[out] SfdpData The Pointer to caller-allocated buffer containing the SFDP data received
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadSfdp (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT8 ComponentNumber,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ OUT UINT8 *SfdpData
+ )
+{
+ SPI_INSTANCE *SpiInstance;
+ EFI_STATUS Status;
+ UINT32 FlashAddress;
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+ Status = EFI_SUCCESS;
+
+ if (ComponentNumber > SpiInstance->NumberOfComponents) {
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FlashAddress = 0;
+ if (ComponentNumber == FlashComponent1) {
+ FlashAddress = SpiInstance->Component1StartAddr;
+ }
+ FlashAddress += Address;
+ //
+ // Sends the command to the SPI interface to execute.
+ //
+ Status = SendSpiCmd (
+ This,
+ FlashRegionAll,
+ FlashCycleReadSfdp,
+ FlashAddress,
+ ByteCount,
+ SfdpData
+ );
+ return Status;
+}
+
+/**
+ Read Jedec Id from the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ComponentNumber The Componen Number for chip select
+ @param[in] ByteCount Number of bytes in JedecId data portion of the SPI cycle, the data size is 3 typically
+ @param[out] JedecId The Pointer to caller-allocated buffer containing JEDEC ID received
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadJedecId (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT8 ComponentNumber,
+ IN UINT32 ByteCount,
+ OUT UINT8 *JedecId
+ )
+{
+ SPI_INSTANCE *SpiInstance;
+ EFI_STATUS Status;
+ UINT32 Address;
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+ Status = EFI_SUCCESS;
+
+ if (ComponentNumber > SpiInstance->NumberOfComponents) {
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Address = 0;
+ if (ComponentNumber == FlashComponent1) {
+ Address = SpiInstance->Component1StartAddr;
+ }
+
+ //
+ // Sends the command to the SPI interface to execute.
+ //
+ Status = SendSpiCmd (
+ This,
+ FlashRegionAll,
+ FlashCycleReadJedecId,
+ Address,
+ ByteCount,
+ JedecId
+ );
+ return Status;
+}
+
+/**
+ Write the status register in the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ByteCount Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+ @param[in] StatusValue The Pointer to caller-allocated buffer containing the value of Status register writing
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashWriteStatus (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 ByteCount,
+ IN UINT8 *StatusValue
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Sends the command to the SPI interface to execute.
+ //
+ Status = SendSpiCmd (
+ This,
+ FlashRegionAll,
+ FlashCycleWriteStatus,
+ 0,
+ ByteCount,
+ StatusValue
+ );
+ return Status;
+}
+
+/**
+ Read status register in the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ByteCount Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+ @param[out] StatusValue The Pointer to caller-allocated buffer containing the value of Status register received.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadStatus (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 ByteCount,
+ OUT UINT8 *StatusValue
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Sends the command to the SPI interface to execute.
+ //
+ Status = SendSpiCmd (
+ This,
+ FlashRegionAll,
+ FlashCycleReadStatus,
+ 0,
+ ByteCount,
+ StatusValue
+ );
+ return Status;
+}
+
+/**
+ Get the SPI region base and size, based on the enum type
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for for the base address which is listed in the Descriptor.
+ @param[out] BaseAddress The Flash Linear Address for the Region 'n' Base
+ @param[out] RegionSize The size for the Region 'n'
+
+ @retval EFI_SUCCESS Read success
+ @retval EFI_INVALID_PARAMETER Invalid region type given
+ @retval EFI_DEVICE_ERROR The region is not used
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolGetRegionAddress (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ OUT UINT32 *BaseAddress,
+ OUT UINT32 *RegionSize
+ )
+{
+ SPI_INSTANCE *SpiInstance;
+ UINTN PchSpiBar0;
+ UINT32 ReadValue;
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+
+ if (FlashRegionType >= FlashRegionMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (FlashRegionType == FlashRegionAll) {
+ *BaseAddress = 0;
+ *RegionSize = SpiInstance->TotalFlashSize;
+ return EFI_SUCCESS;
+ }
+
+ PchSpiBar0 = AcquireSpiBar0 (SpiInstance);
+ ReadValue = MmioRead32 (PchSpiBar0 + (R_PCH_SPI_FREG0_FLASHD + (S_PCH_SPI_FREGX * ((UINT32) FlashRegionType))));
+ ReleaseSpiBar0 (SpiInstance);
+
+ //
+ // If the region is not used, the Region Base is 7FFFh and Region Limit is 0000h
+ //
+ if (ReadValue == B_PCH_SPI_FREGX_BASE_MASK) {
+ return EFI_DEVICE_ERROR;
+ }
+ *BaseAddress = ((ReadValue & B_PCH_SPI_FREGX_BASE_MASK) >> N_PCH_SPI_FREGX_BASE) <<
+ N_PCH_SPI_FREGX_BASE_REPR;
+ //
+ // Region limit address Bits[11:0] are assumed to be FFFh
+ //
+ *RegionSize = ((((ReadValue & B_PCH_SPI_FREGX_LIMIT_MASK) >> N_PCH_SPI_FREGX_LIMIT) + 1) <<
+ N_PCH_SPI_FREGX_LIMIT_REPR) - *BaseAddress;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Read PCH Soft Strap Values
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] SoftStrapAddr PCH Soft Strap address offset from FPSBA.
+ @param[in] ByteCount Number of bytes in SoftStrap data portion of the SPI cycle
+ @param[out] SoftStrapValue The Pointer to caller-allocated buffer containing PCH Soft Strap Value.
+ If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolReadPchSoftStrap (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 SoftStrapAddr,
+ IN UINT32 ByteCount,
+ OUT VOID *SoftStrapValue
+ )
+{
+ SPI_INSTANCE *SpiInstance;
+ UINT32 StrapFlashAddr;
+ EFI_STATUS Status;
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+
+ if (ByteCount == 0) {
+ *(UINT16 *) SoftStrapValue = SpiInstance->PchStrapSize;
+ return EFI_SUCCESS;
+ }
+
+ if ((SoftStrapAddr + ByteCount) > (UINT32) SpiInstance->PchStrapSize) {
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // PCH Strap Flash Address = FPSBA + RamAddr
+ //
+ StrapFlashAddr = SpiInstance->PchStrapBaseAddr + SoftStrapAddr;
+
+ //
+ // Read PCH Soft straps from using execute command
+ //
+ Status = SendSpiCmd (
+ This,
+ FlashRegionDescriptor,
+ FlashCycleRead,
+ StrapFlashAddr,
+ ByteCount,
+ SoftStrapValue
+ );
+ return Status;
+}
+
+/**
+ Read CPU Soft Strap Values
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] SoftStrapAddr CPU Soft Strap address offset from FCPUSBA.
+ @param[in] ByteCount Number of bytes in SoftStrap data portion of the SPI cycle.
+ @param[out] SoftStrapValue The Pointer to caller-allocated buffer containing CPU Soft Strap Value.
+ If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolReadCpuSoftStrap (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 SoftStrapAddr,
+ IN UINT32 ByteCount,
+ OUT VOID *SoftStrapValue
+ )
+{
+ SPI_INSTANCE *SpiInstance;
+ UINT32 StrapFlashAddr;
+ EFI_STATUS Status;
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+
+ if (ByteCount == 0) {
+ *(UINT16 *) SoftStrapValue = SpiInstance->CpuStrapSize;
+ return EFI_SUCCESS;
+ }
+
+ if ((SoftStrapAddr + ByteCount) > (UINT32) SpiInstance->CpuStrapSize) {
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // CPU Strap Flash Address = FCPUSBA + RamAddr
+ //
+ StrapFlashAddr = SpiInstance->CpuStrapBaseAddr + SoftStrapAddr;
+
+ //
+ // Read Cpu Soft straps from using execute command
+ //
+ Status = SendSpiCmd (
+ This,
+ FlashRegionDescriptor,
+ FlashCycleRead,
+ StrapFlashAddr,
+ ByteCount,
+ SoftStrapValue
+ );
+ return Status;
+}
+
+/**
+ This function sends the programmed SPI command to the slave device.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] SpiRegionType The SPI Region type for flash cycle which is listed in the Descriptor
+ @param[in] FlashCycleType The Flash SPI cycle type list in HSFC (Hardware Sequencing Flash Control Register) register
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+ @param[in,out] Buffer Pointer to caller-allocated buffer containing the dada received or sent during the SPI cycle.
+
+ @retval EFI_SUCCESS SPI command completes successfully.
+ @retval EFI_DEVICE_ERROR Device error, the command aborts abnormally.
+ @retval EFI_ACCESS_DENIED Some unrecognized command encountered in hardware sequencing mode
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+**/
+EFI_STATUS
+SendSpiCmd (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN FLASH_CYCLE_TYPE FlashCycleType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ IN OUT UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Index;
+ SPI_INSTANCE *SpiInstance;
+ UINTN SpiBaseAddress;
+ UINTN PchSpiBar0;
+ UINT32 HardwareSpiAddr;
+ UINT32 FlashRegionSize;
+ UINT32 SpiDataCount;
+ UINT32 FlashCycle;
+ UINT32 SmiEnSave;
+ UINT16 ABase;
+
+ Status = EFI_SUCCESS;
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+ SpiBaseAddress = SpiInstance->PchSpiBase;
+ PchSpiBar0 = AcquireSpiBar0 (SpiInstance);
+ SpiBaseAddress = SpiInstance->PchSpiBase;
+ ABase = SpiInstance->PchAcpiBase;
+
+ //
+ // Disable SMIs to make sure normal mode flash access is not interrupted by an SMI
+ // whose SMI handler accesses flash (e.g. for error logging)
+ //
+ // *** NOTE: if the SMI_LOCK bit is set (i.e., PMC PCI Offset A0h [4]='1'),
+ // clearing B_GBL_SMI_EN will not have effect. In this situation, some other
+ // synchronization methods must be applied here or in the consumer of the
+ // SendSpiCmd. An example method is disabling the specific SMI sources
+ // whose SMI handlers access flash before flash cycle and re-enabling the SMI
+ // sources after the flash cycle .
+ //
+ SmiEnSave = IoRead32 ((UINTN) (ABase + R_PCH_SMI_EN));
+ IoWrite32 ((UINTN) (ABase + R_PCH_SMI_EN), SmiEnSave & (UINT32) (~B_PCH_SMI_EN_GBL_SMI));
+
+ //
+ // If it's write cycle, disable Prefetching, Caching and disable BIOS Write Protect
+ //
+ if ((FlashCycleType == FlashCycleWrite) ||
+ (FlashCycleType == FlashCycleErase)) {
+ Status = DisableBiosWriteProtect ();
+ if (EFI_ERROR (Status)) {
+ goto SendSpiCmdEnd;
+ }
+ }
+ //
+ // Make sure it's safe to program the command.
+ //
+ if (!WaitForSpiCycleComplete (This, PchSpiBar0, FALSE)) {
+ Status = EFI_DEVICE_ERROR;
+ goto SendSpiCmdEnd;
+ }
+
+ Status = SpiProtocolGetRegionAddress (This, FlashRegionType, &HardwareSpiAddr, &FlashRegionSize);
+ if (EFI_ERROR (Status)) {
+ goto SendSpiCmdEnd;
+ }
+ HardwareSpiAddr += Address;
+ if ((Address + ByteCount) > FlashRegionSize) {
+ Status = EFI_INVALID_PARAMETER;
+ goto SendSpiCmdEnd;
+ }
+
+ //
+ // Check for PCH SPI hardware sequencing required commands
+ //
+ FlashCycle = 0;
+ switch (FlashCycleType) {
+ case FlashCycleRead:
+ FlashCycle = (UINT32) (V_PCH_SPI_HSFSC_CYCLE_READ << N_PCH_SPI_HSFSC_CYCLE);
+ break;
+ case FlashCycleWrite:
+ FlashCycle = (UINT32) (V_PCH_SPI_HSFSC_CYCLE_WRITE << N_PCH_SPI_HSFSC_CYCLE);
+ break;
+ case FlashCycleErase:
+ if (((ByteCount % SIZE_4KB) != 0) ||
+ ((HardwareSpiAddr % SIZE_4KB) != 0)) {
+ ASSERT (FALSE);
+ Status = EFI_INVALID_PARAMETER;
+ goto SendSpiCmdEnd;
+ }
+ break;
+ case FlashCycleReadSfdp:
+ FlashCycle = (UINT32) (V_PCH_SPI_HSFSC_CYCLE_READ_SFDP << N_PCH_SPI_HSFSC_CYCLE);
+ break;
+ case FlashCycleReadJedecId:
+ FlashCycle = (UINT32) (V_PCH_SPI_HSFSC_CYCLE_READ_JEDEC_ID << N_PCH_SPI_HSFSC_CYCLE);
+ break;
+ case FlashCycleWriteStatus:
+ FlashCycle = (UINT32) (V_PCH_SPI_HSFSC_CYCLE_WRITE_STATUS << N_PCH_SPI_HSFSC_CYCLE);
+ break;
+ case FlashCycleReadStatus:
+ FlashCycle = (UINT32) (V_PCH_SPI_HSFSC_CYCLE_READ_STATUS << N_PCH_SPI_HSFSC_CYCLE);
+ break;
+ default:
+ //
+ // Unrecognized Operation
+ //
+ ASSERT (FALSE);
+ Status = EFI_INVALID_PARAMETER;
+ goto SendSpiCmdEnd;
+ break;
+ }
+
+ do {
+ SpiDataCount = ByteCount;
+ if ((FlashCycleType == FlashCycleRead) ||
+ (FlashCycleType == FlashCycleWrite) ||
+ (FlashCycleType == FlashCycleReadSfdp)) {
+ //
+ // Trim at 256 byte boundary per operation,
+ // - PCH SPI controller requires trimming at 4KB boundary
+ // - Some SPI chips require trimming at 256 byte boundary for write operation
+ // - Trimming has limited performance impact as we can read / write atmost 64 byte
+ // per operation
+ //
+ if (HardwareSpiAddr + ByteCount > ((HardwareSpiAddr + BIT8) &~(BIT8 - 1))) {
+ SpiDataCount = (((UINT32) (HardwareSpiAddr) + BIT8) &~(BIT8 - 1)) - (UINT32) (HardwareSpiAddr);
+ }
+ //
+ // Calculate the number of bytes to shift in/out during the SPI data cycle.
+ // Valid settings for the number of bytes duing each data portion of the
+ // PCH SPI cycles are: 0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 24, 32, 40, 48, 56, 64
+ //
+ if (SpiDataCount >= 64) {
+ SpiDataCount = 64;
+ } else if ((SpiDataCount &~0x07) != 0) {
+ SpiDataCount = SpiDataCount &~0x07;
+ }
+ }
+ if (FlashCycleType == FlashCycleErase) {
+ if (((ByteCount / SIZE_64KB) != 0) &&
+ ((ByteCount % SIZE_64KB) == 0) &&
+ ((HardwareSpiAddr % SIZE_64KB) == 0)) {
+ if (HardwareSpiAddr < SpiInstance->Component1StartAddr) {
+ //
+ // Check whether Component0 support 64k Erase
+ //
+ if ((SpiInstance->SfdpVscc0Value & B_PCH_SPI_SFDPX_VSCCX_EO_64K) != 0) {
+ SpiDataCount = SIZE_64KB;
+ } else {
+ SpiDataCount = SIZE_4KB;
+ }
+ } else {
+ //
+ // Check whether Component1 support 64k Erase
+ //
+ if ((SpiInstance->SfdpVscc1Value & B_PCH_SPI_SFDPX_VSCCX_EO_64K) != 0) {
+ SpiDataCount = SIZE_64KB;
+ } else {
+ SpiDataCount = SIZE_4KB;
+ }
+ }
+ } else {
+ SpiDataCount = SIZE_4KB;
+ }
+ if (SpiDataCount == SIZE_4KB) {
+ FlashCycle = (UINT32) (V_PCH_SPI_HSFSC_CYCLE_4K_ERASE << N_PCH_SPI_HSFSC_CYCLE);
+ } else {
+ FlashCycle = (UINT32) (V_PCH_SPI_HSFSC_CYCLE_64K_ERASE << N_PCH_SPI_HSFSC_CYCLE);
+ }
+ }
+ //
+ // If it's write cycle, load data into the SPI data buffer.
+ //
+ if ((FlashCycleType == FlashCycleWrite) || (FlashCycleType == FlashCycleWriteStatus)) {
+ if ((SpiDataCount & 0x07) != 0) {
+ //
+ // Use Byte write if Data Count is 0, 1, 2, 3, 4, 5, 6, 7
+ //
+ for (Index = 0; Index < SpiDataCount; Index++) {
+ MmioWrite8 (PchSpiBar0 + R_PCH_SPI_FDATA00 + Index, Buffer[Index]);
+ }
+ } else {
+ //
+ // Use Dword write if Data Count is 8, 16, 24, 32, 40, 48, 56, 64
+ //
+ for (Index = 0; Index < SpiDataCount; Index += sizeof (UINT32)) {
+ MmioWrite32 (PchSpiBar0 + R_PCH_SPI_FDATA00 + Index, *(UINT32 *) (Buffer + Index));
+ }
+ }
+ }
+
+ //
+ // Set the Flash Address
+ //
+ MmioWrite32 (
+ (PchSpiBar0 + R_PCH_SPI_FADDR),
+ (UINT32) (HardwareSpiAddr & B_PCH_SPI_FADDR_MASK)
+ );
+
+ //
+ // Set Data count, Flash cycle, and Set Go bit to start a cycle
+ //
+ MmioAndThenOr32 (
+ PchSpiBar0 + R_PCH_SPI_HSFSC,
+ (UINT32) (~(B_PCH_SPI_HSFSC_FDBC_MASK | B_PCH_SPI_HSFSC_CYCLE_MASK)),
+ (UINT32) ((((SpiDataCount - 1) << N_PCH_SPI_HSFSC_FDBC) & B_PCH_SPI_HSFSC_FDBC_MASK) | FlashCycle | B_PCH_SPI_HSFSC_CYCLE_FGO)
+ );
+ //
+ // end of command execution
+ //
+ // Wait the SPI cycle to complete.
+ //
+ if (!WaitForSpiCycleComplete (This, PchSpiBar0, TRUE)) {
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ goto SendSpiCmdEnd;
+ }
+ //
+ // If it's read cycle, load data into the call's buffer.
+ //
+ if ((FlashCycleType == FlashCycleRead) ||
+ (FlashCycleType == FlashCycleReadSfdp) ||
+ (FlashCycleType == FlashCycleReadJedecId) ||
+ (FlashCycleType == FlashCycleReadStatus)) {
+ if ((SpiDataCount & 0x07) != 0) {
+ //
+ // Use Byte read if Data Count is 0, 1, 2, 3, 4, 5, 6, 7
+ //
+ for (Index = 0; Index < SpiDataCount; Index++) {
+ Buffer[Index] = MmioRead8 (PchSpiBar0 + R_PCH_SPI_FDATA00 + Index);
+ }
+ } else {
+ //
+ // Use Dword read if Data Count is 8, 16, 24, 32, 40, 48, 56, 64
+ //
+ for (Index = 0; Index < SpiDataCount; Index += sizeof (UINT32)) {
+ *(UINT32 *) (Buffer + Index) = MmioRead32 (PchSpiBar0 + R_PCH_SPI_FDATA00 + Index);
+ }
+ }
+ }
+
+ HardwareSpiAddr += SpiDataCount;
+ Buffer += SpiDataCount;
+ ByteCount -= SpiDataCount;
+ } while (ByteCount > 0);
+
+SendSpiCmdEnd:
+ //
+ // Restore the settings for SPI Prefetching and Caching and enable BIOS Write Protect
+ //
+ if ((FlashCycleType == FlashCycleWrite) ||
+ (FlashCycleType == FlashCycleErase)) {
+ EnableBiosWriteProtect ();
+ }
+ //
+ // Restore SMIs.
+ //
+ IoWrite32 ((UINTN) (ABase + R_PCH_SMI_EN), SmiEnSave);
+
+ ReleaseSpiBar0 (SpiInstance);
+ return Status;
+}
+
+/**
+ Wait execution cycle to complete on the SPI interface.
+
+ @param[in] This The SPI protocol instance
+ @param[in] PchSpiBar0 Spi MMIO base address
+ @param[in] ErrorCheck TRUE if the SpiCycle needs to do the error check
+
+ @retval TRUE SPI cycle completed on the interface.
+ @retval FALSE Time out while waiting the SPI cycle to complete.
+ It's not safe to program the next command on the SPI interface.
+**/
+BOOLEAN
+WaitForSpiCycleComplete (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINTN PchSpiBar0,
+ IN BOOLEAN ErrorCheck
+ )
+{
+ UINT64 WaitTicks;
+ UINT64 WaitCount;
+ UINT32 Data32;
+ SPI_INSTANCE *SpiInstance;
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+
+ //
+ // Convert the wait period allowed into to tick count
+ //
+ WaitCount = SPI_WAIT_TIME / SPI_WAIT_PERIOD;
+ //
+ // Wait for the SPI cycle to complete.
+ //
+ for (WaitTicks = 0; WaitTicks < WaitCount; WaitTicks++) {
+ Data32 = MmioRead32 (PchSpiBar0 + R_PCH_SPI_HSFSC);
+ if ((Data32 & B_PCH_SPI_HSFSC_SCIP) == 0) {
+ MmioWrite32 (PchSpiBar0 + R_PCH_SPI_HSFSC, B_PCH_SPI_HSFSC_FCERR | B_PCH_SPI_HSFSC_FDONE);
+ if (((Data32 & B_PCH_SPI_HSFSC_FCERR) != 0) && (ErrorCheck == TRUE)) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+ }
+ PchPmTimerStallRuntimeSafe (SpiInstance->PchAcpiBase, SPI_WAIT_PERIOD);
+ }
+ return FALSE;
+}
diff --git a/Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.c b/Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.c
new file mode 100644
index 0000000000..268b04d25a
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.c
@@ -0,0 +1,410 @@
+/** @file
+ A DXE_RUNTIME_DRIVER providing synchronous SMI activations via the
+ EFI_SMM_CONTROL2_PROTOCOL.
+
+ We expect the PEI phase to have covered the following:
+ - ensure that the underlying QEMU machine type be X58
+ (responsible: OvmfPkg/SmmAccess/SmmAccessPei.inf)
+ - ensure that the ACPI PM IO space be configured
+ (responsible: OvmfPkg/PlatformPei/PlatformPei.inf)
+
+ Our own entry point is responsible for confirming the SMI feature and for
+ configuring it.
+
+ Copyright (C) 2013, 2015, Red Hat, Inc.<BR>
+ Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Register/X58Ich10.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/S3SaveState.h>
+#include <Protocol/SmmControl2.h>
+
+//
+// Forward declaration.
+//
+STATIC
+VOID
+EFIAPI
+OnS3SaveStateInstalled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+//
+// The absolute IO port address of the SMI Control and Enable Register. It is
+// only used to carry information from the entry point function to the
+// S3SaveState protocol installation callback, strictly before the runtime
+// phase.
+//
+STATIC UINTN mSmiEnable;
+
+//
+// Event signaled when an S3SaveState protocol interface is installed.
+//
+STATIC EFI_EVENT mS3SaveStateInstalled;
+
+/**
+ Clear the SMI status
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_DEVICE_ERROR Something error occurred
+
+**/
+EFI_STATUS
+EFIAPI
+SmmClear(
+ VOID
+)
+{
+ EFI_STATUS Status;
+ UINT32 OutputData;
+ UINT32 OutputPort;
+ UINT32 PmBase;
+
+ Status = EFI_SUCCESS;
+ PmBase = ICH10_PMBASE_IO;
+
+ OutputPort = PmBase + ICH10_PMBASE_OFS_SMI_STS;
+ OutputData = ICH10_SMI_STS_APM;
+ IoWrite32(
+ (UINTN)OutputPort,
+ (UINT32)(OutputData)
+ );
+
+ ///
+ /// Set the EOS Bit
+ ///
+ OutputPort = PmBase + ICH10_PMBASE_OFS_SMI_EN;
+ OutputData = IoRead32((UINTN)OutputPort);
+ OutputData |= ICH10_SMI_EN_EOS;
+ IoWrite32(
+ (UINTN)OutputPort,
+ (UINT32)(OutputData)
+ );
+
+ ///
+ /// There is no need to read EOS back and check if it is set.
+ /// This can lead to a reading of zero if an SMI occurs right after the SMI_EN port read
+ /// but before the data is returned to the CPU.
+ /// SMM Dispatcher should make sure that EOS is set after all SMI sources are processed.
+ ///
+ return Status;
+}
+
+/**
+ Invokes SMI activation from either the preboot or runtime environment.
+
+ This function generates an SMI.
+
+ @param[in] This The EFI_SMM_CONTROL2_PROTOCOL instance.
+ @param[in,out] CommandPort The value written to the command port.
+ @param[in,out] DataPort The value written to the data port.
+ @param[in] Periodic Optional mechanism to engender a periodic
+ stream.
+ @param[in] ActivationInterval Optional parameter to repeat at this
+ period one time or, if the Periodic
+ Boolean is set, periodically.
+
+ @retval EFI_SUCCESS The SMI/PMI has been engendered.
+ @retval EFI_DEVICE_ERROR The timing is unsupported.
+ @retval EFI_INVALID_PARAMETER The activation period is unsupported.
+ @retval EFI_INVALID_PARAMETER The last periodic activation has not been
+ cleared.
+ @retval EFI_NOT_STARTED The SMM base service has not been initialized.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmControl2DxeTrigger (
+ IN CONST EFI_SMM_CONTROL2_PROTOCOL *This,
+ IN OUT UINT8 *CommandPort OPTIONAL,
+ IN OUT UINT8 *DataPort OPTIONAL,
+ IN BOOLEAN Periodic OPTIONAL,
+ IN UINTN ActivationInterval OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ //
+ // No support for queued or periodic activation.
+ //
+ if (Periodic || ActivationInterval > 0) {
+ return EFI_DEVICE_ERROR;
+ }
+ ///
+ /// Clear any pending the APM SMI
+ ///
+ Status = SmmClear();
+ //
+ // The so-called "Advanced Power Management Status Port Register" is in fact
+ // a generic data passing register, between the caller and the SMI
+ // dispatcher. The ICH9 spec calls it "scratchpad register" -- calling it
+ // "status" elsewhere seems quite the misnomer. Status registers usually
+ // report about hardware status, while this register is fully governed by
+ // software.
+ //
+ // Write to the status register first, as this won't trigger the SMI just
+ // yet. Then write to the control register.
+ //
+ IoWrite8 (ICH10_APM_STS, DataPort == NULL ? 0 : *DataPort);
+ IoWrite8 (ICH10_APM_CNT, CommandPort == NULL ? 0 : *CommandPort);
+ return EFI_SUCCESS;
+}
+
+/**
+ Clears any system state that was created in response to the Trigger() call.
+
+ This function acknowledges and causes the deassertion of the SMI activation
+ source.
+
+ @param[in] This The EFI_SMM_CONTROL2_PROTOCOL instance.
+ @param[in] Periodic Optional parameter to repeat at this period
+ one time
+
+ @retval EFI_SUCCESS The SMI/PMI has been engendered.
+ @retval EFI_DEVICE_ERROR The source could not be cleared.
+ @retval EFI_INVALID_PARAMETER The service did not support the Periodic input
+ argument.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmControl2DxeClear (
+ IN CONST EFI_SMM_CONTROL2_PROTOCOL *This,
+ IN BOOLEAN Periodic OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+
+ if (Periodic) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // The PI spec v1.4 explains that Clear() is only supposed to clear software
+ // status; it is not in fact responsible for deasserting the SMI. It gives
+ // two reasons for this: (a) many boards clear the SMI automatically when
+ // entering SMM, (b) if Clear() actually deasserted the SMI, then it could
+ // incorrectly suppress an SMI that was asynchronously asserted between the
+ // last return of the SMI handler and the call made to Clear().
+ //
+ // In fact QEMU automatically deasserts CPU_INTERRUPT_SMI in:
+ // - x86_cpu_exec_interrupt() [target-i386/seg_helper.c], and
+ // - kvm_arch_pre_run() [target-i386/kvm.c].
+ //
+ // So, nothing to do here.
+ //
+ Status = SmmClear();
+
+ return EFI_SUCCESS;
+}
+
+STATIC EFI_SMM_CONTROL2_PROTOCOL mControl2 = {
+ &SmmControl2DxeTrigger,
+ &SmmControl2DxeClear,
+ MAX_UINTN // MinimumTriggerPeriod -- we don't support periodic SMIs
+};
+
+//
+// Entry point of this driver.
+//
+EFI_STATUS
+EFIAPI
+SmmControl2DxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ UINT32 PmBase;
+ UINT32 SmiEnableVal;
+ EFI_STATUS Status;
+
+ //
+ // This module should only be included if SMRAM support is required.
+ //
+ ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
+
+ //
+ // Calculate the absolute IO port address of the SMI Control and Enable
+ // Register. (As noted at the top, the PEI phase has left us with a working
+ // ACPI PM IO space.)
+ //
+ PmBase = PciRead32 (POWER_MGMT_REGISTER_ICH10 (ICH10_PMBASE)) &
+ ICH10_PMBASE_MASK;
+ mSmiEnable = PmBase + ICH10_PMBASE_OFS_SMI_EN;
+
+ //
+ // If APMC_EN is pre-set in SMI_EN, that's QEMU's way to tell us that SMI
+ // support is not available. (For example due to KVM lacking it.) Otherwise,
+ // this bit is clear after each reset.
+ //
+ SmiEnableVal = IoRead32 (mSmiEnable);
+ if ((SmiEnableVal & ICH10_SMI_EN_APMC_EN) != 0) {
+ DEBUG ((EFI_D_ERROR, "%a: this X58 implementation lacks SMI\n",
+ __FUNCTION__));
+ }
+
+ //
+ // Otherwise, configure the board to inject an SMI when ICH10_APM_CNT is
+ // written to. (See the Trigger() method above.)
+ //
+ SmiEnableVal |= ICH10_SMI_EN_APMC_EN | ICH10_SMI_EN_GBL_SMI_EN;
+ IoWrite32 (mSmiEnable, SmiEnableVal);
+
+ //
+ // Prevent software from undoing the above (until platform reset).
+ //
+ PciOr16 (POWER_MGMT_REGISTER_ICH10 (ICH10_GEN_PMCON_1),
+ ICH10_GEN_PMCON_1_SMI_LOCK);
+
+ //
+ // If we can clear GBL_SMI_EN now, that means QEMU's SMI support is not
+ // appropriate.
+ //
+ IoWrite32 (mSmiEnable, SmiEnableVal & ~(UINT32)ICH10_SMI_EN_GBL_SMI_EN);
+ if (IoRead32 (mSmiEnable) != SmiEnableVal) {
+ DEBUG ((EFI_D_ERROR, "%a: failed to lock down GBL_SMI_EN\n",
+ __FUNCTION__));
+ goto FatalError;
+ }
+
+ VOID *Registration;
+
+ //
+ // On S3 resume the above register settings have to be repeated. Register a
+ // protocol notify callback that, when boot script saving becomes
+ // available, saves operations equivalent to the above to the boot script.
+ //
+ Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
+ OnS3SaveStateInstalled, NULL /* Context */,
+ &mS3SaveStateInstalled);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: CreateEvent: %r\n", __FUNCTION__, Status));
+ goto FatalError;
+ }
+
+ Status = gBS->RegisterProtocolNotify (&gEfiS3SaveStateProtocolGuid,
+ mS3SaveStateInstalled, &Registration);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: RegisterProtocolNotify: %r\n", __FUNCTION__,
+ Status));
+ goto ReleaseEvent;
+ }
+
+ //
+ // Kick the event right now -- maybe the boot script is already saveable.
+ //
+ Status = gBS->SignalEvent (mS3SaveStateInstalled);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: SignalEvent: %r\n", __FUNCTION__, Status));
+ goto ReleaseEvent;
+ }
+
+ //
+ // We have no pointers to convert to virtual addresses. The handle itself
+ // doesn't matter, as protocol services are not accessible at runtime.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
+ &gEfiSmmControl2ProtocolGuid, &mControl2,
+ NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: InstallMultipleProtocolInterfaces: %r\n",
+ __FUNCTION__, Status));
+ goto ReleaseEvent;
+ }
+
+ return EFI_SUCCESS;
+
+ReleaseEvent:
+ if (mS3SaveStateInstalled != NULL) {
+ gBS->CloseEvent (mS3SaveStateInstalled);
+ }
+
+FatalError:
+ //
+ // We really don't want to continue in this case.
+ //
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Notification callback for S3SaveState installation.
+
+ @param[in] Event Event whose notification function is being invoked.
+
+ @param[in] Context The pointer to the notification function's context, which
+ is implementation-dependent.
+**/
+STATIC
+VOID
+EFIAPI
+OnS3SaveStateInstalled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_S3_SAVE_STATE_PROTOCOL *S3SaveState;
+ UINT32 SmiEnOrMask, SmiEnAndMask;
+ UINT16 GenPmCon1OrMask, GenPmCon1AndMask;
+
+ ASSERT (Event == mS3SaveStateInstalled);
+
+ Status = gBS->LocateProtocol (&gEfiS3SaveStateProtocolGuid,
+ NULL /* Registration */, (VOID **)&S3SaveState);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ //
+ // These operations were originally done, verified and explained in the entry
+ // point function of the driver.
+ //
+ SmiEnOrMask = ICH10_SMI_EN_APMC_EN | ICH10_SMI_EN_GBL_SMI_EN;
+ SmiEnAndMask = MAX_UINT32;
+ Status = S3SaveState->Write (
+ S3SaveState,
+ EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE,
+ EfiBootScriptWidthUint32,
+ (UINT64)mSmiEnable,
+ &SmiEnOrMask,
+ &SmiEnAndMask
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE: %r\n",
+ __FUNCTION__, Status));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+
+ GenPmCon1OrMask = ICH10_GEN_PMCON_1_SMI_LOCK;
+ GenPmCon1AndMask = MAX_UINT16;
+ Status = S3SaveState->Write (
+ S3SaveState,
+ EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE,
+ EfiBootScriptWidthUint16,
+ (UINT64)POWER_MGMT_REGISTER_ICH10 (ICH10_GEN_PMCON_1),
+ &GenPmCon1OrMask,
+ &GenPmCon1AndMask
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR,
+ "%a: EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE: %r\n", __FUNCTION__,
+ Status));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+
+ DEBUG ((EFI_D_VERBOSE, "%a: boot script fragment saved\n", __FUNCTION__));
+ gBS->CloseEvent (Event);
+ mS3SaveStateInstalled = NULL;
+}
diff --git a/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.c b/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.c
new file mode 100644
index 0000000000..0baf730a48
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.c
@@ -0,0 +1,175 @@
+/** @file
+ PCH SPI SMM Driver implements the SPI Host Controller Compatibility Interface.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchSpi.h"
+
+//
+// Global variables
+//
+GLOBAL_REMOVE_IF_UNREFERENCED SPI_INSTANCE *mSpiInstance;
+//
+// mPchSpiResvMmioAddr keeps the reserved MMIO range assiged to SPI.
+// In SMM it always set back the reserved MMIO address to SPI BAR0 to ensure the MMIO range
+// won't overlap with SMRAM range, and trusted.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mSpiResvMmioAddr;
+
+/**
+ <b>SPI Runtime SMM Module Entry Point</b>\n
+ - <b>Introduction</b>\n
+ The SPI SMM module provide a standard way for other modules to use the PCH SPI Interface in SMM.
+
+ - @pre
+ - EFI_SMM_BASE2_PROTOCOL
+ - Documented in System Management Mode Core Interface Specification .
+
+ - @result
+ The SPI SMM driver produces @link _PCH_SPI_PROTOCOL PCH_SPI_PROTOCOL @endlink with GUID
+ gPchSmmSpiProtocolGuid which is different from SPI RUNTIME driver.
+
+ - <b>Integration Check List</b>\n
+ - This driver supports Descriptor Mode only.
+ - This driver supports Hardware Sequence only.
+ - When using SMM SPI Protocol to perform flash access in an SMI handler,
+ and the SMI occurrence is asynchronous to normal mode code execution,
+ proper synchronization mechanism must be applied, e.g. disable SMI before
+ the normal mode SendSpiCmd() starts and re-enable SMI after
+ the normal mode SendSpiCmd() completes.
+ @note The implementation of SendSpiCmd() uses GBL_SMI_EN in
+ SMI_EN register (ABase + 30h) to disable and enable SMIs. But this may
+ not be effective as platform may well set the SMI_LOCK bit (i.e., PMC PCI Offset A0h [4]).
+ So the synchronization at caller level is likely needed.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Global system service table.
+
+ @retval EFI_SUCCESS Initialization complete.
+ @exception EFI_UNSUPPORTED The chipset is unsupported by this driver.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver.
+ @retval EFI_DEVICE_ERROR Device error, driver exits abnormally.
+**/
+EFI_STATUS
+EFIAPI
+InstallPchSpi (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Init PCH spi reserved MMIO address.
+ //
+ mSpiResvMmioAddr = PCH_SPI_BASE_ADDRESS;
+
+ ///
+ /// Allocate pool for SPI protocol instance
+ ///
+ Status = gSmst->SmmAllocatePool (
+ EfiRuntimeServicesData, /// MemoryType don't care
+ sizeof (SPI_INSTANCE),
+ (VOID **) &mSpiInstance
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (mSpiInstance == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMem ((VOID *) mSpiInstance, sizeof (SPI_INSTANCE));
+ ///
+ /// Initialize the SPI protocol instance
+ ///
+ Status = SpiProtocolConstructor (mSpiInstance);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Install the SMM EFI_SPI_PROTOCOL interface
+ //
+ Status = gSmst->SmmInstallProtocolInterface (
+ &(mSpiInstance->Handle),
+ &gEfiSmmSpiProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &(mSpiInstance->SpiProtocol)
+ );
+ if (EFI_ERROR (Status)) {
+ gSmst->SmmFreePool (mSpiInstance);
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Acquire PCH spi mmio address.
+ It is not expected for this BAR0 to change because the SPI device is hidden
+ from the OS for SKL PCH LP/H B stepping and above (refer to section 3.5.1),
+ but if it is ever different from the preallocated address, reassign it back.
+ In SMM, it always override the BAR0 and returns the reserved MMIO range for SPI.
+
+ @param[in] SpiInstance Pointer to SpiInstance to initialize
+
+ @retval PchSpiBar0 return SPI MMIO address
+**/
+UINTN
+AcquireSpiBar0 (
+ IN SPI_INSTANCE *SpiInstance
+ )
+{
+ //
+ // SPIBAR0 will be different before and after PCI enum so need to get it from SPI BAR0 reg.
+ //
+ return mSpiResvMmioAddr;
+}
+
+/**
+ Release pch spi mmio address. Do nothing.
+
+ @param[in] SpiInstance Pointer to SpiInstance to initialize
+
+ @retval None
+**/
+VOID
+ReleaseSpiBar0 (
+ IN SPI_INSTANCE *SpiInstance
+ )
+{
+}
+
+/**
+ This function is a hook for Spi to disable BIOS Write Protect
+
+ @retval EFI_SUCCESS The protocol instance was properly initialized
+ @retval EFI_ACCESS_DENIED The BIOS Region can only be updated in SMM phase
+
+**/
+EFI_STATUS
+EFIAPI
+DisableBiosWriteProtect (
+ VOID
+ )
+{
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is a hook for Spi to enable BIOS Write Protect
+
+
+**/
+VOID
+EFIAPI
+EnableBiosWriteProtect (
+ VOID
+ )
+{
+}
diff --git a/Silicon/Intel/SimicsIch10Pkg/Ich10Pkg.dec b/Silicon/Intel/SimicsIch10Pkg/Ich10Pkg.dec
new file mode 100644
index 0000000000..ad0a599fc5
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Ich10Pkg.dec
@@ -0,0 +1,26 @@
+## @file
+# Copyright (c) 2014 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = Ich10Pkg
+ PACKAGE_GUID = 4E97AC4B-F64C-4008-BBDE-01CC3B0BAA6B
+ PACKAGE_VERSION = 0.91
+
+[Includes]
+ Include
+
+[Ppis]
+
+[Guids]
+ gEfiPchTokenSpaceGuid = { 0x89a1b278, 0xa1a1, 0x4df7, { 0xb1, 0x37, 0xde, 0x5a, 0xd7, 0xc4, 0x79, 0x13 } }
+[Protocols]
+ gEfiSmmSpiProtocolGuid = {0xbd75fe35, 0xfdce, 0x49d7, {0xa9, 0xdd, 0xb2, 0x6f, 0x1f, 0xc6, 0xb4, 0x37}}
+
+[PcdsFixedAtBuild]
+ gEfiPchTokenSpaceGuid.PcdFlashAreaBaseAddress|0xFFE00000|UINT32|0x10000001
+ gEfiPchTokenSpaceGuid.PcdFlashAreaSize|0x00200000|UINT32|0x10000002
\ No newline at end of file
diff --git a/Silicon/Intel/SimicsIch10Pkg/IchCommonLib.dsc b/Silicon/Intel/SimicsIch10Pkg/IchCommonLib.dsc
new file mode 100644
index 0000000000..143abda7c1
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/IchCommonLib.dsc
@@ -0,0 +1,12 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE libraries.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[LibraryClasses.common]
+ ResetSystemLib|$(PCH_PKG)/Library/ResetSystemLib/ResetSystemLib.inf
+ PchSpiCommonLib|$(PCH_PKG)/LibraryPrivate/BasePchSpiCommonLib/BasePchSpiCommonLib.inf
diff --git a/Silicon/Intel/SimicsIch10Pkg/IchPostMemoryInclude.fdf b/Silicon/Intel/SimicsIch10Pkg/IchPostMemoryInclude.fdf
new file mode 100644
index 0000000000..12e43e86d0
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/IchPostMemoryInclude.fdf
@@ -0,0 +1,9 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
diff --git a/Silicon/Intel/SimicsIch10Pkg/IchPreMemoryInclude.fdf b/Silicon/Intel/SimicsIch10Pkg/IchPreMemoryInclude.fdf
new file mode 100644
index 0000000000..079b81574b
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/IchPreMemoryInclude.fdf
@@ -0,0 +1,9 @@
+## @file
+# Component description file for the Ich10 SiPkg PEI drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
diff --git a/Silicon/Intel/SimicsIch10Pkg/IchUefiBootInclude.fdf b/Silicon/Intel/SimicsIch10Pkg/IchUefiBootInclude.fdf
new file mode 100644
index 0000000000..1b683ba97c
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/IchUefiBootInclude.fdf
@@ -0,0 +1,13 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+ INF $(PCH_PKG)/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
+ INF $(PCH_PKG)/Spi/Smm/PchSpiSmm.inf
+!endif
diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/Library/SpiFlashCommonLib.h b/Silicon/Intel/SimicsIch10Pkg/Include/Library/SpiFlashCommonLib.h
new file mode 100644
index 0000000000..53c11bb59a
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Include/Library/SpiFlashCommonLib.h
@@ -0,0 +1,98 @@
+/** @file
+ The header file includes the common header files, defines
+ internal structure and functions used by SpiFlashCommonLib.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __SPI_FLASH_COMMON_LIB_H__
+#define __SPI_FLASH_COMMON_LIB_H__
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#define SECTOR_SIZE_4KB 0x1000 // Common 4kBytes sector size
+/**
+ Enable block protection on the Serial Flash device.
+
+ @retval EFI_SUCCESS Opertion is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashLock (
+ VOID
+ );
+
+/**
+ Read NumBytes bytes of data from the address specified by
+ PAddress into Buffer.
+
+ @param[in] Address The starting physical address of the read.
+ @param[in,out] NumBytes On input, the number of bytes to read. On output, the number
+ of bytes actually read.
+ @param[out] Buffer The destination data buffer for the read.
+
+ @retval EFI_SUCCESS Opertion is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashRead (
+ IN UINTN Address,
+ IN OUT UINT32 *NumBytes,
+ OUT UINT8 *Buffer
+ );
+
+/**
+ Write NumBytes bytes of data from Buffer to the address specified by
+ PAddresss.
+
+ @param[in] Address The starting physical address of the write.
+ @param[in,out] NumBytes On input, the number of bytes to write. On output,
+ the actual number of bytes written.
+ @param[in] Buffer The source data buffer for the write.
+
+ @retval EFI_SUCCESS Opertion is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashWrite (
+ IN UINTN Address,
+ IN OUT UINT32 *NumBytes,
+ IN UINT8 *Buffer
+ );
+
+/**
+ Erase the block starting at Address.
+
+ @param[in] Address The starting physical address of the block to be erased.
+ This library assume that caller garantee that the PAddress
+ is at the starting address of this block.
+ @param[in] NumBytes On input, the number of bytes of the logical block to be erased.
+ On output, the actual number of bytes erased.
+
+ @retval EFI_SUCCESS. Opertion is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashBlockErase (
+ IN UINTN Address,
+ IN UINTN *NumBytes
+ );
+
+#endif
diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/PchAccess.h b/Silicon/Intel/SimicsIch10Pkg/Include/PchAccess.h
new file mode 100644
index 0000000000..8be6ecd83b
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Include/PchAccess.h
@@ -0,0 +1,43 @@
+/** @file
+ Macros that simplify accessing PCH devices's PCI registers.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_ACCESS_H_
+#define _PCH_ACCESS_H_
+
+#include "PchReservedResources.h"
+
+#ifndef STALL_ONE_MICRO_SECOND
+#define STALL_ONE_MICRO_SECOND 1
+#endif
+#ifndef STALL_ONE_SECOND
+#define STALL_ONE_SECOND 1000000
+#endif
+
+
+///
+/// The default PCH PCI bus number
+///
+#define DEFAULT_PCI_BUS_NUMBER_PCH 0
+
+//
+// Default Vendor ID and Subsystem ID
+//
+#define V_PCH_INTEL_VENDOR_ID 0x8086 ///< Default Intel PCH Vendor ID
+#define V_PCH_DEFAULT_SID 0x7270 ///< Default Intel PCH Subsystem ID
+#define V_PCH_DEFAULT_SVID_SID (V_INTEL_VENDOR_ID + (V_PCH_DEFAULT_SID << 16)) ///< Default INTEL PCH Vendor ID and Subsystem ID
+
+//
+// Include device register definitions
+//
+
+#include "Register/PchRegsPmc.h"
+
+#include "Register/PchRegsSpi.h"
+
+#endif
+
diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/PchLimits.h b/Silicon/Intel/SimicsIch10Pkg/Include/PchLimits.h
new file mode 100644
index 0000000000..35bb5741a8
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Include/PchLimits.h
@@ -0,0 +1,94 @@
+/** @file
+ Build time limits of PCH resources.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_LIMITS_H_
+#define _PCH_LIMITS_H_
+
+//
+// PCIe limits
+//
+#define PCH_MAX_PCIE_ROOT_PORTS PCH_H_PCIE_MAX_ROOT_PORTS
+#define PCH_H_PCIE_MAX_ROOT_PORTS 20
+#define PCH_LP_PCIE_MAX_ROOT_PORTS 12
+
+#define PCH_MAX_PCIE_CONTROLLERS PCH_H_PCIE_MAX_CONTROLLERS
+#define PCH_PCIE_CONTROLLER_PORTS 4
+#define PCH_H_PCIE_MAX_CONTROLLERS (PCH_H_PCIE_MAX_ROOT_PORTS / PCH_PCIE_CONTROLLER_PORTS)
+#define PCH_LP_PCIE_MAX_CONTROLLERS (PCH_LP_PCIE_MAX_ROOT_PORTS / PCH_PCIE_CONTROLLER_PORTS)
+
+//
+// PCIe clocks limits
+//
+#define PCH_LP_PCIE_MAX_CLK_REQ 6
+#define PCH_H_PCIE_MAX_CLK_REQ 16
+
+//
+// RST PCIe Storage Cycle Router limits
+//
+#define PCH_MAX_RST_PCIE_STORAGE_CR 3
+
+//
+// SATA limits
+//
+#define PCH_MAX_SATA_PORTS PCH_H_AHCI_MAX_PORTS
+#define PCH_H_AHCI_MAX_PORTS 8 ///< Max number of sata ports in SKL PCH H
+#define PCH_LP_AHCI_MAX_PORTS 3 ///< Max number of sata ports in SKL PCH LP
+#define PCH_SATA_MAX_DEVICES_PER_PORT 1 ///< Max support device numner per port, Port Multiplier is not support.
+
+//
+// USB limits
+//
+#define PCH_MAX_USB2_PORTS PCH_H_XHCI_MAX_USB2_PORTS
+
+#define PCH_H_XHCI_MAX_USB2_PHYSICAL_PORTS 14 ///< Max Physical Connector XHCI, not counting virtual ports like USB-R.
+#define PCH_LP_XHCI_MAX_USB2_PHYSICAL_PORTS 10 ///< Max Physical Connector XHCI, not counting virtual ports like USB-R.
+
+#define PCH_H_XHCI_MAX_USB2_PORTS 16 ///< 14 High Speed lanes + Including two ports reserved for USBr
+#define PCH_LP_XHCI_MAX_USB2_PORTS 12 ///< 10 High Speed lanes + Including two ports reserved for USBr
+
+#define PCH_MAX_USB3_PORTS PCH_H_XHCI_MAX_USB3_PORTS
+
+#define PCH_H_XHCI_MAX_USB3_PORTS 10 ///< 10 Super Speed lanes
+#define PCH_LP_XHCI_MAX_USB3_PORTS 6 ///< 6 Super Speed lanes
+
+#define PCH_XHCI_MAX_SSIC_PORT_COUNT 2 ///< 2 SSIC ports in SKL PCH-LP and SKL PCH-H
+
+//
+// SerialIo limits
+//
+#define PCH_SERIALIO_MAX_CONTROLLERS 11 ///< Number of SerialIo controllers, this includes I2C, SPI and UART
+#define PCH_SERIALIO_MAX_I2C_CONTROLLERS 6 ///< Number of SerialIo I2C controllers
+#define PCH_LP_SERIALIO_MAX_I2C_CONTROLLERS 6 ///< Number of SerialIo I2C controllers for PCH-LP
+#define PCH_H_SERIALIO_MAX_I2C_CONTROLLERS 4 ///< Number of SerialIo I2C controllers for PCH-H
+#define PCH_SERIALIO_MAX_SPI_CONTROLLERS 2 ///< Number of SerialIo SPI controllers
+#define PCH_SERIALIO_MAX_UART_CONTROLLERS 3 ///< Number of SerialIo UART controllers
+
+//
+// ISH limits
+//
+#define PCH_ISH_MAX_GP_PINS 8
+#define PCH_ISH_MAX_UART_CONTROLLERS 2
+#define PCH_ISH_MAX_I2C_CONTROLLERS 3
+#define PCH_ISH_MAX_SPI_CONTROLLERS 1
+
+//
+// SCS limits
+//
+#define PCH_SCS_MAX_CONTROLLERS 3 ///< Number of Storage and Communication Subsystem controllers, this includes eMMC, SDIO, SDCARD
+
+//
+// Flash Protection Range Register
+//
+#define PCH_FLASH_PROTECTED_RANGES 5
+
+//
+// Number of eSPI slaves
+//
+#define PCH_ESPI_MAX_SLAVE_ID 2
+#endif // _PCH_LIMITS_H_
+
diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/PchReservedResources.h b/Silicon/Intel/SimicsIch10Pkg/Include/PchReservedResources.h
new file mode 100644
index 0000000000..5e978237dd
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Include/PchReservedResources.h
@@ -0,0 +1,60 @@
+/** @file
+ PCH preserved MMIO resource definitions.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_PRESERVED_RESOURCES_H_
+#define _PCH_PRESERVED_RESOURCES_H_
+
+/**
+ PCH preserved MMIO range, 24 MB, from 0xFD000000 to 0xFE7FFFFF
+
+ Detailed recommended static allocation
+ +-------------------------------------------------------------------------+
+ | Size | Start | End | Usage |
+ | 16 MB | 0xFD000000 | 0xFDFFFFFF | SBREG |
+ | 64 KB | 0xFE000000 | 0xFE00FFFF | PMC MBAR |
+ | 4 KB | 0xFE010000 | 0xFE010FFF | SPI BAR0 |
+ | 88 KB | 0xFE020000 | 0xFE035FFF | SerialIo BAR in ACPI mode |
+ | 24 KB | 0xFE036000 | 0xFE03BFFF | Unused |
+ | 4 KB | 0xFE03C000 | 0xFE03CFFF | Thermal Device in ACPI mode |
+ | 524 KB | 0xFE03D000 | 0xFE0BFFFF | Unused |
+ | 256 KB | 0xFE0C0000 | 0xFE0FFFFF | TraceHub FW BAR |
+ | 1 MB | 0xFE100000 | 0xFE1FFFFF | TraceHub MTB BAR |
+ | 2 MB | 0xFE200000 | 0xFE3FFFFF | TraceHub SW BAR |
+ | 64 KB | 0xFE400000 | 0xFE40FFFF | CIO2 MMIO BAR in ACPI mode |
+ | 2 MB - 64KB | 0xFE410000 | 0xFE5FFFFF | Unused |
+ | 2 MB | 0xFE600000 | 0xFE7FFFFF | Temp address |
+ +-------------------------------------------------------------------------+
+**/
+#define PCH_PRESERVED_BASE_ADDRESS 0xFD000000 ///< Pch preserved MMIO base address
+#define PCH_PRESERVED_MMIO_SIZE 0x01800000 ///< 24MB
+#define PCH_PCR_BASE_ADDRESS 0xFD000000 ///< SBREG MMIO base address
+#define PCH_PCR_MMIO_SIZE 0x01000000 ///< 16MB
+#define PCH_PWRM_BASE_ADDRESS 0xFE000000 ///< PMC MBAR MMIO base address
+#define PCH_PWRM_MMIO_SIZE 0x00010000 ///< 64KB
+#define PCH_SPI_BASE_ADDRESS 0xFED1C000 + 0x3800 ///< SPI MBAR MMIO base address
+#define PCH_SPI_MMIO_SIZE 0x00001000 ///< 4KB
+#define PCH_SERIAL_IO_BASE_ADDRESS 0xFE020000 ///< SerialIo MMIO base address
+#define PCH_SERIAL_IO_MMIO_SIZE 0x00016000 ///< 88KB
+#define PCH_THERMAL_BASE_ADDRESS 0xFE03C000 ///< Thermal Device in ACPI mode
+#define PCH_THERMAL_MMIO_SIZE 0x00001000 ///< 4KB
+#define PCH_TRACE_HUB_FW_BASE_ADDRESS 0xFE0C0000 ///< TraceHub FW MMIO base address
+#define PCH_TRACE_HUB_FW_MMIO_SIZE 0x00040000 ///< 256KB
+#define PCH_TRACE_HUB_MTB_BASE_ADDRESS 0xFE100000 ///< TraceHub MTB MMIO base address
+#define PCH_TRACE_HUB_MTB_MMIO_SIZE 0x00100000 ///< 1MB
+#define PCH_TRACE_HUB_SW_BASE_ADDRESS 0xFE200000 ///< TraceHub SW MMIO base address
+#define PCH_TRACE_HUB_SW_MMIO_SIZE 0x00200000 ///< 2MB
+#define PCH_CIO2_BASE_ADDRESS 0xFE400000 ///< CIO2 MMIO BAR in ACPI mode
+#define PCH_CIO2_MMIO_SIZE 0x00010000 ///< 64KB
+#define PCH_TEMP_BASE_ADDRESS 0xFE600000 ///< preserved temp address for misc usage
+#define PCH_TEMP_MMIO_SIZE 0x00200000 ///< 2MB
+
+#define RCRB 0xFED1C000
+#define SPIBAR 0x3800
+
+#endif // _PCH_PRESERVED_RESOURCES_H_
+
diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/Protocol/Spi.h b/Silicon/Intel/SimicsIch10Pkg/Include/Protocol/Spi.h
new file mode 100644
index 0000000000..b0c5b3d0e6
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Include/Protocol/Spi.h
@@ -0,0 +1,295 @@
+/** @file
+ This file defines the PCH SPI Protocol which implements the
+ Intel(R) PCH SPI Host Controller Compatibility Interface.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SPI_PROTOCOL_H_
+#define _PCH_SPI_PROTOCOL_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gEfiSpiProtocolGuid;
+extern EFI_GUID gEfiSmmSpiProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _PCH_SPI_PROTOCOL EFI_SPI_PROTOCOL;
+
+//
+// SPI protocol data structures and definitions
+//
+
+/**
+ Flash Region Type
+**/
+typedef enum {
+ FlashRegionDescriptor,
+ FlashRegionBios,
+ FlashRegionMe,
+ FlashRegionGbE,
+ FlashRegionPlatformData,
+ FlashRegionDer,
+ FlashRegionAll,
+ FlashRegionMax
+} FLASH_REGION_TYPE;
+
+
+//
+// Protocol member functions
+//
+
+/**
+ Read data from the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+ @param[out] Buffer The Pointer to caller-allocated buffer containing the dada received.
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_READ) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ OUT UINT8 *Buffer
+ );
+
+/**
+ Write data to the flash part. Remark: Erase may be needed before write to the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+ @param[in] Buffer Pointer to caller-allocated buffer containing the data sent during the SPI cycle.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_WRITE) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ IN UINT8 *Buffer
+ );
+
+/**
+ Erase some area on the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_ERASE) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount
+ );
+
+/**
+ Read SFDP data from the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ComponentNumber The Componen Number for chip select
+ @param[in] Address The starting byte address for SFDP data read.
+ @param[in] ByteCount Number of bytes in SFDP data portion of the SPI cycle
+ @param[out] SfdpData The Pointer to caller-allocated buffer containing the SFDP data received
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_READ_SFDP) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT8 ComponentNumber,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ OUT UINT8 *SfdpData
+ );
+
+/**
+ Read Jedec Id from the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ComponentNumber The Componen Number for chip select
+ @param[in] ByteCount Number of bytes in JedecId data portion of the SPI cycle, the data size is 3 typically
+ @param[out] JedecId The Pointer to caller-allocated buffer containing JEDEC ID received
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_READ_JEDEC_ID) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT8 ComponentNumber,
+ IN UINT32 ByteCount,
+ OUT UINT8 *JedecId
+ );
+
+/**
+ Write the status register in the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ByteCount Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+ @param[in] StatusValue The Pointer to caller-allocated buffer containing the value of Status register writing
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_WRITE_STATUS) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 ByteCount,
+ IN UINT8 *StatusValue
+ );
+
+/**
+ Read status register in the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ByteCount Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+ @param[out] StatusValue The Pointer to caller-allocated buffer containing the value of Status register received.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_READ_STATUS) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 ByteCount,
+ OUT UINT8 *StatusValue
+ );
+
+/**
+ Get the SPI region base and size, based on the enum type
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for for the base address which is listed in the Descriptor.
+ @param[out] BaseAddress The Flash Linear Address for the Region 'n' Base
+ @param[out] RegionSize The size for the Region 'n'
+
+ @retval EFI_SUCCESS Read success
+ @retval EFI_INVALID_PARAMETER Invalid region type given
+ @retval EFI_DEVICE_ERROR The region is not used
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_GET_REGION_ADDRESS) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ OUT UINT32 *BaseAddress,
+ OUT UINT32 *RegionSize
+ );
+
+/**
+ Read PCH Soft Strap Values
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] SoftStrapAddr PCH Soft Strap address offset from FPSBA.
+ @param[in] ByteCount Number of bytes in SoftStrap data portion of the SPI cycle
+ @param[out] SoftStrapValue The Pointer to caller-allocated buffer containing PCH Soft Strap Value.
+ If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_READ_PCH_SOFTSTRAP) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 SoftStrapAddr,
+ IN UINT32 ByteCount,
+ OUT VOID *SoftStrapValue
+ );
+
+/**
+ Read CPU Soft Strap Values
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] SoftStrapAddr CPU Soft Strap address offset from FCPUSBA.
+ @param[in] ByteCount Number of bytes in SoftStrap data portion of the SPI cycle.
+ @param[out] SoftStrapValue The Pointer to caller-allocated buffer containing CPU Soft Strap Value.
+ If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_READ_CPU_SOFTSTRAP) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 SoftStrapAddr,
+ IN UINT32 ByteCount,
+ OUT VOID *SoftStrapValue
+ );
+
+/**
+ These protocols/PPI allows a platform module to perform SPI operations through the
+ Intel PCH SPI Host Controller Interface.
+**/
+struct _PCH_SPI_PROTOCOL {
+ /**
+ This member specifies the revision of this structure. This field is used to
+ indicate backwards compatible changes to the protocol.
+ **/
+ UINT8 Revision;
+ PCH_SPI_FLASH_READ FlashRead; ///< Read data from the flash part.
+ PCH_SPI_FLASH_WRITE FlashWrite; ///< Write data to the flash part. Remark: Erase may be needed before write to the flash part.
+ PCH_SPI_FLASH_ERASE FlashErase; ///< Erase some area on the flash part.
+ PCH_SPI_FLASH_READ_SFDP FlashReadSfdp; ///< Read SFDP data from the flash part.
+ PCH_SPI_FLASH_READ_JEDEC_ID FlashReadJedecId; ///< Read Jedec Id from the flash part.
+ PCH_SPI_FLASH_WRITE_STATUS FlashWriteStatus; ///< Write the status register in the flash part.
+ PCH_SPI_FLASH_READ_STATUS FlashReadStatus; ///< Read status register in the flash part.
+ PCH_SPI_GET_REGION_ADDRESS GetRegionAddress; ///< Get the SPI region base and size
+ PCH_SPI_READ_PCH_SOFTSTRAP ReadPchSoftStrap; ///< Read PCH Soft Strap Values
+ PCH_SPI_READ_CPU_SOFTSTRAP ReadCpuSoftStrap; ///< Read CPU Soft Strap Values
+};
+
+/**
+ PCH SPI PPI/PROTOCOL revision number
+
+ Revision 1: Initial version
+**/
+#define PCH_SPI_SERVICES_REVISION 1
+
+#endif
diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsPmc.h b/Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsPmc.h
new file mode 100644
index 0000000000..4c495475cb
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsPmc.h
@@ -0,0 +1,647 @@
+/** @file
+ Register names for PCH PMC device
+
+ Conventions:
+
+ - Prefixes:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values within the bits
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+ - In general, PCH registers are denoted by "_PCH_" in register names
+ - Registers / bits that are different between PCH generations are denoted by
+ "_PCH_[generation_name]_" in register/bit names.
+ - Registers / bits that are specific to PCH-H denoted by "_H_" in register/bit names.
+ Registers / bits that are specific to PCH-LP denoted by "_LP_" in register/bit names.
+ e.g., "_PCH_H_", "_PCH_LP_"
+ Registers / bits names without _H_ or _LP_ apply for both H and LP.
+ - Registers / bits that are different between SKUs are denoted by "_[SKU_name]"
+ at the end of the register/bit names
+ - Registers / bits of new devices introduced in a PCH generation will be just named
+ as "_PCH_" without [generation_name] inserted.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_PMC_H_
+#define _PCH_REGS_PMC_H_
+
+//
+// PMC Registers (D31:F2)
+//
+#define PCI_DEVICE_NUMBER_PCH_PMC 31
+#define PCI_FUNCTION_NUMBER_PCH_PMC 2
+
+#define R_PCH_PMC_PM_DATA_BAR 0x10
+#define B_PCH_PMC_PM_DATA_BAR 0xFFFFC000
+#define R_PCH_PMC_ACPI_BASE 0x40
+#define B_PCH_PMC_ACPI_BASE_BAR 0xFFFC
+#define R_PCH_PMC_ACPI_CNT 0x44
+#define B_PCH_PMC_ACPI_CNT_PWRM_EN BIT8 ///< PWRM enable
+#define B_PCH_PMC_ACPI_CNT_ACPI_EN BIT7 ///< ACPI eanble
+#define B_PCH_PMC_ACPI_CNT_SCIS (BIT2 | BIT1 | BIT0) ///< SCI IRQ select
+#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ9 0
+#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ10 1
+#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ11 2
+#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ20 4
+#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ21 5
+#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ22 6
+#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ23 7
+#define R_PCH_PMC_PWRM_BASE 0x48
+#define B_PCH_PMC_PWRM_BASE_BAR 0xFFFF0000 ///< PWRM must be 64KB alignment to align the source decode.
+#define R_PCH_PMC_GEN_PMCON_A 0xA0
+#define B_PCH_PMC_GEN_PMCON_A_DC_PP_DIS BIT30
+#define B_PCH_PMC_GEN_PMCON_A_DSX_PP_DIS BIT29
+#define B_PCH_PMC_GEN_PMCON_A_AG3_PP_EN BIT28
+#define B_PCH_PMC_GEN_PMCON_A_SX_PP_EN BIT27
+#define B_PCH_PMC_GEN_PMCON_A_DISB BIT23
+#define B_PCH_PMC_GEN_PMCON_A_MEM_SR BIT21
+#define B_PCH_PMC_GEN_PMCON_A_MS4V BIT18
+#define B_PCH_PMC_GEN_PMCON_A_GBL_RST_STS BIT16
+#define B_PCH_PMC_GEN_PMCON_A_ALLOW_OPI_PLL_SD_INC0 BIT13
+#define B_PCH_PMC_GEN_PMCON_A_ALLOW_SPXB_CG_INC0 BIT12
+#define B_PCH_PMC_GEN_PMCON_A_BIOS_PCI_EXP_EN BIT10
+#define B_PCH_PMC_GEN_PMCON_A_PWRBTN_LVL BIT9
+#define B_PCH_PMC_GEN_PMCON_A_ALLOW_L1LOW_C0 BIT7
+#define B_PCH_PMC_GEN_PMCON_A_ALLOW_L1LOW_OPI_ON BIT6
+#define B_PCH_PMC_GEN_PMCON_A_ALLOW_L1LOW_BCLKREQ_ON BIT5
+#define B_PCH_PMC_GEN_PMCON_A_SMI_LOCK BIT4
+#define B_PCH_PMC_GEN_PMCON_A_ESPI_SMI_LOCK BIT3 ///< ESPI SMI lock
+#define B_PCH_PMC_GEN_PMCON_A_PER_SMI_SEL 0x0003
+#define V_PCH_PMC_GEN_PMCON_A_PER_SMI_64S 0x0000
+#define V_PCH_PMC_GEN_PMCON_A_PER_SMI_32S 0x0001
+#define V_PCH_PMC_GEN_PMCON_A_PER_SMI_16S 0x0002
+#define V_PCH_PMC_GEN_PMCON_A_PER_SMI_8S 0x0003
+#define R_PCH_PMC_GEN_PMCON_B 0xA4
+#define B_PCH_PMC_GEN_PMCON_B_SLPSX_STR_POL_LOCK BIT18 ///< Lock down SLP_S3/SLP_S4 Minimum Assertion width
+#define B_PCH_PMC_GEN_PMCON_B_ACPI_BASE_LOCK BIT17 ///< Lock ACPI BASE at 0x40, only cleared by reset when set
+#define B_PCH_PMC_GEN_PMCON_B_PM_DATA_BAR_DIS BIT16
+#define B_PCH_PMC_GEN_PMCON_B_PME_B0_S5_DIS BIT15
+#define B_PCH_PMC_GEN_PMCON_B_SUS_PWR_FLR BIT14
+#define B_PCH_PMC_GEN_PMCON_B_WOL_EN_OVRD BIT13
+#define B_PCH_PMC_GEN_PMCON_B_DISABLE_SX_STRETCH BIT12
+#define B_PCH_PMC_GEN_PMCON_B_SLP_S3_MAW 0xC00
+#define V_PCH_PMC_GEN_PMCON_B_SLP_S3_MAW_60US 0x000
+#define V_PCH_PMC_GEN_PMCON_B_SLP_S3_MAW_1MS 0x400
+#define V_PCH_PMC_GEN_PMCON_B_SLP_S3_MAW_50MS 0x800
+#define V_PCH_PMC_GEN_PMCON_B_SLP_S3_MAW_2S 0xC00
+#define B_PCH_PMC_GEN_PMCON_B_HOST_RST_STS BIT9
+#define B_PCH_PMC_GEN_PMCON_B_SWSMI_RTSL 0xC0
+#define V_PCH_PMC_GEN_PMCON_B_SWSMI_RTSL_64MS 0xC0
+#define V_PCH_PMC_GEN_PMCON_B_SWSMI_RTSL_32MS 0x80
+#define V_PCH_PMC_GEN_PMCON_B_SWSMI_RTSL_16MS 0x40
+#define V_PCH_PMC_GEN_PMCON_B_SWSMI_RTSL_1_5MS 0x00
+#define B_PCH_PMC_GEN_PMCON_B_SLP_S4_MAW 0x30
+#define V_PCH_PMC_GEN_PMCON_B_SLP_S4_MAW_1S 0x30
+#define V_PCH_PMC_GEN_PMCON_B_SLP_S4_MAW_2S 0x20
+#define V_PCH_PMC_GEN_PMCON_B_SLP_S4_MAW_3S 0x10
+#define V_PCH_PMC_GEN_PMCON_B_SLP_S4_MAW_4S 0x00
+#define B_PCH_PMC_GEN_PMCON_B_SLP_S4_ASE BIT3
+#define B_PCH_PMC_GEN_PMCON_B_RTC_PWR_STS BIT2
+#define B_PCH_PMC_GEN_PMCON_B_PWR_FLR BIT1
+#define B_PCH_PMC_GEN_PMCON_B_AFTERG3_EN BIT0
+#define R_PCH_PMC_BM_CX_CNF 0xA8
+#define B_PCH_PMC_BM_CX_CNF_STORAGE_BREAK_EN BIT31
+#define B_PCH_PMC_BM_CX_CNF_PCIE_BREAK_EN BIT30
+#define B_PCH_PMC_BM_CX_CNF_AZ_BREAK_EN BIT24
+#define B_PCH_PMC_BM_CX_CNF_DPSN_BREAK_EN BIT19
+#define B_PCH_PMC_BM_CX_CNF_XHCI_BREAK_EN BIT17
+#define B_PCH_PMC_BM_CX_CNF_SATA3_BREAK_EN BIT16
+#define B_PCH_PMC_BM_CX_CNF_SCRATCHPAD BIT15
+#define B_PCH_PMC_BM_CX_CNF_PHOLD_BM_STS_BLOCK BIT14
+#define B_PCH_PMC_BM_CX_CNF_MASK_CF BIT11
+#define B_PCH_PMC_BM_CX_CNF_BM_STS_ZERO_EN BIT10
+#define B_PCH_PMC_BM_CX_CNF_PM_SYNC_MSG_MODE BIT9
+#define R_PCH_PMC_ETR3 0xAC
+#define B_PCH_PMC_ETR3_CF9LOCK BIT31 ///< CF9h Lockdown
+#define B_PCH_PMC_ETR3_USB_CACHE_DIS BIT21
+#define B_PCH_PMC_ETR3_CF9GR BIT20 ///< CF9h Global Reset
+#define B_PCH_PMC_ETR3_SKIP_HOST_RST_HS BIT19
+#define B_PCH_PMC_ETR3_CWORWRE BIT18
+
+//
+// ACPI and legacy I/O register offsets from ACPIBASE
+//
+#define R_PCH_ACPI_PM1_STS 0x00
+#define S_PCH_ACPI_PM1_STS 2
+#define B_PCH_ACPI_PM1_STS_WAK BIT15
+#define B_PCH_ACPI_PM1_STS_PCIEXP_WAKE_STS BIT14
+#define B_PCH_ACPI_PM1_STS_PRBTNOR BIT11
+#define B_PCH_ACPI_PM1_STS_RTC BIT10
+#define B_PCH_ACPI_PM1_STS_PWRBTN BIT8
+#define B_PCH_ACPI_PM1_STS_GBL BIT5
+#define B_PCH_ACPI_PM1_STS_BM BIT4
+#define B_PCH_ACPI_PM1_STS_TMROF BIT0
+#define N_PCH_ACPI_PM1_STS_WAK 15
+#define N_PCH_ACPI_PM1_STS_PCIEXP_WAKE_STS 14
+#define N_PCH_ACPI_PM1_STS_PRBTNOR 11
+#define N_PCH_ACPI_PM1_STS_RTC 10
+#define N_PCH_ACPI_PM1_STS_PWRBTN 8
+#define N_PCH_ACPI_PM1_STS_GBL 5
+#define N_PCH_ACPI_PM1_STS_BM 4
+#define N_PCH_ACPI_PM1_STS_TMROF 0
+
+#define R_PCH_ACPI_PM1_EN 0x02
+#define S_PCH_ACPI_PM1_EN 2
+#define B_PCH_ACPI_PM1_EN_PCIEXP_WAKE_DIS BIT14
+#define B_PCH_ACPI_PM1_EN_RTC BIT10
+#define B_PCH_ACPI_PM1_EN_PWRBTN BIT8
+#define B_PCH_ACPI_PM1_EN_GBL BIT5
+#define B_PCH_ACPI_PM1_EN_TMROF BIT0
+#define N_PCH_ACPI_PM1_EN_PCIEXP_WAKE_DIS 14
+#define N_PCH_ACPI_PM1_EN_RTC 10
+#define N_PCH_ACPI_PM1_EN_PWRBTN 8
+#define N_PCH_ACPI_PM1_EN_GBL 5
+#define N_PCH_ACPI_PM1_EN_TMROF 0
+
+#define R_PCH_ACPI_PM1_CNT 0x04
+#define S_PCH_ACPI_PM1_CNT 4
+#define B_PCH_ACPI_PM1_CNT_SLP_EN BIT13
+#define B_PCH_ACPI_PM1_CNT_SLP_TYP (BIT12 | BIT11 | BIT10)
+#define V_PCH_ACPI_PM1_CNT_S0 0
+#define V_PCH_ACPI_PM1_CNT_S1 BIT10
+#define V_PCH_ACPI_PM1_CNT_S3 (BIT12 | BIT10)
+#define V_PCH_ACPI_PM1_CNT_S4 (BIT12 | BIT11)
+#define V_PCH_ACPI_PM1_CNT_S5 (BIT12 | BIT11 | BIT10)
+#define B_PCH_ACPI_PM1_CNT_GBL_RLS BIT2
+#define B_PCH_ACPI_PM1_CNT_BM_RLD BIT1
+#define B_PCH_ACPI_PM1_CNT_SCI_EN BIT0
+
+#define R_PCH_ACPI_PM1_TMR 0x08
+#define V_PCH_ACPI_TMR_FREQUENCY 3579545
+#define B_PCH_ACPI_PM1_TMR_VAL 0xFFFFFF
+#define V_PCH_ACPI_PM1_TMR_MAX_VAL 0x1000000 ///< The timer is 24 bit overflow
+
+#define R_PCH_SMI_EN 0x30
+#define S_PCH_SMI_EN 4
+#define B_PCH_SMI_EN_LEGACY_USB3 BIT31
+#define B_PCH_SMI_EN_GPIO_UNLOCK_SMI BIT27
+#define B_PCH_SMI_EN_LEGACY_USB2 BIT17
+#define B_PCH_SMI_EN_PERIODIC BIT14
+#define B_PCH_SMI_EN_TCO BIT13
+#define B_PCH_SMI_EN_MCSMI BIT11
+#define B_PCH_SMI_EN_BIOS_RLS BIT7
+#define B_PCH_SMI_EN_SWSMI_TMR BIT6
+#define B_PCH_SMI_EN_APMC BIT5
+#define B_PCH_SMI_EN_ON_SLP_EN BIT4
+#define B_PCH_SMI_EN_LEGACY_USB BIT3
+#define B_PCH_SMI_EN_BIOS BIT2
+#define B_PCH_SMI_EN_EOS BIT1
+#define B_PCH_SMI_EN_GBL_SMI BIT0
+#define N_PCH_SMI_EN_LEGACY_USB3 31
+#define N_PCH_SMI_EN_ESPI 28
+#define N_PCH_SMI_EN_GPIO_UNLOCK 27
+#define N_PCH_SMI_EN_INTEL_USB2 18
+#define N_PCH_SMI_EN_LEGACY_USB2 17
+#define N_PCH_SMI_EN_PERIODIC 14
+#define N_PCH_SMI_EN_TCO 13
+#define N_PCH_SMI_EN_MCSMI 11
+#define N_PCH_SMI_EN_BIOS_RLS 7
+#define N_PCH_SMI_EN_SWSMI_TMR 6
+#define N_PCH_SMI_EN_APMC 5
+#define N_PCH_SMI_EN_ON_SLP_EN 4
+#define N_PCH_SMI_EN_LEGACY_USB 3
+#define N_PCH_SMI_EN_BIOS 2
+#define N_PCH_SMI_EN_EOS 1
+#define N_PCH_SMI_EN_GBL_SMI 0
+
+#define R_PCH_SMI_STS 0x34
+#define S_PCH_SMI_STS 4
+#define B_PCH_SMI_STS_LEGACY_USB3 BIT31
+#define B_PCH_SMI_STS_GPIO_UNLOCK BIT27
+#define B_PCH_SMI_STS_SPI BIT26
+#define B_PCH_SMI_STS_MONITOR BIT21
+#define B_PCH_SMI_STS_PCI_EXP BIT20
+#define B_PCH_SMI_STS_PATCH BIT19
+#define B_PCH_SMI_STS_INTEL_USB2 BIT18
+#define B_PCH_SMI_STS_LEGACY_USB2 BIT17
+#define B_PCH_SMI_STS_SMBUS BIT16
+#define B_PCH_SMI_STS_SERIRQ BIT15
+#define B_PCH_SMI_STS_PERIODIC BIT14
+#define B_PCH_SMI_STS_TCO BIT13
+#define B_PCH_SMI_STS_DEVMON BIT12
+#define B_PCH_SMI_STS_MCSMI BIT11
+#define B_PCH_SMI_STS_GPIO_SMI BIT10
+#define B_PCH_SMI_STS_GPE0 BIT9
+#define B_PCH_SMI_STS_PM1_STS_REG BIT8
+#define B_PCH_SMI_STS_SWSMI_TMR BIT6
+#define B_PCH_SMI_STS_APM BIT5
+#define B_PCH_SMI_STS_ON_SLP_EN BIT4
+#define B_PCH_SMI_STS_LEGACY_USB BIT3
+#define B_PCH_SMI_STS_BIOS BIT2
+#define N_PCH_SMI_STS_LEGACY_USB3 31
+#define N_PCH_SMI_STS_ESPI 28
+#define N_PCH_SMI_STS_GPIO_UNLOCK 27
+#define N_PCH_SMI_STS_SPI 26
+#define N_PCH_SMI_STS_MONITOR 21
+#define N_PCH_SMI_STS_PCI_EXP 20
+#define N_PCH_SMI_STS_PATCH 19
+#define N_PCH_SMI_STS_INTEL_USB2 18
+#define N_PCH_SMI_STS_LEGACY_USB2 17
+#define N_PCH_SMI_STS_SMBUS 16
+#define N_PCH_SMI_STS_SERIRQ 15
+#define N_PCH_SMI_STS_PERIODIC 14
+#define N_PCH_SMI_STS_TCO 13
+#define N_PCH_SMI_STS_DEVMON 12
+#define N_PCH_SMI_STS_MCSMI 11
+#define N_PCH_SMI_STS_GPIO_SMI 10
+#define N_PCH_SMI_STS_GPE0 9
+#define N_PCH_SMI_STS_PM1_STS_REG 8
+#define N_PCH_SMI_STS_SWSMI_TMR 6
+#define N_PCH_SMI_STS_APM 5
+#define N_PCH_SMI_STS_ON_SLP_EN 4
+#define N_PCH_SMI_STS_LEGACY_USB 3
+#define N_PCH_SMI_STS_BIOS 2
+
+#define R_PCH_ACPI_GPE_CNTL 0x40
+#define B_PCH_ACPI_GPE_CNTL_SWGPE_CTRL BIT17
+
+#define R_PCH_DEVACT_STS 0x44
+#define S_PCH_DEVACT_STS 2
+#define B_PCH_DEVACT_STS_MASK 0x13E1
+#define B_PCH_DEVACT_STS_KBC BIT12
+#define B_PCH_DEVACT_STS_PIRQDH BIT9
+#define B_PCH_DEVACT_STS_PIRQCG BIT8
+#define B_PCH_DEVACT_STS_PIRQBF BIT7
+#define B_PCH_DEVACT_STS_PIRQAE BIT6
+#define B_PCH_DEVACT_STS_D0_TRP BIT0
+#define N_PCH_DEVACT_STS_KBC 12
+#define N_PCH_DEVACT_STS_PIRQDH 9
+#define N_PCH_DEVACT_STS_PIRQCG 8
+#define N_PCH_DEVACT_STS_PIRQBF 7
+#define N_PCH_DEVACT_STS_PIRQAE 6
+
+#define R_PCH_ACPI_PM2_CNT 0x50
+#define B_PCH_ACPI_PM2_CNT_ARB_DIS BIT0
+
+#define R_PCH_OC_WDT_CTL 0x54
+#define B_PCH_OC_WDT_CTL_RLD BIT31
+#define B_PCH_OC_WDT_CTL_ICCSURV_STS BIT25
+#define B_PCH_OC_WDT_CTL_NO_ICCSURV_STS BIT24
+#define B_PCH_OC_WDT_CTL_FORCE_ALL BIT15
+#define B_PCH_OC_WDT_CTL_EN BIT14
+#define B_PCH_OC_WDT_CTL_ICCSURV BIT13
+#define B_PCH_OC_WDT_CTL_LCK BIT12
+#define B_PCH_OC_WDT_CTL_TOV_MASK 0x3FF
+#define B_PCH_OC_WDT_CTL_FAILURE_STS BIT23
+#define B_PCH_OC_WDT_CTL_UNXP_RESET_STS BIT22
+#define B_PCH_OC_WDT_CTL_AFTER_POST 0x3F0000
+#define V_PCH_OC_WDT_CTL_STATUS_FAILURE 1
+#define V_PCH_OC_WDT_CTL_STATUS_OK 0
+
+#define R_PCH_ACPI_GPE0_STS_31_0 0x80
+#define R_PCH_ACPI_GPE0_STS_63_32 0x84
+#define R_PCH_ACPI_GPE0_STS_95_64 0x88
+#define R_PCH_ACPI_GPE0_STS_127_96 0x8C
+#define S_PCH_ACPI_GPE0_STS_127_96 4
+#define B_PCH_ACPI_GPE0_STS_127_96_WADT BIT18
+#define B_PCH_ACPI_GPE0_STS_127_96_LAN_WAKE BIT16
+#define B_PCH_ACPI_GPE0_STS_127_96_PME_B0 BIT13
+#define B_PCH_ACPI_GPE0_STS_127_96_ME_SCI BIT12
+#define B_PCH_ACPI_GPE0_STS_127_96_PME BIT11
+#define B_PCH_ACPI_GPE0_STS_127_96_BATLOW BIT10
+#define B_PCH_ACPI_GPE0_STS_127_96_PCI_EXP BIT9
+#define B_PCH_ACPI_GPE0_STS_127_96_RI BIT8
+#define B_PCH_ACPI_GPE0_STS_127_96_SMB_WAK BIT7
+#define B_PCH_ACPI_GPE0_STS_127_96_TC0SCI BIT6
+#define B_PCH_ACPI_GPE0_STS_127_96_SWGPE BIT2
+#define B_PCH_ACPI_GPE0_STS_127_96_HOT_PLUG BIT1
+#define N_PCH_ACPI_GPE0_STS_127_96_PME_B0 13
+#define N_PCH_ACPI_GPE0_STS_127_96_PME 11
+#define N_PCH_ACPI_GPE0_STS_127_96_BATLOW 10
+#define N_PCH_ACPI_GPE0_STS_127_96_PCI_EXP 9
+#define N_PCH_ACPI_GPE0_STS_127_96_RI 8
+#define N_PCH_ACPI_GPE0_STS_127_96_SMB_WAK 7
+#define N_PCH_ACPI_GPE0_STS_127_96_TC0SCI 6
+#define N_PCH_ACPI_GPE0_STS_127_96_SWGPE 2
+#define N_PCH_ACPI_GPE0_STS_127_96_HOT_PLUG 1
+
+#define R_PCH_ACPI_GPE0_EN_31_0 0x90
+#define R_PCH_ACPI_GPE0_EN_63_32 0x94
+#define R_PCH_ACPI_GPE0_EN_95_64 0x98
+#define R_PCH_ACPI_GPE0_EN_127_96 0x9C
+#define S_PCH_ACPI_GPE0_EN_127_96 4
+#define B_PCH_ACPI_GPE0_EN_127_96_WADT BIT18
+#define B_PCH_ACPI_GPE0_EN_127_96_LAN_WAKE BIT16
+#define B_PCH_ACPI_GPE0_EN_127_96_PME_B0 BIT13
+#define B_PCH_ACPI_GPE0_EN_127_96_ME_SCI BIT12
+#define B_PCH_ACPI_GPE0_EN_127_96_PME BIT11
+#define B_PCH_ACPI_GPE0_EN_127_96_BATLOW BIT10
+#define B_PCH_ACPI_GPE0_EN_127_96_PCI_EXP BIT9
+#define B_PCH_ACPI_GPE0_EN_127_96_RI BIT8
+#define B_PCH_ACPI_GPE0_EN_127_96_TC0SCI BIT6
+#define B_PCH_ACPI_GPE0_EN_127_96_SWGPE BIT2
+#define B_PCH_ACPI_GPE0_EN_127_96_HOT_PLUG BIT1
+#define N_PCH_ACPI_GPE0_EN_127_96_PME_B0 13
+#define N_PCH_ACPI_GPE0_EN_127_96_USB3 12
+#define N_PCH_ACPI_GPE0_EN_127_96_PME 11
+#define N_PCH_ACPI_GPE0_EN_127_96_BATLOW 10
+#define N_PCH_ACPI_GPE0_EN_127_96_PCI_EXP 9
+#define N_PCH_ACPI_GPE0_EN_127_96_RI 8
+#define N_PCH_ACPI_GPE0_EN_127_96_TC0SCI 6
+#define N_PCH_ACPI_GPE0_EN_127_96_SWGPE 2
+#define N_PCH_ACPI_GPE0_EN_127_96_HOT_PLUG 1
+
+
+//
+// TCO register I/O map
+//
+#define R_PCH_TCO_RLD 0x0
+#define R_PCH_TCO_DAT_IN 0x2
+#define R_PCH_TCO_DAT_OUT 0x3
+#define R_PCH_TCO1_STS 0x04
+#define S_PCH_TCO1_STS 2
+#define B_PCH_TCO1_STS_DMISERR BIT12
+#define B_PCH_TCO1_STS_DMISMI BIT10
+#define B_PCH_TCO1_STS_DMISCI BIT9
+#define B_PCH_TCO1_STS_BIOSWR BIT8
+#define B_PCH_TCO1_STS_NEWCENTURY BIT7
+#define B_PCH_TCO1_STS_TIMEOUT BIT3
+#define B_PCH_TCO1_STS_TCO_INT BIT2
+#define B_PCH_TCO1_STS_SW_TCO_SMI BIT1
+#define B_PCH_TCO1_STS_NMI2SMI BIT0
+#define N_PCH_TCO1_STS_DMISMI 10
+#define N_PCH_TCO1_STS_BIOSWR 8
+#define N_PCH_TCO1_STS_NEWCENTURY 7
+#define N_PCH_TCO1_STS_TIMEOUT 3
+#define N_PCH_TCO1_STS_SW_TCO_SMI 1
+#define N_PCH_TCO1_STS_NMI2SMI 0
+
+#define R_PCH_TCO2_STS 0x06
+#define S_PCH_TCO2_STS 2
+#define B_PCH_TCO2_STS_SMLINK_SLV_SMI BIT4
+#define B_PCH_TCO2_STS_BAD_BIOS BIT3
+#define B_PCH_TCO2_STS_BOOT BIT2
+#define B_PCH_TCO2_STS_SECOND_TO BIT1
+#define B_PCH_TCO2_STS_INTRD_DET BIT0
+#define N_PCH_TCO2_STS_INTRD_DET 0
+
+#define R_PCH_TCO1_CNT 0x08
+#define S_PCH_TCO1_CNT 2
+#define B_PCH_TCO_CNT_LOCK BIT12
+#define B_PCH_TCO_CNT_TMR_HLT BIT11
+#define B_PCH_TCO_CNT_NMI2SMI_EN BIT9
+#define B_PCH_TCO_CNT_NMI_NOW BIT8
+#define N_PCH_TCO_CNT_NMI2SMI_EN 9
+
+#define R_PCH_TCO2_CNT 0x0A
+#define S_PCH_TCO2_CNT 2
+#define B_PCH_TCO2_CNT_OS_POLICY 0x0030
+#define B_PCH_TCO2_CNT_GPI11_ALERT_DISABLE 0x0008
+#define B_PCH_TCO2_CNT_INTRD_SEL 0x0006
+#define N_PCH_TCO2_CNT_INTRD_SEL 2
+
+#define R_PCH_TCO_MESSAGE1 0x0C
+#define R_PCH_TCO_MESSAGE2 0x0D
+#define R_PCH_TCO_WDCNT 0x0E
+#define R_PCH_TCO_SW_IRQ_GEN 0x10
+#define B_PCH_TCO_IRQ12_CAUSE BIT1
+#define B_PCH_TCO_IRQ1_CAUSE BIT0
+#define R_PCH_TCO_TMR 0x12
+
+//
+// PWRM Registers
+//
+#define R_PCH_WADT_AC 0x0 ///< Wake Alarm Device Timer: AC
+#define R_PCH_WADT_DC 0x4 ///< Wake Alarm Device Timer: DC
+#define R_PCH_WADT_EXP_AC 0x8 ///< Wake Alarm Device Expired Timer: AC
+#define R_PCH_WADT_EXP_DC 0xC ///< Wake Alarm Device Expired Timer: DC
+#define R_PCH_PWRM_PRSTS 0x10 ///< Power and Reset Status
+#define B_PCH_PWRM_PRSTS_VE_WD_TMR_STS BIT7 ///< VE Watchdog Timer Status
+#define B_PCH_PWRM_PRSTS_WOL_OVR_WK_STS BIT5
+#define B_PCH_PWRM_PRSTS_FIELD_1 BIT4
+#define B_PCH_PWRM_PRSTS_ME_WAKE_STS BIT0
+#define R_PCH_PWRM_14 0x14
+#define R_PCH_PWRM_CFG 0x18 ///< Power Management Configuration
+#define B_PCH_PWRM_CFG_ALLOW_24_OSC_SD BIT29 ///< Allow 24MHz Crystal Oscillator Shutdown
+#define B_PCH_PWRM_CFG_ALLOW_USB2_CORE_PG BIT25 ///< Allow USB2 Core Power Gating
+#define B_PCH_PWRM_CFG_RTC_DS_WAKE_DIS BIT21 ///< RTC Wake from Deep S4/S5 Disable
+#define B_PCH_PWRM_CFG_SSMAW_MASK (BIT19 | BIT18) ///< SLP_SUS# Min Assertion Width
+#define V_PCH_PWRM_CFG_SSMAW_4S (BIT19 | BIT18) ///< 4 seconds
+#define V_PCH_PWRM_CFG_SSMAW_1S BIT19 ///< 1 second
+#define V_PCH_PWRM_CFG_SSMAW_0_5S BIT18 ///< 0.5 second (500ms)
+#define V_PCH_PWRM_CFG_SSMAW_0S 0 ///< 0 second
+#define B_PCH_PWRM_CFG_SAMAW_MASK (BIT17 | BIT16) ///< SLP_A# Min Assertion Width
+#define V_PCH_PWRM_CFG_SAMAW_2S (BIT17 | BIT16) ///< 2 seconds
+#define V_PCH_PWRM_CFG_SAMAW_98ms BIT17 ///< 98ms
+#define V_PCH_PWRM_CFG_SAMAW_4S BIT16 ///< 4 seconds
+#define V_PCH_PWRM_CFG_SAMAW_0S 0 ///< 0 second
+#define B_PCH_PWRM_CFG_RPCD_MASK (BIT9 | BIT8) ///< Reset Power Cycle Duration
+#define V_PCH_PWRM_CFG_RPCD_1S (BIT9 | BIT8) ///< 1-2 seconds
+#define V_PCH_PWRM_CFG_RPCD_2S BIT9 ///< 2-3 seconds
+#define V_PCH_PWRM_CFG_RPCD_3S BIT8 ///< 3-4 seconds
+#define V_PCH_PWRM_CFG_RPCD_4S 0 ///< 4-5 seconds (Default)
+#define R_PCH_PWRM_PCH_PM_STS 0x1C ///< Contains misc. fields used to record PCH power management events
+#define B_PCH_PWRM_PCH_PM_STS_PMC_MSG_FULL_STS BIT24 ///< MTPMC transport mechanism full indication
+#define R_PCH_PWRM_MTPMC 0x20 ///< Message to PMC
+#define V_PCH_PWRM_MTPMC_COMMAND_PG_LANE_0_15 0xE ///< Command to override lanes 0-15 power gating
+#define V_PCH_PWRM_MTPMC_COMMAND_PG_LANE_16_31 0xF ///< Command to override lanes 16-31 power gating
+#define B_PCH_PWRM_MTPMC_PG_CMD_DATA 0xFFFF0000 ///< Data part of PowerGate Message to PMC
+#define N_PCH_PWRM_MTPMC_PG_CMD_DATA 16
+#define R_PCH_PWRM_PCH_PM_STS2 0x24 ///< PCH Power Management Status
+#define R_PCH_PWRM_S3_PWRGATE_POL 0x28 ///< S3 Power Gating Policies
+#define B_PCH_PWRM_S3DC_GATE_SUS BIT1 ///< Deep S3 Enable in DC Mode
+#define B_PCH_PWRM_S3AC_GATE_SUS BIT0 ///< Deep S3 Enable in AC Mode
+#define R_PCH_PWRM_S4_PWRGATE_POL 0x2C ///< Deep S4 Power Policies
+#define B_PCH_PWRM_S4DC_GATE_SUS BIT1 ///< Deep S4 Enable in DC Mode
+#define B_PCH_PWRM_S4AC_GATE_SUS BIT0 ///< Deep S4 Enable in AC Mode
+#define R_PCH_PWRM_S5_PWRGATE_POL 0x30 ///< Deep S5 Power Policies
+#define B_PCH_PWRM_S5DC_GATE_SUS BIT15 ///< Deep S5 Enable in DC Mode
+#define B_PCH_PWRM_S5AC_GATE_SUS BIT14 ///< Deep S5 Enable in AC Mode
+#define R_PCH_PWRM_DSX_CFG 0x34 ///< Deep SX Configuration
+#define B_PCH_PWRM_DSX_CFG_WAKE_PIN_DSX_EN BIT2 ///< WAKE# Pin DeepSx Enable
+#define B_PCH_PWRM_DSX_CFG_ACPRES_PD_DSX_DIS BIT1 ///< AC_PRESENT pin pulldown in DeepSx disable
+#define B_PCH_PWRM_DSX_CFG_LAN_WAKE_EN BIT0 ///< LAN_WAKE Pin DeepSx Enable
+#define R_PCH_PWRM_CFG2 0x3C ///< Power Management Configuration Reg 2
+#define B_PCH_PWRM_CFG2_PBOP (BIT31 | BIT30 | BIT29) ///< Power Button Override Period (PBOP)
+#define N_PCH_PWRM_CFG2_PBOP 29 ///< Power Button Override Period (PBOP)
+#define B_PCH_PWRM_CFG2_PB_DIS BIT28 ///< Power Button Native Mode Disable (PB_DIS)
+#define B_PCH_PWRM_CFG2_DRAM_RESET_CTL BIT26 ///< DRAM RESET# control
+#define R_PCH_PWRM_EN_SN_SLOW_RING 0x48 ///< Enable Snoop Request to SLOW_RING
+#define R_PCH_PWRM_EN_SN_SLOW_RING2 0x4C ///< Enable Snoop Request to SLOW_RING 2nd Reg
+#define R_PCH_PWRM_EN_SN_SA 0x50 ///< Enable Snoop Request to SA
+#define R_PCH_PWRM_EN_SN_SA2 0x54 ///< Enable Snoop Request to SA 2nd Reg
+#define R_PCH_PWRM_EN_SN_SLOW_RING_CF 0x58 ///< Enable Snoop Request to SLOW_RING_CF
+#define R_PCH_PWRM_EN_NS_SA 0x68 ///< Enable Non-Snoop Request to SA
+#define R_PCH_PWRM_EN_CW_SLOW_RING 0x80 ///< Enable Clock Wake to SLOW_RING
+#define R_PCH_PWRM_EN_CW_SLOW_RING2 0x84 ///< Enable Clock Wake to SLOW_RING 2nd Reg
+#define R_PCH_PWRM_EN_CW_SA 0x88 ///< Enable Clock Wake to SA
+#define R_PCH_PWRM_EN_CW_SA2 0x8C ///< Enable Clock Wake to SA 2nd Reg
+#define R_PCH_PWRM_EN_CW_SLOW_RING_CF 0x98 ///< Enable Clock Wake to SLOW_RING_CF
+#define R_PCH_PWRM_EN_PA_SLOW_RING 0xA8 ///< Enable Pegged Active to SLOW_RING
+#define R_PCH_PWRM_EN_PA_SLOW_RING2 0xAC ///< Enable Pegged Active to SLOW_RING 2nd Reg
+#define R_PCH_PWRM_EN_PA_SA 0xB0 ///< Enable Pegged Active to SA
+#define R_PCH_PWRM_EN_PA_SA2 0xB4 ///< Enable Pegged Active to SA 2nd Reg
+#define R_PCH_PWRM_EN_MISC_EVENT 0xC0 ///< Enable Misc PM_SYNC Events
+#define R_PCH_PWRM_PMSYNC_TPR_CONFIG 0xC4
+#define B_PCH_PWRM_PMSYNC_TPR_CONFIG_LOCK BIT31
+#define B_PCH_PWRM_PMSYNC_PCH2CPU_TT_EN BIT26
+#define B_PCH_PWRM_PMSYNC_PCH2CPU_TT_STATE (BIT25 | BIT24)
+#define N_PCH_PWRM_PMSYNC_PCH2CPU_TT_STATE 24
+#define V_PCH_PWRM_PMSYNC_PCH2CPU_TT_STATE_1 1
+#define R_PCH_PWRM_PMSYNC_MISC_CFG 0xC8
+#define B_PCH_PWRM_PMSYNC_PM_SYNC_LOCK BIT15 ///< PM_SYNC Configuration Lock
+#define B_PCH_PWRM_PMSYNC_GPIO_D_SEL BIT11
+#define B_PCH_PWRM_PMSYNC_GPIO_C_SEL BIT10
+#define R_PCH_PWRM_PM_SYNC_STATE_HYS 0xD0 ///< PM_SYNC State Hysteresis
+#define R_PCH_PWRM_PM_SYNC_MODE 0xD4 ///< PM_SYNC Pin Mode
+#define R_PCH_PWRM_CFG3 0xE0 ///< Power Management Configuration Reg 3
+#define B_PCH_PWRM_CFG3_DSX_WLAN_PP_EN BIT16 ///< Deep-Sx WLAN Phy Power Enable
+#define B_PCH_PWRM_CFG3_HOST_WLAN_PP_EN BIT17 ///< Host Wireless LAN Phy Power Enable
+#define B_PCH_PWRM_CFG3_PWRG_LOCK BIT2 ///< Lock power gating override messages
+#define R_PCH_PWRM_PM_DOWN_PPB_CFG 0xE4 ///< PM_DOWN PCH_POWER_BUDGET CONFIGURATION
+#define R_PCH_PWRM_CFG4 0xE8 ///< Power Management Configuration Reg 4
+#define B_PCH_PWRM_CFG4_U2_PHY_PG_EN BIT30 ///< USB2 PHY SUS Well Power Gating Enable
+#define B_PCH_PWRM_CFG4_CPU_IOVR_RAMP_DUR (0x000001FF) ///< CPU I/O VR Ramp Duration, [8:0]
+#define N_PCH_PWRM_CFG4_CPU_IOVR_RAMP_DUR 0
+#define V_PCH_PWRM_CFG4_CPU_IOVR_RAMP_DUR_70US 0x007
+#define V_PCH_PWRM_CFG4_CPU_IOVR_RAMP_DUR_240US 0x018
+#define R_PCH_PWRM_CPU_EPOC 0xEC
+#define R_PCH_PWRM_VR_MISC_CTL 0x100
+#define B_PCH_PWRM_VR_MISC_CTL_VIDSOVEN BIT3
+#define R_PCH_PWRM_GPIO_CFG 0x120
+#define B_PCH_PWRM_GPIO_CFG_GPE0_DW2 (BIT11 | BIT10 | BIT9 | BIT8)
+#define N_PCH_PWRM_GPIO_CFG_GPE0_DW2 8
+#define B_PCH_PWRM_GPIO_CFG_GPE0_DW1 (BIT7 | BIT6 | BIT5 | BIT4)
+#define N_PCH_PWRM_GPIO_CFG_GPE0_DW1 4
+#define B_PCH_PWRM_GPIO_CFG_GPE0_DW0 (BIT3 | BIT2 | BIT1 | BIT0)
+#define N_PCH_PWRM_GPIO_CFG_GPE0_DW0 0
+#define R_PCH_PWRM_PM_SYNC_MODE_C0 0xF4 ///< PM_SYNC Pin Mode in C0
+#define R_PCH_PWRM_ACPI_TMR_CTL 0xFC
+#define B_PCH_PWRM_ACPI_TMR_DIS BIT1
+#define R_PCH_PWRM_124 0x124
+#define R_PCH_PWRM_SLP_S0_RESIDENCY_COUNTER 0x13C
+#define R_PCH_PWRM_MODPHY_PM_CFG1 0x200
+#define R_PCH_PWRM_MODPHY_PM_CFG1_MLSXSWPGP 0xFFFF
+#define R_PCH_PWRM_MODPHY_PM_CFG2 0x204 ///< ModPHY Power Management Configuration Reg 2
+#define B_PCH_PWRM_MODPHY_PM_CFG2_MLSPDDGE BIT30 ///< ModPHY Lane SUS Power Domain Dynamic Gating Enable
+#define B_PCH_PWRM_MODPHY_PM_CFG2_EMFC BIT29 ///< Enable ModPHY FET Control
+#define B_PCH_PWRM_MODPHY_PM_CFG2_EFRT (BIT28 | BIT27 | BIT26 | BIT25 | BIT24) ///< External FET Ramp Time
+#define N_PCH_PWRM_MODPHY_PM_CFG2_EFRT 24
+#define V_PCH_PWRM_MODPHY_PM_CFG2_EFRT_200US 0x0A
+#define B_PCH_PWRM_MODPHY_PM_CFG2_ASLOR_UFS BIT16 ///< UFS ModPHY SPD SPD Override
+#define R_PCH_PWRM_MODPHY_PM_CFG3 0x208 ///< ModPHY Power Management Configuration Reg 3
+#define B_PCH_PWRM_MODPHY_PM_CFG3_MSPDRTREQ_UFS BIT16 ///< UFS ModPHY SPD RT Request
+#define B_PCH_PWRM_MODPHY_PM_CFG3_MSPDRTREQ_XDCI BIT15 ///< xDCI ModPHY SPD RT Request
+#define B_PCH_PWRM_MODPHY_PM_CFG3_MSPDRTREQ_XHCI BIT14 ///< xHCI ModPHY SPD RT Request
+#define B_PCH_PWRM_MODPHY_PM_CFG3_MSPDRTREQ_GBE BIT13 ///< GbE ModPHY SPD RT Request
+#define B_PCH_PWRM_MODPHY_PM_CFG3_MSPDRTREQ_SATA BIT12 ///< SATA ModPHY SPD RT Request
+#define R_PCH_PWRM_30C 0x30C
+#define R_PCH_PWRM_OBFF_CFG 0x314 ///< OBFF Configuration
+#define R_PCH_PWRM_31C 0x31C
+#define R_PCH_PWRM_CPPM_MISC_CFG 0x320 ///< CPPM Miscellaneous Configuration
+#define R_PCH_PWRM_CPPM_CG_POL1A 0x324 ///< CPPM Clock Gating Policy Reg 1
+#define R_PCH_PWRM_CPPM_CG_POL2A 0x340 ///< CPPM Clock Gating Policy Reg 3
+#define R_PCH_PWRM_34C 0x34C
+#define R_PCH_PWRM_CPPM_CG_POL3A 0x3A8 ///< CPPM Clock Gating Policy Reg 5
+#define B_PCH_PWRM_CPPM_CG_POLXA_CPPM_GX_QUAL BIT30 ///< CPPM Shutdown Qualifier Enable for Clock Source Group X
+#define B_PCH_PWRM_CPPM_CG_POLXA_LTR_GX_THRESH (0x000001FF) ///< LTR Threshold for Clock Source Group X, [8:0]
+#define R_PCH_PWRM_3D0 0x3D0
+#define R_PCH_PWRM_CPPM_MPG_POL1A 0x3E0 ///< CPPM ModPHY Gating Policy Reg 1A
+#define B_PCH_PWRM_CPPM_MPG_POL1A_CPPM_MODPHY_QUAL BIT30 ///< CPPM Shutdown Qualifier Enable for ModPHY
+#define B_PCH_PWRM_CPPM_MPG_POL1A_LT_MODPHY_SEL BIT29 ///< ASLT/PLT Selection for ModPHY
+#define B_PCH_PWRM_CPPM_MPG_POL1A_LTR_MODPHY_THRESH (0x000001FF) ///< LTR Threshold for ModPHY, [8:0]
+#define R_PCH_PWRM_CS_SD_CTL1 0x3E8 ///< Clock Source Shutdown Control Reg 1
+#define B_PCH_PWRM_CS_SD_CTL1_CS5_CTL_CFG (BIT22 | BIT21 | BIT20) ///< Clock Source 5 Control Configuration
+#define N_PCH_PWRM_CS_SD_CTL1_CS5_CTL_CFG 20
+#define B_PCH_PWRM_CS_SD_CTL1_CS1_CTL_CFG (BIT2 | BIT1 | BIT0) ///< Clock Source 1 Control Configuration
+#define N_PCH_PWRM_CS_SD_CTL1_CS1_CTL_CFG 0
+#define R_PCH_PWRM_CS_SD_CTL2 0x3EC ///< Clock Source Shutdown Control Reg 2
+#define R_PCH_PWRM_HSWPGCR1 0x5D0
+#define B_PCH_PWRM_SW_PG_CTRL_LOCK BIT31
+#define B_PCH_PWRM_DFX_SW_PG_CTRL BIT0
+#define R_PCH_PWRM_600 0x600
+#define R_PCH_PWRM_604 0x604
+#define R_PCH_PWRM_ST_PG_FDIS_PMC_1 0x620 ///< Static PG Related Function Disable Register 1
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_1_ST_FDIS_LK BIT31 ///< Static Function Disable Lock (ST_FDIS_LK)
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_1_CAM_FDIS_PMC BIT6 ///< Camera Function Disable (PMC Version) (CAM_FDIS_PMC)
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_1_ISH_FDIS_PMC BIT5 ///< SH Function Disable (PMC Version) (ISH_FDIS_PMC)
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_1_GBE_FDIS_PMC BIT0 ///< GBE Function Disable (PMC Version) (GBE_FDIS_PMC)
+#define R_PCH_PWRM_ST_PG_FDIS_PMC_2 0x624 ///< Static Function Disable Control Register 2
+#define V_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_FDIS_PMC 0x7FF ///< Static Function Disable Control Register 2
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_GSPI1_FDIS_PMC BIT10 ///< SerialIo Controller GSPI Device 1 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_GSPI0_FDIS_PMC BIT9 ///< SerialIo Controller GSPI Device 0 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_UART2_FDIS_PMC BIT8 ///< SerialIo Controller UART Device 2 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_UART1_FDIS_PMC BIT7 ///< SerialIo Controller UART Device 1 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_UART0_FDIS_PMC BIT6 ///< SerialIo Controller UART Device 0 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C5_FDIS_PMC BIT5 ///< SerialIo Controller I2C Device 5 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C4_FDIS_PMC BIT4 ///< SerialIo Controller I2C Device 4 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C3_FDIS_PMC BIT3 ///< SerialIo Controller I2C Device 3 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C2_FDIS_PMC BIT2 ///< SerialIo Controller I2C Device 2 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C1_FDIS_PMC BIT1 ///< SerialIo Controller I2C Device 1 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C0_FDIS_PMC BIT0 ///< SerialIo Controller I2C Device 0 Function Disable
+#define R_PCH_PWRM_NST_PG_FDIS_1 0x628
+#define B_PCH_PWRM_NST_PG_FDIS_1_SCC_FDIS_PMC BIT25 ///< SCC Function Disable. This is only avaiable in B0 onward.
+#define B_PCH_PWRM_NST_PG_FDIS_1_XDCI_FDIS_PMC BIT24 ///< XDCI Function Disable. This is only avaiable in B0 onward.
+#define B_PCH_PWRM_NST_PG_FDIS_1_ADSP_FDIS_PMC BIT23 ///< ADSP Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_SATA_FDIS_PMC BIT22 ///< SATA Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_C3_FDIS_PMC BIT13 ///< PCIe Controller C Port 3 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_C2_FDIS_PMC BIT12 ///< PCIe Controller C Port 2 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_C1_FDIS_PMC BIT11 ///< PCIe Controller C Port 1 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_C0_FDIS_PMC BIT10 ///< PCIe Controller C Port 0 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_B3_FDIS_PMC BIT9 ///< PCIe Controller B Port 3 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_B2_FDIS_PMC BIT8 ///< PCIe Controller B Port 2 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_B1_FDIS_PMC BIT7 ///< PCIe Controller B Port 1 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_B0_FDIS_PMC BIT6 ///< PCIe Controller B Port 0 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_A3_FDIS_PMC BIT5 ///< PCIe Controller A Port 3 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_A2_FDIS_PMC BIT4 ///< PCIe Controller A Port 2 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_A1_FDIS_PMC BIT3 ///< PCIe Controller A Port 1 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_A0_FDIS_PMC BIT2 ///< PCIe Controller A Port 0 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_XHCI_FDIS_PMC BIT0 ///< XHCI Function Disable
+#define R_PCH_PWRM_FUSE_DIS_RD_1 0x640 ///< Fuse Disable Read 1 Register
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_E3_FUSE_DIS BIT21 ///< PCIe Controller E Port 3 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_E2_FUSE_DIS BIT20 ///< PCIe Controller E Port 2 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_E1_FUSE_DIS BIT19 ///< PCIe Controller E Port 1 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_E0_FUSE_DIS BIT18 ///< PCIe Controller E Port 0 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_D3_FUSE_DIS BIT17 ///< PCIe Controller D Port 3 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_D2_FUSE_DIS BIT16 ///< PCIe Controller D Port 2 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_D1_FUSE_DIS BIT15 ///< PCIe Controller D Port 1 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_D0_FUSE_DIS BIT14 ///< PCIe Controller D Port 0 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_C3_FUSE_DIS BIT13 ///< PCIe Controller C Port 3 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_C2_FUSE_DIS BIT12 ///< PCIe Controller C Port 2 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_C1_FUSE_DIS BIT11 ///< PCIe Controller C Port 1 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_C0_FUSE_DIS BIT10 ///< PCIe Controller C Port 0 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_B3_FUSE_DIS BIT9 ///< PCIe Controller B Port 3 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_B2_FUSE_DIS BIT8 ///< PCIe Controller B Port 2 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_B1_FUSE_DIS BIT7 ///< PCIe Controller B Port 1 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_B0_FUSE_DIS BIT6 ///< PCIe Controller B Port 0 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_A3_FUSE_DIS BIT5 ///< PCIe Controller A Port 3 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_A2_FUSE_DIS BIT4 ///< PCIe Controller A Port 2 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_A1_FUSE_DIS BIT3 ///< PCIe Controller A Port 1 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_A0_FUSE_DIS BIT2 ///< PCIe Controller A Port 0 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_XHCI_FUSE_DIS BIT0 ///< XHCI Fuse Disable
+#define R_PCH_PWRM_FUSE_DIS_RD_2 0x644 ///< Fuse Disable Read 2 Register
+#define B_PCH_PWRM_FUSE_DIS_RD_2_SPC_SS_DIS BIT25 ///< SPC Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_SPB_SS_DIS BIT24 ///< SPB Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_SPA_SS_DIS BIT23 ///< SPA Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_PSTH_FUSE_SS_DIS BIT21 ///< PSTH Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_DMI_FUSE_SS_DIS BIT20 ///< DMI Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_OTG_FUSE_SS_DIS BIT19 ///< OTG Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_XHCI_SS_DIS BIT18 ///< XHCI Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_FIA_FUSE_SS_DIS BIT17 ///< FIA Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_DSP_FUSE_SS_DIS BIT16 ///< DSP Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_SATA_FUSE_SS_DIS BIT15 ///< SATA Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_ICC_FUSE_SS_DIS BIT14 ///< ICC Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_LPC_FUSE_SS_DIS BIT13 ///< LPC Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_RTC_FUSE_SS_DIS BIT12 ///< RTC Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_P2S_FUSE_SS_DIS BIT11 ///< P2S Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_TRSB_FUSE_SS_DIS BIT10 ///< TRSB Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_SMB_FUSE_SS_DIS BIT9 ///< SMB Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_ITSS_FUSE_SS_DIS BIT8 ///< ITSS Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_SERIALIO_FUSE_SS_DIS BIT6 ///< SerialIo Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_SCC_FUSE_SS_DIS BIT4 ///< SCC Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_P2D_FUSE_SS_DIS BIT3 ///< P2D Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_CAM_FUSE_SS_DIS BIT2 ///< Camera Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_ISH_FUSE_SS_DIS BIT1 ///< ISH Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_GBE_FUSE_SS_DIS BIT0 ///< GBE Fuse or Soft Strap Disable
+#define R_PCH_PWRM_FUSE_DIS_RD_3 0x648 ///< Static PG Fuse and Soft Strap Disable Read Register 3
+#define B_PCH_PWRM_FUSE_DIS_RD_3_PNCRA3_FUSE_SS_DIS BIT3 ///< PNCRA3 Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_3_PNCRA2_FUSE_SS_DIS BIT2 ///< PNCRA2 Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_3_PNCRA1_FUSE_SS_DIS BIT1 ///< PNCRA1 Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_3_PNCRA_FUSE_SS_DIS BIT0 ///< PNCRA Fuse or Soft Strap Disable
+
+
+#endif
diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsSpi.h b/Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsSpi.h
new file mode 100644
index 0000000000..56831b6afe
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsSpi.h
@@ -0,0 +1,304 @@
+/** @file
+ Register names for PCH SPI device.
+
+ Conventions:
+
+ - Prefixes:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values within the bits
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+ - In general, PCH registers are denoted by "_PCH_" in register names
+ - Registers / bits that are different between PCH generations are denoted by
+ "_PCH_[generation_name]_" in register/bit names.
+ - Registers / bits that are specific to PCH-H denoted by "_H_" in register/bit names.
+ Registers / bits that are specific to PCH-LP denoted by "_LP_" in register/bit names.
+ e.g., "_PCH_H_", "_PCH_LP_"
+ Registers / bits names without _H_ or _LP_ apply for both H and LP.
+ - Registers / bits that are different between SKUs are denoted by "_[SKU_name]"
+ at the end of the register/bit names
+ - Registers / bits of new devices introduced in a PCH generation will be just named
+ as "_PCH_" without [generation_name] inserted.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_SPI_H_
+#define _PCH_REGS_SPI_H_
+
+//
+// SPI Registers (D31:F5)
+//
+
+#define PCI_DEVICE_NUMBER_PCH_SPI 31
+#define PCI_FUNCTION_NUMBER_PCH_SPI 5
+
+#define R_PCH_SPI_BAR0 0x10
+#define B_PCH_SPI_BAR0_MASK 0x0FFF
+
+#define R_PCH_SPI_BDE 0xD8
+#define B_PCH_SPI_BDE_F8 0x8000
+#define B_PCH_SPI_BDE_F0 0x4000
+#define B_PCH_SPI_BDE_E8 0x2000
+#define B_PCH_SPI_BDE_E0 0x1000
+#define B_PCH_SPI_BDE_D8 0x0800
+#define B_PCH_SPI_BDE_D0 0x0400
+#define B_PCH_SPI_BDE_C8 0x0200
+#define B_PCH_SPI_BDE_C0 0x0100
+#define B_PCH_SPI_BDE_LEG_F 0x0080
+#define B_PCH_SPI_BDE_LEG_E 0x0040
+#define B_PCH_SPI_BDE_70 0x0008
+#define B_PCH_SPI_BDE_60 0x0004
+#define B_PCH_SPI_BDE_50 0x0002
+#define B_PCH_SPI_BDE_40 0x0001
+
+#define R_PCH_SPI_BC 0xDC
+#define S_PCH_SPI_BC 4
+#define N_PCH_SPI_BC_ASE_BWP 11
+#define B_PCH_SPI_BC_ASE_BWP BIT11
+#define N_PCH_SPI_BC_ASYNC_SS 10
+#define B_PCH_SPI_BC_ASYNC_SS BIT10
+#define B_PCH_SPI_BC_OSFH BIT9 ///< OS Function Hide
+#define N_PCH_SPI_BC_SYNC_SS 8
+#define B_PCH_SPI_BC_SYNC_SS BIT8
+#define B_PCH_SPI_BC_BILD BIT7
+#define B_PCH_SPI_BC_BBS BIT6 ///< Boot BIOS strap
+#define N_PCH_SPI_BC_BBS 6
+#define V_PCH_SPI_BC_BBS_SPI 0 ///< Boot BIOS strapped to SPI
+#define V_PCH_SPI_BC_BBS_LPC 1 ///< Boot BIOS strapped to LPC
+#define B_PCH_SPI_BC_EISS BIT5 ///< Enable InSMM.STS
+#define B_PCH_SPI_BC_TSS BIT4
+#define B_PCH_SPI_BC_SRC (BIT3 | BIT2)
+#define N_PCH_SPI_BC_SRC 2
+#define V_PCH_SPI_BC_SRC_PREF_EN_CACHE_EN 0x02 ///< Prefetching and Caching enabled
+#define V_PCH_SPI_BC_SRC_PREF_DIS_CACHE_DIS 0x01 ///< No prefetching and no caching
+#define V_PCH_SPI_BC_SRC_PREF_DIS_CACHE_EN 0x00 ///< No prefetching, but caching enabled
+#define B_PCH_SPI_BC_LE BIT1 ///< Lock Enable
+#define N_PCH_SPI_BC_BLE 1
+#define B_PCH_SPI_BC_WPD BIT0 ///< Write Protect Disable
+
+//
+// BIOS Flash Program Registers (based on SPI_BAR0)
+//
+#define R_PCH_SPI_BFPR 0x00 ///< BIOS Flash Primary Region Register(32bits), which is RO and contains the same value from FREG1
+#define B_PCH_SPI_BFPR_PRL 0x7FFF0000 ///< BIOS Flash Primary Region Limit mask
+#define N_PCH_SPI_BFPR_PRL 16 ///< BIOS Flash Primary Region Limit bit position
+#define B_PCH_SPI_BFPR_PRB 0x00007FFF ///< BIOS Flash Primary Region Base mask
+#define N_PCH_SPI_BFPR_PRB 0 ///< BIOS Flash Primary Region Base bit position
+#define R_PCH_SPI_HSFSC 0x04 ///< Hardware Sequencing Flash Status and Control Register(32bits)
+#define B_PCH_SPI_HSFSC_FSMIE BIT31 ///< Flash SPI SMI# Enable
+#define B_PCH_SPI_HSFSC_FDBC_MASK 0x3F000000 ///< Flash Data Byte Count ( <= 64), Count = (Value in this field) + 1.
+#define N_PCH_SPI_HSFSC_FDBC 24
+#define B_PCH_SPI_HSFSC_CYCLE_MASK 0x001E0000 ///< Flash Cycle.
+#define N_PCH_SPI_HSFSC_CYCLE 17
+#define V_PCH_SPI_HSFSC_CYCLE_READ 0 ///< Flash Cycle Read
+#define V_PCH_SPI_HSFSC_CYCLE_WRITE 2 ///< Flash Cycle Write
+#define V_PCH_SPI_HSFSC_CYCLE_4K_ERASE 3 ///< Flash Cycle 4K Block Erase
+#define V_PCH_SPI_HSFSC_CYCLE_64K_ERASE 4 ///< Flash Cycle 64K Sector Erase
+#define V_PCH_SPI_HSFSC_CYCLE_READ_SFDP 5 ///< Flash Cycle Read SFDP
+#define V_PCH_SPI_HSFSC_CYCLE_READ_JEDEC_ID 6 ///< Flash Cycle Read JEDEC ID
+#define V_PCH_SPI_HSFSC_CYCLE_WRITE_STATUS 7 ///< Flash Cycle Write Status
+#define V_PCH_SPI_HSFSC_CYCLE_READ_STATUS 8 ///< Flash Cycle Read Status
+#define B_PCH_SPI_HSFSC_CYCLE_FGO BIT16 ///< Flash Cycle Go.
+#define B_PCH_SPI_HSFSC_FLOCKDN BIT15 ///< Flash Configuration Lock-Down
+#define B_PCH_SPI_HSFSC_FDV BIT14 ///< Flash Descriptor Valid, once valid software can use hareware sequencing regs
+#define B_PCH_SPI_HSFSC_FDOPSS BIT13 ///< Flash Descriptor Override Pin-Strap Status
+#define B_PCH_SPI_HSFSC_PRR34_LOCKDN BIT12 ///< PRR3 PRR4 Lock-Down
+#define B_PCH_SPI_HSFSC_SAF_CE BIT8 ///< SAF ctype error
+#define B_PCH_SPI_HSFSC_SAF_MODE_ACTIVE BIT7 ///< Indicates flash is attached either directly to the PCH via the SPI bus or EC/BMC
+#define B_PCH_SPI_HSFSC_SAF_LE BIT6 ///< SAF link error
+#define B_PCH_SPI_HSFSC_SCIP BIT5 ///< SPI cycle in progress
+#define B_PCH_SPI_HSFSC_SAF_DLE BIT4 ///< SAF Data length error
+#define B_PCH_SPI_HSFSC_SAF_ERROR BIT3 ///< SAF Error
+#define B_PCH_SPI_HSFSC_AEL BIT2 ///< Access Error Log
+#define B_PCH_SPI_HSFSC_FCERR BIT1 ///< Flash Cycle Error
+#define B_PCH_SPI_HSFSC_FDONE BIT0 ///< Flash Cycle Done
+#define R_PCH_SPI_FADDR 0x08 ///< SPI Flash Address
+#define B_PCH_SPI_FADDR_MASK 0x01FFFFFF ///< SPI Flash Address Mask (0~24bit)
+#define R_PCH_SPI_DLOCK 0x0C ///< Discrete Lock Bits
+#define B_PCH_SPI_DLOCK_PR0LOCKDN BIT8 ///< PR0LOCKDN
+#define R_PCH_SPI_FDATA00 0x10 ///< SPI Data 00 (32 bits)
+#define R_PCH_SPI_FDATA01 0x14 ///< SPI Data 01
+#define R_PCH_SPI_FDATA02 0x18 ///< SPI Data 02
+#define R_PCH_SPI_FDATA03 0x1C ///< SPI Data 03
+#define R_PCH_SPI_FDATA04 0x20 ///< SPI Data 04
+#define R_PCH_SPI_FDATA05 0x24 ///< SPI Data 05
+#define R_PCH_SPI_FDATA06 0x28 ///< SPI Data 06
+#define R_PCH_SPI_FDATA07 0x2C ///< SPI Data 07
+#define R_PCH_SPI_FDATA08 0x30 ///< SPI Data 08
+#define R_PCH_SPI_FDATA09 0x34 ///< SPI Data 09
+#define R_PCH_SPI_FDATA10 0x38 ///< SPI Data 10
+#define R_PCH_SPI_FDATA11 0x3C ///< SPI Data 11
+#define R_PCH_SPI_FDATA12 0x40 ///< SPI Data 12
+#define R_PCH_SPI_FDATA13 0x44 ///< SPI Data 13
+#define R_PCH_SPI_FDATA14 0x48 ///< SPI Data 14
+#define R_PCH_SPI_FDATA15 0x4C ///< SPI Data 15
+#define R_PCH_SPI_FRAP 0x50 ///< Flash Region Access Permisions Register
+#define B_PCH_SPI_FRAP_BRWA_MASK 0x0000FF00 ///< BIOS Region Write Access MASK, Region0~7 - 0: Flash Descriptor; 1: BIOS; 2: ME; 3: GbE; 4: PlatformData
+#define N_PCH_SPI_FRAP_BRWA 8 ///< BIOS Region Write Access bit position
+#define B_PCH_SPI_FRAP_BRRA_MASK 0x000000FF ///< BIOS Region Read Access MASK, Region0~7 - 0: Flash Descriptor; 1: BIOS; 2: ME; 3: GbE; 4: PlatformData
+#define B_PCH_SPI_FRAP_BMRAG_MASK 0x00FF0000 ///< BIOS Master Read Access Grant
+#define B_PCH_SPI_FRAP_BMWAG_MASK 0xFF000000 ///< BIOS Master Write Access Grant
+#define R_PCH_SPI_FREG0_FLASHD 0x54 ///< Flash Region 0(Flash Descriptor)(32bits)
+#define R_PCH_SPI_FREG1_BIOS 0x58 ///< Flash Region 1(BIOS)(32bits)
+#define R_PCH_SPI_FREG2_ME 0x5C ///< Flash Region 2(ME)(32bits)
+#define R_PCH_SPI_FREG3_GBE 0x60 ///< Flash Region 3(GbE)(32bits)
+#define R_PCH_SPI_FREG4_PLATFORM_DATA 0x64 ///< Flash Region 4(Platform Data)(32bits)
+#define R_PCH_SPI_FREG5_DER 0x68 ///< Flash Region 5(Device Expansion Region)(32bits)
+#define S_PCH_SPI_FREGX 4 ///< Size of Flash Region register
+#define B_PCH_SPI_FREGX_LIMIT_MASK 0x7FFF0000 ///< Flash Region Limit [30:16] represents [26:12], [11:0] are assumed to be FFFh
+#define N_PCH_SPI_FREGX_LIMIT 16 ///< Region limit bit position
+#define N_PCH_SPI_FREGX_LIMIT_REPR 12 ///< Region limit bit represents position
+#define B_PCH_SPI_FREGX_BASE_MASK 0x00007FFF ///< Flash Region Base, [14:0] represents [26:12]
+#define N_PCH_SPI_FREGX_BASE 0 ///< Region base bit position
+#define N_PCH_SPI_FREGX_BASE_REPR 12 ///< Region base bit represents position
+#define R_PCH_SPI_PR0 0x84 ///< Protected Region 0 Register
+#define R_PCH_SPI_PR1 0x88 ///< Protected Region 1 Register
+#define R_PCH_SPI_PR2 0x8C ///< Protected Region 2 Register
+#define R_PCH_SPI_PR3 0x90 ///< Protected Region 3 Register
+#define R_PCH_SPI_PR4 0x94 ///< Protected Region 4 Register
+#define S_PCH_SPI_PRX 4 ///< Protected Region X Register size
+#define B_PCH_SPI_PRX_WPE BIT31 ///< Write Protection Enable
+#define B_PCH_SPI_PRX_PRL_MASK 0x7FFF0000 ///< Protected Range Limit Mask, [30:16] here represents upper limit of address [26:12]
+#define N_PCH_SPI_PRX_PRL 16 ///< Protected Range Limit bit position
+#define B_PCH_SPI_PRX_RPE BIT15 ///< Read Protection Enable
+#define B_PCH_SPI_PRX_PRB_MASK 0x00007FFF ///< Protected Range Base Mask, [14:0] here represents base limit of address [26:12]
+#define N_PCH_SPI_PRX_PRB 0 ///< Protected Range Base bit position
+#define R_PCH_SPI_SFRAP 0xB0 ///< Secondary Flash Regions Access Permisions Register
+#define R_PCH_SPI_FDOC 0xB4 ///< Flash Descriptor Observability Control Register(32 bits)
+#define B_PCH_SPI_FDOC_FDSS_MASK (BIT14 | BIT13 | BIT12) ///< Flash Descritor Section Select
+#define V_PCH_SPI_FDOC_FDSS_FSDM 0x0000 ///< Flash Signature and Descriptor Map
+#define V_PCH_SPI_FDOC_FDSS_COMP 0x1000 ///< Component
+#define V_PCH_SPI_FDOC_FDSS_REGN 0x2000 ///< Region
+#define V_PCH_SPI_FDOC_FDSS_MSTR 0x3000 ///< Master
+#define V_PCH_SPI_FDOC_FDSS_PCHS 0x4000 ///< PCH soft straps
+#define V_PCH_SPI_FDOC_FDSS_SFDP 0x5000 ///< SFDP Parameter Table
+#define B_PCH_SPI_FDOC_FDSI_MASK 0x0FFC ///< Flash Descriptor Section Index
+#define R_PCH_SPI_FDOD 0xB8 ///< Flash Descriptor Observability Data Register(32 bits)
+#define R_PCH_SPI_SFDP0_VSCC0 0xC4 ///< Vendor Specific Component Capabilities Register(32 bits)
+#define B_PCH_SPI_SFDPX_VSCCX_CPPTV BIT31 ///< Component Property Parameter Table Valid
+#define B_PCH_SPI_SFDP0_VSCC0_VCL BIT30 ///< Vendor Component Lock
+#define B_PCH_SPI_SFDPX_VSCCX_EO_64K BIT29 ///< 64k Erase valid (EO_64k_valid)
+#define B_PCH_SPI_SFDPX_VSCCX_EO_4K BIT28 ///< 4k Erase valid (EO_4k_valid)
+#define B_PCH_SPI_SFDPX_VSCCX_RPMC BIT27 ///< RPMC Supported
+#define B_PCH_SPI_SFDPX_VSCCX_DPD BIT26 ///< Deep Powerdown Supported
+#define B_PCH_SPI_SFDPX_VSCCX_SUSRES BIT25 ///< Suspend/Resume Supported
+#define B_PCH_SPI_SFDPX_VSCCX_SOFTRES BIT24 ///< Soft Reset Supported
+#define B_PCH_SPI_SFDPX_VSCCX_64k_EO_MASK 0x00FF0000 ///< 64k Erase Opcode (EO_64k)
+#define B_PCH_SPI_SFDPX_VSCCX_4k_EO_MASK 0x0000FF00 ///< 4k Erase Opcode (EO_4k)
+#define B_PCH_SPI_SFDPX_VSCCX_QER (BIT7 | BIT6 | BIT5) ///< Quad Enable Requirements
+#define B_PCH_SPI_SFDPX_VSCCX_WEWS BIT4 ///< Write Enable on Write Status
+#define B_PCH_SPI_SFDPX_VSCCX_WSR BIT3 ///< Write Status Required
+#define B_PCH_SPI_SFDPX_VSCCX_WG_64B BIT2 ///< Write Granularity, 0: 1 Byte; 1: 64 Bytes
+#define R_PCH_SPI_SFDP1_VSCC1 0xC8 ///< Vendor Specific Component Capabilities Register(32 bits)
+#define R_PCH_SPI_PINTX 0xCC ///< Parameter Table Index
+#define N_PCH_SPI_PINTX_SPT 14
+#define V_PCH_SPI_PINTX_SPT_CPT0 0x0 ///< Component 0 Property Parameter Table
+#define V_PCH_SPI_PINTX_SPT_CPT1 0x1 ///< Component 1 Property Parameter Table
+#define N_PCH_SPI_PINTX_HORD 12
+#define V_PCH_SPI_PINTX_HORD_SFDP 0x0 ///< SFDP Header
+#define V_PCH_SPI_PINTX_HORD_PT 0x1 ///< Parameter Table Header
+#define V_PCH_SPI_PINTX_HORD_DATA 0x2 ///< Data
+#define R_PCH_SPI_PTDATA 0xD0 ///< Parameter Table Data
+#define R_PCH_SPI_SBRS 0xD4 ///< SPI Bus Requester Status
+#define R_PCH_SPI_SSML 0xF0 ///< Set Strap Msg Lock
+#define B_PCH_SPI_SSML_SSL BIT0 ///< Set_Strap Lock
+#define R_PCH_SPI_SSMC 0xF4 ///< Set Strap Msg Control
+#define B_PCH_SPI_SSMC_SSMS BIT0 ///< Set_Strap Mux Select
+#define R_PCH_SPI_SSMD 0xF8 ///< Set Strap Msg Data
+//
+// @todo Follow up with EDS owner if it should be 3FFF or FFFF.
+//
+#define B_PCH_SPI_SRD_SSD 0x0000FFFF ///< Set_Strap Data
+//
+// Flash Descriptor Base Address Region (FDBAR) from Flash Region 0
+//
+#define R_PCH_SPI_FDBAR_FLVALSIG 0x00 ///< Flash Valid Signature
+#define V_PCH_SPI_FDBAR_FLVALSIG 0x0FF0A55A
+#define R_PCH_SPI_FDBAR_FLASH_MAP0 0x04
+#define B_PCH_SPI_FDBAR_FCBA 0x000000FF ///< Flash Component Base Address
+#define B_PCH_SPI_FDBAR_NC 0x00000300 ///< Number Of Components
+#define N_PCH_SPI_FDBAR_NC 8 ///< Number Of Components
+#define V_PCH_SPI_FDBAR_NC_1 0x00000000
+#define V_PCH_SPI_FDBAR_NC_2 0x00000100
+#define B_PCH_SPI_FDBAR_FRBA 0x00FF0000 ///< Flash Region Base Address
+#define B_PCH_SPI_FDBAR_NR 0x07000000 ///< Number Of Regions
+#define R_PCH_SPI_FDBAR_FLASH_MAP1 0x08
+#define B_PCH_SPI_FDBAR_FMBA 0x000000FF ///< Flash Master Base Address
+#define B_PCH_SPI_FDBAR_NM 0x00000700 ///< Number Of Masters
+#define B_PCH_SPI_FDBAR_FPSBA 0x00FF0000 ///< PCH Strap Base Address, [23:16] represents [11:4]
+#define N_PCH_SPI_FDBAR_FPSBA 16 ///< PCH Strap base Address bit position
+#define N_PCH_SPI_FDBAR_FPSBA_REPR 4 ///< PCH Strap base Address bit represents position
+#define B_PCH_SPI_FDBAR_PCHSL 0xFF000000 ///< PCH Strap Length, [31:24] represents number of Dwords
+#define N_PCH_SPI_FDBAR_PCHSL 24 ///< PCH Strap Length bit position
+#define R_PCH_SPI_FDBAR_FLASH_MAP2 0x0C
+#define B_PCH_SPI_FDBAR_FCPUSBA 0x000000FF ///< CPU Strap Base Address, [7:0] represents [11:4]
+#define N_PCH_SPI_FDBAR_FCPUSBA 0 ///< CPU Strap Base Address bit position
+#define N_PCH_SPI_FDBAR_FCPUSBA_REPR 4 ///< CPU Strap Base Address bit represents position
+#define B_PCH_SPI_FDBAR_CPUSL 0x0000FF00 ///< CPU Strap Length, [15:8] represents number of Dwords
+#define N_PCH_SPI_FDBAR_CPUSL 8 ///< CPU Strap Length bit position
+//
+// Flash Component Base Address (FCBA) from Flash Region 0
+//
+#define R_PCH_SPI_FCBA_FLCOMP 0x00 ///< Flash Components Register
+#define B_PCH_SPI_FLCOMP_RIDS_FREQ (BIT29 | BIT28 | BIT27) ///< Read ID and Read Status Clock Frequency
+#define B_PCH_SPI_FLCOMP_WE_FREQ (BIT26 | BIT25 | BIT24) ///< Write and Erase Clock Frequency
+#define B_PCH_SPI_FLCOMP_FRCF_FREQ (BIT23 | BIT22 | BIT21) ///< Fast Read Clock Frequency
+#define B_PCH_SPI_FLCOMP_FR_SUP BIT20 ///< Fast Read Support.
+#define B_PCH_SPI_FLCOMP_RC_FREQ (BIT19 | BIT18 | BIT17) ///< Read Clock Frequency.
+#define V_PCH_SPI_FLCOMP_FREQ_48MHZ 0x02
+#define V_PCH_SPI_FLCOMP_FREQ_30MHZ 0x04
+#define V_PCH_SPI_FLCOMP_FREQ_17MHZ 0x06
+#define B_PCH_SPI_FLCOMP_COMP1_MASK 0xF0 ///< Flash Component 1 Size MASK
+#define N_PCH_SPI_FLCOMP_COMP1 4 ///< Flash Component 1 Size bit position
+#define B_PCH_SPI_FLCOMP_COMP0_MASK 0x0F ///< Flash Component 0 Size MASK
+#define V_PCH_SPI_FLCOMP_COMP_512KB 0x80000
+//
+// Descriptor Upper Map Section from Flash Region 0
+//
+#define R_PCH_SPI_FLASH_UMAP1 0xEFC ///< Flash Upper Map 1
+#define B_PCH_SPI_FLASH_UMAP1_VTBA 0x000000FF ///< VSCC Table Base Address
+#define B_PCH_SPI_FLASH_UMAP1_VTL 0x0000FF00 ///< VSCC Table Length
+
+#define R_PCH_SPI_VTBA_JID0 0x00 ///< JEDEC-ID 0 Register
+#define S_PCH_SPI_VTBA_JID0 0x04
+#define B_PCH_SPI_VTBA_JID0_VID 0x000000FF
+#define B_PCH_SPI_VTBA_JID0_DID0 0x0000FF00
+#define B_PCH_SPI_VTBA_JID0_DID1 0x00FF0000
+#define N_PCH_SPI_VTBA_JID0_DID0 0x08
+#define N_PCH_SPI_VTBA_JID0_DID1 0x10
+#define R_PCH_SPI_VTBA_VSCC0 0x04
+#define S_PCH_SPI_VTBA_VSCC0 0x04
+
+
+//
+// SPI Private Configuration Space Registers
+//
+#define R_PCH_PCR_SPI_CLK_CTL 0xC004
+#define R_PCH_PCR_SPI_PWR_CTL 0xC008
+#define R_PCH_PCR_SPI_ESPI_SOFTSTRAPS 0xC210
+#define B_PCH_PCR_SPI_ESPI_SOFTSTRAPS_SLAVE BIT12
+
+//
+// MMP0
+//
+#define R_PCH_SPI_STRP_MMP0 0xC4 ///< MMP0 Soft strap offset
+#define B_PCH_SPI_STRP_MMP0 0x10 ///< MMP0 Soft strap bit
+
+
+#define R_PCH_SPI_STRP_SFDP 0xF0 ///< PCH Soft Strap SFDP
+#define B_PCH_SPI_STRP_SFDP_QIORE BIT3 ///< Quad IO Read Enable
+#define B_PCH_SPI_STRP_SFDP_QORE BIT2 ///< Quad Output Read Enable
+#define B_PCH_SPI_STRP_SFDP_DIORE BIT1 ///< Dual IO Read Enable
+#define B_PCH_SPI_STRP_SFDP_DORE BIT0 ///< Dual Output Read Enable
+
+//
+// Descriptor Record 0
+//
+#define R_PCH_SPI_STRP_DSCR_0 0x00 ///< PCH Soft Strap 0
+#define B_PCH_SPI_STRP_DSCR_0_PTT_SUPP BIT22 ///< PTT Supported
+
+#endif
diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/Register/X58Ich10.h b/Silicon/Intel/SimicsIch10Pkg/Include/Register/X58Ich10.h
new file mode 100644
index 0000000000..12dfb5ce40
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Include/Register/X58Ich10.h
@@ -0,0 +1,113 @@
+/** @file
+ Various register numbers and value bits based on the following publications:
+ - Intel(R) datasheet 319973-003
+ - Intel(R) datasheet 319974-017US
+
+ Copyright (C) 2015, Red Hat, Inc.
+ Copyright (c) 2014, Gabriel L. Somlo <somlo@cmu.edu>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __X58_ICH10_H__
+#define __X58_ICH10_H__
+
+#include <Library/PciLib.h>
+#include <IndustryStandard/Pci22.h>
+
+//
+// Simics Host Bridge DID Address
+//
+#define SIMICS_HOSTBRIDGE_DID \
+ PCI_LIB_ADDRESS (0, 0, 0, PCI_DEVICE_ID_OFFSET)
+
+//
+// Host Bridge Device ID (DID) value for ICH10
+//
+#define INTEL_ICH10_DEVICE_ID 0x3400
+
+//
+// B/D/F/Type: 0/0/0/PCI
+//
+#define DRAMC_REGISTER_Q35(Offset) PCI_LIB_ADDRESS (0, 0, 0, (Offset))
+#define DRAMC_REGISTER_X58(Offset) PCI_LIB_ADDRESS (0, 20, 0, (Offset))
+#define MCH_GGC 0x52
+#define MCH_GGC_IVD BIT1
+
+#define MCH_PCIEXBAR_LOW 0x10C
+#define MCH_PCIEXBAR_LID 0x10E
+#define MCH_PCIEXBAR_SHIFT 16
+#define MCH_PCIEXBAR_LOWMASK 0x0FFFFFFF
+#define MCH_PCIEXBAR_BUS_FF 0
+#define MCH_PCIEXBAR_EN BIT0
+
+#define MCH_PCIEXBAR_HIGH 0x64
+#define MCH_PCIEXBAR_HIGHMASK 0xFFFFFFF0
+
+#define MCH_SMRAM 0x9D
+#define MCH_SMRAM_D_LCK BIT4
+#define MCH_SMRAM_G_SMRAME BIT3
+
+#define MCH_ESMRAMC 0x9E
+#define MCH_ESMRAMC_H_SMRAME BIT7
+#define MCH_ESMRAMC_E_SMERR BIT6
+#define MCH_ESMRAMC_SM_CACHE BIT5
+#define MCH_ESMRAMC_SM_L1 BIT4
+#define MCH_ESMRAMC_SM_L2 BIT3
+#define MCH_ESMRAMC_TSEG_8MB BIT3
+#define MCH_ESMRAMC_TSEG_2MB BIT2
+#define MCH_ESMRAMC_TSEG_1MB BIT1
+#define MCH_ESMRAMC_TSEG_MASK (BIT3 | BIT2 | BIT1)
+#define MCH_ESMRAMC_T_EN BIT0
+
+#define MCH_GBSM 0xA4
+#define MCH_GBSM_MB_SHIFT 20
+
+#define MCH_BGSM 0xA8
+#define MCH_BGSM_MB_SHIFT 20
+
+#define MCH_TSEGMB 0xA8
+#define MCH_TSEGMB_MB_SHIFT 20
+
+#define MCH_TOLUD 0xD0
+
+//
+// B/D/F/Type: 0/0x1f/0/PCI
+//
+#define POWER_MGMT_REGISTER_ICH10(Offset) \
+ PCI_LIB_ADDRESS (0, 0x1f, 0, (Offset))
+
+#define ICH10_PMBASE 0x40
+#define ICH10_PMBASE_MASK (BIT15 | BIT14 | BIT13 | BIT12 | BIT11 | \
+ BIT10 | BIT9 | BIT8 | BIT7)
+
+#define ICH10_ACPI_CNTL 0x44
+#define ICH10_ACPI_CNTL_ACPI_EN BIT7
+
+#define ICH10_GEN_PMCON_1 0xA0
+#define ICH10_GEN_PMCON_1_SMI_LOCK BIT4
+
+#define ICH10_RCBA 0xF0
+#define ICH10_RCBA_EN BIT0
+
+#define ICH10_PMBASE_IO 0x400
+//
+// IO ports
+//
+#define ICH10_APM_CNT 0xB2
+#define ICH10_APM_STS 0xB3
+
+//
+// IO ports relative to PMBASE
+//
+#define ICH10_PMBASE_OFS_SMI_EN 0x30
+#define ICH10_SMI_EN_APMC_EN BIT5
+#define ICH10_SMI_EN_GBL_SMI_EN BIT0
+#define ICH10_SMI_EN_EOS BIT1 // End of SMI
+
+#define ICH10_PMBASE_OFS_SMI_STS 0x34
+#define ICH10_SMI_STS_APM BIT5 // APM Status
+
+#define ICH10_ROOT_COMPLEX_BASE 0xFED1C000
+
+#endif
diff --git a/Silicon/Intel/SimicsIch10Pkg/IncludePrivate/Library/PchSpiCommonLib.h b/Silicon/Intel/SimicsIch10Pkg/IncludePrivate/Library/PchSpiCommonLib.h
new file mode 100644
index 0000000000..cf60f1fd58
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/IncludePrivate/Library/PchSpiCommonLib.h
@@ -0,0 +1,396 @@
+/** @file
+ Header file for the PCH SPI Common Driver.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SPI_COMMON_LIB_H_
+#define _PCH_SPI_COMMON_LIB_H_
+
+//
+// Maximum time allowed while waiting the SPI cycle to complete
+// Wait Time = 6 seconds = 6000000 microseconds
+// Wait Period = 10 microseconds
+//
+#define SPI_WAIT_TIME 6000000 ///< Wait Time = 6 seconds = 6000000 microseconds
+#define SPI_WAIT_PERIOD 10 ///< Wait Period = 10 microseconds
+
+///
+/// Flash cycle Type
+///
+typedef enum {
+ FlashCycleRead,
+ FlashCycleWrite,
+ FlashCycleErase,
+ FlashCycleReadSfdp,
+ FlashCycleReadJedecId,
+ FlashCycleWriteStatus,
+ FlashCycleReadStatus,
+ FlashCycleMax
+} FLASH_CYCLE_TYPE;
+
+///
+/// Flash Component Number
+///
+typedef enum {
+ FlashComponent0,
+ FlashComponent1,
+ FlashComponentMax
+} FLASH_COMPONENT_NUM;
+
+///
+/// Private data structure definitions for the driver
+///
+#define PCH_SPI_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('P', 'S', 'P', 'I')
+
+typedef struct {
+ UINT32 Signature;
+ EFI_HANDLE Handle;
+ EFI_SPI_PROTOCOL SpiProtocol;
+ UINT16 PchAcpiBase;
+ UINTN PchSpiBase;
+ UINT16 ReadPermission;
+ UINT16 WritePermission;
+ UINT32 SfdpVscc0Value;
+ UINT32 SfdpVscc1Value;
+ UINT16 PchStrapBaseAddr;
+ UINT16 PchStrapSize;
+ UINT16 CpuStrapBaseAddr;
+ UINT16 CpuStrapSize;
+ UINT8 NumberOfComponents;
+ UINT32 Component1StartAddr;
+ UINT32 TotalFlashSize;
+} SPI_INSTANCE;
+
+#define SPI_INSTANCE_FROM_SPIPROTOCOL(a) CR (a, SPI_INSTANCE, SpiProtocol, PCH_SPI_PRIVATE_DATA_SIGNATURE)
+
+//
+// Function prototypes used by the SPI protocol.
+//
+
+/**
+ Initialize an SPI protocol instance.
+
+ @param[in] SpiInstance Pointer to SpiInstance to initialize
+
+ @retval EFI_SUCCESS The protocol instance was properly initialized
+ @exception EFI_UNSUPPORTED The PCH is not supported by this module
+**/
+EFI_STATUS
+SpiProtocolConstructor (
+ IN SPI_INSTANCE *SpiInstance
+ );
+
+/**
+ This function is a hook for Spi to disable BIOS Write Protect
+
+ @retval EFI_SUCCESS The protocol instance was properly initialized
+ @retval EFI_ACCESS_DENIED The BIOS Region can only be updated in SMM phase
+
+**/
+EFI_STATUS
+EFIAPI
+DisableBiosWriteProtect (
+ VOID
+ );
+
+/**
+ This function is a hook for Spi to enable BIOS Write Protect
+
+
+**/
+VOID
+EFIAPI
+EnableBiosWriteProtect (
+ VOID
+ );
+
+/**
+ Acquire pch spi mmio address.
+
+ @param[in] SpiInstance Pointer to SpiInstance to initialize
+
+ @retval PchSpiBar0 return SPI MMIO address
+**/
+UINTN
+AcquireSpiBar0 (
+ IN SPI_INSTANCE *SpiInstance
+ );
+
+/**
+ Release pch spi mmio address.
+
+ @param[in] SpiInstance Pointer to SpiInstance to initialize
+
+ @retval None
+**/
+VOID
+ReleaseSpiBar0 (
+ IN SPI_INSTANCE *SpiInstance
+ );
+
+/**
+ Read data from the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+ @param[out] Buffer The Pointer to caller-allocated buffer containing the dada received.
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashRead (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ OUT UINT8 *Buffer
+ );
+
+/**
+ Write data to the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+ @param[in] Buffer Pointer to caller-allocated buffer containing the data sent during the SPI cycle.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashWrite (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ IN UINT8 *Buffer
+ );
+
+/**
+ Erase some area on the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashErase (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount
+ );
+
+/**
+ Read SFDP data from the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ComponentNumber The Componen Number for chip select
+ @param[in] Address The starting byte address for SFDP data read.
+ @param[in] ByteCount Number of bytes in SFDP data portion of the SPI cycle
+ @param[out] SfdpData The Pointer to caller-allocated buffer containing the SFDP data received
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadSfdp (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT8 ComponentNumber,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ OUT UINT8 *SfdpData
+ );
+
+/**
+ Read Jedec Id from the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ComponentNumber The Componen Number for chip select
+ @param[in] ByteCount Number of bytes in JedecId data portion of the SPI cycle, the data size is 3 typically
+ @param[out] JedecId The Pointer to caller-allocated buffer containing JEDEC ID received
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadJedecId (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT8 ComponentNumber,
+ IN UINT32 ByteCount,
+ OUT UINT8 *JedecId
+ );
+
+/**
+ Write the status register in the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ByteCount Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+ @param[in] StatusValue The Pointer to caller-allocated buffer containing the value of Status register writing
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashWriteStatus (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 ByteCount,
+ IN UINT8 *StatusValue
+ );
+
+/**
+ Read status register in the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ByteCount Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+ @param[out] StatusValue The Pointer to caller-allocated buffer containing the value of Status register received.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadStatus (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 ByteCount,
+ OUT UINT8 *StatusValue
+ );
+
+/**
+ Get the SPI region base and size, based on the enum type
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for for the base address which is listed in the Descriptor.
+ @param[out] BaseAddress The Flash Linear Address for the Region 'n' Base
+ @param[out] RegionSize The size for the Region 'n'
+
+ @retval EFI_SUCCESS Read success
+ @retval EFI_INVALID_PARAMETER Invalid region type given
+ @retval EFI_DEVICE_ERROR The region is not used
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolGetRegionAddress (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ OUT UINT32 *BaseAddress,
+ OUT UINT32 *RegionSize
+ );
+
+/**
+ Read PCH Soft Strap Values
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] SoftStrapAddr PCH Soft Strap address offset from FPSBA.
+ @param[in] ByteCount Number of bytes in SoftStrap data portion of the SPI cycle
+ @param[out] SoftStrapValue The Pointer to caller-allocated buffer containing PCH Soft Strap Value.
+ If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolReadPchSoftStrap (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 SoftStrapAddr,
+ IN UINT32 ByteCount,
+ OUT VOID *SoftStrapValue
+ );
+
+/**
+ Read CPU Soft Strap Values
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] SoftStrapAddr CPU Soft Strap address offset from FCPUSBA.
+ @param[in] ByteCount Number of bytes in SoftStrap data portion of the SPI cycle.
+ @param[out] SoftStrapValue The Pointer to caller-allocated buffer containing CPU Soft Strap Value.
+ If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolReadCpuSoftStrap (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 SoftStrapAddr,
+ IN UINT32 ByteCount,
+ OUT VOID *SoftStrapValue
+ );
+
+/**
+ This function sends the programmed SPI command to the slave device.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] SpiRegionType The SPI Region type for flash cycle which is listed in the Descriptor
+ @param[in] FlashCycleType The Flash SPI cycle type list in HSFC (Hardware Sequencing Flash Control Register) register
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+ @param[in,out] Buffer Pointer to caller-allocated buffer containing the dada received or sent during the SPI cycle.
+
+ @retval EFI_SUCCESS SPI command completes successfully.
+ @retval EFI_DEVICE_ERROR Device error, the command aborts abnormally.
+ @retval EFI_ACCESS_DENIED Some unrecognized command encountered in hardware sequencing mode
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+**/
+EFI_STATUS
+SendSpiCmd (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN FLASH_CYCLE_TYPE FlashCycleType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ IN OUT UINT8 *Buffer
+ );
+
+/**
+ Wait execution cycle to complete on the SPI interface.
+
+ @param[in] This The SPI protocol instance
+ @param[in] PchSpiBar0 Spi MMIO base address
+ @param[in] ErrorCheck TRUE if the SpiCycle needs to do the error check
+
+ @retval TRUE SPI cycle completed on the interface.
+ @retval FALSE Time out while waiting the SPI cycle to complete.
+ It's not safe to program the next command on the SPI interface.
+**/
+BOOLEAN
+WaitForSpiCycleComplete (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINTN PchSpiBar0,
+ IN BOOLEAN ErrorCheck
+ );
+
+#endif
diff --git a/Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.inf b/Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.inf
new file mode 100644
index 0000000000..7b50ee8867
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.inf
@@ -0,0 +1,34 @@
+## @file
+# Library instance for ResetSystem library class for OVMF
+#
+# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ResetSystemLib
+ FILE_GUID = 66564872-21d4-4d2a-a68b-1e844f980820
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ResetSystemLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ ResetSystemLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[LibraryClasses]
+ DebugLib
+ IoLib
+ TimerLib
diff --git a/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf b/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
new file mode 100644
index 0000000000..23b334a080
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
@@ -0,0 +1,50 @@
+## @file
+# SMM Library instance of Spi Flash Common Library Class
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = SmmSpiFlashCommonLib
+ FILE_GUID = 9632D96E-E849-4217-9217-DC500B8AAE47
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_SMM_DRIVER
+ LIBRARY_CLASS = SpiFlashCommonLib|DXE_SMM_DRIVER
+ CONSTRUCTOR = SmmSpiFlashCommonLibConstructor
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[LibraryClasses]
+ PciLib
+ IoLib
+ MemoryAllocationLib
+ BaseLib
+ UefiLib
+ SmmServicesTableLib
+ BaseMemoryLib
+ DebugLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[Pcd]
+ gEfiPchTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
+ gEfiPchTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
+
+[Sources]
+ SpiFlashCommonSmmLib.c
+ SpiFlashCommon.c
+
+[Protocols]
+ gEfiSmmSpiProtocolGuid ## CONSUMES
+
+[Depex.X64.DXE_SMM_DRIVER]
+ gEfiSmmSpiProtocolGuid
diff --git a/Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePchSpiCommonLib.inf b/Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePchSpiCommonLib.inf
new file mode 100644
index 0000000000..df1da274a6
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePchSpiCommonLib.inf
@@ -0,0 +1,31 @@
+## @file
+# Component description file for the PchSpiCommonLib
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BasePchSpiCommonLib
+ FILE_GUID = A37CB67E-7D85-45B3-B07E-BF65BDB603E8
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PchSpiCommonLib
+
+[Sources]
+ SpiCommon.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[LibraryClasses]
+ IoLib
+ DebugLib
+
+[Pcd]
+ gEfiPchTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
+ gEfiPchTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
diff --git a/Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf b/Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
new file mode 100644
index 0000000000..d8bc156dca
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
@@ -0,0 +1,61 @@
+## @file
+# A DXE_RUNTIME_DRIVER providing synchronous SMI activations via the
+# EFI_SMM_CONTROL2_PROTOCOL.
+#
+# We expect the PEI phase to have covered the following:
+# - ensure that the underlying QEMU machine type be X58
+# (responsible: OvmfPkg/SmmAccess/SmmAccessPei.inf)
+# - ensure that the ACPI PM IO space be configured
+# (responsible: OvmfPkg/PlatformPei/PlatformPei.inf)
+#
+# Our own entry point is responsible for confirming the SMI feature and for
+# configuring it.
+#
+# Copyright (C) 2013, 2015, Red Hat, Inc.
+# Copyright (C) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmmControl2Dxe
+ FILE_GUID = 1206F7CA-A475-4624-A83E-E6FC9BB38E49
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010400
+ ENTRY_POINT = SmmControl2DxeEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ SmmControl2Dxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SimicsX58SktPkg/SktPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ IoLib
+ PcdLib
+ PciLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEfiS3SaveStateProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiSmmControl2ProtocolGuid ## PRODUCES
+
+[FeaturePcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
+
+[Depex]
+ TRUE
diff --git a/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.h b/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.h
new file mode 100644
index 0000000000..6ada9b121d
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.h
@@ -0,0 +1,23 @@
+/** @file
+ Header file for the PCH SPI SMM Driver.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SPI_H_
+#define _PCH_SPI_H_
+
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <PchAccess.h>
+#include <Protocol/Spi.h>
+#include <IncludePrivate/Library/PchSpiCommonLib.h>
+
+#endif
diff --git a/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpiSmm.inf b/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpiSmm.inf
new file mode 100644
index 0000000000..7b60d36c5b
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpiSmm.inf
@@ -0,0 +1,44 @@
+## @file
+# Component description file for the SPI SMM driver.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = PchSpiSmm
+ FILE_GUID = 27F4917B-A707-4aad-9676-26DF168CBF0D
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_SMM_DRIVER
+ PI_SPECIFICATION_VERSION = 1.10
+ ENTRY_POINT = InstallPchSpi
+
+
+ [LibraryClasses]
+ DebugLib
+ IoLib
+ UefiDriverEntryPoint
+ UefiBootServicesTableLib
+ BaseLib
+ SmmServicesTableLib
+ PchSpiCommonLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[Sources]
+ PchSpi.h
+ PchSpi.c
+
+
+[Protocols]
+ gEfiSmmSpiProtocolGuid # PRODUCES #SERVER_BIOS
+
+
+[Depex]
+ gEfiSmmBase2ProtocolGuid #This is for SmmServicesTableLib
+ AND gEfiSmmCpuProtocolGuid # This is for CpuSmmDisableBiosWriteProtect()
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [edk2-platforms PATCH v2 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules
2019-08-28 0:40 [edk2-platforms PATCH v2 0/7] Add Initial QSP MinPlatform Pkg for SIMICS David Wei
2019-08-28 0:40 ` [edk2-platforms PATCH v2 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58 David Wei
2019-08-28 0:40 ` [edk2-platforms PATCH v2 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10 David Wei
@ 2019-08-28 0:40 ` David Wei
2019-08-28 22:02 ` Nate DeSimone
2019-08-28 0:40 ` [edk2-platforms PATCH v2 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio David Wei
` (3 subsequent siblings)
6 siblings, 1 reply; 16+ messages in thread
From: David Wei @ 2019-08-28 0:40 UTC (permalink / raw)
To: devel
Cc: Hao Wu, Liming Gao, Ankit Sinha, Agyeman Prince,
Kubacki Michael A, Nate DeSimone, Michael D Kinney
Add modules AcpiTables, Include, Library, SimicsDxe, SimicsPei, Policy, SmbiosPlatformDxe
and SecCore for Simics QSP platform support
Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c | 647 ++++++++
.../Library/LoadLinuxLib/Linux.c | 662 +++++++++
.../Library/LoadLinuxLib/LinuxGdt.c | 175 +++
.../Library/NvVarsFileLib/FsAccess.c | 507 +++++++
.../Library/NvVarsFileLib/NvVarsFileLib.c | 77 +
.../Library/PciHostBridgeLib/PciHostBridgeLib.c | 419 ++++++
.../SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c | 100 ++
.../Library/PeiReportFvLib/PeiReportFvLib.c | 118 ++
.../Library/PlatformBootManagerLib/BdsPlatform.c | 1553 ++++++++++++++++++++
.../Library/PlatformBootManagerLib/PlatformData.c | 35 +
.../SerializeVariablesLib/SerializeVariablesLib.c | 869 +++++++++++
.../SiliconPolicyInitLib/SiliconPolicyInitLib.c | 108 ++
.../SiliconPolicyUpdateLib.c | 70 +
.../Intel/SimicsOpenBoardPkg/SecCore/SecMain.c | 956 ++++++++++++
.../Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c | 865 +++++++++++
.../SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c | 123 ++
Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c | 57 +
.../SimicsOpenBoardPkg/SimicsPei/FeatureControl.c | 114 ++
.../Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c | 568 +++++++
.../Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c | 630 ++++++++
.../SmbiosPlatformDxe/SmbiosPlatformDxe.c | 148 ++
.../SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf | 31 +
.../Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl | 821 +++++++++++
.../Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h | 75 +
.../Include/Guid/SimicsBoardConfig.h | 17 +
.../Include/IndustryStandard/I440FxPiix4.h | 49 +
.../Include/IndustryStandard/LinuxBzImage.h | 158 ++
.../Include/Library/LoadLinuxLib.h | 205 +++
.../Include/Library/SerializeVariablesLib.h | 223 +++
.../SimicsOpenBoardPkg/Include/SimicsPlatforms.h | 55 +
.../Library/DxeLogoLib/DxeLogoLib.inf | 55 +
.../Library/DxeLogoLib/OEMBadging.h | 83 ++
.../Library/LoadLinuxLib/DxeLoadLinuxLib.inf | 42 +
.../Library/LoadLinuxLib/Ia32/JumpToKernel.nasm | 41 +
.../Library/LoadLinuxLib/LoadLinuxLib.h | 52 +
.../Library/LoadLinuxLib/X64/JumpToKernel.nasm | 85 ++
.../Library/NvVarsFileLib/NvVarsFileLib.h | 55 +
.../Library/NvVarsFileLib/NvVarsFileLib.inf | 53 +
.../Library/PciHostBridgeLib/PciHostBridge.h | 68 +
.../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 51 +
.../Library/PeiReportFvLib/PeiReportFvLib.inf | 56 +
.../Library/PlatformBootManagerLib/BdsPlatform.h | 172 +++
.../PlatformBootManagerLib.inf | 72 +
.../SerializeVariablesLib/SerializeVariablesLib.h | 33 +
.../SerializeVariablesLib.inf | 36 +
.../SiliconPolicyInitLib/SiliconPolicyInitLib.inf | 38 +
.../SiliconPolicyUpdateLib.inf | 35 +
.../SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm | 45 +
.../Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf | 73 +
.../SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm | 45 +
.../Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h | 37 +
.../SimicsOpenBoardPkg/SimicsDxe/Platform.uni | 31 +
.../SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h | 51 +
.../SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr | 67 +
.../SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf | 65 +
Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h | 50 +
.../Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h | 88 ++
.../SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf | 104 ++
.../SmbiosPlatformDxe/SmbiosPlatformDxe.h | 38 +
.../SmbiosPlatformDxe/SmbiosPlatformDxe.inf | 51 +
60 files changed, 12207 insertions(+)
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/PlatformData.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/FeatureControl.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsBoardConfig.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/I440FxPiix4.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/LinuxBzImage.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Library/LoadLinuxLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Library/SerializeVariablesLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/DxeLogoLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/OEMBadging.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/DxeLoadLinuxLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.nasm
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel.nasm
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridge.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c
new file mode 100644
index 0000000000..4a75f3673f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c
@@ -0,0 +1,647 @@
+/** @file
+ BDS Lib functions which contain all the code to connect console device
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiDxe.h>
+#include <Protocol/SimpleTextOut.h>
+#include <OEMBadging.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/UgaDraw.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+
+#include <IndustryStandard/Bmp.h>
+#include <Protocol/BootLogo.h>
+
+/**
+ Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer
+ is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt
+ buffer is passed in it will be used if it is big enough.
+
+ @param BmpImage Pointer to BMP file
+ @param BmpImageSize Number of bytes in BmpImage
+ @param GopBlt Buffer containing GOP version of BmpImage.
+ @param GopBltSize Size of GopBlt in bytes.
+ @param PixelHeight Height of GopBlt/BmpImage in pixels
+ @param PixelWidth Width of GopBlt/BmpImage in pixels
+
+ @retval EFI_SUCCESS GopBlt and GopBltSize are returned.
+ @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image
+ @retval EFI_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big enough.
+ GopBltSize will contain the required size.
+ @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate.
+
+**/
+EFI_STATUS
+ConvertBmpToGopBlt (
+ IN VOID *BmpImage,
+ IN UINTN BmpImageSize,
+ IN OUT VOID **GopBlt,
+ IN OUT UINTN *GopBltSize,
+ OUT UINTN *PixelHeight,
+ OUT UINTN *PixelWidth
+ )
+{
+ UINT8 *Image;
+ UINT8 *ImageHeader;
+ BMP_IMAGE_HEADER *BmpHeader;
+ BMP_COLOR_MAP *BmpColorMap;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
+ UINT64 BltBufferSize;
+ UINTN Index;
+ UINTN Height;
+ UINTN Width;
+ UINTN ImageIndex;
+ UINT32 DataSizePerLine;
+ BOOLEAN IsAllocated;
+ UINT32 ColorMapNum;
+
+ if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;
+
+ if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Doesn't support compress.
+ //
+ if (BmpHeader->CompressionType != 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Only support BITMAPINFOHEADER format.
+ // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER
+ //
+ if (BmpHeader->HeaderSize != sizeof (BMP_IMAGE_HEADER) - OFFSET_OF(BMP_IMAGE_HEADER, HeaderSize)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // The data size in each line must be 4 byte alignment.
+ //
+ DataSizePerLine = ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel + 31) >> 3) & (~0x3);
+ BltBufferSize = MultU64x32 (DataSizePerLine, BmpHeader->PixelHeight);
+ if (BltBufferSize > (UINT32) ~0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((BmpHeader->Size != BmpImageSize) ||
+ (BmpHeader->Size < BmpHeader->ImageOffset) ||
+ (BmpHeader->Size - BmpHeader->ImageOffset != BmpHeader->PixelHeight * DataSizePerLine)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Calculate Color Map offset in the image.
+ //
+ Image = BmpImage;
+ BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));
+ if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) {
+ switch (BmpHeader->BitPerPixel) {
+ case 1:
+ ColorMapNum = 2;
+ break;
+ case 4:
+ ColorMapNum = 16;
+ break;
+ case 8:
+ ColorMapNum = 256;
+ break;
+ default:
+ ColorMapNum = 0;
+ break;
+ }
+ //
+ // BMP file may has padding data between the bmp header section and the bmp data section.
+ //
+ if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) < sizeof (BMP_COLOR_MAP) * ColorMapNum) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
+ // Calculate graphics image data address in the image
+ //
+ Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;
+ ImageHeader = Image;
+
+ //
+ // Calculate the BltBuffer needed size.
+ //
+ BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight);
+ //
+ // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
+ //
+ if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+ return EFI_UNSUPPORTED;
+ }
+ BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+
+ IsAllocated = FALSE;
+ if (*GopBlt == NULL) {
+ //
+ // GopBlt is not allocated by caller.
+ //
+ *GopBltSize = (UINTN) BltBufferSize;
+ *GopBlt = AllocatePool (*GopBltSize);
+ IsAllocated = TRUE;
+ if (*GopBlt == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else {
+ //
+ // GopBlt has been allocated by caller.
+ //
+ if (*GopBltSize < (UINTN) BltBufferSize) {
+ *GopBltSize = (UINTN) BltBufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ }
+
+ *PixelWidth = BmpHeader->PixelWidth;
+ *PixelHeight = BmpHeader->PixelHeight;
+
+ //
+ // Convert image from BMP to Blt buffer format
+ //
+ BltBuffer = *GopBlt;
+ for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {
+ Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];
+ for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {
+ switch (BmpHeader->BitPerPixel) {
+ case 1:
+ //
+ // Convert 1-bit (2 colors) BMP to 24-bit color
+ //
+ for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {
+ Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;
+ Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;
+ Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;
+ Blt++;
+ Width++;
+ }
+
+ Blt--;
+ Width--;
+ break;
+
+ case 4:
+ //
+ // Convert 4-bit (16 colors) BMP Palette to 24-bit color
+ //
+ Index = (*Image) >> 4;
+ Blt->Red = BmpColorMap[Index].Red;
+ Blt->Green = BmpColorMap[Index].Green;
+ Blt->Blue = BmpColorMap[Index].Blue;
+ if (Width < (BmpHeader->PixelWidth - 1)) {
+ Blt++;
+ Width++;
+ Index = (*Image) & 0x0f;
+ Blt->Red = BmpColorMap[Index].Red;
+ Blt->Green = BmpColorMap[Index].Green;
+ Blt->Blue = BmpColorMap[Index].Blue;
+ }
+ break;
+
+ case 8:
+ //
+ // Convert 8-bit (256 colors) BMP Palette to 24-bit color
+ //
+ Blt->Red = BmpColorMap[*Image].Red;
+ Blt->Green = BmpColorMap[*Image].Green;
+ Blt->Blue = BmpColorMap[*Image].Blue;
+ break;
+
+ case 24:
+ //
+ // It is 24-bit BMP.
+ //
+ Blt->Blue = *Image++;
+ Blt->Green = *Image++;
+ Blt->Red = *Image;
+ break;
+
+ default:
+ //
+ // Other bit format BMP is not supported.
+ //
+ if (IsAllocated) {
+ FreePool (*GopBlt);
+ *GopBlt = NULL;
+ }
+ return EFI_UNSUPPORTED;
+ break;
+ };
+
+ }
+
+ ImageIndex = (UINTN) (Image - ImageHeader);
+ if ((ImageIndex % 4) != 0) {
+ //
+ // Bmp Image starts each row on a 32-bit boundary!
+ //
+ Image = Image + (4 - (ImageIndex % 4));
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Use SystemTable Conout to stop video based Simple Text Out consoles from going
+ to the video device. Put up LogoFile on every video device that is a console.
+
+ @param[in] LogoFile File name of logo to display on the center of the screen.
+
+ @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed.
+ @retval EFI_UNSUPPORTED Logo not found
+
+**/
+EFI_STATUS
+EFIAPI
+EnableBootLogo (
+ IN EFI_GUID *LogoFile
+ )
+{
+ EFI_STATUS Status;
+ EFI_OEM_BADGING_PROTOCOL *Badging;
+ UINT32 SizeOfX;
+ UINT32 SizeOfY;
+ INTN DestX;
+ INTN DestY;
+ UINT8 *ImageData;
+ UINTN ImageSize;
+ UINTN BltSize;
+ UINT32 Instance;
+ EFI_BADGING_FORMAT Format;
+ EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;
+ UINTN CoordinateX;
+ UINTN CoordinateY;
+ UINTN Height;
+ UINTN Width;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
+ EFI_UGA_DRAW_PROTOCOL *UgaDraw;
+ UINT32 ColorDepth;
+ UINT32 RefreshRate;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+ EFI_BOOT_LOGO_PROTOCOL *BootLogo;
+ UINTN NumberOfLogos;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LogoBlt;
+ UINTN LogoDestX;
+ UINTN LogoDestY;
+ UINTN LogoHeight;
+ UINTN LogoWidth;
+ UINTN NewDestX;
+ UINTN NewDestY;
+ UINTN NewHeight;
+ UINTN NewWidth;
+ UINT64 BufferSize;
+
+ UgaDraw = NULL;
+ //
+ // Try to open GOP first
+ //
+ Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);
+ if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
+ GraphicsOutput = NULL;
+ //
+ // Open GOP failed, try to open UGA
+ //
+ Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);
+ }
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Try to open Boot Logo Protocol.
+ //
+ BootLogo = NULL;
+ gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);
+
+ //
+ // Erase Cursor from screen
+ //
+ gST->ConOut->EnableCursor (gST->ConOut, FALSE);
+
+ Badging = NULL;
+ Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);
+
+ if (GraphicsOutput != NULL) {
+ SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
+ SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
+
+ } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
+ Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ Blt = NULL;
+ NumberOfLogos = 0;
+ LogoDestX = 0;
+ LogoDestY = 0;
+ LogoHeight = 0;
+ LogoWidth = 0;
+ NewDestX = 0;
+ NewDestY = 0;
+ NewHeight = 0;
+ NewWidth = 0;
+ Instance = 0;
+ while (1) {
+ ImageData = NULL;
+ ImageSize = 0;
+
+ if (Badging != NULL) {
+ //
+ // Get image from OEMBadging protocol.
+ //
+ Status = Badging->GetImage (
+ Badging,
+ &Instance,
+ &Format,
+ &ImageData,
+ &ImageSize,
+ &Attribute,
+ &CoordinateX,
+ &CoordinateY
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ } else {
+ //
+ // Get the specified image from FV.
+ //
+ Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ CoordinateX = 0;
+ CoordinateY = 0;
+ Attribute = EfiBadgingDisplayAttributeCenter;
+ }
+
+ if (Blt != NULL) {
+ FreePool (Blt);
+ }
+
+ //
+ // Try BMP decoder
+ //
+ Blt = NULL;
+ Status = ConvertBmpToGopBlt (
+ ImageData,
+ ImageSize,
+ (VOID **) &Blt,
+ &BltSize,
+ &Height,
+ &Width
+ );
+
+ if (EFI_ERROR (Status)) {
+ FreePool (ImageData);
+
+ if (Badging == NULL) {
+ return Status;
+ } else {
+ continue;
+ }
+ }
+
+ //
+ // Calculate the display position according to Attribute.
+ //
+ switch (Attribute) {
+ case EfiBadgingDisplayAttributeLeftTop:
+ DestX = CoordinateX;
+ DestY = CoordinateY;
+ break;
+
+ case EfiBadgingDisplayAttributeCenterTop:
+ DestX = (SizeOfX - Width) / 2;
+ DestY = CoordinateY;
+ break;
+
+ case EfiBadgingDisplayAttributeRightTop:
+ DestX = (SizeOfX - Width - CoordinateX);
+ DestY = CoordinateY;;
+ break;
+
+ case EfiBadgingDisplayAttributeCenterRight:
+ DestX = (SizeOfX - Width - CoordinateX);
+ DestY = (SizeOfY - Height) / 2;
+ break;
+
+ case EfiBadgingDisplayAttributeRightBottom:
+ DestX = (SizeOfX - Width - CoordinateX);
+ DestY = (SizeOfY - Height - CoordinateY);
+ break;
+
+ case EfiBadgingDisplayAttributeCenterBottom:
+ DestX = (SizeOfX - Width) / 2;
+ DestY = (SizeOfY - Height - CoordinateY);
+ break;
+
+ case EfiBadgingDisplayAttributeLeftBottom:
+ DestX = CoordinateX;
+ DestY = (SizeOfY - Height - CoordinateY);
+ break;
+
+ case EfiBadgingDisplayAttributeCenterLeft:
+ DestX = CoordinateX;
+ DestY = (SizeOfY - Height) / 2;
+ break;
+
+ case EfiBadgingDisplayAttributeCenter:
+ DestX = (SizeOfX - Width) / 2;
+ DestY = (SizeOfY - Height) / 2;
+ break;
+
+ default:
+ DestX = CoordinateX;
+ DestY = CoordinateY;
+ break;
+ }
+
+ if ((DestX >= 0) && (DestY >= 0)) {
+ if (GraphicsOutput != NULL) {
+ Status = GraphicsOutput->Blt (
+ GraphicsOutput,
+ Blt,
+ EfiBltBufferToVideo,
+ 0,
+ 0,
+ (UINTN) DestX,
+ (UINTN) DestY,
+ Width,
+ Height,
+ Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+ );
+ } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
+ Status = UgaDraw->Blt (
+ UgaDraw,
+ (EFI_UGA_PIXEL *) Blt,
+ EfiUgaBltBufferToVideo,
+ 0,
+ 0,
+ (UINTN) DestX,
+ (UINTN) DestY,
+ Width,
+ Height,
+ Width * sizeof (EFI_UGA_PIXEL)
+ );
+ } else {
+ Status = EFI_UNSUPPORTED;
+ }
+
+ //
+ // Report displayed Logo information.
+ //
+ if (!EFI_ERROR (Status)) {
+ NumberOfLogos++;
+
+ if (LogoWidth == 0) {
+ //
+ // The first Logo.
+ //
+ LogoDestX = (UINTN) DestX;
+ LogoDestY = (UINTN) DestY;
+ LogoWidth = Width;
+ LogoHeight = Height;
+ } else {
+ //
+ // Merge new logo with old one.
+ //
+ NewDestX = MIN ((UINTN) DestX, LogoDestX);
+ NewDestY = MIN ((UINTN) DestY, LogoDestY);
+ NewWidth = MAX ((UINTN) DestX + Width, LogoDestX + LogoWidth) - NewDestX;
+ NewHeight = MAX ((UINTN) DestY + Height, LogoDestY + LogoHeight) - NewDestY;
+
+ LogoDestX = NewDestX;
+ LogoDestY = NewDestY;
+ LogoWidth = NewWidth;
+ LogoHeight = NewHeight;
+ }
+ }
+ }
+
+ FreePool (ImageData);
+
+ if (Badging == NULL) {
+ break;
+ }
+ }
+
+Done:
+ if (BootLogo == NULL || NumberOfLogos == 0) {
+ //
+ // No logo displayed.
+ //
+ if (Blt != NULL) {
+ FreePool (Blt);
+ }
+
+ return Status;
+ }
+
+ //
+ // Advertise displayed Logo information.
+ //
+ if (NumberOfLogos == 1) {
+ //
+ // Only one logo displayed, use its Blt buffer directly for BootLogo protocol.
+ //
+ LogoBlt = Blt;
+ Status = EFI_SUCCESS;
+ } else {
+ //
+ // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation.
+ //
+ if (Blt != NULL) {
+ FreePool (Blt);
+ }
+
+ //
+ // Ensure the LogoHeight * LogoWidth doesn't overflow
+ //
+ if (LogoHeight > DivU64x64Remainder ((UINTN) ~0, LogoWidth, NULL)) {
+ return EFI_UNSUPPORTED;
+ }
+ BufferSize = MultU64x64 (LogoWidth, LogoHeight);
+
+ //
+ // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
+ //
+ if (BufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+ return EFI_UNSUPPORTED;
+ }
+
+ LogoBlt = AllocateZeroPool ((UINTN)BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ if (LogoBlt == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (GraphicsOutput != NULL) {
+ Status = GraphicsOutput->Blt (
+ GraphicsOutput,
+ LogoBlt,
+ EfiBltVideoToBltBuffer,
+ LogoDestX,
+ LogoDestY,
+ 0,
+ 0,
+ LogoWidth,
+ LogoHeight,
+ LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+ );
+ } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
+ Status = UgaDraw->Blt (
+ UgaDraw,
+ (EFI_UGA_PIXEL *) LogoBlt,
+ EfiUgaVideoToBltBuffer,
+ LogoDestX,
+ LogoDestY,
+ 0,
+ 0,
+ LogoWidth,
+ LogoHeight,
+ LogoWidth * sizeof (EFI_UGA_PIXEL)
+ );
+ } else {
+ Status = EFI_UNSUPPORTED;
+ }
+ }
+
+ if (!EFI_ERROR (Status)) {
+ BootLogo->SetBootLogo (BootLogo, LogoBlt, LogoDestX, LogoDestY, LogoWidth, LogoHeight);
+ }
+ FreePool (LogoBlt);
+
+ return Status;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
new file mode 100644
index 0000000000..631bb7ee69
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
@@ -0,0 +1,662 @@
+/** @file
+ Copyright (c) 2011 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "LoadLinuxLib.h"
+
+
+/**
+ A simple check of the kernel setup image
+
+ An assumption is made that the size of the data is at least the
+ size of struct boot_params.
+
+ @param[in] KernelSetup - The kernel setup image
+
+ @retval EFI_SUCCESS - The kernel setup looks valid and supported
+ @retval EFI_INVALID_PARAMETER - KernelSetup was NULL
+ @retval EFI_UNSUPPORTED - The kernel setup is not valid or supported
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BasicKernelSetupCheck (
+ IN VOID *KernelSetup
+ )
+{
+ return LoadLinuxCheckKernelSetup(KernelSetup, sizeof (struct boot_params));
+}
+
+
+EFI_STATUS
+EFIAPI
+LoadLinuxCheckKernelSetup (
+ IN VOID *KernelSetup,
+ IN UINTN KernelSetupSize
+ )
+{
+ struct boot_params *Bp;
+
+ if (KernelSetup == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (KernelSetupSize < sizeof (*Bp)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Bp = (struct boot_params*) KernelSetup;
+
+ if ((Bp->hdr.signature != 0xAA55) || // Check boot sector signature
+ (Bp->hdr.header != SETUP_HDR) ||
+ (Bp->hdr.version < 0x205) || // We only support relocatable kernels
+ (!Bp->hdr.relocatable_kernel)
+ ) {
+ return EFI_UNSUPPORTED;
+ } else {
+ return EFI_SUCCESS;
+ }
+}
+
+
+UINTN
+EFIAPI
+LoadLinuxGetKernelSize (
+ IN VOID *KernelSetup,
+ IN UINTN KernelSize
+ )
+{
+ struct boot_params *Bp;
+
+ if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) {
+ return 0;
+ }
+
+ Bp = (struct boot_params*) KernelSetup;
+
+ if (Bp->hdr.version > 0x20a) {
+ return Bp->hdr.init_size;
+ } else {
+ //
+ // Add extra size for kernel decompression
+ //
+ return 3 * KernelSize;
+ }
+}
+
+
+VOID*
+EFIAPI
+LoadLinuxAllocateKernelSetupPages (
+ IN UINTN Pages
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Address;
+
+ Address = BASE_1GB;
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiLoaderData,
+ Pages,
+ &Address
+ );
+ if (!EFI_ERROR (Status)) {
+ return (VOID*)(UINTN) Address;
+ } else {
+ return NULL;
+ }
+}
+
+EFI_STATUS
+EFIAPI
+LoadLinuxInitializeKernelSetup (
+ IN VOID *KernelSetup
+ )
+{
+ EFI_STATUS Status;
+ UINTN SetupEnd;
+ struct boot_params *Bp;
+
+ Status = BasicKernelSetupCheck (KernelSetup);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Bp = (struct boot_params*) KernelSetup;
+
+ SetupEnd = 0x202 + (Bp->hdr.jump & 0xff);
+
+ //
+ // Clear all but the setup_header
+ //
+ ZeroMem (KernelSetup, 0x1f1);
+ ZeroMem (((UINT8 *)KernelSetup) + SetupEnd, 4096 - SetupEnd);
+ DEBUG ((EFI_D_INFO, "Cleared kernel setup 0-0x1f1, 0x%Lx-0x1000\n",
+ (UINT64)SetupEnd));
+
+ return EFI_SUCCESS;
+}
+
+VOID*
+EFIAPI
+LoadLinuxAllocateKernelPages (
+ IN VOID *KernelSetup,
+ IN UINTN Pages
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS KernelAddress;
+ UINT32 Loop;
+ struct boot_params *Bp;
+
+ if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) {
+ return NULL;
+ }
+
+ Bp = (struct boot_params*) KernelSetup;
+
+ for (Loop = 1; Loop < 512; Loop++) {
+ KernelAddress = MultU64x32 (
+ 2 * Bp->hdr.kernel_alignment,
+ Loop
+ );
+ Status = gBS->AllocatePages (
+ AllocateAddress,
+ EfiLoaderData,
+ Pages,
+ &KernelAddress
+ );
+ if (!EFI_ERROR (Status)) {
+ return (VOID*)(UINTN) KernelAddress;
+ }
+ }
+
+ return NULL;
+}
+
+
+VOID*
+EFIAPI
+LoadLinuxAllocateCommandLinePages (
+ IN UINTN Pages
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Address;
+
+ Address = 0xa0000;
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiLoaderData,
+ Pages,
+ &Address
+ );
+ if (!EFI_ERROR (Status)) {
+ return (VOID*)(UINTN) Address;
+ } else {
+ return NULL;
+ }
+}
+
+
+VOID*
+EFIAPI
+LoadLinuxAllocateInitrdPages (
+ IN VOID *KernelSetup,
+ IN UINTN Pages
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Address;
+
+ struct boot_params *Bp;
+
+ if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) {
+ return NULL;
+ }
+
+ Bp = (struct boot_params*) KernelSetup;
+
+ Address = (EFI_PHYSICAL_ADDRESS)(UINTN) Bp->hdr.ramdisk_max;
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiLoaderData,
+ Pages,
+ &Address
+ );
+ if (!EFI_ERROR (Status)) {
+ return (VOID*)(UINTN) Address;
+ } else {
+ return NULL;
+ }
+}
+
+
+STATIC
+VOID
+SetupLinuxMemmap (
+ IN OUT struct boot_params *Bp
+ )
+{
+ EFI_STATUS Status;
+ UINT8 TmpMemoryMap[1];
+ UINTN MapKey;
+ UINTN DescriptorSize;
+ UINT32 DescriptorVersion;
+ UINTN MemoryMapSize;
+ EFI_MEMORY_DESCRIPTOR *MemoryMap;
+ EFI_MEMORY_DESCRIPTOR *MemoryMapPtr;
+ UINTN Index;
+ struct efi_info *Efi;
+ struct e820_entry *LastE820;
+ struct e820_entry *E820;
+ UINTN E820EntryCount;
+ EFI_PHYSICAL_ADDRESS LastEndAddr;
+
+ //
+ // Get System MemoryMapSize
+ //
+ MemoryMapSize = sizeof (TmpMemoryMap);
+ Status = gBS->GetMemoryMap (
+ &MemoryMapSize,
+ (EFI_MEMORY_DESCRIPTOR *)TmpMemoryMap,
+ &MapKey,
+ &DescriptorSize,
+ &DescriptorVersion
+ );
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+ //
+ // Enlarge space here, because we will allocate pool now.
+ //
+ MemoryMapSize += EFI_PAGE_SIZE;
+ Status = gBS->AllocatePool (
+ EfiLoaderData,
+ MemoryMapSize,
+ (VOID **) &MemoryMap
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get System MemoryMap
+ //
+ Status = gBS->GetMemoryMap (
+ &MemoryMapSize,
+ MemoryMap,
+ &MapKey,
+ &DescriptorSize,
+ &DescriptorVersion
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ LastE820 = NULL;
+ E820 = &Bp->e820_map[0];
+ E820EntryCount = 0;
+ LastEndAddr = 0;
+ MemoryMapPtr = MemoryMap;
+ for (Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++) {
+ UINTN E820Type = 0;
+
+ if (MemoryMap->NumberOfPages == 0) {
+ continue;
+ }
+
+ switch(MemoryMap->Type) {
+ case EfiReservedMemoryType:
+ case EfiRuntimeServicesCode:
+ case EfiRuntimeServicesData:
+ case EfiMemoryMappedIO:
+ case EfiMemoryMappedIOPortSpace:
+ case EfiPalCode:
+ E820Type = E820_RESERVED;
+ break;
+
+ case EfiUnusableMemory:
+ E820Type = E820_UNUSABLE;
+ break;
+
+ case EfiACPIReclaimMemory:
+ E820Type = E820_ACPI;
+ break;
+
+ case EfiLoaderCode:
+ case EfiLoaderData:
+ case EfiBootServicesCode:
+ case EfiBootServicesData:
+ case EfiConventionalMemory:
+ E820Type = E820_RAM;
+ break;
+
+ case EfiACPIMemoryNVS:
+ E820Type = E820_NVS;
+ break;
+
+ default:
+ DEBUG ((
+ EFI_D_ERROR,
+ "Invalid EFI memory descriptor type (0x%x)!\n",
+ MemoryMap->Type
+ ));
+ continue;
+ }
+
+ if ((LastE820 != NULL) &&
+ (LastE820->type == (UINT32) E820Type) &&
+ (MemoryMap->PhysicalStart == LastEndAddr)) {
+ LastE820->size += EFI_PAGES_TO_SIZE ((UINTN) MemoryMap->NumberOfPages);
+ LastEndAddr += EFI_PAGES_TO_SIZE ((UINTN) MemoryMap->NumberOfPages);
+ } else {
+ if (E820EntryCount >= (sizeof (Bp->e820_map) / sizeof (Bp->e820_map[0]))) {
+ break;
+ }
+ E820->type = (UINT32) E820Type;
+ E820->addr = MemoryMap->PhysicalStart;
+ E820->size = EFI_PAGES_TO_SIZE ((UINTN) MemoryMap->NumberOfPages);
+ LastE820 = E820;
+ LastEndAddr = E820->addr + E820->size;
+ E820++;
+ E820EntryCount++;
+ }
+
+ //
+ // Get next item
+ //
+ MemoryMap = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemoryMap + DescriptorSize);
+ }
+ Bp->e820_entries = (UINT8) E820EntryCount;
+
+ Efi = &Bp->efi_info;
+ Efi->efi_systab = (UINT32)(UINTN) gST;
+ Efi->efi_memdesc_size = (UINT32) DescriptorSize;
+ Efi->efi_memdesc_version = DescriptorVersion;
+ Efi->efi_memmap = (UINT32)(UINTN) MemoryMapPtr;
+ Efi->efi_memmap_size = (UINT32) MemoryMapSize;
+#ifdef MDE_CPU_IA32
+ Efi->efi_loader_signature = SIGNATURE_32 ('E', 'L', '3', '2');
+#else
+ Efi->efi_systab_hi = (UINT32) (((UINT64)(UINTN) gST) >> 32);
+ Efi->efi_memmap_hi = (UINT32) (((UINT64)(UINTN) MemoryMapPtr) >> 32);
+ Efi->efi_loader_signature = SIGNATURE_32 ('E', 'L', '6', '4');
+#endif
+
+ gBS->ExitBootServices (gImageHandle, MapKey);
+}
+
+
+EFI_STATUS
+EFIAPI
+LoadLinuxSetCommandLine (
+ IN OUT VOID *KernelSetup,
+ IN CHAR8 *CommandLine
+ )
+{
+ EFI_STATUS Status;
+ struct boot_params *Bp;
+
+ Status = BasicKernelSetupCheck (KernelSetup);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Bp = (struct boot_params*) KernelSetup;
+
+ Bp->hdr.cmd_line_ptr = (UINT32)(UINTN) CommandLine;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+LoadLinuxSetInitrd (
+ IN OUT VOID *KernelSetup,
+ IN VOID *Initrd,
+ IN UINTN InitrdSize
+ )
+{
+ EFI_STATUS Status;
+ struct boot_params *Bp;
+
+ Status = BasicKernelSetupCheck (KernelSetup);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Bp = (struct boot_params*) KernelSetup;
+
+ Bp->hdr.ramdisk_start = (UINT32)(UINTN) Initrd;
+ Bp->hdr.ramdisk_len = (UINT32) InitrdSize;
+
+ return EFI_SUCCESS;
+}
+
+
+STATIC VOID
+FindBits (
+ unsigned long Mask,
+ UINT8 *Pos,
+ UINT8 *Size
+ )
+{
+ UINT8 First, Len;
+
+ First = 0;
+ Len = 0;
+
+ if (Mask) {
+ while (!(Mask & 0x1)) {
+ Mask = Mask >> 1;
+ First++;
+ }
+
+ while (Mask & 0x1) {
+ Mask = Mask >> 1;
+ Len++;
+ }
+ }
+ *Pos = First;
+ *Size = Len;
+}
+
+
+STATIC
+EFI_STATUS
+SetupGraphicsFromGop (
+ struct screen_info *Si,
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop
+ )
+{
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
+ EFI_STATUS Status;
+ UINTN Size;
+
+ Status = Gop->QueryMode(Gop, Gop->Mode->Mode, &Size, &Info);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ /* We found a GOP */
+
+ /* EFI framebuffer */
+ Si->orig_video_isVGA = 0x70;
+
+ Si->orig_x = 0;
+ Si->orig_y = 0;
+ Si->orig_video_page = 0;
+ Si->orig_video_mode = 0;
+ Si->orig_video_cols = 0;
+ Si->orig_video_lines = 0;
+ Si->orig_video_ega_bx = 0;
+ Si->orig_video_points = 0;
+
+ Si->lfb_base = (UINT32) Gop->Mode->FrameBufferBase;
+ Si->lfb_size = (UINT32) Gop->Mode->FrameBufferSize;
+ Si->lfb_width = (UINT16) Info->HorizontalResolution;
+ Si->lfb_height = (UINT16) Info->VerticalResolution;
+ Si->pages = 1;
+ Si->vesapm_seg = 0;
+ Si->vesapm_off = 0;
+
+ if (Info->PixelFormat == PixelRedGreenBlueReserved8BitPerColor) {
+ Si->lfb_depth = 32;
+ Si->red_size = 8;
+ Si->red_pos = 0;
+ Si->green_size = 8;
+ Si->green_pos = 8;
+ Si->blue_size = 8;
+ Si->blue_pos = 16;
+ Si->rsvd_size = 8;
+ Si->rsvd_pos = 24;
+ Si->lfb_linelength = (UINT16) (Info->PixelsPerScanLine * 4);
+
+ } else if (Info->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
+ Si->lfb_depth = 32;
+ Si->red_size = 8;
+ Si->red_pos = 16;
+ Si->green_size = 8;
+ Si->green_pos = 8;
+ Si->blue_size = 8;
+ Si->blue_pos = 0;
+ Si->rsvd_size = 8;
+ Si->rsvd_pos = 24;
+ Si->lfb_linelength = (UINT16) (Info->PixelsPerScanLine * 4);
+ } else if (Info->PixelFormat == PixelBitMask) {
+ FindBits(Info->PixelInformation.RedMask,
+ &Si->red_pos, &Si->red_size);
+ FindBits(Info->PixelInformation.GreenMask,
+ &Si->green_pos, &Si->green_size);
+ FindBits(Info->PixelInformation.BlueMask,
+ &Si->blue_pos, &Si->blue_size);
+ FindBits(Info->PixelInformation.ReservedMask,
+ &Si->rsvd_pos, &Si->rsvd_size);
+ Si->lfb_depth = Si->red_size + Si->green_size +
+ Si->blue_size + Si->rsvd_size;
+ Si->lfb_linelength = (UINT16) ((Info->PixelsPerScanLine * Si->lfb_depth) / 8);
+ } else {
+ Si->lfb_depth = 4;
+ Si->red_size = 0;
+ Si->red_pos = 0;
+ Si->green_size = 0;
+ Si->green_pos = 0;
+ Si->blue_size = 0;
+ Si->blue_pos = 0;
+ Si->rsvd_size = 0;
+ Si->rsvd_pos = 0;
+ Si->lfb_linelength = Si->lfb_width / 2;
+ }
+
+ return Status;
+}
+
+
+STATIC
+EFI_STATUS
+SetupGraphics (
+ IN OUT struct boot_params *Bp
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount;
+ UINTN Index;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
+
+ ZeroMem ((VOID*)&Bp->screen_info, sizeof(Bp->screen_info));
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiGraphicsOutputProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (!EFI_ERROR (Status)) {
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiGraphicsOutputProtocolGuid,
+ (VOID*) &Gop
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ Status = SetupGraphicsFromGop (&Bp->screen_info, Gop);
+ if (!EFI_ERROR (Status)) {
+ FreePool (HandleBuffer);
+ return EFI_SUCCESS;
+ }
+ }
+
+ FreePool (HandleBuffer);
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+STATIC
+EFI_STATUS
+SetupLinuxBootParams (
+ IN OUT struct boot_params *Bp
+ )
+{
+ SetupGraphics (Bp);
+
+ SetupLinuxMemmap (Bp);
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+LoadLinux (
+ IN VOID *Kernel,
+ IN OUT VOID *KernelSetup
+ )
+{
+ EFI_STATUS Status;
+ struct boot_params *Bp;
+
+ Status = BasicKernelSetupCheck (KernelSetup);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Bp = (struct boot_params *) KernelSetup;
+
+ if (Bp->hdr.version < 0x205 || !Bp->hdr.relocatable_kernel) {
+ //
+ // We only support relocatable kernels
+ //
+ return EFI_UNSUPPORTED;
+ }
+
+ InitLinuxDescriptorTables ();
+
+ Bp->hdr.code32_start = (UINT32)(UINTN) Kernel;
+ if (Bp->hdr.version >= 0x20c && Bp->hdr.handover_offset &&
+ (Bp->hdr.xloadflags & (sizeof (UINTN) == 4 ? BIT2 : BIT3))) {
+ DEBUG ((EFI_D_INFO, "Jumping to kernel EFI handover point at ofs %x\n", Bp->hdr.handover_offset));
+
+ DisableInterrupts ();
+ JumpToUefiKernel ((VOID*) gImageHandle, (VOID*) gST, KernelSetup, Kernel);
+ }
+
+ //
+ // Old kernels without EFI handover protocol
+ //
+ SetupLinuxBootParams (KernelSetup);
+
+ DEBUG ((EFI_D_INFO, "Jumping to kernel\n"));
+ DisableInterrupts ();
+ SetLinuxDescriptorTables ();
+ JumpToKernel (Kernel, (VOID*) KernelSetup);
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
new file mode 100644
index 0000000000..fda185e3d7
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
@@ -0,0 +1,175 @@
+/** @file
+ Initialize GDT for Linux.
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "LoadLinuxLib.h"
+
+
+//
+// Local structure definitions
+//
+
+#pragma pack (1)
+
+//
+// Global Descriptor Entry structures
+//
+
+typedef struct _GDT_ENTRY {
+ UINT16 Limit15_0;
+ UINT16 Base15_0;
+ UINT8 Base23_16;
+ UINT8 Type;
+ UINT8 Limit19_16_and_flags;
+ UINT8 Base31_24;
+} GDT_ENTRY;
+
+typedef
+struct _GDT_ENTRIES {
+ GDT_ENTRY Null;
+ GDT_ENTRY Null2;
+ GDT_ENTRY Linear;
+ GDT_ENTRY LinearCode;
+ GDT_ENTRY TaskSegment;
+ GDT_ENTRY Spare4;
+ GDT_ENTRY Spare5;
+} GDT_ENTRIES;
+
+#pragma pack ()
+
+STATIC GDT_ENTRIES *mGdt = NULL;
+
+//
+// Global descriptor table (GDT) Template
+//
+STATIC GDT_ENTRIES GdtTemplate = {
+ //
+ // Null
+ //
+ {
+ 0x0, // limit 15:0
+ 0x0, // base 15:0
+ 0x0, // base 23:16
+ 0x0, // type
+ 0x0, // limit 19:16, flags
+ 0x0, // base 31:24
+ },
+ //
+ // Null2
+ //
+ {
+ 0x0, // limit 15:0
+ 0x0, // base 15:0
+ 0x0, // base 23:16
+ 0x0, // type
+ 0x0, // limit 19:16, flags
+ 0x0, // base 31:24
+ },
+ //
+ // Linear
+ //
+ {
+ 0x0FFFF, // limit 0xFFFFF
+ 0x0, // base 0
+ 0x0,
+ 0x09A, // present, ring 0, data, expand-up, writable
+ 0x0CF, // page-granular, 32-bit
+ 0x0,
+ },
+ //
+ // LinearCode
+ //
+ {
+ 0x0FFFF, // limit 0xFFFFF
+ 0x0, // base 0
+ 0x0,
+ 0x092, // present, ring 0, data, expand-up, writable
+ 0x0CF, // page-granular, 32-bit
+ 0x0,
+ },
+ //
+ // TaskSegment
+ //
+ {
+ 0x0, // limit 0
+ 0x0, // base 0
+ 0x0,
+ 0x089, // ?
+ 0x080, // ?
+ 0x0,
+ },
+ //
+ // Spare4
+ //
+ {
+ 0x0, // limit 0
+ 0x0, // base 0
+ 0x0,
+ 0x0, // present, ring 0, data, expand-up, writable
+ 0x0, // page-granular, 32-bit
+ 0x0,
+ },
+ //
+ // Spare5
+ //
+ {
+ 0x0, // limit 0
+ 0x0, // base 0
+ 0x0,
+ 0x0, // present, ring 0, data, expand-up, writable
+ 0x0, // page-granular, 32-bit
+ 0x0,
+ },
+};
+
+/**
+ Initialize Global Descriptor Table.
+
+**/
+VOID
+InitLinuxDescriptorTables (
+ VOID
+ )
+{
+ //
+ // Allocate Runtime Data for the GDT
+ //
+ mGdt = AllocateRuntimePool (sizeof (GdtTemplate) + 8);
+ ASSERT (mGdt != NULL);
+ mGdt = ALIGN_POINTER (mGdt, 8);
+
+ //
+ // Initialize all GDT entries
+ //
+ CopyMem (mGdt, &GdtTemplate, sizeof (GdtTemplate));
+
+}
+
+/**
+ Initialize Global Descriptor Table.
+
+**/
+VOID
+SetLinuxDescriptorTables (
+ VOID
+ )
+{
+ IA32_DESCRIPTOR GdtPtr;
+ IA32_DESCRIPTOR IdtPtr;
+
+ //
+ // Write GDT register
+ //
+ GdtPtr.Base = (UINT32)(UINTN)(VOID*) mGdt;
+ GdtPtr.Limit = (UINT16) (sizeof (GdtTemplate) - 1);
+ AsmWriteGdtr (&GdtPtr);
+
+ IdtPtr.Base = (UINT32) 0;
+ IdtPtr.Limit = (UINT16) 0;
+ AsmWriteIdtr (&IdtPtr);
+}
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
new file mode 100644
index 0000000000..3d98291410
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
@@ -0,0 +1,507 @@
+/** @file
+ File System Access for NvVarsFileLib
+
+ Copyright (c) 2004 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "NvVarsFileLib.h"
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+
+/**
+ Open the NvVars file for reading or writing
+
+ @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
+ @param[in] ReadingFile - TRUE: open the file for reading. FALSE: writing
+ @param[out] NvVarsFile - If EFI_SUCCESS is returned, then this is updated
+ with the opened NvVars file.
+
+ @return EFI_SUCCESS if the file was opened
+
+**/
+EFI_STATUS
+GetNvVarsFile (
+ IN EFI_HANDLE FsHandle,
+ IN BOOLEAN ReadingFile,
+ OUT EFI_FILE_HANDLE *NvVarsFile
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs;
+ EFI_FILE_HANDLE Root;
+
+ //
+ // Get the FileSystem protocol on that handle
+ //
+ Status = gBS->HandleProtocol (
+ FsHandle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ (VOID **)&Fs
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get the volume (the root directory)
+ //
+ Status = Fs->OpenVolume (Fs, &Root);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Attempt to open the NvVars file in the root directory
+ //
+ Status = Root->Open (
+ Root,
+ NvVarsFile,
+ L"NvVars",
+ ReadingFile ?
+ EFI_FILE_MODE_READ :
+ (
+ EFI_FILE_MODE_CREATE |
+ EFI_FILE_MODE_READ |
+ EFI_FILE_MODE_WRITE
+ ),
+ 0
+ );
+
+ return Status;
+}
+
+
+/**
+ Open the NvVars file for reading or writing
+
+ @param[in] File - The file to inspect
+ @param[out] Exists - Returns whether the file exists
+ @param[out] Size - Returns the size of the file
+ (0 if the file does not exist)
+
+**/
+VOID
+NvVarsFileReadCheckup (
+ IN EFI_FILE_HANDLE File,
+ OUT BOOLEAN *Exists,
+ OUT UINTN *Size
+ )
+{
+ EFI_FILE_INFO *FileInfo;
+
+ *Exists = FALSE;
+ *Size = 0;
+
+ FileInfo = FileHandleGetInfo (File);
+ if (FileInfo == NULL) {
+ return;
+ }
+
+ if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) {
+ FreePool (FileInfo);
+ return;
+ }
+
+ *Exists = TRUE;
+ *Size = (UINTN) FileInfo->FileSize;
+
+ FreePool (FileInfo);
+}
+
+
+/**
+ Open the NvVars file for reading or writing
+
+ @param[in] File - The file to inspect
+ @param[out] Exists - Returns whether the file exists
+ @param[out] Size - Returns the size of the file
+ (0 if the file does not exist)
+
+**/
+EFI_STATUS
+FileHandleEmpty (
+ IN EFI_FILE_HANDLE File
+ )
+{
+ EFI_STATUS Status;
+ EFI_FILE_INFO *FileInfo;
+
+ //
+ // Retrieve the FileInfo structure
+ //
+ FileInfo = FileHandleGetInfo (File);
+ if (FileInfo == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // If the path is a directory, then return an error
+ //
+ if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) {
+ FreePool (FileInfo);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // If the file size is already 0, then it is empty, so
+ // we can return success.
+ //
+ if (FileInfo->FileSize == 0) {
+ FreePool (FileInfo);
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Set the file size to 0.
+ //
+ FileInfo->FileSize = 0;
+ Status = FileHandleSetInfo (File, FileInfo);
+
+ FreePool (FileInfo);
+
+ return Status;
+}
+
+
+/**
+ Reads a file to a newly allocated buffer
+
+ @param[in] File - The file to read
+ @param[in] ReadSize - The size of data to read from the file
+
+ @return Pointer to buffer allocated to hold the file
+ contents. NULL if an error occurred.
+
+**/
+VOID*
+FileHandleReadToNewBuffer (
+ IN EFI_FILE_HANDLE FileHandle,
+ IN UINTN ReadSize
+ )
+{
+ EFI_STATUS Status;
+ UINTN ActualReadSize;
+ VOID *FileContents;
+
+ ActualReadSize = ReadSize;
+ FileContents = AllocatePool (ReadSize);
+ if (FileContents != NULL) {
+ Status = FileHandleRead (
+ FileHandle,
+ &ReadSize,
+ FileContents
+ );
+ if (EFI_ERROR (Status) || (ActualReadSize != ReadSize)) {
+ FreePool (FileContents);
+ return NULL;
+ }
+ }
+
+ return FileContents;
+}
+
+
+/**
+ Reads the contents of the NvVars file on the file system
+
+ @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
+
+ @return EFI_STATUS based on the success or failure of the file read
+
+**/
+EFI_STATUS
+ReadNvVarsFile (
+ IN EFI_HANDLE FsHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_FILE_HANDLE File;
+ UINTN FileSize;
+ BOOLEAN FileExists;
+ VOID *FileContents;
+ EFI_HANDLE SerializedVariables;
+
+ Status = GetNvVarsFile (FsHandle, TRUE, &File);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "FsAccess.c: Could not open NV Variables file on this file system\n"));
+ return Status;
+ }
+
+ NvVarsFileReadCheckup (File, &FileExists, &FileSize);
+ if (FileSize == 0) {
+ FileHandleClose (File);
+ return EFI_UNSUPPORTED;
+ }
+
+ FileContents = FileHandleReadToNewBuffer (File, FileSize);
+ if (FileContents == NULL) {
+ FileHandleClose (File);
+ return EFI_UNSUPPORTED;
+ }
+
+ DEBUG ((
+ EFI_D_INFO,
+ "FsAccess.c: Read %Lu bytes from NV Variables file\n",
+ (UINT64)FileSize
+ ));
+
+ Status = SerializeVariablesNewInstanceFromBuffer (
+ &SerializedVariables,
+ FileContents,
+ FileSize
+ );
+ if (!RETURN_ERROR (Status)) {
+ Status = SerializeVariablesSetSerializedVariables (SerializedVariables);
+ }
+
+ FreePool (FileContents);
+ FileHandleClose (File);
+
+ return Status;
+}
+
+
+/**
+ Writes a variable to indicate that the NV variables
+ have been loaded from the file system.
+
+**/
+STATIC
+VOID
+SetNvVarsVariable (
+ VOID
+ )
+{
+ BOOLEAN VarData;
+ UINTN Size;
+
+ //
+ // Write a variable to indicate we've already loaded the
+ // variable data. If it is found, we skip the loading on
+ // subsequent attempts.
+ //
+ Size = sizeof (VarData);
+ VarData = TRUE;
+ gRT->SetVariable (
+ L"NvVars",
+ &gEfiSimpleFileSystemProtocolGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ Size,
+ (VOID*) &VarData
+ );
+}
+
+
+/**
+ Loads the non-volatile variables from the NvVars file on the
+ given file system.
+
+ @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
+
+ @return EFI_STATUS based on the success or failure of load operation
+
+**/
+EFI_STATUS
+LoadNvVarsFromFs (
+ EFI_HANDLE FsHandle
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN VarData;
+ UINTN Size;
+
+ DEBUG ((EFI_D_INFO, "FsAccess.c: LoadNvVarsFromFs\n"));
+
+ //
+ // We write a variable to indicate we've already loaded the
+ // variable data. If it is found, we skip the loading.
+ //
+ // This is relevant if the non-volatile variable have been
+ // able to survive a reboot operation. In that case, we don't
+ // want to re-load the file as it would overwrite newer changes
+ // made to the variables.
+ //
+ Size = sizeof (VarData);
+ VarData = TRUE;
+ Status = gRT->GetVariable (
+ L"NvVars",
+ &gEfiSimpleFileSystemProtocolGuid,
+ NULL,
+ &Size,
+ (VOID*) &VarData
+ );
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((EFI_D_INFO, "NV Variables were already loaded\n"));
+ return EFI_ALREADY_STARTED;
+ }
+
+ //
+ // Attempt to restore the variables from the NvVars file.
+ //
+ Status = ReadNvVarsFile (FsHandle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "Error while restoring NV variable data\n"));
+ return Status;
+ }
+
+ //
+ // Write a variable to indicate we've already loaded the
+ // variable data. If it is found, we skip the loading on
+ // subsequent attempts.
+ //
+ SetNvVarsVariable();
+
+ DEBUG ((
+ EFI_D_INFO,
+ "FsAccess.c: Read NV Variables file (size=%Lu)\n",
+ (UINT64)Size
+ ));
+
+ return Status;
+}
+
+
+STATIC
+RETURN_STATUS
+EFIAPI
+IterateVariablesCallbackAddAllNvVariables (
+ IN VOID *Context,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ EFI_HANDLE Instance;
+
+ Instance = (EFI_HANDLE) Context;
+
+ //
+ // Only save non-volatile variables
+ //
+ if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
+ return RETURN_SUCCESS;
+ }
+
+ return SerializeVariablesAddVariable (
+ Instance,
+ VariableName,
+ VendorGuid,
+ Attributes,
+ DataSize,
+ Data
+ );
+}
+
+
+/**
+ Saves the non-volatile variables into the NvVars file on the
+ given file system.
+
+ @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
+
+ @return EFI_STATUS based on the success or failure of load operation
+
+**/
+EFI_STATUS
+SaveNvVarsToFs (
+ EFI_HANDLE FsHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_FILE_HANDLE File;
+ UINTN WriteSize;
+ UINTN VariableDataSize;
+ VOID *VariableData;
+ EFI_HANDLE SerializedVariables;
+
+ SerializedVariables = NULL;
+
+ Status = SerializeVariablesNewInstance (&SerializedVariables);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = SerializeVariablesIterateSystemVariables (
+ IterateVariablesCallbackAddAllNvVariables,
+ (VOID*) SerializedVariables
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ VariableData = NULL;
+ VariableDataSize = 0;
+ Status = SerializeVariablesToBuffer (
+ SerializedVariables,
+ NULL,
+ &VariableDataSize
+ );
+ if (Status == RETURN_BUFFER_TOO_SMALL) {
+ VariableData = AllocatePool (VariableDataSize);
+ if (VariableData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ Status = SerializeVariablesToBuffer (
+ SerializedVariables,
+ VariableData,
+ &VariableDataSize
+ );
+ }
+ }
+
+ SerializeVariablesFreeInstance (SerializedVariables);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Open the NvVars file for writing.
+ //
+ Status = GetNvVarsFile (FsHandle, FALSE, &File);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "FsAccess.c: Unable to open file to saved NV Variables\n"));
+ return Status;
+ }
+
+ //
+ // Empty the starting file contents.
+ //
+ Status = FileHandleEmpty (File);
+ if (EFI_ERROR (Status)) {
+ FileHandleClose (File);
+ return Status;
+ }
+
+ WriteSize = VariableDataSize;
+ Status = FileHandleWrite (File, &WriteSize, VariableData);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ FileHandleClose (File);
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Write a variable to indicate we've already loaded the
+ // variable data. If it is found, we skip the loading on
+ // subsequent attempts.
+ //
+ SetNvVarsVariable();
+
+ DEBUG ((EFI_D_INFO, "Saved NV Variables to NvVars file\n"));
+ }
+
+ return Status;
+}
+
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c
new file mode 100644
index 0000000000..2e9618455d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c
@@ -0,0 +1,77 @@
+/** @file
+ Save Non-Volatile Variables to a file system.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "NvVarsFileLib.h"
+#include <Library/DebugLib.h>
+#include <Library/NvVarsFileLib.h>
+
+EFI_HANDLE mNvVarsFileLibFsHandle = NULL;
+
+
+/**
+ Attempts to connect the NvVarsFileLib to the specified file system.
+
+ @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
+
+ @return The EFI_STATUS while attempting to connect the NvVarsFileLib
+ to the file system instance.
+ @retval EFI_SUCCESS - The given file system was connected successfully
+
+**/
+EFI_STATUS
+EFIAPI
+ConnectNvVarsToFileSystem (
+ IN EFI_HANDLE FsHandle
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // We might fail to load the variable, since the file system initially
+ // will not have the NvVars file.
+ //
+ LoadNvVarsFromFs (FsHandle);
+
+ //
+ // We must be able to save the variables successfully to the file system
+ // to have connected successfully.
+ //
+ Status = SaveNvVarsToFs (FsHandle);
+ if (!EFI_ERROR (Status)) {
+ mNvVarsFileLibFsHandle = FsHandle;
+ }
+
+ return Status;
+}
+
+
+/**
+ Update non-volatile variables stored on the file system.
+
+ @return The EFI_STATUS while attempting to update the variable on
+ the connected file system.
+ @retval EFI_SUCCESS - The non-volatile variables were saved to the disk
+ @retval EFI_NOT_STARTED - A file system has not been connected
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateNvVarsOnFileSystem (
+ )
+{
+ if (mNvVarsFileLibFsHandle == NULL) {
+ //
+ // A file system had not been connected to the library.
+ //
+ return EFI_NOT_STARTED;
+ } else {
+ return SaveNvVarsToFs (mNvVarsFileLibFsHandle);
+ }
+}
+
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
new file mode 100644
index 0000000000..53c421d40b
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -0,0 +1,419 @@
+/** @file
+ SIMICS QSP's instance of the PCI Host Bridge Library.
+
+ Copyright (C) 2016, Red Hat, Inc.
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiDxe.h>
+
+#include <IndustryStandard/Pci.h>
+#include <Register/X58Ich10.h>
+
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciHostBridgeLib.h>
+#include <Library/PciLib.h>
+#include "PciHostBridge.h"
+
+
+#pragma pack(1)
+typedef struct {
+ ACPI_HID_DEVICE_PATH AcpiDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
+} OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH;
+#pragma pack ()
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {
+ L"Mem", L"I/O", L"Bus"
+};
+
+
+STATIC
+CONST
+OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate = {
+ {
+ {
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ {
+ (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+ (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+ }
+ },
+ EISA_PNP_ID(0x0A03), // HID
+ 0 // UID
+ },
+
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+};
+
+STATIC PCI_ROOT_BRIDGE_APERTURE mNonExistAperture = { MAX_UINT64, 0 };
+
+/**
+ Initialize a PCI_ROOT_BRIDGE structure.
+
+ @param[in] Supports Supported attributes.
+
+ @param[in] Attributes Initial attributes.
+
+ @param[in] AllocAttributes Allocation attributes.
+
+ @param[in] RootBusNumber The bus number to store in RootBus.
+
+ @param[in] MaxSubBusNumber The inclusive maximum bus number that can be
+ assigned to any subordinate bus found behind any
+ PCI bridge hanging off this root bus.
+
+ The caller is repsonsible for ensuring that
+ RootBusNumber <= MaxSubBusNumber. If
+ RootBusNumber equals MaxSubBusNumber, then the
+ root bus has no room for subordinate buses.
+
+ @param[in] Io IO aperture.
+
+ @param[in] Mem MMIO aperture.
+
+ @param[in] MemAbove4G MMIO aperture above 4G.
+
+ @param[in] PMem Prefetchable MMIO aperture.
+
+ @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G.
+
+ @param[out] RootBus The PCI_ROOT_BRIDGE structure (allocated by the
+ caller) that should be filled in by this
+ function.
+
+ @retval EFI_SUCCESS Initialization successful. A device path
+ consisting of an ACPI device path node, with
+ UID = RootBusNumber, has been allocated and
+ linked into RootBus.
+
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
+**/
+EFI_STATUS
+InitRootBridge (
+ IN UINT64 Supports,
+ IN UINT64 Attributes,
+ IN UINT64 AllocAttributes,
+ IN UINT8 RootBusNumber,
+ IN UINT8 MaxSubBusNumber,
+ IN PCI_ROOT_BRIDGE_APERTURE *Io,
+ IN PCI_ROOT_BRIDGE_APERTURE *Mem,
+ IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,
+ IN PCI_ROOT_BRIDGE_APERTURE *PMem,
+ IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G,
+ OUT PCI_ROOT_BRIDGE *RootBus
+ )
+{
+ OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath;
+
+ //
+ // Be safe if other fields are added to PCI_ROOT_BRIDGE later.
+ //
+ ZeroMem (RootBus, sizeof *RootBus);
+
+ RootBus->Segment = 0;
+
+ RootBus->Supports = Supports;
+ RootBus->Attributes = Attributes;
+
+ RootBus->DmaAbove4G = FALSE;
+
+ RootBus->AllocationAttributes = AllocAttributes;
+ RootBus->Bus.Base = RootBusNumber;
+ RootBus->Bus.Limit = MaxSubBusNumber;
+ CopyMem (&RootBus->Io, Io, sizeof (*Io));
+ CopyMem (&RootBus->Mem, Mem, sizeof (*Mem));
+ CopyMem (&RootBus->MemAbove4G, MemAbove4G, sizeof (*MemAbove4G));
+ CopyMem (&RootBus->PMem, PMem, sizeof (*PMem));
+ CopyMem (&RootBus->PMemAbove4G, PMemAbove4G, sizeof (*PMemAbove4G));
+
+ RootBus->NoExtendedConfigSpace = (PcdGet16 (PcdSimicsX58HostBridgePciDevId) !=
+ INTEL_ICH10_DEVICE_ID);
+
+ DevicePath = AllocateCopyPool (sizeof mRootBridgeDevicePathTemplate,
+ &mRootBridgeDevicePathTemplate);
+ if (DevicePath == NULL) {
+ DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ DevicePath->AcpiDevicePath.UID = RootBusNumber;
+ RootBus->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;
+
+ DEBUG ((EFI_D_INFO,
+ "%a: populated root bus %d, with room for %d subordinate bus(es)\n",
+ __FUNCTION__, RootBusNumber, MaxSubBusNumber - RootBusNumber));
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Uninitialize a PCI_ROOT_BRIDGE structure set up with InitRootBridge().
+
+ param[in] RootBus The PCI_ROOT_BRIDGE structure, allocated by the caller and
+ initialized with InitRootBridge(), that should be
+ uninitialized. This function doesn't free RootBus.
+**/
+STATIC
+VOID
+UninitRootBridge (
+ IN PCI_ROOT_BRIDGE *RootBus
+ )
+{
+ FreePool (RootBus->DevicePath);
+}
+
+
+/**
+ Return all the root bridge instances in an array.
+
+ @param Count Return the count of root bridge instances.
+
+ @return All the root bridge instances in an array.
+ The array should be passed into PciHostBridgeFreeRootBridges()
+ when it's not used.
+**/
+PCI_ROOT_BRIDGE *
+EFIAPI
+PciHostBridgeGetRootBridges (
+ UINTN *Count
+ )
+{
+ EFI_STATUS Status;
+ UINT64 ExtraRootBridges;
+ PCI_ROOT_BRIDGE *Bridges;
+ UINTN Initialized;
+ UINTN LastRootBridgeNumber;
+ UINTN RootBridgeNumber;
+ UINT64 Attributes;
+ UINT64 AllocationAttributes;
+ PCI_ROOT_BRIDGE_APERTURE Io;
+ PCI_ROOT_BRIDGE_APERTURE Mem;
+ PCI_ROOT_BRIDGE_APERTURE MemAbove4G;
+
+ ZeroMem (&Io, sizeof (Io));
+ ZeroMem (&Mem, sizeof (Mem));
+ ZeroMem (&MemAbove4G, sizeof (MemAbove4G));
+
+ Attributes = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO |
+ EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO |
+ EFI_PCI_ATTRIBUTE_ISA_IO_16 |
+ EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO |
+ EFI_PCI_ATTRIBUTE_VGA_MEMORY |
+ EFI_PCI_ATTRIBUTE_VGA_IO_16 |
+ EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
+
+ AllocationAttributes = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM;
+ if (PcdGet64 (PcdPciMmio64Size) > 0) {
+ AllocationAttributes |= EFI_PCI_HOST_BRIDGE_MEM64_DECODE;
+ MemAbove4G.Base = PcdGet64 (PcdPciMmio64Base);
+ MemAbove4G.Limit = PcdGet64 (PcdPciMmio64Base) +
+ PcdGet64 (PcdPciMmio64Size) - 1;
+ } else {
+ CopyMem (&MemAbove4G, &mNonExistAperture, sizeof (mNonExistAperture));
+ }
+
+ Io.Base = PcdGet64 (PcdPciIoBase);
+ Io.Limit = PcdGet64 (PcdPciIoBase) + (PcdGet64 (PcdPciIoSize) - 1);
+ Mem.Base = PcdGet64 (PcdPciMmio32Base);
+ Mem.Limit = PcdGet64 (PcdPciMmio32Base) + (PcdGet64 (PcdPciMmio32Size) - 1);
+
+ *Count = 0;
+ ExtraRootBridges = 0;
+
+ //
+ // Allocate the "main" root bridge, and any extra root bridges.
+ //
+ Bridges = AllocatePool ((1 + (UINTN)ExtraRootBridges) * sizeof *Bridges);
+ if (Bridges == NULL) {
+ DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES));
+ return NULL;
+ }
+ Initialized = 0;
+
+ //
+ // The "main" root bus is always there.
+ //
+ LastRootBridgeNumber = 0;
+
+ //
+ // Scan all other root buses. If function 0 of any device on a bus returns a
+ // VendorId register value different from all-bits-one, then that bus is
+ // alive.
+ //
+ for (RootBridgeNumber = 1;
+ RootBridgeNumber <= PCI_MAX_BUS && Initialized < ExtraRootBridges;
+ ++RootBridgeNumber) {
+ UINTN Device;
+
+ for (Device = 0; Device <= PCI_MAX_DEVICE; ++Device) {
+ if (PciRead16 (PCI_LIB_ADDRESS (RootBridgeNumber, Device, 0,
+ PCI_VENDOR_ID_OFFSET)) != MAX_UINT16) {
+ break;
+ }
+ }
+ if (Device <= PCI_MAX_DEVICE) {
+ //
+ // Found the next root bus. We can now install the *previous* one,
+ // because now we know how big a bus number range *that* one has, for any
+ // subordinate buses that might exist behind PCI bridges hanging off it.
+ //
+ Status = InitRootBridge (
+ Attributes,
+ Attributes,
+ AllocationAttributes,
+ (UINT8) LastRootBridgeNumber,
+ (UINT8) (RootBridgeNumber - 1),
+ &Io,
+ &Mem,
+ &MemAbove4G,
+ &mNonExistAperture,
+ &mNonExistAperture,
+ &Bridges[Initialized]
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreeBridges;
+ }
+ ++Initialized;
+ LastRootBridgeNumber = RootBridgeNumber;
+ }
+ }
+
+ //
+ // Install the last root bus (which might be the only, ie. main, root bus, if
+ // we've found no extra root buses).
+ //
+ Status = InitRootBridge (
+ Attributes,
+ Attributes,
+ AllocationAttributes,
+ (UINT8) LastRootBridgeNumber,
+ PCI_MAX_BUS,
+ &Io,
+ &Mem,
+ &MemAbove4G,
+ &mNonExistAperture,
+ &mNonExistAperture,
+ &Bridges[Initialized]
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreeBridges;
+ }
+ ++Initialized;
+
+ *Count = Initialized;
+ return Bridges;
+
+FreeBridges:
+ while (Initialized > 0) {
+ --Initialized;
+ UninitRootBridge (&Bridges[Initialized]);
+ }
+
+ FreePool (Bridges);
+ return NULL;
+}
+
+
+/**
+ Free the root bridge instances array returned from
+ PciHostBridgeGetRootBridges().
+
+ @param The root bridge instances array.
+ @param The count of the array.
+**/
+VOID
+EFIAPI
+PciHostBridgeFreeRootBridges (
+ PCI_ROOT_BRIDGE *Bridges,
+ UINTN Count
+ )
+{
+ if (Bridges == NULL && Count == 0) {
+ return;
+ }
+ ASSERT (Bridges != NULL && Count > 0);
+
+ do {
+ --Count;
+ UninitRootBridge (&Bridges[Count]);
+ } while (Count > 0);
+
+ FreePool (Bridges);
+}
+
+
+/**
+ Inform the platform that the resource conflict happens.
+
+ @param HostBridgeHandle Handle of the Host Bridge.
+ @param Configuration Pointer to PCI I/O and PCI memory resource
+ descriptors. The Configuration contains the resources
+ for all the root bridges. The resource for each root
+ bridge is terminated with END descriptor and an
+ additional END is appended indicating the end of the
+ entire resources. The resource descriptor field
+ values follow the description in
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+ .SubmitResources().
+**/
+VOID
+EFIAPI
+PciHostBridgeResourceConflict (
+ EFI_HANDLE HostBridgeHandle,
+ VOID *Configuration
+ )
+{
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
+ UINTN RootBridgeIndex;
+ DEBUG ((EFI_D_ERROR, "PciHostBridge: Resource conflict happens!\n"));
+
+ RootBridgeIndex = 0;
+ Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
+ while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+ DEBUG ((EFI_D_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));
+ for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
+ ASSERT (Descriptor->ResType <
+ (sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr) /
+ sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr[0])
+ )
+ );
+ DEBUG ((EFI_D_ERROR, " %s: Length/Alignment = 0x%lx / 0x%lx\n",
+ mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType],
+ Descriptor->AddrLen, Descriptor->AddrRangeMax
+ ));
+ if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
+ DEBUG ((EFI_D_ERROR, " Granularity/SpecificFlag = %ld / %02x%s\n",
+ Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag,
+ ((Descriptor->SpecificFlag &
+ EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE
+ ) != 0) ? L" (Prefetchable)" : L""
+ ));
+ }
+ }
+ //
+ // Skip the END descriptor for root bridge
+ //
+ ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);
+ Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)(
+ (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1
+ );
+ }
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c
new file mode 100644
index 0000000000..4e3762465a
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c
@@ -0,0 +1,100 @@
+/** @file
+ Build FV related hobs for platform.
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PiPei.h"
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+
+BOOLEAN mS3Supported = TRUE;
+
+/**
+ Publish PEI & DXE (Decompressed) Memory based FVs to let PEI
+ and DXE know about them.
+
+ @retval EFI_SUCCESS Platform PEI FVs were initialized successfully.
+
+**/
+EFI_STATUS
+PeiFvInitialization (
+ VOID
+ )
+{
+ BOOLEAN SecureS3Needed;
+
+ DEBUG ((EFI_D_INFO, "Platform PEI Firmware Volume Initialization\n"));
+
+ DEBUG (
+ (EFI_D_ERROR, "Firmware Volume HOB: 0x%x 0x%x\n",
+ PcdGet32 (PcdSimicsPeiMemFvBase),
+ PcdGet32 (PcdSimicsPeiMemFvSize)
+ )
+ );
+ //
+ // Create a memory allocation HOB for the PEI FV.
+ //
+ // Allocate as ACPI NVS is S3 is supported
+ //
+ BuildMemoryAllocationHob (
+ PcdGet32 (PcdSimicsPeiMemFvBase),
+ PcdGet32 (PcdSimicsPeiMemFvSize),
+ mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
+ );
+
+ //
+ // Let DXE know about the DXE FV
+ //
+ BuildFvHob (PcdGet32 (PcdSimicsDxeMemFvBase), PcdGet32 (PcdSimicsDxeMemFvSize));
+
+ SecureS3Needed = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire);
+
+ //
+ // Create a memory allocation HOB for the DXE FV.
+ //
+ // If "secure" S3 is needed, then SEC will decompress both PEI and DXE
+ // firmware volumes at S3 resume too, hence we need to keep away the OS from
+ // DXEFV as well. Otherwise we only need to keep away DXE itself from the
+ // DXEFV area.
+ //
+ BuildMemoryAllocationHob (
+ PcdGet32 (PcdSimicsDxeMemFvBase),
+ PcdGet32 (PcdSimicsDxeMemFvSize),
+ SecureS3Needed ? EfiACPIMemoryNVS : EfiBootServicesData
+ );
+
+ //
+ // Additionally, said decompression will use temporary memory above the end
+ // of DXEFV, so let's keep away the OS from there too.
+ //
+ if (SecureS3Needed) {
+ UINT32 DxeMemFvEnd;
+
+ DxeMemFvEnd = PcdGet32 (PcdSimicsDxeMemFvBase) +
+ PcdGet32 (PcdSimicsDxeMemFvSize);
+ BuildMemoryAllocationHob (
+ DxeMemFvEnd,
+ PcdGet32 (PcdSimicsDecompressionScratchEnd) - DxeMemFvEnd,
+ EfiACPIMemoryNVS
+ );
+ }
+
+ //
+ // Let PEI know about the DXE FV so it can find the DXE Core
+ //
+ PeiServicesInstallFvInfoPpi (
+ NULL,
+ (VOID *)(UINTN) PcdGet32 (PcdSimicsDxeMemFvBase),
+ PcdGet32 (PcdSimicsDxeMemFvSize),
+ NULL,
+ NULL
+ );
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
new file mode 100644
index 0000000000..1760eb954c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
@@ -0,0 +1,118 @@
+/** @file
+ Source code file for Report Firmware Volume (FV) library
+
+Copyright (c) 2018, 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/FirmwareVolumeInfo.h>
+#include <Library/IoLib.h>
+#include <Register/X58Ich10.h>
+
+EFI_STATUS
+PeiFvInitialization(
+ VOID
+);
+
+VOID
+ReportPreMemFv (
+ VOID
+ )
+{
+ if (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) != 0x5) { // not S3 resume
+ PeiFvInitialization();
+ }
+
+ DEBUG ((DEBUG_INFO, "Install FlashFvSecurity - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvSecurityBase), PcdGet32 (PcdFlashFvSecuritySize)));
+ PeiServicesInstallFvInfo2Ppi (
+ &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvSecurityBase))->FileSystemGuid),
+ (VOID *) (UINTN) PcdGet32 (PcdFlashFvSecurityBase),
+ PcdGet32 (PcdFlashFvSecuritySize),
+ NULL,
+ NULL,
+ 0
+ );
+ DEBUG ((DEBUG_INFO, "Install FlashFvAdvanced - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvAdvancedBase), PcdGet32 (PcdFlashFvAdvancedSize)));
+ PeiServicesInstallFvInfo2Ppi (
+ &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvAdvancedBase))->FileSystemGuid),
+ (VOID *) (UINTN) PcdGet32 (PcdFlashFvAdvancedBase),
+ PcdGet32 (PcdFlashFvAdvancedSize),
+ NULL,
+ NULL,
+ 0
+ );
+}
+
+VOID
+ReportPostMemFv (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+
+ Status = PeiServicesGetBootMode (&BootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Build HOB for DXE
+ ///
+ if (BootMode == BOOT_IN_RECOVERY_MODE) {
+ ///
+ /// Prepare the recovery service
+ ///
+ } else {
+ DEBUG ((DEBUG_INFO, "Install FlashFvPostMemory - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvPostMemoryBase), PcdGet32 (PcdFlashFvPostMemorySize)));
+ PeiServicesInstallFvInfo2Ppi (
+ &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvPostMemoryBase))->FileSystemGuid),
+ (VOID *) (UINTN) PcdGet32 (PcdFlashFvPostMemoryBase),
+ PcdGet32 (PcdFlashFvPostMemorySize),
+ NULL,
+ NULL,
+ 0
+ );
+ DEBUG ((DEBUG_INFO, "Install FlashFvUefiBoot - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvUefiBootBase), PcdGet32 (PcdFlashFvUefiBootSize)));
+ PeiServicesInstallFvInfo2Ppi (
+ &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvUefiBootBase))->FileSystemGuid),
+ (VOID *) (UINTN) PcdGet32 (PcdFlashFvUefiBootBase),
+ PcdGet32 (PcdFlashFvUefiBootSize),
+ NULL,
+ NULL,
+ 0
+ );
+ DEBUG ((DEBUG_INFO, "Install FlashFvOsBoot - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvOsBootBase), PcdGet32 (PcdFlashFvOsBootSize)));
+ PeiServicesInstallFvInfo2Ppi (
+ &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvOsBootBase))->FileSystemGuid),
+ (VOID *) (UINTN) PcdGet32 (PcdFlashFvOsBootBase),
+ PcdGet32 (PcdFlashFvOsBootSize),
+ NULL,
+ NULL,
+ 0
+ );
+ }
+
+ //
+ // Report resource HOB for flash FV
+ //
+ 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/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatform.c
new file mode 100644
index 0000000000..117c72b35f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatform.c
@@ -0,0 +1,1553 @@
+/** @file
+ Platform BDS customizations.
+
+ Copyright (c) 2004 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BdsPlatform.h"
+#include <Guid/RootBridgesConnectedEventGroup.h>
+#include <Protocol/FirmwareVolume2.h>
+
+#define LEGACY_8259_MASK_REGISTER_MASTER 0x21
+#define LEGACY_8259_MASK_REGISTER_SLAVE 0xA1
+#define LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER 0x4D0
+#define LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE 0x4D1
+
+//
+// Global data
+//
+
+VOID *mEfiDevPathNotifyReg;
+EFI_EVENT mEfiDevPathEvent;
+VOID *mEmuVariableEventReg;
+EFI_EVENT mEmuVariableEvent;
+BOOLEAN mDetectVgaOnly;
+UINT16 mHostBridgeDevId;
+
+//
+// Table of host IRQs matching PCI IRQs A-D
+// (for configuring PCI Interrupt Line register)
+//
+CONST UINT8 PciHostIrqs[] = {
+ 0x0a, 0x0a, 0x0b, 0x0b
+};
+
+//
+// Type definitions
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *PROTOCOL_INSTANCE_CALLBACK)(
+ IN EFI_HANDLE Handle,
+ IN VOID *Instance,
+ IN VOID *Context
+ );
+
+/**
+ @param[in] Handle - Handle of PCI device instance
+ @param[in] PciIo - PCI IO protocol instance
+ @param[in] Pci - PCI Header register block
+**/
+typedef
+EFI_STATUS
+(EFIAPI *VISIT_PCI_INSTANCE_CALLBACK)(
+ IN EFI_HANDLE Handle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN PCI_TYPE00 *Pci
+ );
+
+
+//
+// Function prototypes
+//
+
+EFI_STATUS
+VisitAllInstancesOfProtocol (
+ IN EFI_GUID *Id,
+ IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction,
+ IN VOID *Context
+ );
+
+EFI_STATUS
+VisitAllPciInstancesOfProtocol (
+ IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
+ );
+
+VOID
+InstallDevicePathCallback (
+ VOID
+ );
+
+VOID
+PlatformRegisterFvBootOption (
+ EFI_GUID *FileGuid,
+ CHAR16 *Description,
+ UINT32 Attributes
+ )
+{
+ EFI_STATUS Status;
+ INTN OptionIndex;
+ EFI_BOOT_MANAGER_LOAD_OPTION NewOption;
+ EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
+ UINTN BootOptionCount;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ Status = gBS->HandleProtocol (
+ gImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **) &LoadedImage
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
+ DevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);
+ ASSERT (DevicePath != NULL);
+ DevicePath = AppendDevicePathNode (
+ DevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
+ );
+ ASSERT (DevicePath != NULL);
+
+ Status = EfiBootManagerInitializeLoadOption (
+ &NewOption,
+ LoadOptionNumberUnassigned,
+ LoadOptionTypeBoot,
+ Attributes,
+ Description,
+ DevicePath,
+ NULL,
+ 0
+ );
+ ASSERT_EFI_ERROR (Status);
+ FreePool (DevicePath);
+
+ BootOptions = EfiBootManagerGetLoadOptions (
+ &BootOptionCount, LoadOptionTypeBoot
+ );
+
+ OptionIndex = EfiBootManagerFindLoadOption (
+ &NewOption, BootOptions, BootOptionCount
+ );
+
+ if (OptionIndex == -1) {
+ Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);
+ ASSERT_EFI_ERROR (Status);
+ }
+ EfiBootManagerFreeLoadOption (&NewOption);
+ EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+}
+
+/**
+ Remove all MemoryMapped(...)/FvFile(...) and Fv(...)/FvFile(...) boot options
+ whose device paths do not resolve exactly to an FvFile in the system.
+
+ This removes any boot options that point to binaries built into the firmware
+ and have become stale due to any of the following:
+ - DXEFV's base address or size changed (historical),
+ - DXEFV's FvNameGuid changed,
+ - the FILE_GUID of the pointed-to binary changed,
+ - the referenced binary is no longer built into the firmware.
+
+ EfiBootManagerFindLoadOption() used in PlatformRegisterFvBootOption() only
+ avoids exact duplicates.
+**/
+VOID
+RemoveStaleFvFileOptions (
+ VOID
+ )
+{
+ EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
+ UINTN BootOptionCount;
+ UINTN Index;
+
+ BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount,
+ LoadOptionTypeBoot);
+
+ for (Index = 0; Index < BootOptionCount; ++Index) {
+ EFI_DEVICE_PATH_PROTOCOL *Node1, *Node2, *SearchNode;
+ EFI_STATUS Status;
+ EFI_HANDLE FvHandle;
+
+ //
+ // If the device path starts with neither MemoryMapped(...) nor Fv(...),
+ // then keep the boot option.
+ //
+ Node1 = BootOptions[Index].FilePath;
+ if (!(DevicePathType (Node1) == HARDWARE_DEVICE_PATH &&
+ DevicePathSubType (Node1) == HW_MEMMAP_DP) &&
+ !(DevicePathType (Node1) == MEDIA_DEVICE_PATH &&
+ DevicePathSubType (Node1) == MEDIA_PIWG_FW_VOL_DP)) {
+ continue;
+ }
+
+ //
+ // If the second device path node is not FvFile(...), then keep the boot
+ // option.
+ //
+ Node2 = NextDevicePathNode (Node1);
+ if (DevicePathType (Node2) != MEDIA_DEVICE_PATH ||
+ DevicePathSubType (Node2) != MEDIA_PIWG_FW_FILE_DP) {
+ continue;
+ }
+
+ //
+ // Locate the Firmware Volume2 protocol instance that is denoted by the
+ // boot option. If this lookup fails (i.e., the boot option references a
+ // firmware volume that doesn't exist), then we'll proceed to delete the
+ // boot option.
+ //
+ SearchNode = Node1;
+ Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid,
+ &SearchNode, &FvHandle);
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // The firmware volume was found; now let's see if it contains the FvFile
+ // identified by GUID.
+ //
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFileNode;
+ UINTN BufferSize;
+ EFI_FV_FILETYPE FoundType;
+ EFI_FV_FILE_ATTRIBUTES FileAttributes;
+ UINT32 AuthenticationStatus;
+
+ Status = gBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID **)&FvProtocol);
+ ASSERT_EFI_ERROR (Status);
+
+ FvFileNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)Node2;
+ //
+ // Buffer==NULL means we request metadata only: BufferSize, FoundType,
+ // FileAttributes.
+ //
+ Status = FvProtocol->ReadFile (
+ FvProtocol,
+ &FvFileNode->FvFileName, // NameGuid
+ NULL, // Buffer
+ &BufferSize,
+ &FoundType,
+ &FileAttributes,
+ &AuthenticationStatus
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // The FvFile was found. Keep the boot option.
+ //
+ continue;
+ }
+ }
+
+ //
+ // Delete the boot option.
+ //
+ Status = EfiBootManagerDeleteLoadOptionVariable (
+ BootOptions[Index].OptionNumber, LoadOptionTypeBoot);
+ DEBUG_CODE (
+ CHAR16 *DevicePathString;
+
+ DevicePathString = ConvertDevicePathToText(BootOptions[Index].FilePath,
+ FALSE, FALSE);
+ DEBUG ((
+ EFI_ERROR (Status) ? EFI_D_WARN : EFI_D_VERBOSE,
+ "%a: removing stale Boot#%04x %s: %r\n",
+ __FUNCTION__,
+ (UINT32)BootOptions[Index].OptionNumber,
+ DevicePathString == NULL ? L"<unavailable>" : DevicePathString,
+ Status
+ ));
+ if (DevicePathString != NULL) {
+ FreePool (DevicePathString);
+ }
+ );
+ }
+
+ EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+}
+
+VOID
+PlatformRegisterOptionsAndKeys (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_INPUT_KEY Enter;
+ EFI_INPUT_KEY F2;
+ EFI_INPUT_KEY Esc;
+ EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
+
+ //
+ // Register ENTER as CONTINUE key
+ //
+ Enter.ScanCode = SCAN_NULL;
+ Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
+ Status = EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Map F2 to Boot Manager Menu
+ //
+ F2.ScanCode = SCAN_F2;
+ F2.UnicodeChar = CHAR_NULL;
+ Esc.ScanCode = SCAN_ESC;
+ Esc.UnicodeChar = CHAR_NULL;
+ Status = EfiBootManagerGetBootManagerMenu (&BootOption);
+ ASSERT_EFI_ERROR (Status);
+ Status = EfiBootManagerAddKeyOptionVariable (
+ NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL
+ );
+ ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
+ Status = EfiBootManagerAddKeyOptionVariable (
+ NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL
+ );
+ ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
+}
+
+EFI_STATUS
+EFIAPI
+ConnectRootBridge (
+ IN EFI_HANDLE RootBridgeHandle,
+ IN VOID *Instance,
+ IN VOID *Context
+ );
+
+STATIC
+VOID
+SaveS3BootScript (
+ VOID
+ );
+
+//
+// BDS Platform Functions
+//
+/**
+ Do the platform init, can be customized by OEM/IBV
+
+ Possible things that can be done in PlatformBootManagerBeforeConsole:
+
+ > Update console variable: 1. include hot-plug devices;
+ > 2. Clear ConIn and add SOL for AMT
+ > Register new Driver#### or Boot####
+ > Register new Key####: e.g.: F12
+ > Signal ReadyToLock event
+ > Authentication action: 1. connect Auth devices;
+ > 2. Identify auto logon user.
+**/
+VOID
+EFIAPI
+PlatformBootManagerBeforeConsole (
+ VOID
+ )
+{
+// EFI_HANDLE Handle;
+// EFI_STATUS Status;
+
+ DEBUG ((EFI_D_INFO, "PlatformBootManagerBeforeConsole\n"));
+ InstallDevicePathCallback ();
+
+ VisitAllInstancesOfProtocol (&gEfiPciRootBridgeIoProtocolGuid,
+ ConnectRootBridge, NULL);
+ //
+ // Enable LPC
+ //
+ PciOr16(POWER_MGMT_REGISTER_ICH10(0x04),
+ BIT0 | BIT1 | BIT2);
+ //
+ // We can't signal End-of-Dxe earlier than this. Namely, End-of-Dxe triggers
+ // the preparation of S3 system information. That logic has a hard dependency
+ // on the presence of the FACS ACPI table. Since our ACPI tables are only
+ // installed after PCI enumeration completes, we must not trigger the S3 save
+ // earlier, hence we can't signal End-of-Dxe earlier.
+ //
+ EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
+
+ PlatformInitializeConsole (gPlatformConsole);
+
+ PlatformRegisterOptionsAndKeys ();
+}
+
+
+EFI_STATUS
+EFIAPI
+ConnectRootBridge (
+ IN EFI_HANDLE RootBridgeHandle,
+ IN VOID *Instance,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Make the PCI bus driver connect the root bridge, non-recursively. This
+ // will produce a number of child handles with PciIo on them.
+ //
+ Status = gBS->ConnectController (
+ RootBridgeHandle, // ControllerHandle
+ NULL, // DriverImageHandle
+ NULL, // RemainingDevicePath -- produce all
+ // children
+ FALSE // Recursive
+ );
+ return Status;
+}
+
+
+/**
+ Add IsaKeyboard to ConIn; add IsaSerial to ConOut, ConIn, ErrOut.
+
+ @param[in] DeviceHandle Handle of the LPC Bridge device.
+
+ @retval EFI_SUCCESS Console devices on the LPC bridge have been added to
+ ConOut, ConIn, and ErrOut.
+
+ @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing
+ from DeviceHandle.
+**/
+EFI_STATUS
+PrepareLpcBridgeDevicePath (
+ IN EFI_HANDLE DeviceHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ CHAR16 *DevPathStr;
+
+ DevicePath = NULL;
+ Status = gBS->HandleProtocol (
+ DeviceHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID*)&DevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ TempDevicePath = DevicePath;
+
+ //
+ // Register Keyboard
+ //
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);
+
+ EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
+
+ //
+ // Register COM1
+ //
+ DevicePath = TempDevicePath;
+ gPnp16550ComPortDeviceNode.UID = 0;
+
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
+
+ //
+ // Print Device Path
+ //
+ DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
+ if (DevPathStr != NULL) {
+ DEBUG((
+ EFI_D_INFO,
+ "BdsPlatform.c+%d: COM%d DevPath: %s\n",
+ __LINE__,
+ gPnp16550ComPortDeviceNode.UID + 1,
+ DevPathStr
+ ));
+ FreePool(DevPathStr);
+ }
+
+ EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
+
+ //
+ // Register COM2
+ //
+ DevicePath = TempDevicePath;
+ gPnp16550ComPortDeviceNode.UID = 1;
+
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
+
+ //
+ // Print Device Path
+ //
+ DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
+ if (DevPathStr != NULL) {
+ DEBUG((
+ EFI_D_INFO,
+ "BdsPlatform.c+%d: COM%d DevPath: %s\n",
+ __LINE__,
+ gPnp16550ComPortDeviceNode.UID + 1,
+ DevPathStr
+ ));
+ FreePool(DevPathStr);
+ }
+
+ EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetGopDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,
+ OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath
+ )
+{
+ UINTN Index;
+ EFI_STATUS Status;
+ EFI_HANDLE PciDeviceHandle;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath;
+ UINTN GopHandleCount;
+ EFI_HANDLE *GopHandleBuffer;
+
+ if (PciDevicePath == NULL || GopDevicePath == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Initialize the GopDevicePath to be PciDevicePath
+ //
+ *GopDevicePath = PciDevicePath;
+ TempPciDevicePath = PciDevicePath;
+
+ Status = gBS->LocateDevicePath (
+ &gEfiDevicePathProtocolGuid,
+ &TempPciDevicePath,
+ &PciDeviceHandle
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Try to connect this handle, so that GOP driver could start on this
+ // device and create child handles with GraphicsOutput Protocol installed
+ // on them, then we get device paths of these child handles and select
+ // them as possible console device.
+ //
+ gBS->ConnectController (PciDeviceHandle, NULL, NULL, FALSE);
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiGraphicsOutputProtocolGuid,
+ NULL,
+ &GopHandleCount,
+ &GopHandleBuffer
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Add all the child handles as possible Console Device
+ //
+ for (Index = 0; Index < GopHandleCount; Index++) {
+ Status = gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+ if (CompareMem (
+ PciDevicePath,
+ TempDevicePath,
+ GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH
+ ) == 0) {
+ //
+ // In current implementation, we only enable one of the child handles
+ // as console device, i.e. sotre one of the child handle's device
+ // path to variable "ConOut"
+ // In future, we could select all child handles to be console device
+ //
+
+ *GopDevicePath = TempDevicePath;
+
+ //
+ // Delete the PCI device's path that added by
+ // GetPlugInPciVgaDevicePath(). Add the integrity GOP device path.
+ //
+ EfiBootManagerUpdateConsoleVariable (ConOutDev, NULL, PciDevicePath);
+ EfiBootManagerUpdateConsoleVariable (ConOutDev, TempDevicePath, NULL);
+ }
+ }
+ gBS->FreePool (GopHandleBuffer);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Add PCI display to ConOut.
+
+ @param[in] DeviceHandle Handle of the PCI display device.
+
+ @retval EFI_SUCCESS The PCI display device has been added to ConOut.
+
+ @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing
+ from DeviceHandle.
+**/
+EFI_STATUS
+PreparePciDisplayDevicePath (
+ IN EFI_HANDLE DeviceHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;
+
+ DevicePath = NULL;
+ GopDevicePath = NULL;
+ Status = gBS->HandleProtocol (
+ DeviceHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID*)&DevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ GetGopDevicePath (DevicePath, &GopDevicePath);
+ DevicePath = GopDevicePath;
+
+ EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Add PCI Serial to ConOut, ConIn, ErrOut.
+
+ @param[in] DeviceHandle Handle of the PCI serial device.
+
+ @retval EFI_SUCCESS The PCI serial device has been added to ConOut, ConIn,
+ ErrOut.
+
+ @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing
+ from DeviceHandle.
+**/
+EFI_STATUS
+PreparePciSerialDevicePath (
+ IN EFI_HANDLE DeviceHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ DevicePath = NULL;
+ Status = gBS->HandleProtocol (
+ DeviceHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID*)&DevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
+
+ EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+VisitAllInstancesOfProtocol (
+ IN EFI_GUID *Id,
+ IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Index;
+ VOID *Instance;
+
+ //
+ // Start to check all the PciIo to find all possible device
+ //
+ HandleCount = 0;
+ HandleBuffer = NULL;
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ Id,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = gBS->HandleProtocol (HandleBuffer[Index], Id, &Instance);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ Status = (*CallBackFunction) (
+ HandleBuffer[Index],
+ Instance,
+ Context
+ );
+ }
+
+ gBS->FreePool (HandleBuffer);
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+VisitingAPciInstance (
+ IN EFI_HANDLE Handle,
+ IN VOID *Instance,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ PCI_TYPE00 Pci;
+
+ PciIo = (EFI_PCI_IO_PROTOCOL*) Instance;
+
+ //
+ // Check for all PCI device
+ //
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ sizeof (Pci) / sizeof (UINT32),
+ &Pci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return (*(VISIT_PCI_INSTANCE_CALLBACK)(UINTN) Context) (
+ Handle,
+ PciIo,
+ &Pci
+ );
+
+}
+
+
+
+EFI_STATUS
+VisitAllPciInstances (
+ IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
+ )
+{
+ return VisitAllInstancesOfProtocol (
+ &gEfiPciIoProtocolGuid,
+ VisitingAPciInstance,
+ (VOID*)(UINTN) CallBackFunction
+ );
+}
+
+
+/**
+ Do platform specific PCI Device check and add them to
+ ConOut, ConIn, ErrOut.
+
+ @param[in] Handle - Handle of PCI device instance
+ @param[in] PciIo - PCI IO protocol instance
+ @param[in] Pci - PCI Header register block
+
+ @retval EFI_SUCCESS - PCI Device check and Console variable update
+ successfully.
+ @retval EFI_STATUS - PCI Device check or Console variable update fail.
+
+**/
+EFI_STATUS
+EFIAPI
+DetectAndPreparePlatformPciDevicePath (
+ IN EFI_HANDLE Handle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN PCI_TYPE00 *Pci
+ )
+{
+ EFI_STATUS Status;
+
+ Status = PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationEnable,
+ EFI_PCI_DEVICE_ENABLE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (!mDetectVgaOnly) {
+ //
+ // Here we decide whether it is LPC Bridge
+ //
+ if ((IS_PCI_LPC (Pci)) ||
+ ((IS_PCI_ISA_PDECODE (Pci)) &&
+ (Pci->Hdr.VendorId == 0x8086) &&
+ (Pci->Hdr.DeviceId == 0x7000)
+ )
+ ) {
+ //
+ // Add IsaKeyboard to ConIn,
+ // add IsaSerial to ConOut, ConIn, ErrOut
+ //
+ DEBUG ((EFI_D_INFO, "Found LPC Bridge device\n"));
+ PrepareLpcBridgeDevicePath (Handle);
+ return EFI_SUCCESS;
+ }
+ //
+ // Here we decide which Serial device to enable in PCI bus
+ //
+ if (IS_PCI_16550SERIAL (Pci)) {
+ //
+ // Add them to ConOut, ConIn, ErrOut.
+ //
+ DEBUG ((EFI_D_INFO, "Found PCI 16550 SERIAL device\n"));
+ PreparePciSerialDevicePath (Handle);
+ return EFI_SUCCESS;
+ }
+ }
+
+ //
+ // Here we decide which display device to enable in PCI bus
+ //
+ if (IS_PCI_DISPLAY (Pci)) {
+ //
+ // Add them to ConOut.
+ //
+ DEBUG ((EFI_D_INFO, "Found PCI display device\n"));
+ PreparePciDisplayDevicePath (Handle);
+ return EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
+
+/**
+ Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
+
+ @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.
+
+ @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
+ @retval EFI_STATUS - PCI Device check or Console variable update fail.
+
+**/
+EFI_STATUS
+DetectAndPreparePlatformPciDevicePaths (
+ BOOLEAN DetectVgaOnly
+ )
+{
+ mDetectVgaOnly = DetectVgaOnly;
+ return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath);
+}
+
+/**
+ Connect the predefined platform default console device.
+
+ Always try to find and enable PCI display devices.
+
+ @param[in] PlatformConsole Predefined platform default console device array.
+**/
+VOID
+PlatformInitializeConsole (
+ IN PLATFORM_CONSOLE_CONNECT_ENTRY *PlatformConsole
+ )
+{
+ UINTN Index;
+ EFI_DEVICE_PATH_PROTOCOL *VarConout;
+ EFI_DEVICE_PATH_PROTOCOL *VarConin;
+
+ //
+ // Connect RootBridge
+ //
+ GetEfiGlobalVariable2 (EFI_CON_OUT_VARIABLE_NAME, (VOID **) &VarConout, NULL);
+ GetEfiGlobalVariable2 (EFI_CON_IN_VARIABLE_NAME, (VOID **) &VarConin, NULL);
+
+ if (VarConout == NULL || VarConin == NULL) {
+ //
+ // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
+ //
+ DetectAndPreparePlatformPciDevicePaths (FALSE);
+ DetectAndPreparePlatformPciDevicePaths(TRUE);
+ //
+ // Have chance to connect the platform default console,
+ // the platform default console is the minimue device group
+ // the platform should support
+ //
+ for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {
+ //
+ // Update the console variable with the connect type
+ //
+ if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
+ EfiBootManagerUpdateConsoleVariable (ConIn, PlatformConsole[Index].DevicePath, NULL);
+ }
+ if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
+ EfiBootManagerUpdateConsoleVariable (ConOut, PlatformConsole[Index].DevicePath, NULL);
+ }
+ if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
+ EfiBootManagerUpdateConsoleVariable (ErrOut, PlatformConsole[Index].DevicePath, NULL);
+ }
+ }
+ } else {
+ //
+ // Only detect VGA device and add them to ConOut
+ //
+ DetectAndPreparePlatformPciDevicePaths (TRUE);
+ }
+}
+
+
+/**
+ Configure PCI Interrupt Line register for applicable devices
+ Ported from SeaBIOS, src/fw/pciinit.c, *_pci_slot_get_irq()
+
+ @param[in] Handle - Handle of PCI device instance
+ @param[in] PciIo - PCI IO protocol instance
+ @param[in] PciHdr - PCI Header register block
+
+ @retval EFI_SUCCESS - PCI Interrupt Line register configured successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+SetPciIntLine (
+ IN EFI_HANDLE Handle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN PCI_TYPE00 *PciHdr
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+ UINTN RootSlot;
+ UINTN Idx;
+ UINT8 IrqLine;
+ EFI_STATUS Status;
+ UINT32 RootBusNumber;
+
+ Status = EFI_SUCCESS;
+
+ if (PciHdr->Device.InterruptPin != 0) {
+
+ DevPathNode = DevicePathFromHandle (Handle);
+ ASSERT (DevPathNode != NULL);
+ DevPath = DevPathNode;
+
+ RootBusNumber = 0;
+ if (DevicePathType (DevPathNode) == ACPI_DEVICE_PATH &&
+ DevicePathSubType (DevPathNode) == ACPI_DP &&
+ ((ACPI_HID_DEVICE_PATH *)DevPathNode)->HID == EISA_PNP_ID(0x0A03)) {
+ RootBusNumber = ((ACPI_HID_DEVICE_PATH *)DevPathNode)->UID;
+ }
+
+ //
+ // Compute index into PciHostIrqs[] table by walking
+ // the device path and adding up all device numbers
+ //
+ Status = EFI_NOT_FOUND;
+ RootSlot = 0;
+ Idx = PciHdr->Device.InterruptPin - 1;
+ while (!IsDevicePathEnd (DevPathNode)) {
+ if (DevicePathType (DevPathNode) == HARDWARE_DEVICE_PATH &&
+ DevicePathSubType (DevPathNode) == HW_PCI_DP) {
+
+ Idx += ((PCI_DEVICE_PATH *)DevPathNode)->Device;
+
+ //
+ // Unlike SeaBIOS, which starts climbing from the leaf device
+ // up toward the root, we traverse the device path starting at
+ // the root moving toward the leaf node.
+ // The slot number of the top-level parent bridge is needed
+ // with more than 24 slots on the root bus.
+ //
+ if (Status != EFI_SUCCESS) {
+ Status = EFI_SUCCESS;
+ RootSlot = ((PCI_DEVICE_PATH *)DevPathNode)->Device;
+ }
+ }
+
+ DevPathNode = NextDevicePathNode (DevPathNode);
+ }
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ if (RootBusNumber == 0 && RootSlot == 0) {
+ return Status; //bugbug: workaround; need SIMICS change B0/D0/F0 PCI_IntPin reg(0x3D) = 0X0
+// DEBUG((
+// EFI_D_ERROR,
+// "%a: PCI host bridge (00:00.0) should have no interrupts!\n",
+// __FUNCTION__
+// ));
+// ASSERT (FALSE);
+ }
+
+ //
+ // Final PciHostIrqs[] index calculation depends on the platform
+ // and should match SeaBIOS src/fw/pciinit.c *_pci_slot_get_irq()
+ //
+ switch (mHostBridgeDevId) {
+ case INTEL_82441_DEVICE_ID:
+ Idx -= 1;
+ break;
+ case INTEL_ICH10_DEVICE_ID:
+ //
+ // SeaBIOS contains the following comment:
+ // "Slots 0-24 rotate slot:pin mapping similar to piix above, but
+ // with a different starting index.
+ //
+ // Slots 25-31 all use LNKA mapping (or LNKE, but A:D = E:H)"
+ //
+ if (RootSlot > 24) {
+ //
+ // in this case, subtract back out RootSlot from Idx
+ // (SeaBIOS never adds it to begin with, but that would make our
+ // device path traversal loop above too awkward)
+ //
+ Idx -= RootSlot;
+ }
+ break;
+ default:
+ ASSERT (FALSE); // should never get here
+ }
+ Idx %= ARRAY_SIZE (PciHostIrqs);
+ IrqLine = PciHostIrqs[Idx];
+
+ DEBUG_CODE_BEGIN ();
+ {
+ CHAR16 *DevPathString;
+ STATIC CHAR16 Fallback[] = L"<failed to convert>";
+ UINTN Segment, Bus, Device, Function;
+
+ DevPathString = ConvertDevicePathToText (DevPath, FALSE, FALSE);
+ if (DevPathString == NULL) {
+ DevPathString = Fallback;
+ }
+ Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_VERBOSE, "%a: [%02x:%02x.%x] %s -> 0x%02x\n", __FUNCTION__,
+ (UINT32)Bus, (UINT32)Device, (UINT32)Function, DevPathString,
+ IrqLine));
+
+ if (DevPathString != Fallback) {
+ FreePool (DevPathString);
+ }
+ }
+ DEBUG_CODE_END ();
+
+ //
+ // Set PCI Interrupt Line register for this device to PciHostIrqs[Idx]
+ //
+ Status = PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint8,
+ PCI_INT_LINE_OFFSET,
+ 1,
+ &IrqLine
+ );
+ }
+
+ return Status;
+}
+
+/**
+Write to mask and edge/level triggered registers of master and slave 8259 PICs.
+
+@param[in] Mask low byte for master PIC mask register,
+high byte for slave PIC mask register.
+@param[in] EdgeLevel low byte for master PIC edge/level triggered register,
+high byte for slave PIC edge/level triggered register.
+
+**/
+VOID
+Interrupt8259WriteMask(
+ IN UINT16 Mask,
+ IN UINT16 EdgeLevel
+)
+{
+ IoWrite8(LEGACY_8259_MASK_REGISTER_MASTER, (UINT8)Mask);
+ IoWrite8(LEGACY_8259_MASK_REGISTER_SLAVE, (UINT8)(Mask >> 8));
+ IoWrite8(LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER, (UINT8)EdgeLevel);
+ IoWrite8(LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE, (UINT8)(EdgeLevel >> 8));
+}
+
+VOID
+PciAcpiInitialization (
+ )
+{
+ UINTN Pmba;
+
+ //
+ // Query Host Bridge DID to determine platform type
+ //
+ mHostBridgeDevId = PcdGet16 (PcdSimicsX58HostBridgePciDevId);
+ switch (mHostBridgeDevId) {
+ case INTEL_82441_DEVICE_ID:
+ Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
+ //
+ // 00:01.0 ISA Bridge (PIIX4) LNK routing targets
+ //
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // A
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // B
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // C
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // D
+ break;
+ case INTEL_ICH10_DEVICE_ID:
+ Pmba = POWER_MGMT_REGISTER_ICH10 (ICH10_PMBASE);
+ //
+ // 00:1f.0 LPC Bridge LNK routing targets
+ //
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x60), 0x0a); // A
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x61), 0x0a); // B
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x62), 0x0b); // C
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x63), 0x0b); // D
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x68), 0x0a); // E
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x69), 0x0a); // F
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6a), 0x0b); // G
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), 0x0b); // H
+ break;
+ default:
+ DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
+ __FUNCTION__, mHostBridgeDevId));
+ ASSERT (FALSE);
+ return;
+ }
+
+ //
+ // Initialize PCI_INTERRUPT_LINE for applicable present PCI devices
+ //
+ VisitAllPciInstances (SetPciIntLine);
+
+ //
+ // Set ACPI SCI_EN bit in PMCNTRL
+ //
+ IoOr16 ((PciRead32 (Pmba) & ~BIT0) + 4, BIT0);
+ //
+ // Set all 8259 interrupts to edge triggered and disabled
+ //
+ Interrupt8259WriteMask(0xFFFF, 0x0000);
+}
+
+EFI_STATUS
+EFIAPI
+ConnectRecursivelyIfPciMassStorage (
+ IN EFI_HANDLE Handle,
+ IN EFI_PCI_IO_PROTOCOL *Instance,
+ IN PCI_TYPE00 *PciHeader
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ CHAR16 *DevPathStr;
+
+ //
+ // Recognize PCI Mass Storage
+ //
+ if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE)) {
+ DevicePath = NULL;
+ Status = gBS->HandleProtocol (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID*)&DevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Print Device Path
+ //
+ DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
+ if (DevPathStr != NULL) {
+ DEBUG((
+ EFI_D_INFO,
+ "Found Mass Storage device: %s\n",
+ DevPathStr
+ ));
+ FreePool(DevPathStr);
+ }
+
+ Status = gBS->ConnectController (Handle, NULL, NULL, TRUE);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This notification function is invoked when the
+ EMU Variable FVB has been changed.
+
+ @param Event The event that occurred
+ @param Context For EFI compatibility. Not used.
+
+**/
+VOID
+EFIAPI
+EmuVariablesUpdatedCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ DEBUG ((EFI_D_INFO, "EmuVariablesUpdatedCallback\n"));
+ UpdateNvVarsOnFileSystem ();
+}
+
+
+EFI_STATUS
+EFIAPI
+VisitingFileSystemInstance (
+ IN EFI_HANDLE Handle,
+ IN VOID *Instance,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ STATIC BOOLEAN ConnectedToFileSystem = FALSE;
+
+ if (ConnectedToFileSystem) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ Status = ConnectNvVarsToFileSystem (Handle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ConnectedToFileSystem = TRUE;
+ mEmuVariableEvent =
+ EfiCreateProtocolNotifyEvent (
+ &gEfiDevicePathProtocolGuid,
+ TPL_CALLBACK,
+ EmuVariablesUpdatedCallback,
+ NULL,
+ &mEmuVariableEventReg
+ );
+ PcdSet64 (PcdEmuVariableEvent, (UINT64)(UINTN) mEmuVariableEvent);
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+PlatformBdsRestoreNvVarsFromHardDisk (
+ )
+{
+ VisitAllPciInstances (ConnectRecursivelyIfPciMassStorage);
+ VisitAllInstancesOfProtocol (
+ &gEfiSimpleFileSystemProtocolGuid,
+ VisitingFileSystemInstance,
+ NULL
+ );
+
+}
+
+/**
+ Connect with predefined platform connect sequence.
+
+ The OEM/IBV can customize with their own connect sequence.
+**/
+VOID
+PlatformBdsConnectSequence (
+ VOID
+ )
+{
+ UINTN Index;
+
+ DEBUG ((EFI_D_INFO, "PlatformBdsConnectSequence\n"));
+
+ Index = 0;
+
+ //
+ // Here we can get the customized platform connect sequence
+ // Notes: we can connect with new variable which record the
+ // last time boots connect device path sequence
+ //
+ while (gPlatformConnectSequence[Index] != NULL) {
+ //
+ // Build the platform boot option
+ //
+ EfiBootManagerConnectDevicePath (gPlatformConnectSequence[Index], NULL);
+ Index++;
+ }
+
+ //
+ // Just use the simple policy to connect all devices
+ //
+ DEBUG ((EFI_D_INFO, "EfiBootManagerConnectAll\n"));
+ EfiBootManagerConnectAll ();
+
+ PciAcpiInitialization ();
+}
+
+/**
+ Save the S3 boot script.
+
+ Note that DxeSmmReadyToLock must be signaled after this function returns;
+ otherwise the script wouldn't be saved actually.
+**/
+STATIC
+VOID
+SaveS3BootScript (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_S3_SAVE_STATE_PROTOCOL *BootScript;
+ STATIC CONST UINT8 Info[] = { 0xDE, 0xAD, 0xBE, 0xEF };
+
+ Status = gBS->LocateProtocol (&gEfiS3SaveStateProtocolGuid, NULL,
+ (VOID **) &BootScript);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Despite the opcode documentation in the PI spec, the protocol
+ // implementation embeds a deep copy of the info in the boot script, rather
+ // than storing just a pointer to runtime or NVS storage.
+ //
+ Status = BootScript->Write(BootScript, EFI_BOOT_SCRIPT_INFORMATION_OPCODE,
+ (UINT32) sizeof Info,
+ (EFI_PHYSICAL_ADDRESS)(UINTN) &Info);
+ ASSERT_EFI_ERROR (Status);
+}
+
+
+/**
+ Do the platform specific action after the console is ready
+
+ Possible things that can be done in PlatformBootManagerAfterConsole:
+
+ > Console post action:
+ > Dynamically switch output mode from 100x31 to 80x25 for certain senarino
+ > Signal console ready platform customized event
+ > Run diagnostics like memory testing
+ > Connect certain devices
+ > Dispatch aditional option roms
+ > Special boot: e.g.: USB boot, enter UI
+**/
+VOID
+EFIAPI
+PlatformBootManagerAfterConsole (
+ VOID
+ )
+{
+ EFI_BOOT_MODE BootMode;
+ EFI_HANDLE Handle;
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_INFO, "PlatformBootManagerAfterConsole\n"));
+
+ //
+ // Prevent further changes to LockBoxes or SMRAM.
+ //
+ Handle = NULL;
+ Status = gBS->InstallProtocolInterface(&Handle,
+ &gEfiDxeSmmReadyToLockProtocolGuid, EFI_NATIVE_INTERFACE,
+ NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ if (PcdGetBool (PcdOvmfFlashVariablesEnable)) {
+ DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior: not restoring NvVars "
+ "from disk since flash variables appear to be supported.\n"));
+ } else {
+ //
+ // Try to restore variables from the hard disk early so
+ // they can be used for the other BDS connect operations.
+ //
+ PlatformBdsRestoreNvVarsFromHardDisk ();
+ }
+
+ //
+ // Get current Boot Mode
+ //
+ BootMode = GetBootModeHob ();
+ DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode));
+
+ //
+ // Go the different platform policy with different boot mode
+ // Notes: this part code can be change with the table policy
+ //
+ ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);
+
+ // Perform some platform specific connect sequence
+ //
+ PlatformBdsConnectSequence ();
+ //
+ // Logo show
+ //
+ EnableBootLogo(PcdGetPtr(PcdLogoFile));
+
+ EfiBootManagerRefreshAllBootOption ();
+
+ //
+ // Register UEFI Shell
+ //
+ PlatformRegisterFvBootOption (
+ PcdGetPtr (PcdShellFile), L"EFI Internal Shell", LOAD_OPTION_ACTIVE
+ );
+
+ RemoveStaleFvFileOptions ();
+}
+
+/**
+ This notification function is invoked when an instance of the
+ EFI_DEVICE_PATH_PROTOCOL is produced.
+
+ @param Event The event that occurred
+ @param Context For EFI compatibility. Not used.
+
+**/
+VOID
+EFIAPI
+NotifyDevPath (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_HANDLE Handle;
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
+ ATAPI_DEVICE_PATH *Atapi;
+
+ //
+ // Examine all new handles
+ //
+ for (;;) {
+ //
+ // Get the next handle
+ //
+ BufferSize = sizeof (Handle);
+ Status = gBS->LocateHandle (
+ ByRegisterNotify,
+ NULL,
+ mEfiDevPathNotifyReg,
+ &BufferSize,
+ &Handle
+ );
+
+ //
+ // If not found, we're done
+ //
+ if (EFI_NOT_FOUND == Status) {
+ break;
+ }
+
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ //
+ // Get the DevicePath protocol on that handle
+ //
+ Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevPathNode);
+ ASSERT_EFI_ERROR (Status);
+
+ while (!IsDevicePathEnd (DevPathNode)) {
+ //
+ // Find the handler to dump this device path node
+ //
+ if (
+ (DevicePathType(DevPathNode) == MESSAGING_DEVICE_PATH) &&
+ (DevicePathSubType(DevPathNode) == MSG_ATAPI_DP)
+ ) {
+ Atapi = (ATAPI_DEVICE_PATH*) DevPathNode;
+ PciOr16 (
+ PCI_LIB_ADDRESS (
+ 0,
+ 1,
+ 1,
+ (Atapi->PrimarySecondary == 1) ? 0x42: 0x40
+ ),
+ BIT15
+ );
+ }
+
+ //
+ // Next device path node
+ //
+ DevPathNode = NextDevicePathNode (DevPathNode);
+ }
+ }
+
+ return;
+}
+
+
+VOID
+InstallDevicePathCallback (
+ VOID
+ )
+{
+ DEBUG ((EFI_D_INFO, "Registered NotifyDevPath Event\n"));
+ mEfiDevPathEvent = EfiCreateProtocolNotifyEvent (
+ &gEfiDevicePathProtocolGuid,
+ TPL_CALLBACK,
+ NotifyDevPath,
+ NULL,
+ &mEfiDevPathNotifyReg
+ );
+}
+
+/**
+ This function is called each second during the boot manager waits the
+ timeout.
+
+ @param TimeoutRemain The remaining timeout.
+**/
+VOID
+EFIAPI
+PlatformBootManagerWaitCallback (
+ UINT16 TimeoutRemain
+ )
+{
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White;
+ UINT16 Timeout;
+
+ Timeout = PcdGet16 (PcdPlatformBootTimeOut);
+
+ Black.Raw = 0x00000000;
+ White.Raw = 0x00FFFFFF;
+
+ BootLogoUpdateProgress (
+ White.Pixel,
+ Black.Pixel,
+ L"Start boot option",
+ White.Pixel,
+ (Timeout - TimeoutRemain) * 100 / Timeout,
+ 0
+ );
+}
+
+/**
+ The function is called when no boot option could be launched,
+ including platform recovery options and options pointing to applications
+ built into firmware volumes.
+
+ If this function returns, BDS attempts to enter an infinite loop.
+**/
+VOID
+EFIAPI
+PlatformBootManagerUnableToBoot (
+ VOID
+ )
+{
+ // BUGBUG- will do it if need
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/PlatformData.c b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/PlatformData.c
new file mode 100644
index 0000000000..768843a8bf
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/PlatformData.c
@@ -0,0 +1,35 @@
+/** @file
+ Defined the platform specific device path which will be used by
+ platform Bbd to perform the platform policy connect.
+
+ Copyright (c) 2004 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BdsPlatform.h"
+
+ACPI_HID_DEVICE_PATH gPnpPs2KeyboardDeviceNode = gPnpPs2Keyboard;
+ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode = gPnp16550ComPort;
+UART_DEVICE_PATH gUartDeviceNode = gUart;
+VENDOR_DEVICE_PATH gTerminalTypeDeviceNode = gPcAnsiTerminal;
+
+//
+// Platform specific keyboard device path
+//
+
+//
+// Predefined platform default console device path
+//
+PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[] = {
+ {
+ NULL,
+ 0
+ }
+};
+
+//
+// Predefined platform connect sequence
+//
+EFI_DEVICE_PATH_PROTOCOL *gPlatformConnectSequence[] = { NULL };
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c
new file mode 100644
index 0000000000..be619c838a
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c
@@ -0,0 +1,869 @@
+/** @file
+ Serialize Variables Library implementation
+
+ Copyright (c) 2004 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SerializeVariablesLib.h"
+
+/**
+ Serialization format:
+
+ The SerializeVariablesLib interface does not specify a format
+ for the serialization of the variable data. This library uses
+ a packed array of a non-uniformly sized data structure elements.
+
+ Each variable is stored (packed) as:
+ UINT32 VendorNameSize; // Name size in bytes
+ CHAR16 VendorName[?]; // The variable unicode name including the
+ // null terminating character.
+ EFI_GUID VendorGuid; // The variable GUID
+ UINT32 DataSize; // The size of variable data in bytes
+ UINT8 Data[?]; // The variable data
+
+**/
+
+
+/**
+ Unpacks the next variable from the buffer
+
+ @param[in] Buffer - Buffer pointing to the next variable instance
+ On subsequent calls, the pointer should be incremented
+ by the returned SizeUsed value.
+ @param[in] MaxSize - Max allowable size for the variable data
+ On subsequent calls, this should be decremented
+ by the returned SizeUsed value.
+ @param[out] Name - Variable name string (address in Buffer)
+ @param[out] NameSize - Size of Name in bytes
+ @param[out] Guid - GUID of variable (address in Buffer)
+ @param[out] Attributes - Attributes of variable
+ @param[out] Data - Buffer containing Data for variable (address in Buffer)
+ @param[out] DataSize - Size of Data in bytes
+ @param[out] SizeUsed - Total size used for this variable instance in Buffer
+
+ @return EFI_STATUS based on the success or failure of the operation
+
+**/
+STATIC
+EFI_STATUS
+UnpackVariableFromBuffer (
+ IN VOID *Buffer,
+ IN UINTN MaxSize,
+ OUT CHAR16 **Name,
+ OUT UINT32 *NameSize,
+ OUT EFI_GUID **Guid,
+ OUT UINT32 *Attributes,
+ OUT UINT32 *DataSize,
+ OUT VOID **Data,
+ OUT UINTN *SizeUsed
+ )
+{
+ UINT8 *BytePtr;
+ UINTN Offset;
+
+ BytePtr = (UINT8*)Buffer;
+ Offset = 0;
+
+ *NameSize = *(UINT32*) (BytePtr + Offset);
+ Offset = Offset + sizeof (UINT32);
+
+ if (Offset > MaxSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Name = (CHAR16*) (BytePtr + Offset);
+ Offset = Offset + *(UINT32*)BytePtr;
+ if (Offset > MaxSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Guid = (EFI_GUID*) (BytePtr + Offset);
+ Offset = Offset + sizeof (EFI_GUID);
+ if (Offset > MaxSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Attributes = *(UINT32*) (BytePtr + Offset);
+ Offset = Offset + sizeof (UINT32);
+ if (Offset > MaxSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *DataSize = *(UINT32*) (BytePtr + Offset);
+ Offset = Offset + sizeof (UINT32);
+ if (Offset > MaxSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Data = (VOID*) (BytePtr + Offset);
+ Offset = Offset + *DataSize;
+ if (Offset > MaxSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *SizeUsed = Offset;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Iterates through the variables in the buffer, and calls a callback
+ function for each variable found.
+
+ @param[in] CallbackFunction - Function called for each variable instance
+ @param[in] Context - Passed to each call of CallbackFunction
+ @param[in] Buffer - Buffer containing serialized variables
+ @param[in] MaxSize - Size of Buffer in bytes
+
+ @return EFI_STATUS based on the success or failure of the operation
+
+**/
+STATIC
+EFI_STATUS
+IterateVariablesInBuffer (
+ IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
+ IN VOID *CallbackContext,
+ IN VOID *Buffer,
+ IN UINTN MaxSize
+ )
+{
+ RETURN_STATUS Status;
+ UINTN TotalSizeUsed;
+ UINTN SizeUsed;
+
+ CHAR16 *Name;
+ UINT32 NameSize;
+ CHAR16 *AlignedName;
+ UINT32 AlignedNameMaxSize;
+ EFI_GUID *Guid;
+ UINT32 Attributes;
+ UINT32 DataSize;
+ VOID *Data;
+
+ SizeUsed = 0;
+ AlignedName = NULL;
+ AlignedNameMaxSize = 0;
+ Name = NULL;
+ Guid = NULL;
+ Attributes = 0;
+ DataSize = 0;
+ Data = NULL;
+
+ for (
+ Status = EFI_SUCCESS, TotalSizeUsed = 0;
+ !EFI_ERROR (Status) && (TotalSizeUsed < MaxSize);
+ ) {
+ Status = UnpackVariableFromBuffer (
+ (VOID*) ((UINT8*) Buffer + TotalSizeUsed),
+ (MaxSize - TotalSizeUsed),
+ &Name,
+ &NameSize,
+ &Guid,
+ &Attributes,
+ &DataSize,
+ &Data,
+ &SizeUsed
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // We copy the name to a separately allocated buffer,
+ // to be sure it is 16-bit aligned.
+ //
+ if (NameSize > AlignedNameMaxSize) {
+ if (AlignedName != NULL) {
+ FreePool (AlignedName);
+ }
+ AlignedName = AllocatePool (NameSize);
+ }
+ if (AlignedName == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CopyMem (AlignedName, Name, NameSize);
+
+ TotalSizeUsed = TotalSizeUsed + SizeUsed;
+
+ //
+ // Run the callback function
+ //
+ Status = (*CallbackFunction) (
+ CallbackContext,
+ AlignedName,
+ Guid,
+ Attributes,
+ DataSize,
+ Data
+ );
+
+ }
+
+ if (AlignedName != NULL) {
+ FreePool (AlignedName);
+ }
+
+ //
+ // Make sure the entire buffer was used, or else return an error
+ //
+ if (TotalSizeUsed != MaxSize) {
+ DEBUG ((
+ EFI_D_ERROR,
+ "Deserialize variables error: TotalSizeUsed(%Lu) != MaxSize(%Lu)\n",
+ (UINT64)TotalSizeUsed,
+ (UINT64)MaxSize
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+STATIC
+RETURN_STATUS
+EFIAPI
+IterateVariablesCallbackNop (
+ IN VOID *Context,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ return RETURN_SUCCESS;
+}
+
+
+STATIC
+RETURN_STATUS
+EFIAPI
+IterateVariablesCallbackSetInInstance (
+ IN VOID *Context,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ EFI_HANDLE Instance;
+
+ Instance = (EFI_HANDLE) Context;
+
+ return SerializeVariablesAddVariable (
+ Instance,
+ VariableName,
+ VendorGuid,
+ Attributes,
+ DataSize,
+ Data
+ );
+}
+
+
+STATIC
+RETURN_STATUS
+EFIAPI
+IterateVariablesCallbackSetSystemVariable (
+ IN VOID *Context,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ EFI_STATUS Status;
+ STATIC CONST UINT32 AuthMask =
+ EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS |
+ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
+
+ Status = gRT->SetVariable (
+ VariableName,
+ VendorGuid,
+ Attributes,
+ DataSize,
+ Data
+ );
+
+ if (Status == EFI_SECURITY_VIOLATION && (Attributes & AuthMask) != 0) {
+ DEBUG ((DEBUG_WARN, "%a: setting authenticated variable \"%s\" "
+ "failed with EFI_SECURITY_VIOLATION, ignoring\n", __FUNCTION__,
+ VariableName));
+ Status = EFI_SUCCESS;
+ } else if (Status == EFI_WRITE_PROTECTED) {
+ DEBUG ((DEBUG_WARN, "%a: setting ReadOnly variable \"%s\" "
+ "failed with EFI_WRITE_PROTECTED, ignoring\n", __FUNCTION__,
+ VariableName));
+ Status = EFI_SUCCESS;
+ }
+ return Status;
+}
+
+
+STATIC
+RETURN_STATUS
+EnsureExtraBufferSpace (
+ IN SV_INSTANCE *Instance,
+ IN UINTN Size
+ )
+{
+ VOID *NewBuffer;
+ UINTN NewSize;
+
+ NewSize = Instance->DataSize + Size;
+ if (NewSize <= Instance->BufferSize) {
+ return RETURN_SUCCESS;
+ }
+
+ //
+ // Double the required size to lessen the need to re-allocate in the future
+ //
+ NewSize = 2 * NewSize;
+
+ NewBuffer = AllocatePool (NewSize);
+ if (NewBuffer == NULL) {
+ return RETURN_OUT_OF_RESOURCES;
+ }
+
+ if (Instance->BufferPtr != NULL) {
+ CopyMem (NewBuffer, Instance->BufferPtr, Instance->DataSize);
+ FreePool (Instance->BufferPtr);
+ }
+
+ Instance->BufferPtr = NewBuffer;
+ Instance->BufferSize = NewSize;
+
+ return RETURN_SUCCESS;
+}
+
+
+STATIC
+VOID
+AppendToBuffer (
+ IN SV_INSTANCE *Instance,
+ IN VOID *Data,
+ IN UINTN Size
+ )
+{
+ UINTN NewSize;
+
+ ASSERT (Instance != NULL);
+ ASSERT (Data != NULL);
+
+ NewSize = Instance->DataSize + Size;
+ ASSERT ((Instance->DataSize + Size) <= Instance->BufferSize);
+
+ CopyMem (
+ (VOID*) (((UINT8*) (Instance->BufferPtr)) + Instance->DataSize),
+ Data,
+ Size
+ );
+
+ Instance->DataSize = NewSize;
+}
+
+
+/**
+ Creates a new variable serialization instance
+
+ @param[out] Handle - Handle for a variable serialization instance
+
+ @retval RETURN_SUCCESS - The variable serialization instance was
+ successfully created.
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ create the variable serialization instance.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesNewInstance (
+ OUT EFI_HANDLE *Handle
+ )
+{
+ SV_INSTANCE *New;
+
+ New = AllocateZeroPool (sizeof (*New));
+ if (New == NULL) {
+ return RETURN_OUT_OF_RESOURCES;
+ }
+
+ New->Signature = SV_SIGNATURE;
+
+ *Handle = (EFI_HANDLE) New;
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Free memory associated with a variable serialization instance
+
+ @param[in] Handle - Handle for a variable serialization instance
+
+ @retval RETURN_SUCCESS - The variable serialization instance was
+ successfully freed.
+ @retval RETURN_INVALID_PARAMETER - Handle was not a valid
+ variable serialization instance.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesFreeInstance (
+ IN EFI_HANDLE Handle
+ )
+{
+ SV_INSTANCE *Instance;
+
+ Instance = SV_FROM_HANDLE (Handle);
+
+ if (Instance->Signature != SV_SIGNATURE) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ Instance->Signature = 0;
+
+ if (Instance->BufferPtr != NULL) {
+ FreePool (Instance->BufferPtr);
+ }
+
+ FreePool (Instance);
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Creates a new variable serialization instance using the given
+ binary representation of the variables to fill the new instance
+
+ @param[out] Handle - Handle for a variable serialization instance
+ @param[in] Buffer - A buffer with the serialized representation
+ of the variables. Must be the same format as produced
+ by SerializeVariablesToBuffer.
+ @param[in] Size - This is the size of the binary representation
+ of the variables.
+
+ @retval RETURN_SUCCESS - The binary representation was successfully
+ imported into a new variable serialization instance
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ create the new variable serialization instance
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesNewInstanceFromBuffer (
+ OUT EFI_HANDLE *Handle,
+ IN VOID *Buffer,
+ IN UINTN Size
+ )
+{
+ RETURN_STATUS Status;
+
+ Status = SerializeVariablesNewInstance (Handle);
+ if (RETURN_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = IterateVariablesInBuffer (
+ IterateVariablesCallbackNop,
+ NULL,
+ Buffer,
+ Size
+ );
+ if (RETURN_ERROR (Status)) {
+ SerializeVariablesFreeInstance (*Handle);
+ return Status;
+ }
+
+ Status = IterateVariablesInBuffer (
+ IterateVariablesCallbackSetInInstance,
+ (VOID*) *Handle,
+ Buffer,
+ Size
+ );
+ if (RETURN_ERROR (Status)) {
+ SerializeVariablesFreeInstance (*Handle);
+ return Status;
+ }
+
+ return Status;
+}
+
+
+/**
+ Iterates all variables found with RuntimeServices GetNextVariableName
+
+ @param[in] CallbackFunction - Function called for each variable instance
+ @param[in] Context - Passed to each call of CallbackFunction
+
+ @retval RETURN_SUCCESS - All variables were iterated without the
+ CallbackFunction returning an error
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ iterate through the variables
+ @return Any of RETURN_ERROR indicates an error reading the variable
+ or an error was returned from CallbackFunction
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesIterateSystemVariables (
+ IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
+ IN VOID *Context
+ )
+{
+ RETURN_STATUS Status;
+ UINTN VariableNameBufferSize;
+ UINTN VariableNameSize;
+ CHAR16 *VariableName;
+ EFI_GUID VendorGuid;
+ UINTN VariableDataBufferSize;
+ UINTN VariableDataSize;
+ VOID *VariableData;
+ UINT32 VariableAttributes;
+ VOID *NewBuffer;
+
+ //
+ // Initialize the variable name and data buffer variables.
+ //
+ VariableNameBufferSize = sizeof (CHAR16);
+ VariableName = AllocateZeroPool (VariableNameBufferSize);
+
+ VariableDataBufferSize = 0;
+ VariableData = NULL;
+
+ for (;;) {
+ //
+ // Get the next variable name and guid
+ //
+ VariableNameSize = VariableNameBufferSize;
+ Status = gRT->GetNextVariableName (
+ &VariableNameSize,
+ VariableName,
+ &VendorGuid
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ //
+ // The currently allocated VariableName buffer is too small,
+ // so we allocate a larger buffer, and copy the old buffer
+ // to it.
+ //
+ NewBuffer = AllocatePool (VariableNameSize);
+ if (NewBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ CopyMem (NewBuffer, VariableName, VariableNameBufferSize);
+ if (VariableName != NULL) {
+ FreePool (VariableName);
+ }
+ VariableName = NewBuffer;
+ VariableNameBufferSize = VariableNameSize;
+
+ //
+ // Try to get the next variable name again with the larger buffer.
+ //
+ Status = gRT->GetNextVariableName (
+ &VariableNameSize,
+ VariableName,
+ &VendorGuid
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_NOT_FOUND) {
+ Status = EFI_SUCCESS;
+ }
+ break;
+ }
+
+ //
+ // Get the variable data and attributes
+ //
+ VariableDataSize = VariableDataBufferSize;
+ Status = gRT->GetVariable (
+ VariableName,
+ &VendorGuid,
+ &VariableAttributes,
+ &VariableDataSize,
+ VariableData
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ //
+ // The currently allocated VariableData buffer is too small,
+ // so we allocate a larger buffer.
+ //
+ if (VariableDataBufferSize != 0) {
+ FreePool (VariableData);
+ VariableData = NULL;
+ VariableDataBufferSize = 0;
+ }
+ VariableData = AllocatePool (VariableDataSize);
+ if (VariableData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ VariableDataBufferSize = VariableDataSize;
+
+ //
+ // Try to read the variable again with the larger buffer.
+ //
+ Status = gRT->GetVariable (
+ VariableName,
+ &VendorGuid,
+ &VariableAttributes,
+ &VariableDataSize,
+ VariableData
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ //
+ // Run the callback function
+ //
+ Status = (*CallbackFunction) (
+ Context,
+ VariableName,
+ &VendorGuid,
+ VariableAttributes,
+ VariableDataSize,
+ VariableData
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ }
+
+ if (VariableName != NULL) {
+ FreePool (VariableName);
+ }
+
+ if (VariableData != NULL) {
+ FreePool (VariableData);
+ }
+
+ return Status;
+}
+
+
+/**
+ Iterates all variables found in the variable serialization instance
+
+ @param[in] Handle - Handle for a variable serialization instance
+ @param[in] CallbackFunction - Function called for each variable instance
+ @param[in] Context - Passed to each call of CallbackFunction
+
+ @retval RETURN_SUCCESS - All variables were iterated without the
+ CallbackFunction returning an error
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ iterate through the variables
+ @return Any of RETURN_ERROR indicates an error reading the variable
+ or an error was returned from CallbackFunction
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesIterateInstanceVariables (
+ IN EFI_HANDLE Handle,
+ IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
+ IN VOID *Context
+ )
+{
+ SV_INSTANCE *Instance;
+
+ Instance = SV_FROM_HANDLE (Handle);
+
+ if ((Instance->BufferPtr != NULL) && (Instance->DataSize != 0)) {
+ return IterateVariablesInBuffer (
+ CallbackFunction,
+ Context,
+ Instance->BufferPtr,
+ Instance->DataSize
+ );
+ } else {
+ return RETURN_SUCCESS;
+ }
+}
+
+
+/**
+ Sets all variables found in the variable serialization instance
+
+ @param[in] Handle - Handle for a variable serialization instance
+
+ @retval RETURN_SUCCESS - All variables were set successfully
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ set all the variables
+ @return Any of RETURN_ERROR indicates an error reading the variables
+ or in attempting to set a variable
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesSetSerializedVariables (
+ IN EFI_HANDLE Handle
+ )
+{
+ return SerializeVariablesIterateInstanceVariables (
+ Handle,
+ IterateVariablesCallbackSetSystemVariable,
+ NULL
+ );
+}
+
+
+/**
+ Adds a variable to the variable serialization instance
+
+ @param[in] Handle - Handle for a variable serialization instance
+ @param[in] VariableName - Refer to RuntimeServices GetVariable
+ @param[in] VendorGuid - Refer to RuntimeServices GetVariable
+ @param[in] Attributes - Refer to RuntimeServices GetVariable
+ @param[in] DataSize - Refer to RuntimeServices GetVariable
+ @param[in] Data - Refer to RuntimeServices GetVariable
+
+ @retval RETURN_SUCCESS - All variables were set successfully
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ add the variable
+ @retval RETURN_INVALID_PARAMETER - Handle was not a valid
+ variable serialization instance or
+ VariableName, VariableGuid or Data are NULL.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesAddVariable (
+ IN EFI_HANDLE Handle,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ RETURN_STATUS Status;
+ SV_INSTANCE *Instance;
+ UINT32 SerializedNameSize;
+ UINT32 SerializedDataSize;
+ UINTN SerializedSize;
+
+ Instance = SV_FROM_HANDLE (Handle);
+
+ if ((Instance->Signature != SV_SIGNATURE) ||
+ (VariableName == NULL) || (VendorGuid == NULL) || (Data == NULL)) {
+ }
+
+ SerializedNameSize = (UINT32) StrSize (VariableName);
+
+ SerializedSize =
+ sizeof (SerializedNameSize) +
+ SerializedNameSize +
+ sizeof (*VendorGuid) +
+ sizeof (Attributes) +
+ sizeof (SerializedDataSize) +
+ DataSize;
+
+ Status = EnsureExtraBufferSpace (
+ Instance,
+ SerializedSize
+ );
+ if (RETURN_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Add name size (UINT32)
+ //
+ AppendToBuffer (Instance, (VOID*) &SerializedNameSize, sizeof (SerializedNameSize));
+
+ //
+ // Add variable unicode name string
+ //
+ AppendToBuffer (Instance, (VOID*) VariableName, SerializedNameSize);
+
+ //
+ // Add variable GUID
+ //
+ AppendToBuffer (Instance, (VOID*) VendorGuid, sizeof (*VendorGuid));
+
+ //
+ // Add variable attributes
+ //
+ AppendToBuffer (Instance, (VOID*) &Attributes, sizeof (Attributes));
+
+ //
+ // Add variable data size (UINT32)
+ //
+ SerializedDataSize = (UINT32) DataSize;
+ AppendToBuffer (Instance, (VOID*) &SerializedDataSize, sizeof (SerializedDataSize));
+
+ //
+ // Add variable data
+ //
+ AppendToBuffer (Instance, Data, DataSize);
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Serializes the variables known to this instance into the
+ provided buffer.
+
+ @param[in] Handle - Handle for a variable serialization instance
+ @param[out] Buffer - A buffer to store the binary representation
+ of the variables.
+ @param[in,out] Size - On input this is the size of the buffer.
+ On output this is the size of the binary representation
+ of the variables.
+
+ @retval RETURN_SUCCESS - The binary representation was successfully
+ completed and returned in the buffer.
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ save the variables to the buffer.
+ @retval RETURN_INVALID_PARAMETER - Handle was not a valid
+ variable serialization instance or
+ Size or Buffer were NULL.
+ @retval RETURN_BUFFER_TOO_SMALL - The Buffer size as indicated by
+ the Size parameter was too small for the serialized
+ variable data. Size is returned with the required size.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesToBuffer (
+ IN EFI_HANDLE Handle,
+ OUT VOID *Buffer,
+ IN OUT UINTN *Size
+ )
+{
+ SV_INSTANCE *Instance;
+
+ Instance = SV_FROM_HANDLE (Handle);
+
+ if (Size == NULL) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ if (*Size < Instance->DataSize) {
+ *Size = Instance->DataSize;
+ return RETURN_BUFFER_TOO_SMALL;
+ }
+
+ if (Buffer == NULL) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ *Size = Instance->DataSize;
+ CopyMem (Buffer, Instance->BufferPtr, Instance->DataSize);
+
+ return RETURN_SUCCESS;
+}
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c
new file mode 100644
index 0000000000..383501898d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c
@@ -0,0 +1,108 @@
+/** @file
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+/**
+ Performs silicon pre-mem policy initialization.
+
+ The meaning of Policy is defined by silicon code.
+ It could be the raw data, a handle, a PPI, etc.
+
+ The returned data must be used as input data for SiliconPolicyDonePreMem(),
+ and SiliconPolicyUpdateLib.SiliconPolicyUpdatePreMem().
+
+ 1) In FSP path, the input Policy should be FspmUpd.
+ Value of FspmUpd has been initialized by FSP binary default value.
+ Only a subset of FspmUpd needs to be updated for different silicon sku.
+ The return data is same FspmUpd.
+
+ 2) In non-FSP path, the input policy could be NULL.
+ The return data is the initialized policy.
+
+ @param[in, out] Policy Pointer to policy.
+
+ @return the initialized policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyInitPreMem (
+ IN OUT VOID *Policy OPTIONAL
+ )
+{
+ return Policy;
+}
+
+/*
+ The silicon pre-mem policy is finalized.
+ Silicon code can do initialization based upon the policy data.
+
+ The input Policy must be returned by SiliconPolicyInitPreMem().
+
+ @param[in] Policy Pointer to policy.
+
+ @retval RETURN_SUCCESS The policy is handled consumed by silicon code.
+*/
+RETURN_STATUS
+EFIAPI
+SiliconPolicyDonePreMem (
+ IN VOID *Policy
+ )
+{
+ return RETURN_SUCCESS;
+}
+
+/**
+ Performs silicon post-mem policy initialization.
+
+ The meaning of Policy is defined by silicon code.
+ It could be the raw data, a handle, a PPI, etc.
+
+ The returned data must be used as input data for SiliconPolicyDonePostMem(),
+ and SiliconPolicyUpdateLib.SiliconPolicyUpdatePostMem().
+
+ 1) In FSP path, the input Policy should be FspsUpd.
+ Value of FspsUpd has been initialized by FSP binary default value.
+ Only a subset of FspsUpd needs to be updated for different silicon sku.
+ The return data is same FspsUpd.
+
+ 2) In non-FSP path, the input policy could be NULL.
+ The return data is the initialized policy.
+
+ @param[in, out] Policy Pointer to policy.
+
+ @return the initialized policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyInitPostMem (
+ IN OUT VOID *Policy OPTIONAL
+ )
+{
+ return Policy;
+}
+
+/*
+ The silicon post-mem policy is finalized.
+ Silicon code can do initialization based upon the policy data.
+
+ The input Policy must be returned by SiliconPolicyInitPostMem().
+
+ @param[in] Policy Pointer to policy.
+
+ @retval RETURN_SUCCESS The policy is handled consumed by silicon code.
+*/
+RETURN_STATUS
+EFIAPI
+SiliconPolicyDonePostMem (
+ IN VOID *Policy
+ )
+{
+ return RETURN_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c
new file mode 100644
index 0000000000..3b207a4e78
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c
@@ -0,0 +1,70 @@
+/** @file
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Library/PeiServicesLib.h>
+
+/**
+ Performs silicon pre-mem policy update.
+
+ The meaning of Policy is defined by silicon code.
+ It could be the raw data, a handle, a PPI, etc.
+
+ The input Policy must be returned by SiliconPolicyDonePreMem().
+
+ 1) In FSP path, the input Policy should be FspmUpd.
+ A platform may use this API to update the FSPM UPD policy initialized
+ by the silicon module or the default UPD data.
+ The output of FSPM UPD data from this API is the final UPD data.
+
+ 2) In non-FSP path, the board may use additional way to get
+ the silicon policy data field based upon the input Policy.
+
+ @param[in, out] Policy Pointer to policy.
+
+ @return the updated policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyUpdatePreMem (
+ IN OUT VOID *Policy
+ )
+{
+ return Policy;
+}
+
+/**
+ Performs silicon post-mem policy update.
+
+ The meaning of Policy is defined by silicon code.
+ It could be the raw data, a handle, a PPI, etc.
+
+ The input Policy must be returned by SiliconPolicyDonePostMem().
+
+ 1) In FSP path, the input Policy should be FspsUpd.
+ A platform may use this API to update the FSPS UPD policy initialized
+ by the silicon module or the default UPD data.
+ The output of FSPS UPD data from this API is the final UPD data.
+
+ 2) In non-FSP path, the board may use additional way to get
+ the silicon policy data field based upon the input Policy.
+
+ @param[in, out] Policy Pointer to policy.
+
+ @return the updated policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyUpdatePostMem (
+ IN OUT VOID *Policy
+ )
+{
+ return Policy;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c b/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c
new file mode 100644
index 0000000000..826fc965c9
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c
@@ -0,0 +1,956 @@
+/** @file
+ Main SEC phase code. Transitions to PEI.
+
+ Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+
+#include <Library/PeimEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiCpuLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/IoLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/PeCoffExtraActionLib.h>
+#include <Library/ExtractGuidedSectionLib.h>
+#include <Library/LocalApicLib.h>
+#include <Library/PciCf8Lib.h>
+
+#include <Ppi/TemporaryRamSupport.h>
+#include <Register/X58Ich10.h>
+
+#define SEC_IDT_ENTRY_COUNT 34
+
+typedef struct _SEC_IDT_TABLE {
+ EFI_PEI_SERVICES *PeiService;
+ IA32_IDT_GATE_DESCRIPTOR IdtTable[SEC_IDT_ENTRY_COUNT];
+} SEC_IDT_TABLE;
+
+VOID
+EFIAPI
+SecStartupPhase2 (
+ IN VOID *Context
+ );
+
+EFI_STATUS
+EFIAPI
+TemporaryRamMigration (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ );
+
+EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
+ TemporaryRamMigration
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiTemporaryRamSupportPpiGuid,
+ &mTemporaryRamSupportPpi
+ },
+};
+
+//
+// Template of an IDT entry pointing to 10:FFFFFFE4h.
+//
+IA32_IDT_GATE_DESCRIPTOR mIdtEntryTemplate = {
+ { // Bits
+ 0xffe4, // OffsetLow
+ 0x10, // Selector
+ 0x0, // Reserved_0
+ IA32_IDT_GATE_TYPE_INTERRUPT_32, // GateType
+ 0xffff // OffsetHigh
+ }
+};
+
+/**
+ Locates the main boot firmware volume.
+
+ @param[in,out] BootFv On input, the base of the BootFv
+ On output, the decompressed main firmware volume
+
+ @retval EFI_SUCCESS The main firmware volume was located and decompressed
+ @retval EFI_NOT_FOUND The main firmware volume was not found
+
+**/
+EFI_STATUS
+FindMainFv (
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv
+ )
+{
+ EFI_FIRMWARE_VOLUME_HEADER *Fv;
+ UINTN Distance;
+
+ ASSERT (((UINTN) *BootFv & EFI_PAGE_MASK) == 0);
+
+ Fv = *BootFv;
+ Distance = (UINTN) (*BootFv)->FvLength;
+ do {
+ Fv = (EFI_FIRMWARE_VOLUME_HEADER*) ((UINT8*) Fv - EFI_PAGE_SIZE);
+ Distance += EFI_PAGE_SIZE;
+ if (Distance > SIZE_32MB) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (Fv->Signature != EFI_FVH_SIGNATURE) {
+ continue;
+ }
+
+ if ((UINTN) Fv->FvLength > Distance) {
+ continue;
+ }
+
+ *BootFv = Fv;
+ return EFI_SUCCESS;
+
+ } while (TRUE);
+}
+
+/**
+ Locates a section within a series of sections
+ with the specified section type.
+
+ The Instance parameter indicates which instance of the section
+ type to return. (0 is first instance, 1 is second...)
+
+ @param[in] Sections The sections to search
+ @param[in] SizeOfSections Total size of all sections
+ @param[in] SectionType The section type to locate
+ @param[in] Instance The section instance number
+ @param[out] FoundSection The FFS section if found
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindFfsSectionInstance (
+ IN VOID *Sections,
+ IN UINTN SizeOfSections,
+ IN EFI_SECTION_TYPE SectionType,
+ IN UINTN Instance,
+ OUT EFI_COMMON_SECTION_HEADER **FoundSection
+ )
+{
+ EFI_PHYSICAL_ADDRESS CurrentAddress;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS EndOfSections;
+ EFI_COMMON_SECTION_HEADER *Section;
+ EFI_PHYSICAL_ADDRESS EndOfSection;
+
+ //
+ // Loop through the FFS file sections within the PEI Core FFS file
+ //
+ EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) Sections;
+ EndOfSections = EndOfSection + SizeOfSections;
+ for (;;) {
+ if (EndOfSection == EndOfSections) {
+ break;
+ }
+ CurrentAddress = (EndOfSection + 3) & ~(3ULL);
+ if (CurrentAddress >= EndOfSections) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
+ DEBUG ((EFI_D_VERBOSE, "Section->Type: 0x%x\n", Section->Type));
+
+ Size = SECTION_SIZE (Section);
+ if (Size < sizeof (*Section)) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ EndOfSection = CurrentAddress + Size;
+ if (EndOfSection > EndOfSections) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ //
+ // Look for the requested section type
+ //
+ if (Section->Type == SectionType) {
+ if (Instance == 0) {
+ *FoundSection = Section;
+ return EFI_SUCCESS;
+ } else {
+ Instance--;
+ }
+ }
+ DEBUG ((EFI_D_VERBOSE, "Section->Type (0x%x) != SectionType (0x%x)\n", Section->Type, SectionType));
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Locates a section within a series of sections
+ with the specified section type.
+
+ @param[in] Sections The sections to search
+ @param[in] SizeOfSections Total size of all sections
+ @param[in] SectionType The section type to locate
+ @param[out] FoundSection The FFS section if found
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindFfsSectionInSections (
+ IN VOID *Sections,
+ IN UINTN SizeOfSections,
+ IN EFI_SECTION_TYPE SectionType,
+ OUT EFI_COMMON_SECTION_HEADER **FoundSection
+ )
+{
+ return FindFfsSectionInstance (
+ Sections,
+ SizeOfSections,
+ SectionType,
+ 0,
+ FoundSection
+ );
+}
+
+/**
+ Locates a FFS file with the specified file type and a section
+ within that file with the specified section type.
+
+ @param[in] Fv The firmware volume to search
+ @param[in] FileType The file type to locate
+ @param[in] SectionType The section type to locate
+ @param[out] FoundSection The FFS section if found
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindFfsFileAndSection (
+ IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
+ IN EFI_FV_FILETYPE FileType,
+ IN EFI_SECTION_TYPE SectionType,
+ OUT EFI_COMMON_SECTION_HEADER **FoundSection
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS CurrentAddress;
+ EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
+ EFI_FFS_FILE_HEADER *File;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS EndOfFile;
+
+ if (Fv->Signature != EFI_FVH_SIGNATURE) {
+ DEBUG ((EFI_D_ERROR, "FV at %p does not have FV header signature\n", Fv));
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Fv;
+ EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
+
+ //
+ // Loop through the FFS files in the Boot Firmware Volume
+ //
+ for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
+
+ CurrentAddress = (EndOfFile + 7) & ~(7ULL);
+ if (CurrentAddress > EndOfFirmwareVolume) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
+ Size = *(UINT32*) File->Size & 0xffffff;
+ if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+ DEBUG ((EFI_D_VERBOSE, "File->Type: 0x%x\n", File->Type));
+
+ EndOfFile = CurrentAddress + Size;
+ if (EndOfFile > EndOfFirmwareVolume) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ //
+ // Look for the request file type
+ //
+ if (File->Type != FileType) {
+ DEBUG ((EFI_D_VERBOSE, "File->Type (0x%x) != FileType (0x%x)\n", File->Type, FileType));
+ continue;
+ }
+
+ Status = FindFfsSectionInSections (
+ (VOID*) (File + 1),
+ (UINTN) EndOfFile - (UINTN) (File + 1),
+ SectionType,
+ FoundSection
+ );
+ if (!EFI_ERROR (Status) || (Status == EFI_VOLUME_CORRUPTED)) {
+ return Status;
+ }
+ }
+}
+
+/**
+ Locates the compressed main firmware volume and decompresses it.
+
+ @param[in,out] Fv On input, the firmware volume to search
+ On output, the decompressed BOOT/PEI FV
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+EFI_STATUS
+DecompressMemFvs (
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **Fv
+ )
+{
+ EFI_STATUS Status;
+ EFI_GUID_DEFINED_SECTION *Section;
+ UINT32 OutputBufferSize;
+ UINT32 ScratchBufferSize;
+ UINT16 SectionAttribute;
+ UINT32 AuthenticationStatus;
+ VOID *OutputBuffer;
+ VOID *ScratchBuffer;
+ EFI_COMMON_SECTION_HEADER *FvSection;
+ EFI_FIRMWARE_VOLUME_HEADER *PeiMemFv;
+ EFI_FIRMWARE_VOLUME_HEADER *DxeMemFv;
+ UINT32 FvHeaderSize;
+ UINT32 FvSectionSize;
+
+ FvSection = (EFI_COMMON_SECTION_HEADER*) NULL;
+
+ DEBUG ((EFI_D_VERBOSE, "Find and decompress FV image.\n"));
+ Status = FindFfsFileAndSection (
+ *Fv,
+ EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
+ EFI_SECTION_GUID_DEFINED,
+ (EFI_COMMON_SECTION_HEADER**) &Section
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to find GUID defined section\n"));
+ return Status;
+ }
+
+ Status = ExtractGuidedSectionGetInfo (
+ Section,
+ &OutputBufferSize,
+ &ScratchBufferSize,
+ &SectionAttribute
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to GetInfo for GUIDed section\n"));
+ return Status;
+ }
+
+ OutputBuffer = (VOID*) ((UINT8*)(UINTN) PcdGet32 (PcdSimicsDxeMemFvBase) + SIZE_1MB);
+ ScratchBuffer = ALIGN_POINTER ((UINT8*) OutputBuffer + OutputBufferSize, SIZE_1MB);
+
+ DEBUG ((EFI_D_VERBOSE, "PcdSimicsDxeMemFvBase: 0x%x\n", PcdGet32 (PcdSimicsDxeMemFvBase)));
+ DEBUG ((EFI_D_VERBOSE, "OutputBuffer: 0x%x\n", OutputBuffer));
+ DEBUG ((EFI_D_VERBOSE, "OutputBufferSize: 0x%x\n", OutputBufferSize));
+ DEBUG ((EFI_D_VERBOSE, "ScratchBuffer: 0x%x\n", ScratchBuffer));
+ DEBUG ((EFI_D_VERBOSE, "ScratchBufferSize: 0x%x\n", ScratchBufferSize));
+ DEBUG ((EFI_D_VERBOSE, "PcdSimicsDecompressionScratchEnd: 0x%x\n", PcdGet32 (PcdSimicsDecompressionScratchEnd)));
+
+ DEBUG ((EFI_D_VERBOSE, "%a: OutputBuffer@%p+0x%x ScratchBuffer@%p+0x%x "
+ "PcdSimicsDecompressionScratchEnd=0x%x\n", __FUNCTION__, OutputBuffer,
+ OutputBufferSize, ScratchBuffer, ScratchBufferSize,
+ PcdGet32 (PcdSimicsDecompressionScratchEnd)));
+ ASSERT ((UINTN)ScratchBuffer + ScratchBufferSize ==
+ PcdGet32 (PcdSimicsDecompressionScratchEnd));
+
+ Status = ExtractGuidedSectionDecode (
+ Section,
+ &OutputBuffer,
+ ScratchBuffer,
+ &AuthenticationStatus
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Error during GUID section decode\n"));
+ return Status;
+ }
+
+ Status = FindFfsSectionInstance (
+ OutputBuffer,
+ OutputBufferSize,
+ EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
+ 0,
+ &FvSection
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to find PEI FV section\n"));
+ return Status;
+ }
+
+ ASSERT (SECTION_SIZE (FvSection) ==
+ (PcdGet32 (PcdSimicsPeiMemFvSize) + sizeof (*FvSection)));
+ ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
+
+ PeiMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdSimicsPeiMemFvBase);
+ CopyMem (PeiMemFv, (VOID*) (FvSection + 1), PcdGet32 (PcdSimicsPeiMemFvSize));
+
+ if (PeiMemFv->Signature != EFI_FVH_SIGNATURE) {
+ DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", PeiMemFv));
+ CpuDeadLoop ();
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ Status = FindFfsSectionInstance (
+ OutputBuffer,
+ OutputBufferSize,
+ EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
+ 1,
+ &FvSection
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to find DXE FV section\n"));
+ return Status;
+ }
+
+ ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
+
+ if (IS_SECTION2 (FvSection)) {
+ FvSectionSize = SECTION2_SIZE (FvSection);
+ FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);
+ } else {
+ FvSectionSize = SECTION_SIZE (FvSection);
+ FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);
+ }
+
+ ASSERT (FvSectionSize == (PcdGet32 (PcdSimicsDxeMemFvSize) + FvHeaderSize));
+
+ DxeMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdSimicsDxeMemFvBase);
+ CopyMem (DxeMemFv, (VOID*) ((UINTN)FvSection + FvHeaderSize), PcdGet32 (PcdSimicsDxeMemFvSize));
+
+ if (DxeMemFv->Signature != EFI_FVH_SIGNATURE) {
+ DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", DxeMemFv));
+ CpuDeadLoop ();
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ *Fv = PeiMemFv;
+ return EFI_SUCCESS;
+}
+
+/**
+ Locates the PEI Core entry point address
+
+ @param[in] Fv The firmware volume to search
+ @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindPeiCoreImageBaseInFv (
+ IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
+ OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
+ )
+{
+ EFI_STATUS Status;
+ EFI_COMMON_SECTION_HEADER *Section;
+
+ DEBUG ((EFI_D_VERBOSE, "Find PEI Core image.\n"));
+ Status = FindFfsFileAndSection (
+ Fv,
+ EFI_FV_FILETYPE_PEI_CORE,
+ EFI_SECTION_PE32,
+ &Section
+ );
+ if (EFI_ERROR (Status)) {
+ Status = FindFfsFileAndSection (
+ Fv,
+ EFI_FV_FILETYPE_PEI_CORE,
+ EFI_SECTION_TE,
+ &Section
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to find PEI Core image\n"));
+ return Status;
+ }
+ }
+
+ *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);
+ DEBUG ((EFI_D_VERBOSE, "PEI core image base 0x%016LX.\n", *PeiCoreImageBase));
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Reads 8-bits of CMOS data.
+
+ Reads the 8-bits of CMOS data at the location specified by Index.
+ The 8-bit read value is returned.
+
+ @param Index The CMOS location to read.
+
+ @return The value read.
+
+**/
+STATIC
+UINT8
+CmosRead8 (
+ IN UINTN Index
+ )
+{
+ IoWrite8 (0x70, (UINT8) Index);
+ return IoRead8 (0x71);
+}
+
+
+STATIC
+BOOLEAN
+IsS3Resume (
+ VOID
+ )
+{
+ DEBUG((EFI_D_VERBOSE, "modeValue = %x\n", IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12)));
+ return (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) == 0x5);
+}
+
+
+STATIC
+EFI_STATUS
+GetS3ResumePeiFv (
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **PeiFv
+ )
+{
+ *PeiFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdSimicsPeiMemFvBase);
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Locates the PEI Core entry point address
+
+ @param[in,out] Fv The firmware volume to search
+ @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+VOID
+FindPeiCoreImageBase (
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv,
+ OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
+ )
+{
+ BOOLEAN S3Resume;
+
+ *PeiCoreImageBase = 0;
+
+ S3Resume = IsS3Resume ();
+ if (S3Resume && !FeaturePcdGet (PcdSmmSmramRequire)) {
+ //
+ // A malicious runtime OS may have injected something into our previously
+ // decoded PEI FV, but we don't care about that unless SMM/SMRAM is required.
+ //
+ DEBUG ((EFI_D_VERBOSE, "SEC: S3 resume\n"));
+ GetS3ResumePeiFv (BootFv);
+ } else {
+ //
+ // We're either not resuming, or resuming "securely" -- we'll decompress
+ // both PEI FV and DXE FV from pristine flash.
+ //
+ DEBUG ((EFI_D_VERBOSE, "SEC: %a\n",
+ S3Resume ? "S3 resume (with PEI decompression)" : "Normal boot"));
+ FindMainFv (BootFv);
+
+ DecompressMemFvs (BootFv);
+ }
+
+ FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);
+}
+
+/**
+ Find core image base.
+
+**/
+EFI_STATUS
+FindImageBase (
+ IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,
+ OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase
+ )
+{
+ EFI_PHYSICAL_ADDRESS CurrentAddress;
+ EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
+ EFI_FFS_FILE_HEADER *File;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS EndOfFile;
+ EFI_COMMON_SECTION_HEADER *Section;
+ EFI_PHYSICAL_ADDRESS EndOfSection;
+
+ *SecCoreImageBase = 0;
+
+ CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) BootFirmwareVolumePtr;
+ EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr->FvLength;
+
+ //
+ // Loop through the FFS files in the Boot Firmware Volume
+ //
+ for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; ) {
+
+ CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
+ if (CurrentAddress > EndOfFirmwareVolume) {
+ return EFI_NOT_FOUND;
+ }
+
+ File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
+ Size = *(UINT32*) File->Size & 0xffffff;
+ if (Size < sizeof (*File)) {
+ return EFI_NOT_FOUND;
+ }
+
+ EndOfFile = CurrentAddress + Size;
+ if (EndOfFile > EndOfFirmwareVolume) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Look for SEC Core
+ //
+ if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE) {
+ continue;
+ }
+
+ //
+ // Loop through the FFS file sections within the FFS file
+ //
+ EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) (File + 1);
+ for (;;) {
+ CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL;
+ Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
+
+ Size = *(UINT32*) Section->Size & 0xffffff;
+ if (Size < sizeof (*Section)) {
+ return EFI_NOT_FOUND;
+ }
+
+ EndOfSection = CurrentAddress + Size;
+ if (EndOfSection > EndOfFile) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Look for executable sections
+ //
+ if (Section->Type == EFI_SECTION_PE32 || Section->Type == EFI_SECTION_TE) {
+ if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) {
+ *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) (Section + 1);
+ }
+ break;
+ }
+ }
+
+ //
+ // SEC Core image found
+ //
+ if (*SecCoreImageBase != 0) {
+ return EFI_SUCCESS;
+ }
+ }
+}
+
+/*
+ Find and return Pei Core entry point.
+
+ It also find SEC and PEI Core file debug information. It will report them if
+ remote debug is enabled.
+
+**/
+VOID
+FindAndReportEntryPoints (
+ IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr,
+ OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS SecCoreImageBase;
+ EFI_PHYSICAL_ADDRESS PeiCoreImageBase;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+
+ //
+ // Find SEC Core and PEI Core image base
+ //
+ Status = FindImageBase (*BootFirmwareVolumePtr, &SecCoreImageBase);
+ ASSERT_EFI_ERROR (Status);
+
+ FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);
+
+ ZeroMem ((VOID *) &ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
+ //
+ // Report SEC Core debug information when remote debug is enabled
+ //
+ ImageContext.ImageAddress = SecCoreImageBase;
+ ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);
+ PeCoffLoaderRelocateImageExtraAction (&ImageContext);
+
+ //
+ // Report PEI Core debug information when remote debug is enabled
+ //
+ ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageBase;
+ ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);
+ PeCoffLoaderRelocateImageExtraAction (&ImageContext);
+
+ //
+ // Find PEI Core entry point
+ //
+ Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, (VOID**) PeiCoreEntryPoint);
+ if (EFI_ERROR (Status)) {
+ *PeiCoreEntryPoint = 0;
+ }
+
+ return;
+}
+
+VOID
+EFIAPI
+SecCoreStartupWithStack (
+ IN EFI_FIRMWARE_VOLUME_HEADER *BootFv,
+ IN VOID *TopOfCurrentStack
+ )
+{
+ EFI_SEC_PEI_HAND_OFF SecCoreData;
+ SEC_IDT_TABLE IdtTableInStack;
+ IA32_DESCRIPTOR IdtDescriptor;
+ UINT32 Index;
+ volatile UINT8 *Table;
+
+ //
+ // Initialize floating point operating environment
+ // to be compliant with UEFI spec.
+ //
+ InitializeFloatingPointUnits ();
+
+ //
+ // Initialize the PCIe Configuration base register.
+ //
+ PciCf8Write32 (PCI_CF8_LIB_ADDRESS (0xFF, 0, 1, 0x50), 0xE0000001);
+
+ //
+ // To ensure SMM can't be compromised on S3 resume, we must force re-init of
+ // the BaseExtractGuidedSectionLib. Since this is before library contructors
+ // are called, we must use a loop rather than SetMem.
+ //
+ Table = (UINT8*)(UINTN)FixedPcdGet64 (PcdGuidedExtractHandlerTableAddress);
+ for (Index = 0;
+ Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize);
+ ++Index) {
+ Table[Index] = 0;
+ }
+
+ ProcessLibraryConstructorList (NULL, NULL);
+
+ DEBUG ((EFI_D_INFO,
+ "SecCoreStartupWithStack(0x%x, 0x%x)\n",
+ (UINT32)(UINTN)BootFv,
+ (UINT32)(UINTN)TopOfCurrentStack
+ ));
+
+ //
+ // Initialize IDT
+ //
+ IdtTableInStack.PeiService = NULL;
+ for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
+ CopyMem (&IdtTableInStack.IdtTable[Index], &mIdtEntryTemplate, sizeof (mIdtEntryTemplate));
+ }
+
+ IdtDescriptor.Base = (UINTN)&IdtTableInStack.IdtTable;
+ IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
+
+ AsmWriteIdtr (&IdtDescriptor);
+
+#if defined (MDE_CPU_X64)
+ //
+ // ASSERT that the Page Tables were set by the reset vector code to
+ // the address we expect.
+ //
+ ASSERT (AsmReadCr3 () == (UINTN) PcdGet32 (PcdSimicsSecPageTablesBase));
+#endif
+
+ //
+ // |-------------| <-- TopOfCurrentStack
+ // | Stack | 32k
+ // |-------------|
+ // | Heap | 32k
+ // |-------------| <-- SecCoreData.TemporaryRamBase
+ //
+
+ ASSERT ((UINTN) (PcdGet32 (PcdSimicsSecPeiTempRamBase) +
+ PcdGet32 (PcdSimicsSecPeiTempRamSize)) ==
+ (UINTN) TopOfCurrentStack);
+
+ //
+ // Initialize SEC hand-off state
+ //
+ SecCoreData.DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
+
+ SecCoreData.TemporaryRamSize = (UINTN) PcdGet32 (PcdSimicsSecPeiTempRamSize);
+ SecCoreData.TemporaryRamBase = (VOID*)((UINT8 *)TopOfCurrentStack - SecCoreData.TemporaryRamSize);
+
+ SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;
+ SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize >> 1;
+
+ SecCoreData.StackBase = (UINT8 *)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize;
+ SecCoreData.StackSize = SecCoreData.TemporaryRamSize >> 1;
+
+ SecCoreData.BootFirmwareVolumeBase = BootFv;
+ SecCoreData.BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
+
+ //
+ // Make sure the 8259 is masked before initializing the Debug Agent and the debug timer is enabled
+ //
+ IoWrite8 (0x21, 0xff);
+ IoWrite8 (0xA1, 0xff);
+
+ //
+ // Initialize Local APIC Timer hardware and disable Local APIC Timer
+ // interrupts before initializing the Debug Agent and the debug timer is
+ // enabled.
+ //
+ InitializeApicTimer (0, MAX_UINT32, TRUE, 5);
+ DisableApicTimerInterrupt ();
+
+ //
+ // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.
+ //
+ InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2);
+}
+
+/**
+ Caller provided function to be invoked at the end of InitializeDebugAgent().
+
+ Entry point to the C language phase of SEC. After the SEC assembly
+ code has initialized some temporary memory and set up the stack,
+ the control is transferred to this function.
+
+ @param[in] Context The first input parameter of InitializeDebugAgent().
+
+**/
+VOID
+EFIAPI
+SecStartupPhase2(
+ IN VOID *Context
+ )
+{
+ EFI_SEC_PEI_HAND_OFF *SecCoreData;
+ EFI_FIRMWARE_VOLUME_HEADER *BootFv;
+ EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;
+
+ SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context;
+
+ //
+ // Find PEI Core entry point. It will report SEC and Pei Core debug information if remote debug
+ // is enabled.
+ //
+ BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;
+ FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint);
+ SecCoreData->BootFirmwareVolumeBase = BootFv;
+ SecCoreData->BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
+
+ //
+ // Transfer the control to the PEI core
+ //
+ (*PeiCoreEntryPoint) (SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTable);
+
+ //
+ // If we get here then the PEI Core returned, which is not recoverable.
+ //
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+}
+
+EFI_STATUS
+EFIAPI
+TemporaryRamMigration (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ )
+{
+ IA32_DESCRIPTOR IdtDescriptor;
+ VOID *OldHeap;
+ VOID *NewHeap;
+ VOID *OldStack;
+ VOID *NewStack;
+ DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext;
+ BOOLEAN OldStatus;
+ BASE_LIBRARY_JUMP_BUFFER JumpBuffer;
+
+ DEBUG ((EFI_D_INFO,
+ "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",
+ TemporaryMemoryBase,
+ PermanentMemoryBase,
+ (UINT64)CopySize
+ ));
+
+ OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
+ NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));
+
+ OldStack = (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
+ NewStack = (VOID*)(UINTN)PermanentMemoryBase;
+
+ DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap - (UINTN)OldHeap;
+ DebugAgentContext.StackMigrateOffset = (UINTN)NewStack - (UINTN)OldStack;
+
+ OldStatus = SaveAndSetDebugTimerInterrupt (FALSE);
+ InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *) &DebugAgentContext, NULL);
+
+ //
+ // Migrate Heap
+ //
+ CopyMem (NewHeap, OldHeap, CopySize >> 1);
+
+ //
+ // Migrate Stack
+ //
+ CopyMem (NewStack, OldStack, CopySize >> 1);
+
+ //
+ // Rebase IDT table in permanent memory
+ //
+ AsmReadIdtr (&IdtDescriptor);
+ IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;
+
+ AsmWriteIdtr (&IdtDescriptor);
+
+ //
+ // Use SetJump()/LongJump() to switch to a new stack.
+ //
+ if (SetJump (&JumpBuffer) == 0) {
+#if defined (MDE_CPU_IA32)
+ JumpBuffer.Esp = JumpBuffer.Esp + DebugAgentContext.StackMigrateOffset;
+#endif
+#if defined (MDE_CPU_X64)
+ JumpBuffer.Rsp = JumpBuffer.Rsp + DebugAgentContext.StackMigrateOffset;
+#endif
+ LongJump (&JumpBuffer, (UINTN)-1);
+ }
+
+ SaveAndSetDebugTimerInterrupt (OldStatus);
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c
new file mode 100644
index 0000000000..c7b5237bd3
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c
@@ -0,0 +1,865 @@
+/** @file
+ This driver effectuates QSP platform configuration settings and exposes
+ them via HII.
+
+ Copyright (C) 2014, Red Hat, Inc.
+ Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiHiiServicesLib.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/HiiConfigAccess.h>
+#include <Guid/MdeModuleHii.h>
+#include <Guid/SimicsBoardConfig.h>
+
+#include "Platform.h"
+#include "PlatformConfig.h"
+#include <Library/DxeServicesTableLib.h>
+//
+// The HiiAddPackages() library function requires that any controller (or
+// image) handle, to be associated with the HII packages under installation, be
+// "decorated" with a device path. The tradition seems to be a vendor device
+// path.
+//
+// We'd like to associate our HII packages with the driver's image handle. The
+// first idea is to use the driver image's device path. Unfortunately, loaded
+// images only come with an EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL (not the
+// usual EFI_DEVICE_PATH_PROTOCOL), ie. a different GUID. In addition, even the
+// EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL interface may be NULL, if the image
+// has been loaded from an "unnamed" memory source buffer.
+//
+// Hence let's just stick with the tradition -- use a dedicated vendor device
+// path, with the driver's FILE_GUID.
+//
+#pragma pack(1)
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PKG_DEVICE_PATH;
+#pragma pack()
+
+STATIC PKG_DEVICE_PATH mPkgDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH) ),
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH) >> 8)
+ }
+ },
+ EFI_CALLER_ID_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8) (END_DEVICE_PATH_LENGTH ),
+ (UINT8) (END_DEVICE_PATH_LENGTH >> 8)
+ }
+ }
+};
+
+//
+// The configuration interface between the HII engine (form display etc) and
+// this driver.
+//
+STATIC EFI_HII_CONFIG_ACCESS_PROTOCOL mConfigAccess;
+
+//
+// The handle representing our list of packages after installation.
+//
+STATIC EFI_HII_HANDLE mInstalledPackages;
+
+//
+// The arrays below constitute our HII package list. They are auto-generated by
+// the VFR compiler and linked into the driver image during the build.
+//
+// - The strings package receives its C identifier from the driver's BASE_NAME,
+// plus "Strings".
+//
+// - The forms package receives its C identifier from the VFR file's basename,
+// plus "Bin".
+//
+//
+extern UINT8 SimicsDxeStrings[];
+extern UINT8 PlatformFormsBin[];
+
+//
+// We want to be notified about GOP installations until we find one GOP
+// interface that lets us populate the form.
+//
+STATIC EFI_EVENT mGopEvent;
+
+//
+// The registration record underneath this pointer allows us to iterate through
+// the GOP instances one by one.
+//
+STATIC VOID *mGopTracker;
+
+//
+// Cache the resolutions we get from the GOP.
+//
+typedef struct {
+ UINT32 X;
+ UINT32 Y;
+} GOP_MODE;
+
+STATIC UINTN mNumGopModes;
+STATIC GOP_MODE *mGopModes;
+
+
+/**
+ Load the persistent platform configuration and translate it to binary form
+ state.
+
+ If the platform configuration is missing, then the function fills in a
+ default state.
+
+ @param[out] MainFormState Binary form/widget state after translation.
+
+ @retval EFI_SUCCESS Form/widget state ready.
+ @return Error codes from underlying functions.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+PlatformConfigToFormState (
+ OUT MAIN_FORM_STATE *MainFormState
+ )
+{
+ EFI_STATUS Status;
+ PLATFORM_CONFIG PlatformConfig;
+ UINT64 OptionalElements;
+ UINTN ModeNumber;
+
+ ZeroMem (MainFormState, sizeof *MainFormState);
+
+ Status = PlatformConfigLoad (&PlatformConfig, &OptionalElements);
+ switch (Status) {
+ case EFI_SUCCESS:
+ if (OptionalElements & PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION) {
+ //
+ // Format the preferred resolution as text.
+ //
+ UnicodeSPrintAsciiFormat (
+ (CHAR16 *) MainFormState->CurrentPreferredResolution,
+ sizeof MainFormState->CurrentPreferredResolution,
+ "%Ldx%Ld",
+ (INT64) PlatformConfig.HorizontalResolution,
+ (INT64) PlatformConfig.VerticalResolution);
+
+ //
+ // Try to locate it in the drop-down list too. This may not succeed, but
+ // that's fine.
+ //
+ for (ModeNumber = 0; ModeNumber < mNumGopModes; ++ModeNumber) {
+ if (mGopModes[ModeNumber].X == PlatformConfig.HorizontalResolution &&
+ mGopModes[ModeNumber].Y == PlatformConfig.VerticalResolution) {
+ MainFormState->NextPreferredResolution = (UINT32) ModeNumber;
+ break;
+ }
+ }
+
+ break;
+ }
+ //
+ // fall through otherwise
+ //
+
+ case EFI_NOT_FOUND:
+ UnicodeSPrintAsciiFormat (
+ (CHAR16 *) MainFormState->CurrentPreferredResolution,
+ sizeof MainFormState->CurrentPreferredResolution,
+ "Unset");
+ break;
+
+ default:
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function is called by the HII machinery when it fetches the form state.
+
+ See the precise documentation in the UEFI spec.
+
+ @param[in] This The Config Access Protocol instance.
+
+ @param[in] Request A <ConfigRequest> format UCS-2 string describing the
+ query.
+
+ @param[out] Progress A pointer into Request on output, identifying the query
+ element where processing failed.
+
+ @param[out] Results A <MultiConfigAltResp> format UCS-2 string that has
+ all values filled in for the names in the Request
+ string.
+
+ @retval EFI_SUCCESS Extraction of form state in <MultiConfigAltResp>
+ encoding successful.
+ @return Status codes from underlying functions.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ExtractConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+)
+{
+ MAIN_FORM_STATE MainFormState;
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_VERBOSE, "%a: Request=\"%s\"\n", __FUNCTION__, Request));
+
+ Status = PlatformConfigToFormState (&MainFormState);
+ if (EFI_ERROR (Status)) {
+ *Progress = Request;
+ return Status;
+ }
+
+ //
+ // Answer the textual request keying off the binary form state.
+ //
+ Status = gHiiConfigRouting->BlockToConfig (gHiiConfigRouting, Request,
+ (VOID *) &MainFormState, sizeof MainFormState,
+ Results, Progress);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: BlockToConfig(): %r, Progress=\"%s\"\n",
+ __FUNCTION__, Status, (Status == EFI_DEVICE_ERROR) ? NULL : *Progress));
+ } else {
+ DEBUG ((EFI_D_VERBOSE, "%a: Results=\"%s\"\n", __FUNCTION__, *Results));
+ }
+ return Status;
+}
+
+
+/**
+ Interpret the binary form state and save it as persistent platform
+ configuration.
+
+ @param[in] MainFormState Binary form/widget state to verify and save.
+
+ @retval EFI_SUCCESS Platform configuration saved.
+ @return Error codes from underlying functions.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+FormStateToPlatformConfig (
+ IN CONST MAIN_FORM_STATE *MainFormState
+ )
+{
+ EFI_STATUS Status;
+ PLATFORM_CONFIG PlatformConfig;
+ CONST GOP_MODE *GopMode;
+
+ //
+ // There's nothing to do with the textual CurrentPreferredResolution field.
+ // We verify and translate the selection in the drop-down list.
+ //
+ if (MainFormState->NextPreferredResolution >= mNumGopModes) {
+ return EFI_INVALID_PARAMETER;
+ }
+ GopMode = mGopModes + MainFormState->NextPreferredResolution;
+
+ ZeroMem (&PlatformConfig, sizeof PlatformConfig);
+ PlatformConfig.HorizontalResolution = GopMode->X;
+ PlatformConfig.VerticalResolution = GopMode->Y;
+
+ Status = PlatformConfigSave (&PlatformConfig);
+ return Status;
+}
+
+
+/**
+ This function is called by the HII machinery when it wants the driver to
+ interpret and persist the form state.
+
+ See the precise documentation in the UEFI spec.
+
+ @param[in] This The Config Access Protocol instance.
+
+ @param[in] Configuration A <ConfigResp> format UCS-2 string describing the
+ form state.
+
+ @param[out] Progress A pointer into Configuration on output,
+ identifying the element where processing failed.
+
+ @retval EFI_SUCCESS Configuration verified, state permanent.
+
+ @return Status codes from underlying functions.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+RouteConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+)
+{
+ MAIN_FORM_STATE MainFormState;
+ UINTN BlockSize;
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_VERBOSE, "%a: Configuration=\"%s\"\n", __FUNCTION__,
+ Configuration));
+
+ //
+ // the "read" step in RMW
+ //
+ Status = PlatformConfigToFormState (&MainFormState);
+ if (EFI_ERROR (Status)) {
+ *Progress = Configuration;
+ return Status;
+ }
+
+ //
+ // the "modify" step in RMW
+ //
+ // (Update the binary form state. This update may be partial, which is why in
+ // general we must pre-load the form state from the platform config.)
+ //
+ BlockSize = sizeof MainFormState;
+ Status = gHiiConfigRouting->ConfigToBlock (gHiiConfigRouting, Configuration,
+ (VOID *) &MainFormState, &BlockSize, Progress);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: ConfigToBlock(): %r, Progress=\"%s\"\n",
+ __FUNCTION__, Status,
+ (Status == EFI_BUFFER_TOO_SMALL) ? NULL : *Progress));
+ return Status;
+ }
+
+ //
+ // the "write" step in RMW
+ //
+ Status = FormStateToPlatformConfig (&MainFormState);
+ if (EFI_ERROR (Status)) {
+ *Progress = Configuration;
+ }
+ return Status;
+}
+
+
+STATIC
+EFI_STATUS
+EFIAPI
+Callback (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID QuestionId,
+ IN UINT8 Type,
+ IN OUT EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+ )
+{
+ DEBUG ((EFI_D_VERBOSE, "%a: Action=0x%Lx QuestionId=%d Type=%d\n",
+ __FUNCTION__, (UINT64) Action, QuestionId, Type));
+
+ if (Action != EFI_BROWSER_ACTION_CHANGED) {
+ return EFI_UNSUPPORTED;
+ }
+
+ switch (QuestionId) {
+ case QUESTION_SAVE_EXIT:
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
+ break;
+
+ case QUESTION_DISCARD_EXIT:
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
+ break;
+
+ default:
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Query and save all resolutions supported by the GOP.
+
+ @param[in] Gop The Graphics Output Protocol instance to query.
+
+ @param[out] NumGopModes The number of modes supported by the GOP. On output,
+ this parameter will be positive.
+
+ @param[out] GopModes On output, a dynamically allocated array containing
+ the resolutions returned by the GOP. The caller is
+ responsible for freeing the array after use.
+
+ @retval EFI_UNSUPPORTED No modes found.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate GopModes.
+ @return Error codes from Gop->QueryMode().
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+QueryGopModes (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop,
+ OUT UINTN *NumGopModes,
+ OUT GOP_MODE **GopModes
+ )
+{
+ EFI_STATUS Status;
+ UINT32 ModeNumber;
+
+ if (Gop->Mode->MaxMode == 0) {
+ return EFI_UNSUPPORTED;
+ }
+ *NumGopModes = Gop->Mode->MaxMode;
+
+ *GopModes = AllocatePool (Gop->Mode->MaxMode * sizeof **GopModes);
+ if (*GopModes == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ for (ModeNumber = 0; ModeNumber < Gop->Mode->MaxMode; ++ModeNumber) {
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
+ UINTN SizeOfInfo;
+
+ Status = Gop->QueryMode (Gop, ModeNumber, &SizeOfInfo, &Info);
+ if (EFI_ERROR (Status)) {
+ goto FreeGopModes;
+ }
+
+ (*GopModes)[ModeNumber].X = Info->HorizontalResolution;
+ (*GopModes)[ModeNumber].Y = Info->VerticalResolution;
+ FreePool (Info);
+ }
+
+ return EFI_SUCCESS;
+
+FreeGopModes:
+ FreePool (*GopModes);
+
+ return Status;
+}
+
+
+/**
+ Create a set of "one-of-many" (ie. "drop down list") option IFR opcodes,
+ based on available GOP resolutions, to be placed under a "one-of-many" (ie.
+ "drop down list") opcode.
+
+ @param[in] PackageList The package list with the formset and form for
+ which the drop down options are produced. Option
+ names are added as new strings to PackageList.
+
+ @param[out] OpCodeBuffer On output, a dynamically allocated opcode buffer
+ with drop down list options corresponding to GOP
+ resolutions. The caller is responsible for freeing
+ OpCodeBuffer with HiiFreeOpCodeHandle() after use.
+
+ @param[in] NumGopModes Number of entries in GopModes.
+
+ @param[in] GopModes Array of resolutions retrieved from the GOP.
+
+ @retval EFI_SUCESS Opcodes have been successfully produced.
+
+ @return Status codes from underlying functions. PackageList may
+ have been extended with new strings. OpCodeBuffer is
+ unchanged.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CreateResolutionOptions (
+ IN EFI_HII_HANDLE *PackageList,
+ OUT VOID **OpCodeBuffer,
+ IN UINTN NumGopModes,
+ IN GOP_MODE *GopModes
+ )
+{
+ EFI_STATUS Status;
+ VOID *OutputBuffer;
+ UINTN ModeNumber;
+
+ OutputBuffer = HiiAllocateOpCodeHandle ();
+ if (OutputBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ for (ModeNumber = 0; ModeNumber < NumGopModes; ++ModeNumber) {
+ CHAR16 Desc[MAXSIZE_RES_CUR];
+ EFI_STRING_ID NewString;
+ VOID *OpCode;
+
+ UnicodeSPrintAsciiFormat (Desc, sizeof Desc, "%Ldx%Ld",
+ (INT64) GopModes[ModeNumber].X, (INT64) GopModes[ModeNumber].Y);
+ NewString = HiiSetString (PackageList, 0 /* new string */, Desc,
+ NULL /* for all languages */);
+ if (NewString == 0) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FreeOutputBuffer;
+ }
+ OpCode = HiiCreateOneOfOptionOpCode (OutputBuffer, NewString,
+ 0 /* Flags */, EFI_IFR_NUMERIC_SIZE_4, ModeNumber);
+ if (OpCode == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FreeOutputBuffer;
+ }
+ }
+
+ *OpCodeBuffer = OutputBuffer;
+ return EFI_SUCCESS;
+
+FreeOutputBuffer:
+ HiiFreeOpCodeHandle (OutputBuffer);
+
+ return Status;
+}
+
+
+/**
+ Populate the form identified by the (PackageList, FormSetGuid, FormId)
+ triplet.
+
+ The drop down list of video resolutions is generated from (NumGopModes,
+ GopModes).
+
+ @retval EFI_SUCESS Form successfully updated.
+ @return Status codes from underlying functions.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+PopulateForm (
+ IN EFI_HII_HANDLE *PackageList,
+ IN EFI_GUID *FormSetGuid,
+ IN EFI_FORM_ID FormId,
+ IN UINTN NumGopModes,
+ IN GOP_MODE *GopModes
+ )
+{
+ EFI_STATUS Status;
+ VOID *OpCodeBuffer;
+ VOID *OpCode;
+ EFI_IFR_GUID_LABEL *Anchor;
+ VOID *OpCodeBuffer2;
+
+ OpCodeBuffer2 = NULL;
+
+ //
+ // 1. Allocate an empty opcode buffer.
+ //
+ OpCodeBuffer = HiiAllocateOpCodeHandle ();
+ if (OpCodeBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // 2. Create a label opcode (which is a Tiano extension) inside the buffer.
+ // The label's number must match the "anchor" label in the form.
+ //
+ OpCode = HiiCreateGuidOpCode (OpCodeBuffer, &gEfiIfrTianoGuid,
+ NULL /* optional copy origin */, sizeof *Anchor);
+ if (OpCode == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FreeOpCodeBuffer;
+ }
+ Anchor = OpCode;
+ Anchor->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ Anchor->Number = LABEL_RES_NEXT;
+
+ //
+ // 3. Create the opcodes inside the buffer that are to be inserted into the
+ // form.
+ //
+ // 3.1. Get a list of resolutions.
+ //
+ Status = CreateResolutionOptions (PackageList, &OpCodeBuffer2,
+ NumGopModes, GopModes);
+ if (EFI_ERROR (Status)) {
+ goto FreeOpCodeBuffer;
+ }
+
+ //
+ // 3.2. Create a one-of-many question with the above options.
+ //
+ OpCode = HiiCreateOneOfOpCode (
+ OpCodeBuffer, // create opcode inside this
+ // opcode buffer,
+ QUESTION_RES_NEXT, // ID of question,
+ FORMSTATEID_MAIN_FORM, // identifies form state
+ // storage,
+ (UINT16) OFFSET_OF (MAIN_FORM_STATE, // value of question stored
+ NextPreferredResolution), // at this offset,
+ STRING_TOKEN (STR_RES_NEXT), // Prompt,
+ STRING_TOKEN (STR_RES_NEXT_HELP), // Help,
+ 0, // QuestionFlags,
+ EFI_IFR_NUMERIC_SIZE_4, // see sizeof
+ // NextPreferredResolution,
+ OpCodeBuffer2, // buffer with possible
+ // choices,
+ NULL // DEFAULT opcodes
+ );
+ if (OpCode == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FreeOpCodeBuffer2;
+ }
+
+ //
+ // 4. Update the form with the opcode buffer.
+ //
+ Status = HiiUpdateForm (PackageList, FormSetGuid, FormId,
+ OpCodeBuffer, // buffer with head anchor, and new contents to be
+ // inserted at it
+ NULL // buffer with tail anchor, for deleting old
+ // contents up to it
+ );
+
+FreeOpCodeBuffer2:
+ HiiFreeOpCodeHandle (OpCodeBuffer2);
+
+FreeOpCodeBuffer:
+ HiiFreeOpCodeHandle (OpCodeBuffer);
+
+ return Status;
+}
+
+
+/**
+ Load and execute the platform configuration.
+
+ @retval EFI_SUCCESS Configuration loaded and executed.
+ @return Status codes from PlatformConfigLoad().
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ExecutePlatformConfig (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ PLATFORM_CONFIG PlatformConfig;
+ UINT64 OptionalElements;
+
+ Status = PlatformConfigLoad (&PlatformConfig, &OptionalElements);
+ if (EFI_ERROR (Status)) {
+ DEBUG (((Status == EFI_NOT_FOUND) ? EFI_D_VERBOSE : EFI_D_ERROR,
+ "%a: failed to load platform config: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ if (OptionalElements & PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION) {
+ //
+ // Pass the preferred resolution to GraphicsConsoleDxe via dynamic PCDs.
+ //
+ PcdSet32 (PcdVideoHorizontalResolution,
+ PlatformConfig.HorizontalResolution);
+ PcdSet32 (PcdVideoVerticalResolution,
+ PlatformConfig.VerticalResolution);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Notification callback for GOP interface installation.
+
+ @param[in] Event Event whose notification function is being invoked.
+
+ @param[in] Context The pointer to the notification function's context, which
+ is implementation-dependent.
+**/
+STATIC
+VOID
+EFIAPI
+GopInstalled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
+
+ ASSERT (Event == mGopEvent);
+
+ //
+ // Check further GOPs.
+ //
+ for (;;) {
+ mNumGopModes = 0;
+ mGopModes = NULL;
+
+ Status = gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid, mGopTracker,
+ (VOID **) &Gop);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ Status = QueryGopModes (Gop, &mNumGopModes, &mGopModes);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ Status = PopulateForm (mInstalledPackages, &gSimicsBoardConfigGuid,
+ FORMID_MAIN_FORM, mNumGopModes, mGopModes);
+ if (EFI_ERROR (Status)) {
+ FreePool (mGopModes);
+ continue;
+ }
+
+ break;
+ }
+
+ //
+ // Success -- so uninstall this callback. Closing the event removes all
+ // pending notifications and all protocol registrations.
+ //
+ Status = gBS->CloseEvent (mGopEvent);
+ ASSERT_EFI_ERROR (Status);
+ mGopEvent = NULL;
+ mGopTracker = NULL;
+}
+
+
+/**
+ Entry point for this driver.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Pointer to SystemTable.
+
+ @retval EFI_SUCESS Driver has loaded successfully.
+ @retval EFI_OUT_OF_RESOURCES Failed to install HII packages.
+ @return Error codes from lower level functions.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ ExecutePlatformConfig ();
+
+ mConfigAccess.ExtractConfig = &ExtractConfig;
+ mConfigAccess.RouteConfig = &RouteConfig;
+ mConfigAccess.Callback = &Callback;
+
+ //
+ // Declare ourselves suitable for HII communication.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
+ &gEfiDevicePathProtocolGuid, &mPkgDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess,
+ NULL);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Publish the HII package list to HII Database.
+ //
+ mInstalledPackages = HiiAddPackages (
+ &gEfiCallerIdGuid, // PackageListGuid
+ ImageHandle, // associated DeviceHandle
+ SimicsDxeStrings, // 1st package
+ PlatformFormsBin, // 2nd package
+ NULL // terminator
+ );
+ if (mInstalledPackages == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto UninstallProtocols;
+ }
+
+ Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, &GopInstalled,
+ NULL /* Context */, &mGopEvent);
+ if (EFI_ERROR (Status)) {
+ goto RemovePackages;
+ }
+
+ Status = gBS->RegisterProtocolNotify (&gEfiGraphicsOutputProtocolGuid,
+ mGopEvent, &mGopTracker);
+ if (EFI_ERROR (Status)) {
+ goto CloseGopEvent;
+ }
+
+ //
+ // Check already installed GOPs.
+ //
+ Status = gBS->SignalEvent (mGopEvent);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+
+CloseGopEvent:
+ gBS->CloseEvent (mGopEvent);
+
+RemovePackages:
+ HiiRemovePackages (mInstalledPackages);
+
+UninstallProtocols:
+ gBS->UninstallMultipleProtocolInterfaces (ImageHandle,
+ &gEfiDevicePathProtocolGuid, &mPkgDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess,
+ NULL);
+ return Status;
+}
+
+/**
+ Unload the driver.
+
+ @param[in] ImageHandle Handle that identifies the image to evict.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+**/
+EFI_STATUS
+EFIAPI
+PlatformUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ if (mGopEvent == NULL) {
+ //
+ // The GOP callback ran successfully and unregistered itself. Release the
+ // resources allocated there.
+ //
+ ASSERT (mGopModes != NULL);
+ FreePool (mGopModes);
+ } else {
+ //
+ // Otherwise we need to unregister the callback.
+ //
+ ASSERT (mGopModes == NULL);
+ gBS->CloseEvent (mGopEvent);
+ }
+
+ //
+ // Release resources allocated by the entry point.
+ //
+ HiiRemovePackages (mInstalledPackages);
+ gBS->UninstallMultipleProtocolInterfaces (ImageHandle,
+ &gEfiDevicePathProtocolGuid, &mPkgDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess,
+ NULL);
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c
new file mode 100644
index 0000000000..b1e017bbb0
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c
@@ -0,0 +1,123 @@
+/** @file
+ Utility functions for serializing (persistently storing) and deserializing
+ SIMICS QSP's platform configuration.
+
+ Copyright (C) 2014, Red Hat, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Guid/SimicsBoardConfig.h>
+
+#include "PlatformConfig.h"
+
+//
+// Name of the UEFI variable that we use for persistent storage.
+//
+STATIC CHAR16 mVariableName[] = L"PlatformConfig";
+
+
+/**
+ Serialize and persistently save platform configuration.
+
+ @param[in] PlatformConfig The platform configuration to serialize and save.
+
+ @return Status codes returned by gRT->SetVariable().
+**/
+EFI_STATUS
+EFIAPI
+PlatformConfigSave (
+ IN PLATFORM_CONFIG *PlatformConfig
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // We could implement any kind of translation here, as part of serialization.
+ // For example, we could expose the platform configuration in separate
+ // variables with human-readable contents, allowing other tools to access
+ // them more easily. For now, just save a binary dump.
+ //
+ Status = gRT->SetVariable (mVariableName, &gSimicsBoardConfigGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof *PlatformConfig, PlatformConfig);
+ return Status;
+}
+
+
+/**
+ Load and deserialize platform configuration.
+
+ When the function fails, output parameters are indeterminate.
+
+ @param[out] PlatformConfig The platform configuration to receive the
+ loaded data.
+
+ @param[out] OptionalElements This bitmap describes the presence of optional
+ configuration elements that have been loaded.
+ PLATFORM_CONFIG_F_DOWNGRADE means that some
+ unknown elements, present in the wire format,
+ have been ignored.
+
+ @retval EFI_SUCCESS Loading & deserialization successful.
+ @return Error codes returned by GetVariable2().
+**/
+EFI_STATUS
+EFIAPI
+PlatformConfigLoad (
+ OUT PLATFORM_CONFIG *PlatformConfig,
+ OUT UINT64 *OptionalElements
+ )
+{
+ VOID *Data;
+ UINTN DataSize;
+ EFI_STATUS Status;
+
+ //
+ // Any translation done in PlatformConfigSave() would have to be mirrored
+ // here. For now, just load the binary dump.
+ //
+ // Versioning of the binary wire format is implemented based on size
+ // (only incremental changes, ie. new fields), and on GUID.
+ // (Incompatible changes require a GUID change.)
+ //
+ Status = GetVariable2 (mVariableName, &gSimicsBoardConfigGuid, &Data,
+ &DataSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ *OptionalElements = 0;
+ if (DataSize > sizeof *PlatformConfig) {
+ //
+ // Handle firmware downgrade -- keep only leading part.
+ //
+ CopyMem (PlatformConfig, Data, sizeof *PlatformConfig);
+ *OptionalElements |= PLATFORM_CONFIG_F_DOWNGRADE;
+ } else {
+ CopyMem (PlatformConfig, Data, DataSize);
+
+ //
+ // Handle firmware upgrade -- zero out missing fields.
+ //
+ ZeroMem ((UINT8 *)PlatformConfig + DataSize,
+ sizeof *PlatformConfig - DataSize);
+ }
+
+ //
+ // Based on DataSize, report the optional features that we recognize.
+ //
+ if (DataSize >= (OFFSET_OF (PLATFORM_CONFIG, VerticalResolution) +
+ sizeof PlatformConfig->VerticalResolution)) {
+ *OptionalElements |= PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION;
+ }
+
+ FreePool (Data);
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c
new file mode 100644
index 0000000000..b34ba9283b
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c
@@ -0,0 +1,57 @@
+/** @file
+ PC/AT CMOS access routines
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Cmos.h"
+#include "Library/IoLib.h"
+
+/**
+ Reads 8-bits of CMOS data.
+
+ Reads the 8-bits of CMOS data at the location specified by Index.
+ The 8-bit read value is returned.
+
+ @param Index The CMOS location to read.
+
+ @return The value read.
+
+**/
+UINT8
+EFIAPI
+CmosRead8 (
+ IN UINTN Index
+ )
+{
+ IoWrite8 (0x70, (UINT8) Index);
+ return IoRead8 (0x71);
+}
+
+
+/**
+ Writes 8-bits of CMOS data.
+
+ Writes 8-bits of CMOS data to the location specified by Index
+ with the value specified by Value and returns Value.
+
+ @param Index The CMOS location to write.
+ @param Value The value to write to CMOS.
+
+ @return The value written to CMOS.
+
+**/
+UINT8
+EFIAPI
+CmosWrite8 (
+ IN UINTN Index,
+ IN UINT8 Value
+ )
+{
+ IoWrite8 (0x70, (UINT8) Index);
+ IoWrite8 (0x71, Value);
+ return Value;
+}
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/FeatureControl.c b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/FeatureControl.c
new file mode 100644
index 0000000000..692405e417
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/FeatureControl.c
@@ -0,0 +1,114 @@
+/** @file
+ Install a callback when necessary for setting the Feature Control MSR on all
+ processors.
+
+ Copyright (C) 2016, Red Hat, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/MpServices.h>
+#include <Register/Intel/Msr/Core2Msr.h>
+
+#include "Platform.h"
+
+//
+// The value to be written to the Feature Control MSR, retrieved from fw_cfg.
+//
+STATIC UINT64 mFeatureControlValue = 0x00000005;
+
+/**
+ Write the Feature Control MSR on an Application Processor or the Boot
+ Processor.
+
+ All APs execute this function in parallel. The BSP executes the function
+ separately.
+
+ @param[in,out] WorkSpace Pointer to the input/output argument workspace
+ shared by all processors.
+**/
+STATIC
+VOID
+EFIAPI
+WriteFeatureControl (
+ IN OUT VOID *WorkSpace
+ )
+{
+ AsmWriteMsr64 (MSR_CORE2_FEATURE_CONTROL, mFeatureControlValue);
+}
+
+/**
+ Notification function called when EFI_PEI_MP_SERVICES_PPI becomes available.
+
+ @param[in] PeiServices Indirect reference to the PEI Services Table.
+ @param[in] NotifyDescriptor Address of the notification descriptor data
+ structure.
+ @param[in] Ppi Address of the PPI that was installed.
+
+ @return Status of the notification. The status code returned from this
+ function is ignored.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+OnMpServicesAvailable (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_PEI_MP_SERVICES_PPI *MpServices;
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_VERBOSE, "%a: %a\n", gEfiCallerBaseName, __FUNCTION__));
+ //
+ // Write the MSR on all the APs in parallel.
+ //
+ MpServices = Ppi;
+ Status = MpServices->StartupAllAPs (
+ (CONST EFI_PEI_SERVICES **)PeiServices,
+ MpServices,
+ WriteFeatureControl, // Procedure
+ FALSE, // SingleThread
+ 0, // TimeoutInMicroSeconds: inf.
+ NULL // ProcedureArgument
+ );
+ if (EFI_ERROR (Status) && Status != EFI_NOT_STARTED) {
+ DEBUG ((EFI_D_ERROR, "%a: StartupAllAps(): %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ //
+ // Now write the MSR on the BSP too.
+ //
+ WriteFeatureControl (NULL);
+
+ return EFI_SUCCESS;
+}
+
+//
+// Notification object for registering the callback, for when
+// EFI_PEI_MP_SERVICES_PPI becomes available.
+//
+STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mMpServicesNotify = {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | // Flags
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiMpServicesPpiGuid, // Guid
+ OnMpServicesAvailable // Notify
+};
+
+VOID
+InstallFeatureControlCallback (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = PeiServicesNotifyPpi (&mMpServicesNotify);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: failed to set up MP Services callback: %r\n",
+ __FUNCTION__, Status));
+ }
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c
new file mode 100644
index 0000000000..90e6d1d3cf
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c
@@ -0,0 +1,568 @@
+/** @file
+ Memory Detection for Virtual Machines.
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/ResourcePublicationLib.h>
+#include <Library/MtrrLib.h>
+#include <SimicsPlatforms.h>
+#include <Guid/SmramMemoryReserve.h>
+
+#include "Platform.h"
+#include "Cmos.h"
+
+UINT8 mPhysMemAddressWidth;
+
+STATIC UINT32 mS3AcpiReservedMemoryBase;
+STATIC UINT32 mS3AcpiReservedMemorySize;
+
+STATIC UINT16 mX58TsegMbytes;
+
+VOID
+X58TsegMbytesInitialization(
+ VOID
+)
+{
+
+ if (mHostBridgeDevId != INTEL_ICH10_DEVICE_ID) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: no TSEG (SMRAM) on host bridge DID=0x%04x; "
+ "only DID=0x%04x (X58) is supported\n",
+ __FUNCTION__,
+ mHostBridgeDevId,
+ INTEL_ICH10_DEVICE_ID
+ ));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+
+ //
+ // Check if QEMU offers an extended TSEG.
+ //
+ // This can be seen from writing MCH_EXT_TSEG_MB_QUERY to the MCH_EXT_TSEG_MB
+ // register, and reading back the register.
+ //
+ // On a QEMU machine type that does not offer an extended TSEG, the initial
+ // write overwrites whatever value a malicious guest OS may have placed in
+ // the (unimplemented) register, before entering S3 or rebooting.
+ // Subsequently, the read returns MCH_EXT_TSEG_MB_QUERY unchanged.
+ //
+ // On a QEMU machine type that offers an extended TSEG, the initial write
+ // triggers an update to the register. Subsequently, the value read back
+ // (which is guaranteed to differ from MCH_EXT_TSEG_MB_QUERY) tells us the
+ // number of megabytes.
+ //
+ mX58TsegMbytes = FixedPcdGet8(PcdX58TsegMbytes);
+ return;
+}
+
+
+UINT32
+GetSystemMemorySizeBelow4gb (
+ VOID
+ )
+{
+ UINT8 Cmos0x34;
+ UINT8 Cmos0x35;
+
+ //
+ // CMOS 0x34/0x35 specifies the system memory above 16 MB.
+ // * CMOS(0x35) is the high byte
+ // * CMOS(0x34) is the low byte
+ // * The size is specified in 64kb chunks
+ // * Since this is memory above 16MB, the 16MB must be added
+ // into the calculation to get the total memory size.
+ //
+
+ Cmos0x34 = (UINT8) CmosRead8 (0x34);
+ Cmos0x35 = (UINT8) CmosRead8 (0x35);
+
+ return (UINT32) (((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);
+}
+
+
+STATIC
+UINT64
+GetSystemMemorySizeAbove4gb (
+ )
+{
+ UINT32 Size;
+ UINTN CmosIndex;
+
+ //
+ // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
+ // * CMOS(0x5d) is the most significant size byte
+ // * CMOS(0x5c) is the middle size byte
+ // * CMOS(0x5b) is the least significant size byte
+ // * The size is specified in 64kb chunks
+ //
+
+ Size = 0;
+ for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {
+ Size = (UINT32) (Size << 8) + (UINT32) CmosRead8 (CmosIndex);
+ }
+
+ return LShiftU64 (Size, 16);
+}
+
+
+/**
+ Return the highest address that DXE could possibly use, plus one.
+**/
+STATIC
+UINT64
+GetFirstNonAddress (
+ VOID
+ )
+{
+ UINT64 FirstNonAddress;
+ UINT64 Pci64Base, Pci64Size;
+
+ FirstNonAddress = BASE_4GB + GetSystemMemorySizeAbove4gb ();
+
+ //
+ // If DXE is 32-bit, then we're done; PciBusDxe will degrade 64-bit MMIO
+ // resources to 32-bit anyway. See DegradeResource() in
+ // "PciResourceSupport.c".
+ //
+#ifdef MDE_CPU_IA32
+ if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+ return FirstNonAddress;
+ }
+#endif
+
+ //
+ // Otherwise, in order to calculate the highest address plus one, we must
+ // consider the 64-bit PCI host aperture too. Fetch the default size.
+ //
+ Pci64Size = PcdGet64 (PcdPciMmio64Size);
+
+ if (Pci64Size == 0) {
+ if (mBootMode != BOOT_ON_S3_RESUME) {
+ DEBUG ((EFI_D_INFO, "%a: disabling 64-bit PCI host aperture\n",
+ __FUNCTION__));
+ PcdSet64 (PcdPciMmio64Size, 0);
+ }
+
+ //
+ // There's nothing more to do; the amount of memory above 4GB fully
+ // determines the highest address plus one. The memory hotplug area (see
+ // below) plays no role for the firmware in this case.
+ //
+ return FirstNonAddress;
+ }
+
+ //
+ // SeaBIOS aligns both boundaries of the 64-bit PCI host aperture to 1GB, so
+ // that the host can map it with 1GB hugepages. Follow suit.
+ //
+ Pci64Base = ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB);
+ Pci64Size = ALIGN_VALUE (Pci64Size, (UINT64)SIZE_1GB);
+
+ //
+ // The 64-bit PCI host aperture should also be "naturally" aligned. The
+ // alignment is determined by rounding the size of the aperture down to the
+ // next smaller or equal power of two. That is, align the aperture by the
+ // largest BAR size that can fit into it.
+ //
+ Pci64Base = ALIGN_VALUE (Pci64Base, GetPowerOfTwo64 (Pci64Size));
+
+ if (mBootMode != BOOT_ON_S3_RESUME) {
+ //
+ // The core PciHostBridgeDxe driver will automatically add this range to
+ // the GCD memory space map through our PciHostBridgeLib instance; here we
+ // only need to set the PCDs.
+ //
+ PcdSet64 (PcdPciMmio64Base, Pci64Base);
+ PcdSet64 (PcdPciMmio64Size, Pci64Size);
+ DEBUG ((EFI_D_INFO, "%a: Pci64Base=0x%Lx Pci64Size=0x%Lx\n",
+ __FUNCTION__, Pci64Base, Pci64Size));
+ }
+
+ //
+ // The useful address space ends with the 64-bit PCI host aperture.
+ //
+ FirstNonAddress = Pci64Base + Pci64Size;
+ return FirstNonAddress;
+}
+
+
+/**
+ Initialize the mPhysMemAddressWidth variable, based on guest RAM size.
+**/
+VOID
+AddressWidthInitialization (
+ VOID
+ )
+{
+ UINT64 FirstNonAddress;
+
+ //
+ // As guest-physical memory size grows, the permanent PEI RAM requirements
+ // are dominated by the identity-mapping page tables built by the DXE IPL.
+ // The DXL IPL keys off of the physical address bits advertized in the CPU
+ // HOB. To conserve memory, we calculate the minimum address width here.
+ //
+ FirstNonAddress = GetFirstNonAddress ();
+ mPhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress);
+
+ //
+ // If FirstNonAddress is not an integral power of two, then we need an
+ // additional bit.
+ //
+ if ((FirstNonAddress & (FirstNonAddress - 1)) != 0) {
+ ++mPhysMemAddressWidth;
+ }
+
+ //
+ // The minimum address width is 36 (covers up to and excluding 64 GB, which
+ // is the maximum for Ia32 + PAE). The theoretical architecture maximum for
+ // X64 long mode is 52 bits, but the DXE IPL clamps that down to 48 bits. We
+ // can simply assert that here, since 48 bits are good enough for 256 TB.
+ //
+ if (mPhysMemAddressWidth <= 36) {
+ mPhysMemAddressWidth = 36;
+ }
+ ASSERT (mPhysMemAddressWidth <= 48);
+}
+
+
+/**
+ Calculate the cap for the permanent PEI memory.
+**/
+STATIC
+UINT32
+GetPeiMemoryCap (
+ VOID
+ )
+{
+ BOOLEAN Page1GSupport;
+ UINT32 RegEax;
+ UINT32 RegEdx;
+ UINT32 Pml4Entries;
+ UINT32 PdpEntries;
+ UINTN TotalPages;
+
+ //
+ // If DXE is 32-bit, then just return the traditional 64 MB cap.
+ //
+#ifdef MDE_CPU_IA32
+ if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+ return SIZE_64MB;
+ }
+#endif
+
+ //
+ // Dependent on physical address width, PEI memory allocations can be
+ // dominated by the page tables built for 64-bit DXE. So we key the cap off
+ // of those. The code below is based on CreateIdentityMappingPageTables() in
+ // "MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c".
+ //
+ Page1GSupport = FALSE;
+ if (PcdGetBool (PcdUse1GPageTable)) {
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= 0x80000001) {
+ AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
+ if ((RegEdx & BIT26) != 0) {
+ Page1GSupport = TRUE;
+ }
+ }
+ }
+
+ if (mPhysMemAddressWidth <= 39) {
+ Pml4Entries = 1;
+ PdpEntries = 1 << (mPhysMemAddressWidth - 30);
+ ASSERT (PdpEntries <= 0x200);
+ } else {
+ Pml4Entries = 1 << (mPhysMemAddressWidth - 39);
+ ASSERT (Pml4Entries <= 0x200);
+ PdpEntries = 512;
+ }
+
+ TotalPages = Page1GSupport ? Pml4Entries + 1 :
+ (PdpEntries + 1) * Pml4Entries + 1;
+ ASSERT (TotalPages <= 0x40201);
+
+ //
+ // Add 64 MB for miscellaneous allocations. Note that for
+ // mPhysMemAddressWidth values close to 36, the cap will actually be
+ // dominated by this increment.
+ //
+ return (UINT32)(EFI_PAGES_TO_SIZE (TotalPages) + SIZE_64MB);
+}
+
+
+/**
+ Publish PEI core memory
+
+ @return EFI_SUCCESS The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+PublishPeiMemory (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS MemoryBase;
+ UINT64 MemorySize;
+ UINT32 LowerMemorySize;
+ UINT32 PeiMemoryCap;
+
+ LowerMemorySize = GetSystemMemorySizeBelow4gb ();
+ if (FeaturePcdGet (PcdSmmSmramRequire)) {
+ //
+ // TSEG is chipped from the end of low RAM
+ //
+ LowerMemorySize -= mX58TsegMbytes * SIZE_1MB;
+ }
+
+ //
+ // If S3 is supported, then the S3 permanent PEI memory is placed next,
+ // downwards. Its size is primarily dictated by CpuMpPei. The formula below
+ // is an approximation.
+ //
+ if (mS3Supported) {
+ mS3AcpiReservedMemorySize = SIZE_512KB +
+ mMaxCpuCount *
+ PcdGet32 (PcdCpuApStackSize);
+ mS3AcpiReservedMemoryBase = LowerMemorySize - mS3AcpiReservedMemorySize;
+ LowerMemorySize = mS3AcpiReservedMemoryBase;
+ }
+
+ if (mBootMode == BOOT_ON_S3_RESUME) {
+ MemoryBase = mS3AcpiReservedMemoryBase;
+ MemorySize = mS3AcpiReservedMemorySize;
+ } else {
+ PeiMemoryCap = GetPeiMemoryCap ();
+ DEBUG ((EFI_D_INFO, "%a: mPhysMemAddressWidth=%d PeiMemoryCap=%u KB\n",
+ __FUNCTION__, mPhysMemAddressWidth, PeiMemoryCap >> 10));
+
+ //
+ // Determine the range of memory to use during PEI
+ //
+ // Technically we could lay the permanent PEI RAM over SEC's temporary
+ // decompression and scratch buffer even if "secure S3" is needed, since
+ // their lifetimes don't overlap. However, PeiFvInitialization() will cover
+ // RAM up to PcdOvmfDecompressionScratchEnd with an EfiACPIMemoryNVS memory
+ // allocation HOB, and other allocations served from the permanent PEI RAM
+ // shouldn't overlap with that HOB.
+ //
+ MemoryBase = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire) ?
+ PcdGet32 (PcdSimicsDecompressionScratchEnd) :
+ PcdGet32 (PcdSimicsDxeMemFvBase) + PcdGet32 (PcdSimicsDxeMemFvSize);
+ MemorySize = LowerMemorySize - MemoryBase;
+ }
+ DEBUG((EFI_D_INFO, "MemoryBase=0x%lx MemorySize=0x%lx\n", MemoryBase, MemorySize));
+ //
+ // Publish this memory to the PEI Core
+ //
+ Status = PublishSystemMemory(MemoryBase, MemorySize);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+
+/**
+ Peform Memory Detection for QEMU / KVM
+
+**/
+STATIC
+VOID
+QemuInitializeRam (
+ VOID
+ )
+{
+ UINT64 LowerMemorySize;
+ UINT64 UpperMemorySize;
+ UINTN BufferSize;
+ UINT8 SmramIndex;
+ UINT8 SmramRanges;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *SmramHobDescriptorBlock;
+ UINT8 Index;
+
+ DEBUG ((EFI_D_INFO, "%a called\n", __FUNCTION__));
+
+ //
+ // Determine total memory size available
+ //
+ LowerMemorySize = GetSystemMemorySizeBelow4gb ();
+ UpperMemorySize = GetSystemMemorySizeAbove4gb ();
+
+ if (mBootMode == BOOT_ON_S3_RESUME) {
+ //
+ // Create the following memory HOB as an exception on the S3 boot path.
+ //
+ // Normally we'd create memory HOBs only on the normal boot path. However,
+ // CpuMpPei specifically needs such a low-memory HOB on the S3 path as
+ // well, for "borrowing" a subset of it temporarily, for the AP startup
+ // vector.
+ //
+ // CpuMpPei saves the original contents of the borrowed area in permanent
+ // PEI RAM, in a backup buffer allocated with the normal PEI services.
+ // CpuMpPei restores the original contents ("returns" the borrowed area) at
+ // End-of-PEI. End-of-PEI in turn is emitted by S3Resume2Pei before
+ // transferring control to the OS's wakeup vector in the FACS.
+ //
+ // We expect any other PEIMs that "borrow" memory similarly to CpuMpPei to
+ // restore the original contents. Furthermore, we expect all such PEIMs
+ // (CpuMpPei included) to claim the borrowed areas by producing memory
+ // allocation HOBs, and to honor preexistent memory allocation HOBs when
+ // looking for an area to borrow.
+ //
+ AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
+ } else {
+ //
+ // Create memory HOBs
+ //
+ AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
+
+ if (FeaturePcdGet (PcdSmmSmramRequire)) {
+ UINT32 TsegSize;
+
+ TsegSize = mX58TsegMbytes * SIZE_1MB;
+ AddMemoryRangeHob (BASE_1MB, LowerMemorySize - TsegSize);
+ AddReservedMemoryBaseSizeHob (LowerMemorySize - TsegSize, TsegSize,
+ TRUE);
+
+ BufferSize = sizeof(EFI_SMRAM_HOB_DESCRIPTOR_BLOCK);
+ SmramRanges = 1;
+
+ Hob.Raw = BuildGuidHob(
+ &gEfiSmmPeiSmramMemoryReserveGuid,
+ BufferSize
+ );
+ ASSERT(Hob.Raw);
+
+ SmramHobDescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *)(Hob.Raw);
+ SmramHobDescriptorBlock->NumberOfSmmReservedRegions = SmramRanges;
+
+ SmramIndex = 0;
+ for (Index = 0; Index < SmramRanges; Index++) {
+ //
+ // This is an SMRAM range, create an SMRAM descriptor
+ //
+ SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalStart = LowerMemorySize - TsegSize;
+ SmramHobDescriptorBlock->Descriptor[SmramIndex].CpuStart = LowerMemorySize - TsegSize;
+ SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalSize = TsegSize;
+ SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState = EFI_SMRAM_CLOSED | EFI_CACHEABLE;
+ SmramIndex++;
+ }
+
+ } else {
+ AddMemoryRangeHob (BASE_1MB, LowerMemorySize);
+ }
+
+ //
+ // If QEMU presents an E820 map, then create memory HOBs for the >=4GB RAM
+ // entries. Otherwise, create a single memory HOB with the flat >=4GB
+ // memory size read from the CMOS.
+ //
+ if (UpperMemorySize != 0) {
+ AddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);
+ }
+ }
+}
+
+/**
+ Publish system RAM and reserve memory regions
+
+**/
+VOID
+InitializeRamRegions (
+ VOID
+ )
+{
+ QemuInitializeRam ();
+
+ if (mS3Supported && mBootMode != BOOT_ON_S3_RESUME) {
+ //
+ // This is the memory range that will be used for PEI on S3 resume
+ //
+ BuildMemoryAllocationHob (
+ mS3AcpiReservedMemoryBase,
+ mS3AcpiReservedMemorySize,
+ EfiACPIMemoryNVS
+ );
+
+ //
+ // Cover the initial RAM area used as stack and temporary PEI heap.
+ //
+ // This is reserved as ACPI NVS so it can be used on S3 resume.
+ //
+ BuildMemoryAllocationHob (
+ PcdGet32 (PcdSimicsSecPeiTempRamBase),
+ PcdGet32 (PcdSimicsSecPeiTempRamSize),
+ EfiACPIMemoryNVS
+ );
+
+ //
+ // SEC stores its table of GUIDed section handlers here.
+ //
+ BuildMemoryAllocationHob (
+ PcdGet64 (PcdGuidedExtractHandlerTableAddress),
+ PcdGet32 (PcdGuidedExtractHandlerTableSize),
+ EfiACPIMemoryNVS
+ );
+
+ }
+
+ if (mBootMode != BOOT_ON_S3_RESUME) {
+ if (!FeaturePcdGet (PcdSmmSmramRequire)) {
+ //
+ // Reserve the lock box storage area
+ //
+ // Since this memory range will be used on S3 resume, it must be
+ // reserved as ACPI NVS.
+ //
+ // If S3 is unsupported, then various drivers might still write to the
+ // LockBox area. We ought to prevent DXE from serving allocation requests
+ // such that they would overlap the LockBox storage.
+ //
+ ZeroMem (
+ (VOID*)(UINTN) PcdGet32 (PcdSimicsLockBoxStorageBase),
+ (UINTN) PcdGet32 (PcdSimicsLockBoxStorageSize)
+ );
+ BuildMemoryAllocationHob (
+ (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdSimicsLockBoxStorageBase),
+ (UINT64)(UINTN) PcdGet32 (PcdSimicsLockBoxStorageSize),
+ mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
+ );
+ }
+
+ if (FeaturePcdGet (PcdSmmSmramRequire)) {
+ UINT32 TsegSize;
+
+ //
+ // Make sure the TSEG area that we reported as a reserved memory resource
+ // cannot be used for reserved memory allocations.
+ //
+ TsegSize = mX58TsegMbytes * SIZE_1MB;
+ BuildMemoryAllocationHob (
+ GetSystemMemorySizeBelow4gb() - TsegSize,
+ TsegSize,
+ EfiReservedMemoryType
+ );
+ }
+ }
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c
new file mode 100644
index 0000000000..140a38f27f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c
@@ -0,0 +1,630 @@
+/** @file
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/ResourcePublicationLib.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Ppi/MasterBootMode.h>
+#include <IndustryStandard/Pci22.h>
+#include <SimicsPlatforms.h>
+
+#include "Platform.h"
+#include "Cmos.h"
+
+EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
+ { EfiACPIMemoryNVS, 0x004 },
+ { EfiACPIReclaimMemory, 0x008 },
+ { EfiReservedMemoryType, 0x004 },
+ { EfiRuntimeServicesData, 0x024 },
+ { EfiRuntimeServicesCode, 0x030 },
+ { EfiBootServicesCode, 0x180 },
+ { EfiBootServicesData, 0xF00 },
+ { EfiMaxMemoryType, 0x000 }
+};
+
+
+EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiMasterBootModePpiGuid,
+ NULL
+ }
+};
+
+
+UINT16 mHostBridgeDevId;
+
+EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION;
+
+BOOLEAN mS3Supported = FALSE;
+
+UINT32 mMaxCpuCount;
+
+VOID
+AddIoMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize
+ )
+{
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_MAPPED_IO,
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_TESTED,
+ MemoryBase,
+ MemorySize
+ );
+}
+
+VOID
+AddReservedMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize,
+ BOOLEAN Cacheable
+ )
+{
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_RESERVED,
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ (Cacheable ?
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE :
+ 0
+ ) |
+ EFI_RESOURCE_ATTRIBUTE_TESTED,
+ MemoryBase,
+ MemorySize
+ );
+}
+
+VOID
+AddIoMemoryRangeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ EFI_PHYSICAL_ADDRESS MemoryLimit
+ )
+{
+ AddIoMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
+}
+
+
+VOID
+AddMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize
+ )
+{
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ 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,
+ MemoryBase,
+ MemorySize
+ );
+}
+
+
+VOID
+AddMemoryRangeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ EFI_PHYSICAL_ADDRESS MemoryLimit
+ )
+{
+ AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
+}
+
+
+VOID
+AddUntestedMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize
+ )
+{
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ 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,
+ MemoryBase,
+ MemorySize
+ );
+}
+
+
+VOID
+AddUntestedMemoryRangeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ EFI_PHYSICAL_ADDRESS MemoryLimit
+ )
+{
+ AddUntestedMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
+}
+
+VOID
+AddFlashDeviceRange (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize
+ )
+{
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_FIRMWARE_DEVICE,
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+ MemoryBase,
+ MemorySize
+ );
+
+ BuildMemoryAllocationHob (
+ MemoryBase,
+ MemorySize,
+ EfiMemoryMappedIO
+ );
+}
+
+VOID
+MemMapInitialization (
+ VOID
+ )
+{
+ UINT64 PciIoBase;
+ UINT64 PciIoSize;
+
+ UINT32 TopOfLowRam;
+ UINT64 PciExBarBase;
+ UINT32 PciBase;
+ UINT32 PciSize;
+
+ PciIoBase = 0xC000;
+ PciIoSize = 0x4000;
+
+ //
+ // Create Memory Type Information HOB
+ //
+ BuildGuidDataHob (
+ &gEfiMemoryTypeInformationGuid,
+ mDefaultMemoryTypeInformation,
+ sizeof(mDefaultMemoryTypeInformation)
+ );
+
+ //
+ // Video memory + Legacy BIOS region
+ //
+ AddIoMemoryRangeHob (0x0A0000, BASE_1MB);
+
+ TopOfLowRam = GetSystemMemorySizeBelow4gb ();
+ PciExBarBase = 0;
+ if (mHostBridgeDevId == INTEL_ICH10_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 = FixedPcdGet64 (PcdPciExpressBaseAddress);
+ ASSERT (TopOfLowRam <= PciExBarBase);
+ ASSERT (PciExBarBase <= MAX_UINT32 - SIZE_256MB);
+ PciBase = (UINT32)(PciExBarBase + SIZE_256MB);
+ } else {
+ PciBase = (TopOfLowRam < BASE_2GB) ? BASE_2GB : TopOfLowRam;
+ }
+
+ //
+ // address purpose size
+ // ------------ -------- -------------------------
+ // 0x00000000 TopOfLowRam 0xDF000000
+ // 0xDF000000 Tseg+UMA 0x01000000
+ // 0xE0000000 PciExBarBase 0x10000000
+ // 0xF0000000 PciBase 0x0C000000
+ // -------------------------------------------------
+ // 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 = 0xFC000000 - PciBase;
+ AddIoMemoryBaseSizeHob (PciBase, PciSize);
+ PcdSet64 (PcdPciMmio32Base, PciBase);
+ PcdSet64 (PcdPciMmio32Size, PciSize);
+ AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);
+ AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);
+ if (mHostBridgeDevId == INTEL_ICH10_DEVICE_ID) {
+ AddIoMemoryBaseSizeHob (ICH10_ROOT_COMPLEX_BASE, SIZE_16KB);
+ //
+ // Note: there should be an
+ //
+ // AddIoMemoryBaseSizeHob (PciExBarBase, SIZE_256MB);
+ // BuildMemoryAllocationHob (PciExBarBase, SIZE_256MB, EfiMemoryMappedIO);
+ //
+ // 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 can
+ // *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 area
+ // is most definitely not RAM; so, as an exception, cover it with
+ // uncacheable reserved memory right here.
+ //
+ AddReservedMemoryBaseSizeHob (PciExBarBase, SIZE_256MB, FALSE);
+ BuildMemoryAllocationHob (PciExBarBase, SIZE_256MB,
+ EfiReservedMemoryType);
+ }
+ AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress), SIZE_1MB);
+
+ // Add PCI IO Port space available for PCI resource allocations.
+ //
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_IO,
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED,
+ PciIoBase,
+ PciIoSize
+ );
+ PcdSet64 (PcdPciIoBase, PciIoBase);
+ PcdSet64 (PcdPciIoSize, PciIoSize);
+
+ //
+ // Add flash range.
+ //
+ AddFlashDeviceRange (PcdGet32(PcdFlashAreaBaseAddress), PcdGet32(PcdFlashAreaSize));
+ //
+ // Video memory / ABSEG
+ //
+ AddIoMemoryBaseSizeHob (0x0A0000, 0x20000);
+ //
+ // Legacy BIOS region.
+ //
+ AddReservedMemoryBaseSizeHob (0xC0000, 0x40000, TRUE);
+}
+
+VOID
+MiscInitialization (
+ VOID
+ )
+{
+ 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 during
+ // S3 resume as well, so we build it unconditionally.)
+ //
+ BuildCpuHob (mPhysMemAddressWidth, 16);
+
+ //
+ // Determine platform type and save Host Bridge DID to PCD
+ //
+ switch (mHostBridgeDevId) {
+ case INTEL_82441_DEVICE_ID:
+ PmCmd = POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET);
+ Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
+ PmbaAndVal = ~(UINT32)PIIX4_PMBA_MASK;
+ PmbaOrVal = PIIX4_PMBA_VALUE;
+ AcpiCtlReg = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC);
+ AcpiEnBit = PIIX4_PMREGMISC_PMIOSE;
+ break;
+ case INTEL_ICH10_DEVICE_ID:
+ PmCmd = POWER_MGMT_REGISTER_ICH10 (PCI_COMMAND_OFFSET);
+ Pmba = POWER_MGMT_REGISTER_ICH10 (ICH10_PMBASE);
+ PmbaAndVal = ~(UINT32)ICH10_PMBASE_MASK;
+ PmbaOrVal = ICH10_PMBASE_VALUE;
+ AcpiCtlReg = POWER_MGMT_REGISTER_ICH10 (ICH10_ACPI_CNTL);
+ AcpiEnBit = ICH10_ACPI_CNTL_ACPI_EN;
+ break;
+ default:
+ DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
+ __FUNCTION__, mHostBridgeDevId));
+ ASSERT (FALSE);
+ return;
+ }
+ PcdSet16 (PcdSimicsX58HostBridgePciDevId, mHostBridgeDevId);
+
+ //
+ // 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) == 0) {
+ //
+ // The PEI phase should be exited with fully accessibe ACPI PM IO space:
+ // 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 (mHostBridgeDevId == INTEL_ICH10_DEVICE_ID) {
+ //
+ // Set Root Complex Register Block BAR
+ //
+ PciWrite32 (
+ POWER_MGMT_REGISTER_ICH10 (ICH10_RCBA),
+ ICH10_ROOT_COMPLEX_BASE | ICH10_RCBA_EN
+ );
+
+ }
+ //
+ // Set the PM I/O base address to 0x400
+ //
+ PciAndThenOr32 (
+ PCI_LIB_ADDRESS (
+ 0,
+ 31,
+ 0,
+ 0x40
+ ),
+ (UINT32) ~0xfc0, ICH10_PMBASE_VALUE
+ );
+ //
+ // Enable AHCI and all ports on the SATA controller.
+ //
+ // Address MAP Reg, setting AHCI mode
+ //
+ PciOr16 (PCI_LIB_ADDRESS (0, 31, 2, 0x90), 0x0060);
+ //
+ //Enabling Ports 0-5
+ //
+ PciOr16 (PCI_LIB_ADDRESS (0, 31, 2, 0x92), 0x003F);
+ //
+ //Disabling Sata Controller 2, bit 25 = 1, bit 0 = 1
+ //
+ MmioWrite32(0xFED1F418, 0x02000001);
+ //
+ //Enable HPET at FED0_0000h – FED0_03FFh
+ //
+ MmioWrite8(ICH10_ROOT_COMPLEX_BASE + 0x3404, 0x80);
+ //
+ //Config and enable APIC
+ //
+ MmioWrite32(0xFEC00000 + 0X0, 0);
+ MmioWrite32(0xFEC00000 + 0X10, PcdGet8(PcdIoApicId)<<24);
+ MmioWrite8(ICH10_ROOT_COMPLEX_BASE + 0x31FF, 0x01);
+}
+
+
+VOID
+BootModeInitialization (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG((EFI_D_INFO, "modeValue = %x\n", IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12)));
+ if (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) == 0x5) {
+ mBootMode = BOOT_ON_S3_RESUME;
+ }
+
+ Status = PeiServicesSetBootMode (mBootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PeiServicesInstallPpi (mPpiBootMode);
+ ASSERT_EFI_ERROR (Status);
+}
+
+
+VOID
+ReserveEmuVariableNvStore (
+ )
+{
+ EFI_PHYSICAL_ADDRESS VariableStore;
+
+ //
+ // Allocate storage for NV variables early on so it will be
+ // at a consistent address. Since VM memory is preserved
+ // across reboots, this allows the NV variable storage to survive
+ // a VM reboot.
+ //
+ VariableStore =
+ (EFI_PHYSICAL_ADDRESS)(UINTN)
+ AllocateRuntimePages (
+ EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize))
+ );
+ DEBUG ((EFI_D_INFO,
+ "Reserved variable store memory: 0x%lX; size: %dkb\n",
+ VariableStore,
+ (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / 1024
+ ));
+ PcdSet64 (PcdEmuVariableNvStoreReserved, VariableStore);
+}
+
+
+VOID
+SimicsVersionCheck(
+ VOID
+ )
+{
+
+ UINTN PciAddrPtr;
+ UINT8 CapOffset;
+ STATIC CHAR8 SimicsStr[0x100];
+ UINTN i;
+ UINT32 MajorVersion;
+ UINT32 MinorVersion;
+ UINT32 ModelNumber;
+
+ PciAddrPtr = PCI_LIB_ADDRESS(0, SIMICS_SIDEBANDPCI_DEV, SIMICS_SIDEBANDPCI_FUNC, 0);
+ CapOffset = PciRead8(PciAddrPtr + PCI_CAPBILITY_POINTER_OFFSET);
+ if (CapOffset != 0xFF) {
+ ModelNumber = PciRead32(PciAddrPtr + CapOffset + 4);
+ MajorVersion = PciRead32(PciAddrPtr + CapOffset + 8);
+ MinorVersion = PciRead32(PciAddrPtr + CapOffset + 0xc);
+ for (i = 0; i < 0x80; i++) {
+ SimicsStr[i] = PciRead8(PciAddrPtr + CapOffset + 0x10 + i);
+ }
+ DEBUG((EFI_D_INFO, "=============SIMICS Version info=============\n"));
+ DEBUG((EFI_D_INFO, "Model number = %d\n", ModelNumber));
+ DEBUG((EFI_D_INFO, "Major version = %d\n", MajorVersion));
+ DEBUG((EFI_D_INFO, "Minor version = %d\n", MinorVersion));
+ DEBUG((EFI_D_INFO, "%a\n", SimicsStr));
+ DEBUG((EFI_D_INFO, "=============================================\n"));
+ }
+}
+
+VOID
+DebugDumpCmos (
+ VOID
+ )
+{
+ UINT32 Loop;
+
+ DEBUG ((EFI_D_INFO, "CMOS:\n"));
+
+ for (Loop = 0; Loop < 0x80; Loop++) {
+ if ((Loop % 0x10) == 0) {
+ DEBUG ((EFI_D_INFO, "%02x:", Loop));
+ }
+ DEBUG ((EFI_D_INFO, " %02x", CmosRead8 (Loop)));
+ if ((Loop % 0x10) == 0xf) {
+ DEBUG ((EFI_D_INFO, "\n"));
+ }
+ }
+}
+
+
+/**
+ Fetch the number of boot CPUs from QEMU and expose it to UefiCpuPkg modules.
+ Set the mMaxCpuCount variable.
+**/
+VOID
+MaxCpuCountInitialization (
+ VOID
+ )
+{
+ mMaxCpuCount = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
+ return;
+}
+
+/**
+ Determine if S3 support is explicitly enabled.
+
+ @retval TRUE If S3 support is explicitly enabled. Other functions in this
+ library may be called (subject to their individual
+ restrictions).
+
+ FALSE Otherwise. This includes unavailability of the firmware
+ configuration interface. No other function in this library
+ must be called.
+**/
+BOOLEAN
+EFIAPI
+QemuFwCfgS3Enabled(
+ VOID
+)
+{
+ //TO DO IF NEEDED
+ return TRUE;
+}
+
+/**
+ Perform Platform PEI initialization.
+
+ @param FileHandle Handle of the file being invoked.
+ @param PeiServices Describes the list of possible PEI Services.
+
+ @return EFI_SUCCESS The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializePlatform (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_ERROR, "Platform PEIM Loaded\n"));
+
+ SimicsVersionCheck ();
+ DebugDumpCmos ();
+
+ if (QemuFwCfgS3Enabled ()) {
+ DEBUG ((EFI_D_INFO, "S3 support was detected on SIMICS\n"));
+ mS3Supported = TRUE;
+ Status = PcdSetBoolS (PcdAcpiS3Enable, TRUE);
+ ASSERT_EFI_ERROR (Status);
+ }
+ AddressWidthInitialization ();
+ MaxCpuCountInitialization ();
+
+ mHostBridgeDevId = PciRead16(SIMICS_HOSTBRIDGE_DID);
+
+ if (FeaturePcdGet (PcdSmmSmramRequire)) {
+ X58TsegMbytesInitialization ();
+ }
+
+ PublishPeiMemory ();
+
+ InitializeRamRegions ();
+
+ if (mBootMode != BOOT_ON_S3_RESUME) {
+ if (!FeaturePcdGet (PcdSmmSmramRequire)) {
+ ReserveEmuVariableNvStore ();
+ }
+ MemMapInitialization ();
+ }
+
+ MiscInitialization ();
+ InstallFeatureControlCallback ();
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
new file mode 100644
index 0000000000..bbd96b4e36
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
@@ -0,0 +1,148 @@
+/** @file
+ This driver installs SMBIOS information for QSP
+
+ Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>
+ Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SmbiosPlatformDxe.h"
+
+
+/**
+Reads 8-bits of CMOS data.
+
+Reads the 8-bits of CMOS data at the location specified by Index.
+The 8-bit read value is returned.
+
+@param Index The CMOS location to read.
+
+@return The value read.
+
+**/
+UINT8
+EFIAPI
+CmosRead8(
+ IN UINTN Index
+ )
+{
+ IoWrite8(0x70, (UINT8)Index);
+ return IoRead8(0x71);
+}
+
+UINT32
+GetSystemMemorySizeBelow4gb(
+ VOID
+ )
+{
+ UINT8 Cmos0x34;
+ UINT8 Cmos0x35;
+
+ //
+ // CMOS 0x34/0x35 specifies the system memory above 16 MB.
+ // * CMOS(0x35) is the high byte
+ // * CMOS(0x34) is the low byte
+ // * The size is specified in 64kb chunks
+ // * Since this is memory above 16MB, the 16MB must be added
+ // into the calculation to get the total memory size.
+ //
+
+ Cmos0x34 = (UINT8)CmosRead8(0x34);
+ Cmos0x35 = (UINT8)CmosRead8(0x35);
+
+ return (UINT32)(((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);
+}
+
+STATIC
+UINT64
+GetSystemMemorySizeAbove4gb(
+ VOID
+)
+{
+ UINT32 Size;
+ UINTN CmosIndex;
+
+ //
+ // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
+ // * CMOS(0x5d) is the most significant size byte
+ // * CMOS(0x5c) is the middle size byte
+ // * CMOS(0x5b) is the least significant size byte
+ // * The size is specified in 64kb chunks
+ //
+
+ Size = 0;
+ for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {
+ Size = (UINT32)(Size << 8) + (UINT32)CmosRead8(CmosIndex);
+ }
+
+ return LShiftU64(Size, 16);
+}
+
+/**
+ Installs SMBIOS information for SIMICS QSP
+
+ @param ImageHandle Module's image handle
+ @param SystemTable Pointer of EFI_SYSTEM_TABLE
+
+ @retval EFI_SUCCESS Smbios data successfully installed
+ @retval Other Smbios data was not installed
+
+**/
+EFI_STATUS
+EFIAPI
+SmbiosTablePublishEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMBIOS_PROTOCOL *Smbios;
+ SMBIOS_TABLE_TYPE19 *Type19Record;
+ EFI_SMBIOS_HANDLE MemArrayMappedAddrSmbiosHandle;
+ UINT8 NumSlots;
+ UINT64 TotalMemorySize;
+
+ //
+ // Find the SMBIOS protocol
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiSmbiosProtocolGuid,
+ NULL,
+ (VOID**)&Smbios
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Generate Memory Array Mapped Address info
+ //
+ NumSlots = 2;
+ TotalMemorySize = 0;
+ TotalMemorySize = GetSystemMemorySizeBelow4gb();
+ Type19Record = AllocatePool(sizeof(SMBIOS_TABLE_TYPE19));
+ ZeroMem(Type19Record, sizeof(SMBIOS_TABLE_TYPE19));
+ Type19Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS;
+ Type19Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE19);
+ Type19Record->Hdr.Handle = 0;
+ Type19Record->StartingAddress = 0;
+ Type19Record->EndingAddress = (UINT32)RShiftU64(TotalMemorySize, 10) - 1;
+ Type19Record->MemoryArrayHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Type19Record->PartitionWidth = (UINT8)(NumSlots);
+
+ MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios->Add(Smbios, NULL, &MemArrayMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*)Type19Record);
+ ASSERT_EFI_ERROR(Status);
+
+ TotalMemorySize = GetSystemMemorySizeAbove4gb();
+ Type19Record->StartingAddress = 0xFFFFFFFF;
+ Type19Record->ExtendedStartingAddress = 0xFFFFFFFF;
+ Type19Record->ExtendedEndingAddress = TotalMemorySize + 0xFFFFFFFF - 1;
+
+ MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios->Add(Smbios, NULL, &MemArrayMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*)Type19Record);
+ FreePool(Type19Record);
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf
new file mode 100644
index 0000000000..b8d326cdb6
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf
@@ -0,0 +1,31 @@
+## @file
+# Component description file for PlatformAcpiTables module.
+#
+# ACPI table data and ASL sources required to boot the platform.
+#
+# Copyright (c) 2008 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformAcpiTables
+ FILE_GUID = 7E374E25-8E01-4FEE-87F2-390C23C606CD
+ MODULE_TYPE = USER_DEFINED
+ VERSION_STRING = 1.0
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ Platform.h
+ Dsdt.asl
+
+[Packages]
+ MdePkg/MdePkg.dec
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl
new file mode 100644
index 0000000000..8a6c3792ba
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl
@@ -0,0 +1,821 @@
+/** @file
+ Contains root level name space objects for the platform
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+DefinitionBlock ("Dsdt.aml", "DSDT", 1, "INTEL ", "SIMICS ", 4) {
+ //
+ // System Sleep States
+ //
+ Name (\_S3, Package () {5, 5, 0, 0})
+ Name (\_S4, Package () {6, 6, 0, 0})
+ Name (\_S5, Package () {7, 7, 0, 0})
+
+ Name (GPIC, Zero)
+ Method (_PIC, 1, NotSerialized) // _PIC: Interrupt Model
+ {
+ GPIC = Arg0
+ }
+ //
+ // System Bus
+ //
+ Scope (\_SB) {
+ //
+ // PCI Root Bridge
+ //
+ Device (PCI0) {
+ Name (_HID, EISAID ("PNP0A03"))
+ Name (_ADR, 0x00000000)
+ Name (_BBN, 0x00)
+ Name (_UID, 0x00)
+
+
+ // Current resource settings
+ Name (_CRS, ResourceTemplate () {
+ WORDBusNumber ( // Bus number resource (0); the bridge produces bus numbers for its subsequent buses
+ ResourceProducer, // bit 0 of general flags is 1
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is fixed
+ PosDecode, // PosDecode
+ 0x0000, // Granularity
+ 0x0000, // Min
+ 0x00FF, // Max
+ 0x0000, // Translation
+ 0x0100 // Range Length = Max-Min+1
+ )
+
+ IO (Decode16, 0xCF8, 0xCF8, 0x01, 0x08) //Consumed resource (0xCF8-0xCFF)
+
+ WORDIO ( // Consumed-and-produced resource (all I/O below CF8)
+ ResourceProducer, // bit 0 of general flags is 0
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is fixed
+ PosDecode,
+ EntireRange,
+ 0x0000, // Granularity
+ 0x0000, // Min
+ 0x0CF7, // Max
+ 0x0000, // Translation
+ 0x0CF8 // Range Length
+ )
+
+ WORDIO ( // Consumed-and-produced resource (all I/O above CFF)
+ ResourceProducer, // bit 0 of general flags is 0
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is fixed
+ PosDecode,
+ EntireRange,
+ 0x0000, // Granularity
+ 0x0D00, // Min
+ 0xFFFF, // Max
+ 0x0000, // Translation
+ 0xF300 // Range Length
+ )
+
+ DWORDMEMORY ( // Descriptor for legacy VGA video RAM
+ ResourceProducer, // bit 0 of general flags is 0
+ PosDecode,
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is Fixed
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ 0x000A0000, // Min
+ 0x000BFFFF, // Max
+ 0x00000000, // Translation
+ 0x00020000 // Range Length
+ )
+
+ DWORDMEMORY ( // Descriptor for 32-bit MMIO
+ ResourceProducer, // bit 0 of general flags is 0
+ PosDecode,
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is Fixed
+ NonCacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ 0xF0000000, // Min
+ 0xFBFFFFFF, // Max
+ 0x00000000, // Translation
+ 0x0C000000, // Range Length
+ , // ResourceSourceIndex
+ , // ResourceSource
+ PW32 // DescriptorName
+ )
+ })
+
+ //
+ // PCI Interrupt Routing Table - PIC Mode Only
+ //
+ // If you change the IRQ mapping here you also need
+ // to change the mapping in the south bridge
+ // (pci-conf.py) and in the BIOS.
+ // INTA -> 0xa (10)
+ // INTB -> 0xb (11)
+ // INTC -> 0xa (10)
+ // INTD -> 0xb (11)
+
+ Method (_PRT, 0, NotSerialized) {
+ If (GPIC) {
+ Return (AR00) // APIC Mode
+ }
+ Return (PR00) // PIC Mode
+ }
+
+ Name (PR00, Package(){
+ Package () {0x000FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x000FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x000FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x000FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ //
+ // Bus 0, Device 1
+ //
+ Package () {0x0001FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0001FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0001FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0001FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0002FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0002FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0002FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0002FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+ //
+ // Bus 0, Device 3
+ //
+ Package () {0x0003FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0003FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0003FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0003FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0004FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0004FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0004FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0004FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0005FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0005FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0005FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0005FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0006FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0006FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0006FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0006FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0007FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0007FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0007FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0007FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0008FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0008FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0008FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0008FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0009FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0009FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0009FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0009FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x000AFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x000AFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x000AFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x000AFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x000BFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x000BFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x000BFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x000BFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x000CFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x000CFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x000CFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x000CFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x000DFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x000DFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x000DFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x000DFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x000EFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x000EFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x000EFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x000EFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x000FFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x000FFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x000FFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x000FFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00010FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00010FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00010FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00010FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00011FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00011FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00011FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00011FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00012FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00012FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00012FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00012FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00013FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00013FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00013FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00013FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00014FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00014FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00014FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00014FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00015FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00015FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00015FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00015FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00016FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00016FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00016FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00016FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00017FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00017FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00017FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00017FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00018FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00018FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00018FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00018FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0001EFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0001EFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0001EFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0001EFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00019FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00019FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00019FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00019FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0001AFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0001AFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0001AFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0001AFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0001BFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0001BFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0001BFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0001BFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0001CFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0001CFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0001CFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0001CFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0001DFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0001DFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0001DFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0001DFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0001FFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0001FFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0001FFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0001FFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+ }
+ )
+
+ Name(AR00, Package(){
+
+ Package () {0x000FFFF, 0x00, 0, 16},
+ Package () {0x000FFFF, 0x01, 0, 17},
+ Package () {0x000FFFF, 0x02, 0, 18},
+ Package () {0x000FFFF, 0x03, 0, 19},
+
+ //
+ // Bus 0, Device 1
+ //
+ Package () {0x0001FFFF, 0x00, 0, 16},
+ Package () {0x0001FFFF, 0x01, 0, 17},
+ Package () {0x0001FFFF, 0x02, 0, 18},
+ Package () {0x0001FFFF, 0x03, 0, 19},
+
+ Package () {0x0002FFFF, 0x00, 0, 16},
+ Package () {0x0002FFFF, 0x01, 0, 17},
+ Package () {0x0002FFFF, 0x02, 0, 18},
+ Package () {0x0002FFFF, 0x03, 0, 19},
+ //
+ // Bus 0, Device 3
+ //
+ Package () {0x0003FFFF, 0x00, 0, 16},
+ Package () {0x0003FFFF, 0x01, 0, 17},
+ Package () {0x0003FFFF, 0x02, 0, 18},
+ Package () {0x0003FFFF, 0x03, 0, 19},
+
+ Package () {0x0004FFFF, 0x00, 0, 16},
+ Package () {0x0004FFFF, 0x01, 0, 17},
+ Package () {0x0004FFFF, 0x02, 0, 18},
+ Package () {0x0004FFFF, 0x03, 0, 19},
+
+ Package () {0x0005FFFF, 0x00, 0, 16},
+ Package () {0x0005FFFF, 0x01, 0, 17},
+ Package () {0x0005FFFF, 0x02, 0, 18},
+ Package () {0x0005FFFF, 0x03, 0, 19},
+
+ Package () {0x0006FFFF, 0x00, 0, 16},
+ Package () {0x0006FFFF, 0x01, 0, 17},
+ Package () {0x0006FFFF, 0x02, 0, 18},
+ Package () {0x0006FFFF, 0x03, 0, 19},
+
+ Package () {0x0007FFFF, 0x00, 0, 16},
+ Package () {0x0007FFFF, 0x01, 0, 17},
+ Package () {0x0007FFFF, 0x02, 0, 18},
+ Package () {0x0007FFFF, 0x03, 0, 19},
+
+ Package () {0x0008FFFF, 0x00, 0, 16},
+ Package () {0x0008FFFF, 0x01, 0, 17},
+ Package () {0x0008FFFF, 0x02, 0, 18},
+ Package () {0x0008FFFF, 0x03, 0, 19},
+
+ Package () {0x0009FFFF, 0x00, 0, 16},
+ Package () {0x0009FFFF, 0x01, 0, 17},
+ Package () {0x0009FFFF, 0x02, 0, 18},
+ Package () {0x0009FFFF, 0x03, 0, 19},
+
+ Package () {0x000AFFFF, 0x00, 0, 16},
+ Package () {0x000AFFFF, 0x01, 0, 17},
+ Package () {0x000AFFFF, 0x02, 0, 18},
+ Package () {0x000AFFFF, 0x03, 0, 19},
+
+ Package () {0x000BFFFF, 0x00, 0, 16},
+ Package () {0x000BFFFF, 0x01, 0, 17},
+ Package () {0x000BFFFF, 0x02, 0, 18},
+ Package () {0x000BFFFF, 0x03, 0, 19},
+
+ Package () {0x000CFFFF, 0x00, 0, 16},
+ Package () {0x000CFFFF, 0x01, 0, 17},
+ Package () {0x000CFFFF, 0x02, 0, 18},
+ Package () {0x000CFFFF, 0x03, 0, 19},
+
+ Package () {0x000DFFFF, 0x00, 0, 16},
+ Package () {0x000DFFFF, 0x01, 0, 17},
+ Package () {0x000DFFFF, 0x02, 0, 18},
+ Package () {0x000DFFFF, 0x03, 0, 19},
+
+ Package () {0x000EFFFF, 0x00, 0, 16},
+ Package () {0x000EFFFF, 0x01, 0, 17},
+ Package () {0x000EFFFF, 0x02, 0C, 18},
+ Package () {0x000EFFFF, 0x03, 0, 19},
+
+ Package () {0x000FFFFF, 0x00, 0, 16},
+ Package () {0x000FFFFF, 0x01, 0, 17},
+ Package () {0x000FFFFF, 0x02, 0, 18},
+ Package () {0x000FFFFF, 0x03, 0, 19},
+
+ Package () {0x00010FFFF, 0x00, 0, 16},
+ Package () {0x00010FFFF, 0x01, 0, 17},
+ Package () {0x00010FFFF, 0x02, 0, 18},
+ Package () {0x00010FFFF, 0x03, 0, 19},
+
+ Package () {0x00011FFFF, 0x00, 0, 16},
+ Package () {0x00011FFFF, 0x01, 0, 17},
+ Package () {0x00011FFFF, 0x02, 0, 18},
+ Package () {0x00011FFFF, 0x03, 0, 19},
+
+ Package () {0x00012FFFF, 0x00, 0, 16},
+ Package () {0x00012FFFF, 0x01, 0, 17},
+ Package () {0x00012FFFF, 0x02, 0, 18},
+ Package () {0x00012FFFF, 0x03, 0, 19},
+
+ Package () {0x00013FFFF, 0x00, 0, 16},
+ Package () {0x00013FFFF, 0x01, 0, 17},
+ Package () {0x00013FFFF, 0x02, 0, 18},
+ Package () {0x00013FFFF, 0x03, 0, 19},
+
+ Package () {0x00014FFFF, 0x00, 0, 16},
+ Package () {0x00014FFFF, 0x01, 0, 17},
+ Package () {0x00014FFFF, 0x02, 0, 18},
+ Package () {0x00014FFFF, 0x03, 0, 19},
+
+ Package () {0x00015FFFF, 0x00, 0, 16},
+ Package () {0x00015FFFF, 0x01, 0, 17},
+ Package () {0x00015FFFF, 0x02, 0, 18},
+ Package () {0x00015FFFF, 0x03, 0, 19},
+
+ Package () {0x00016FFFF, 0x00, 0, 16},
+ Package () {0x00016FFFF, 0x01, 0, 17},
+ Package () {0x00016FFFF, 0x02, 0, 18},
+ Package () {0x00016FFFF, 0x03, 0, 19},
+
+ Package () {0x00017FFFF, 0x00, 0, 16},
+ Package () {0x00017FFFF, 0x01, 0, 17},
+ Package () {0x00017FFFF, 0x02, 0, 18},
+ Package () {0x00017FFFF, 0x03, 0, 19},
+
+ Package () {0x00018FFFF, 0x00, 0, 16},
+ Package () {0x00018FFFF, 0x01, 0, 17},
+ Package () {0x00018FFFF, 0x02, 0, 18},
+ Package () {0x00018FFFF, 0x03, 0, 19},
+
+ Package () {0x0001EFFFF, 0x00, 0, 16},
+ Package () {0x0001EFFFF, 0x01, 0, 17},
+ Package () {0x0001EFFFF, 0x02, 0, 18},
+ Package () {0x0001EFFFF, 0x03, 0, 19},
+
+ Package () {0x00019FFFF, 0x00, 0, 16},
+ Package () {0x00019FFFF, 0x01, 0, 17},
+ Package () {0x00019FFFF, 0x02, 0, 18},
+ Package () {0x00019FFFF, 0x03, 0, 19},
+
+ Package () {0x0001AFFFF, 0x00, 0, 16},
+ Package () {0x0001AFFFF, 0x01, 0, 17},
+ Package () {0x0001AFFFF, 0x02, 0, 18},
+ Package () {0x0001AFFFF, 0x03, 0, 19},
+
+ Package () {0x0001BFFFF, 0x00, 0, 16},
+ Package () {0x0001BFFFF, 0x01, 0, 17},
+ Package () {0x0001BFFFF, 0x02, 0, 18},
+ Package () {0x0001BFFFF, 0x03, 0, 19},
+
+ Package () {0x0001CFFFF, 0x00, 0, 16},
+ Package () {0x0001CFFFF, 0x01, 0, 17},
+ Package () {0x0001CFFFF, 0x02, 0, 18},
+ Package () {0x0001CFFFF, 0x03, 0, 19},
+
+ Package () {0x0001DFFFF, 0x00, 0, 16},
+ Package () {0x0001DFFFF, 0x01, 0, 17},
+ Package () {0x0001DFFFF, 0x02, 0, 18},
+ Package () {0x0001DFFFF, 0x03, 0, 19},
+
+ Package () {0x0001FFFFF, 0x00, 0, 16},
+ Package () {0x0001FFFFF, 0x01, 0, 17},
+ Package () {0x0001FFFFF, 0x02, 0, 18},
+ Package () {0x0001FFFFF, 0x03, 0, 19},
+ }
+ )
+
+ //
+ // PCI to ISA Bridge (Bus 0, Device 7, Function 0)
+ //
+ Device (LPC) {
+ Name (_ADR, 0x001F0000)
+
+ //
+ // PCI Interrupt Routing Configuration Registers
+ //
+ OperationRegion (PRR0, PCI_Config, 0x60, 0x0C)
+ Field (PRR0, ANYACC, NOLOCK, PRESERVE) {
+ PIRA, 8,
+ PIRB, 8,
+ PIRC, 8,
+ PIRD, 8,
+ Offset (0x04),
+ PIRE, 8,
+ PIRF, 8,
+ PIRG, 8,
+ PIRH, 8
+ }
+
+ //
+ // _STA method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH
+ //
+ Method (PSTA, 1, NotSerialized) {
+ If (And (Arg0, 0x80)) {
+ Return (0x9)
+ } Else {
+ Return (0xB)
+ }
+ }
+
+ //
+ // _DIS method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH
+ //
+ Method (PDIS, 1, NotSerialized) {
+ Or (Arg0, 0x80, Arg0)
+ }
+
+ //
+ // _CRS method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH
+ //
+ Method (PCRS, 1, NotSerialized) {
+ Name (BUF0, ResourceTemplate () {IRQ (Level, ActiveLow, Shared){0}})
+ //
+ // Define references to buffer elements
+ //
+ CreateWordField (BUF0, 0x01, IRQW) // IRQ low
+ //
+ // Write current settings into IRQ descriptor
+ //
+ If (And (Arg0, 0x80)) {
+ Store (Zero, Local0)
+ } Else {
+ Store (One, Local0)
+ }
+ //
+ // Shift 1 by value in register 70
+ //
+ ShiftLeft (Local0, And (Arg0, 0x0F), IRQW) // Save in buffer
+ Return (BUF0) // Return Buf0
+ }
+
+ //
+ // _PRS resource for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH
+ //
+ Name (PPRS, ResourceTemplate () {
+ IRQ (Level, ActiveLow, Shared) {3, 4, 5, 7, 9, 10, 11, 12, 14, 15}
+ })
+
+ //
+ // _SRS method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH
+ //
+ Method (PSRS, 2, NotSerialized) {
+ CreateWordField (Arg1, 0x01, IRQW) // IRQ low
+ FindSetRightBit (IRQW, Local0) // Set IRQ
+ If (LNotEqual (IRQW, Zero)) {
+ And (Local0, 0x7F, Local0)
+ Decrement (Local0)
+ } Else {
+ Or (Local0, 0x80, Local0)
+ }
+ Store (Local0, Arg0)
+ }
+
+ //
+ // PCI IRQ Link A
+ //
+ Device (LNKA) {
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 1)
+
+ Method (_STA, 0, NotSerialized) { Return (PSTA (PIRA)) }
+ Method (_DIS, 0, NotSerialized) { PDIS (PIRA) }
+ Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRA)) }
+ Method (_PRS, 0, NotSerialized) { Return (PPRS) }
+ Method (_SRS, 1, NotSerialized) { PSRS (PIRA, Arg0) }
+ }
+
+ //
+ // PCI IRQ Link B
+ //
+ Device (LNKB) {
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 2)
+
+ Method (_STA, 0, NotSerialized) { Return (PSTA (PIRB)) }
+ Method (_DIS, 0, NotSerialized) { PDIS (PIRB) }
+ Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRB)) }
+ Method (_PRS, 0, NotSerialized) { Return (PPRS) }
+ Method (_SRS, 1, NotSerialized) { PSRS (PIRB, Arg0) }
+ }
+
+ //
+ // PCI IRQ Link C
+ //
+ Device (LNKC) {
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 3)
+
+ Method (_STA, 0, NotSerialized) { Return (PSTA (PIRC)) }
+ Method (_DIS, 0, NotSerialized) { PDIS (PIRC) }
+ Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRC)) }
+ Method (_PRS, 0, NotSerialized) { Return (PPRS) }
+ Method (_SRS, 1, NotSerialized) { PSRS (PIRC, Arg0) }
+ }
+
+ //
+ // PCI IRQ Link D
+ //
+ Device (LNKD) {
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 4)
+
+ Method (_STA, 0, NotSerialized) { Return (PSTA (PIRD)) }
+ Method (_DIS, 0, NotSerialized) { PDIS (PIRD) }
+ Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRD)) }
+ Method (_PRS, 0, NotSerialized) { Return (PPRS) }
+ Method (_SRS, 1, NotSerialized) { PSRS (PIRD, Arg0) }
+ }
+
+ //
+ // PCI IRQ Link E
+ //
+ Device (LNKE) {
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 5)
+
+ Method (_STA, 0, NotSerialized) { Return (PSTA (PIRE)) }
+ Method (_DIS, 0, NotSerialized) { PDIS (PIRE) }
+ Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRE)) }
+ Method (_PRS, 0, NotSerialized) { Return (PPRS) }
+ Method (_SRS, 1, NotSerialized) { PSRS (PIRE, Arg0) }
+ }
+
+ //
+ // PCI IRQ Link F
+ //
+ Device (LNKF) {
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 6)
+
+ Method (_STA, 0, NotSerialized) { Return (PSTA (PIRF)) }
+ Method (_DIS, 0, NotSerialized) { PDIS (PIRF) }
+ Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRF)) }
+ Method (_PRS, 0, NotSerialized) { Return (PPRS) }
+ Method (_SRS, 1, NotSerialized) { PSRS (PIRF, Arg0) }
+ }
+
+ //
+ // PCI IRQ Link G
+ //
+ Device (LNKG) {
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 7)
+
+ Method (_STA, 0, NotSerialized) { Return (PSTA (PIRG)) }
+ Method (_DIS, 0, NotSerialized) { PDIS (PIRG) }
+ Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRG)) }
+ Method (_PRS, 0, NotSerialized) { Return (PPRS) }
+ Method (_SRS, 1, NotSerialized) { PSRS (PIRG, Arg0) }
+ }
+
+ //
+ // PCI IRQ Link H
+ //
+ Device (LNKH) {
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 8)
+
+ Method (_STA, 0, NotSerialized) { Return (PSTA (PIRH)) }
+ Method (_DIS, 0, NotSerialized) { PDIS (PIRH) }
+ Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRH)) }
+ Method (_PRS, 0, NotSerialized) { Return (PPRS) }
+ Method (_SRS, 1, NotSerialized) { PSRS (PIRH, Arg0) }
+ }
+
+ //
+ // Programmable Interrupt Controller (PIC)
+ //
+ Device(PIC) {
+ Name (_HID, EISAID ("PNP0000"))
+ Name (_CRS, ResourceTemplate () {
+ IO (Decode16, 0x020, 0x020, 0x00, 0x02)
+ IO (Decode16, 0x0A0, 0x0A0, 0x00, 0x02)
+ IO (Decode16, 0x4D0, 0x4D0, 0x00, 0x02)
+ IRQNoFlags () {2}
+ })
+ }
+
+ //
+ // ISA DMA
+ //
+ Device (DMAC) {
+ Name (_HID, EISAID ("PNP0200"))
+ Name (_CRS, ResourceTemplate () {
+ IO (Decode16, 0x00, 0x00, 0, 0x10)
+ IO (Decode16, 0x81, 0x81, 0, 0x03)
+ IO (Decode16, 0x87, 0x87, 0, 0x01)
+ IO (Decode16, 0x89, 0x89, 0, 0x03)
+ IO (Decode16, 0x8f, 0x8f, 0, 0x01)
+ IO (Decode16, 0xc0, 0xc0, 0, 0x20)
+ DMA (Compatibility, NotBusMaster, Transfer8) {4}
+ })
+ }
+
+ //
+ // 8254 Timer
+ //
+ Device(TMR) {
+ Name(_HID,EISAID("PNP0100"))
+ Name(_CRS, ResourceTemplate () {
+ IO (Decode16, 0x40, 0x40, 0x00, 0x04)
+ IRQNoFlags () {0}
+ })
+ }
+
+ //
+ // Real Time Clock
+ //
+ Device (RTC) {
+ Name (_HID, EISAID ("PNP0B00"))
+ Name (_CRS, ResourceTemplate () {
+ IO (Decode16, 0x70, 0x70, 0x00, 0x02)
+ IRQNoFlags () {8}
+ })
+ }
+
+ //
+ // PCAT Speaker
+ //
+ Device(SPKR) {
+ Name (_HID, EISAID("PNP0800"))
+ Name (_CRS, ResourceTemplate () {
+ IO (Decode16, 0x61, 0x61, 0x01, 0x01)
+ })
+ }
+
+ //
+ // Floating Point Coprocessor
+ //
+ Device(FPU) {
+ Name (_HID, EISAID("PNP0C04"))
+ Name (_CRS, ResourceTemplate () {
+ IO (Decode16, 0xF0, 0xF0, 0x00, 0x10)
+ IRQNoFlags () {13}
+ })
+ }
+
+ //
+ // Generic motherboard devices and pieces that don't fit anywhere else
+ //
+ Device(XTRA) {
+ Name (_HID, EISAID ("PNP0C02"))
+ Name (_UID, 0x01)
+ Name (_CRS, ResourceTemplate () {
+ IO (Decode16, 0x010, 0x010, 0x00, 0x10)
+ IO (Decode16, 0x022, 0x022, 0x00, 0x1E)
+ IO (Decode16, 0x044, 0x044, 0x00, 0x1C)
+ IO (Decode16, 0x062, 0x062, 0x00, 0x02)
+ IO (Decode16, 0x065, 0x065, 0x00, 0x0B)
+ IO (Decode16, 0x072, 0x072, 0x00, 0x0E)
+ IO (Decode16, 0x080, 0x080, 0x00, 0x01)
+ IO (Decode16, 0x084, 0x084, 0x00, 0x03)
+ IO (Decode16, 0x088, 0x088, 0x00, 0x01)
+ IO (Decode16, 0x08c, 0x08c, 0x00, 0x03)
+ IO (Decode16, 0x090, 0x090, 0x00, 0x10)
+ IO (Decode16, 0x0A2, 0x0A2, 0x00, 0x1E)
+ IO (Decode16, 0x0E0, 0x0E0, 0x00, 0x10)
+ IO (Decode16, 0x1E0, 0x1E0, 0x00, 0x10)
+ IO (Decode16, 0x160, 0x160, 0x00, 0x10)
+ IO (Decode16, 0x278, 0x278, 0x00, 0x08)
+ IO (Decode16, 0x370, 0x370, 0x00, 0x02)
+ IO (Decode16, 0x378, 0x378, 0x00, 0x08)
+ IO (Decode16, 0x400, 0x400, 0x00, 0x40) // PMBLK1
+ IO (Decode16, 0x440, 0x440, 0x00, 0x10)
+ IO (Decode16, 0x678, 0x678, 0x00, 0x08)
+ IO (Decode16, 0x778, 0x778, 0x00, 0x08)
+ Memory32Fixed (ReadOnly, 0xFEC00000, 0x1000) // IO APIC
+ Memory32Fixed (ReadOnly, 0xFEE00000, 0x100000) // LAPIC
+ })
+ }
+
+ //
+ // PS/2 Keyboard and PC/AT Enhanced Keyboard 101/102
+ //
+ Device (PS2K) {
+ Name (_HID, EISAID ("PNP0303"))
+ Name (_CID, EISAID ("PNP030B"))
+ Name(_CRS,ResourceTemplate() {
+ IO (Decode16, 0x60, 0x60, 0x00, 0x01)
+ IO (Decode16, 0x64, 0x64, 0x00, 0x01)
+ IRQNoFlags () {1}
+ })
+ }
+
+ //
+ // PS/2 Mouse and Microsoft Mouse
+ //
+ Device (PS2M) { // PS/2 stype mouse port
+ Name (_HID, EISAID ("PNP0F03"))
+ Name (_CID, EISAID ("PNP0F13"))
+ Name (_CRS, ResourceTemplate() {
+ IRQNoFlags () {12}
+ })
+ }
+
+ //
+ // UART Serial Port - COM1
+ //
+ Device (UAR1) {
+ Name (_HID, EISAID ("PNP0501"))
+ Name (_DDN, "COM1")
+ Name (_UID, 0x01)
+ Name(_CRS,ResourceTemplate() {
+ IO (Decode16, 0x3F8, 0x3F8, 0x00, 0x08)
+ IRQ (Edge, ActiveHigh, Exclusive, ) {4}
+ })
+ }
+
+ //
+ // UART Serial Port - COM2
+ //
+ Device (UAR2) {
+ Name (_HID, EISAID ("PNP0501"))
+ Name (_DDN, "COM2")
+ Name (_UID, 0x02)
+ Name(_CRS,ResourceTemplate() {
+ IO (Decode16, 0x2F8, 0x2F8, 0x00, 0x08)
+ IRQ (Edge, ActiveHigh, Exclusive, ) {3}
+ })
+ }
+ }
+ }
+ }
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h
new file mode 100644
index 0000000000..6a4fcb172b
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h
@@ -0,0 +1,75 @@
+/** @file
+ Platform specific defines for constructing ACPI tables
+
+ Copyright (c) 2013 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ACPI_PLATFORM_H_
+#define _ACPI_PLATFORM_H_
+
+#include <PiDxe.h>
+#include <IndustryStandard/Acpi.h>
+
+//
+// ACPI table information used to initialize tables.
+//
+#define EFI_ACPI_OEM_ID 'S','I','M','I','C','S' // OEMID 6 bytes long
+#define EFI_ACPI_OEM_TABLE_ID SIGNATURE_64('S','I','M','I','C','S','T','B') // OEM table id 8 bytes long
+#define EFI_ACPI_OEM_REVISION 0x02000820
+#define EFI_ACPI_CREATOR_ID SIGNATURE_32('Q','S','P',' ')
+#define EFI_ACPI_CREATOR_REVISION 0x00000097
+
+#define INT_MODEL 0x01
+#define SCI_INT_VECTOR 0x0009
+#define SMI_CMD_IO_PORT 0xB2
+#define ACPI_ENABLE 0x0E1
+#define ACPI_DISABLE 0x01E
+#define S4BIOS_REQ 0x00
+#define PM1a_EVT_BLK 0x00000400
+#define PM1b_EVT_BLK 0x00000000
+#define PM1a_CNT_BLK 0x00000404
+#define PM1b_CNT_BLK 0x00000000
+#define PM2_CNT_BLK 0x00000450
+#define PM_TMR_BLK 0x00000408
+#define GPE0_BLK 0x00000420
+#define GPE1_BLK 0x00000000
+#define PM1_EVT_LEN 0x04
+#define PM1_CNT_LEN 0x04
+#define PM2_CNT_LEN 0x01
+#define PM_TM_LEN 0x04
+#define GPE0_BLK_LEN 0x10
+#define GPE1_BLK_LEN 0x00
+#define GPE1_BASE 0x00
+#define RESERVED 0x00
+#define P_LVL2_LAT 0x0065
+#define P_LVL3_LAT 0x03E9
+#define FLUSH_SIZE 0x0400
+#define FLUSH_STRIDE 0x0010
+#define DUTY_OFFSET 0x00
+#define DUTY_WIDTH 0x00
+#define DAY_ALRM 0x0D
+#define MON_ALRM 0x00
+#define CENTURY 0x00
+#define FLAG (EFI_ACPI_2_0_WBINVD | \
+ EFI_ACPI_2_0_PROC_C1 | \
+ EFI_ACPI_2_0_SLP_BUTTON | \
+ EFI_ACPI_2_0_RTC_S4 | \
+ EFI_ACPI_2_0_RESET_REG_SUP)
+#define RESET_REG 0xCF9
+#define RESET_VALUE (BIT2 | BIT1) // PIIX3 Reset CPU + System Reset
+
+//
+// Byte-aligned IO port register block initializer for
+// EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE
+//
+#define GAS2_IO(Base, Size) { \
+ EFI_ACPI_2_0_SYSTEM_IO, /* AddressSpaceId */ \
+ (Size) * 8, /* RegisterBitWidth */ \
+ 0, /* RegisterBitOffset */ \
+ 0, /* Reserved */ \
+ (Base) /* Address */ \
+ }
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsBoardConfig.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsBoardConfig.h
new file mode 100644
index 0000000000..dfbb1c0f3c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsBoardConfig.h
@@ -0,0 +1,17 @@
+/** @file
+ GUID for UEFI variables that are specific to Simics Board configuration.
+
+ Copyright (C) 2014, Red Hat, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __SIMICS_BOARD_CONFIG_H__
+#define __SIMICS_BOARD_CONFIG_H__
+
+#define SIMICS_BOARD_CONFIG_GUID \
+{0x8a318e00, 0xfaf5, 0x499f, { 0x91,0x75, 0xce, 0x4d, 0x8d, 0xa6, 0x70, 0xae}}
+
+extern EFI_GUID gSimicsBoardConfigGuid;
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/I440FxPiix4.h b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/I440FxPiix4.h
new file mode 100644
index 0000000000..e7d7fde14c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/I440FxPiix4.h
@@ -0,0 +1,49 @@
+/** @file
+ Various register numbers and value bits based on the following publications:
+ - Intel(R) datasheet 290549-001
+ - Intel(R) datasheet 290562-001
+ - Intel(R) datasheet 297654-006
+ - Intel(R) datasheet 297738-017
+
+ Copyright (C) 2015, Red Hat, Inc.
+ Copyright (c) 2014, Gabriel L. Somlo <somlo@cmu.edu>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __I440FX_PIIX4_H__
+#define __I440FX_PIIX4_H__
+
+#include <Library/PciLib.h>
+
+//
+// Host Bridge Device ID (DID) value for I440FX
+//
+#define INTEL_82441_DEVICE_ID 0x1237
+
+//
+// B/D/F/Type: 0/0/0/PCI
+//
+#define PMC_REGISTER_PIIX4(Offset) PCI_LIB_ADDRESS (0, 0, 0, (Offset))
+
+#define PIIX4_PAM0 0x59
+#define PIIX4_PAM1 0x5A
+#define PIIX4_PAM2 0x5B
+#define PIIX4_PAM3 0x5C
+#define PIIX4_PAM4 0x5D
+#define PIIX4_PAM5 0x5E
+#define PIIX4_PAM6 0x5F
+
+//
+// B/D/F/Type: 0/1/3/PCI
+//
+#define POWER_MGMT_REGISTER_PIIX4(Offset) PCI_LIB_ADDRESS (0, 1, 3, (Offset))
+
+#define PIIX4_PMBA 0x40
+#define PIIX4_PMBA_MASK (BIT15 | BIT14 | BIT13 | BIT12 | BIT11 | \
+ BIT10 | BIT9 | BIT8 | BIT7 | BIT6)
+
+#define PIIX4_PMREGMISC 0x80
+#define PIIX4_PMREGMISC_PMIOSE BIT0
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/LinuxBzImage.h b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/LinuxBzImage.h
new file mode 100644
index 0000000000..58a49e47be
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/LinuxBzImage.h
@@ -0,0 +1,158 @@
+/** @file
+
+ Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __LINUX_BZIMAGE_H__
+#define __LINUX_BZIMAGE_H__
+
+#define BOOTSIG 0x1FE
+#define SETUP_HDR 0x53726448 /* 0x53726448 == "HdrS" */
+
+#define E820_RAM 1
+#define E820_RESERVED 2
+#define E820_ACPI 3
+#define E820_NVS 4
+#define E820_UNUSABLE 5
+
+#pragma pack(1)
+
+struct setup_header {
+ UINT8 setup_secs; /* Sectors for setup code */
+ UINT16 root_flags;
+ UINT32 sys_size;
+ UINT16 ram_size;
+ UINT16 video_mode;
+ UINT16 root_dev;
+ UINT16 signature; /* Boot signature */
+ UINT16 jump;
+ UINT32 header;
+ UINT16 version;
+ UINT16 su_switch;
+ UINT16 setup_seg;
+ UINT16 start_sys;
+ UINT16 kernel_ver;
+ UINT8 loader_id;
+ UINT8 load_flags;
+ UINT16 movesize;
+ UINT32 code32_start; /* Start of code loaded high */
+ UINT32 ramdisk_start; /* Start of initial ramdisk */
+ UINT32 ramdisk_len; /* Length of initial ramdisk */
+ UINT32 bootsect_kludge;
+ UINT16 heap_end;
+ UINT8 ext_loader_ver; /* Extended boot loader version */
+ UINT8 ext_loader_type; /* Extended boot loader ID */
+ UINT32 cmd_line_ptr; /* 32-bit pointer to the kernel command line */
+ UINT32 ramdisk_max; /* Highest legal initrd address */
+ UINT32 kernel_alignment; /* Physical addr alignment required for kernel */
+ UINT8 relocatable_kernel; /* Whether kernel is relocatable or not */
+ UINT8 min_alignment;
+ UINT16 xloadflags;
+ UINT32 cmdline_size;
+ UINT32 hardware_subarch;
+ UINT64 hardware_subarch_data;
+ UINT32 payload_offset;
+ UINT32 payload_length;
+ UINT64 setup_data;
+ UINT64 pref_address;
+ UINT32 init_size;
+ UINT32 handover_offset;
+};
+
+struct efi_info {
+ UINT32 efi_loader_signature;
+ UINT32 efi_systab;
+ UINT32 efi_memdesc_size;
+ UINT32 efi_memdesc_version;
+ UINT32 efi_memmap;
+ UINT32 efi_memmap_size;
+ UINT32 efi_systab_hi;
+ UINT32 efi_memmap_hi;
+};
+
+struct e820_entry {
+ UINT64 addr; /* start of memory segment */
+ UINT64 size; /* size of memory segment */
+ UINT32 type; /* type of memory segment */
+};
+
+struct screen_info {
+ UINT8 orig_x; /* 0x00 */
+ UINT8 orig_y; /* 0x01 */
+ UINT16 ext_mem_k; /* 0x02 */
+ UINT16 orig_video_page; /* 0x04 */
+ UINT8 orig_video_mode; /* 0x06 */
+ UINT8 orig_video_cols; /* 0x07 */
+ UINT8 flags; /* 0x08 */
+ UINT8 unused2; /* 0x09 */
+ UINT16 orig_video_ega_bx;/* 0x0a */
+ UINT16 unused3; /* 0x0c */
+ UINT8 orig_video_lines; /* 0x0e */
+ UINT8 orig_video_isVGA; /* 0x0f */
+ UINT16 orig_video_points;/* 0x10 */
+
+ /* VESA graphic mode -- linear frame buffer */
+ UINT16 lfb_width; /* 0x12 */
+ UINT16 lfb_height; /* 0x14 */
+ UINT16 lfb_depth; /* 0x16 */
+ UINT32 lfb_base; /* 0x18 */
+ UINT32 lfb_size; /* 0x1c */
+ UINT16 cl_magic, cl_offset; /* 0x20 */
+ UINT16 lfb_linelength; /* 0x24 */
+ UINT8 red_size; /* 0x26 */
+ UINT8 red_pos; /* 0x27 */
+ UINT8 green_size; /* 0x28 */
+ UINT8 green_pos; /* 0x29 */
+ UINT8 blue_size; /* 0x2a */
+ UINT8 blue_pos; /* 0x2b */
+ UINT8 rsvd_size; /* 0x2c */
+ UINT8 rsvd_pos; /* 0x2d */
+ UINT16 vesapm_seg; /* 0x2e */
+ UINT16 vesapm_off; /* 0x30 */
+ UINT16 pages; /* 0x32 */
+ UINT16 vesa_attributes; /* 0x34 */
+ UINT32 capabilities; /* 0x36 */
+ UINT8 _reserved[6]; /* 0x3a */
+};
+
+struct boot_params {
+struct screen_info screen_info;
+ UINT8 apm_bios_info[0x14];
+ UINT8 _pad2[4];
+ UINT64 tboot_addr;
+ UINT8 ist_info[0x10];
+ UINT8 _pad3[16];
+ UINT8 hd0_info[16];
+ UINT8 hd1_info[16];
+ UINT8 sys_desc_table[0x10];
+ UINT8 olpc_ofw_header[0x10];
+ UINT8 _pad4[128];
+ UINT8 edid_info[0x80];
+ struct efi_info efi_info;
+ UINT32 alt_mem_k;
+ UINT32 scratch;
+ UINT8 e820_entries;
+ UINT8 eddbuf_entries;
+ UINT8 edd_mbr_sig_buf_entries;
+ UINT8 _pad6[6];
+ struct setup_header hdr;
+ UINT8 _pad7[0x290-0x1f1-sizeof(struct setup_header)];
+ UINT32 edd_mbr_sig_buffer[16];
+ struct e820_entry e820_map[128];
+ UINT8 _pad8[48];
+ UINT8 eddbuf[0x1ec];
+ UINT8 _pad9[276];
+};
+
+typedef struct {
+ UINT16 limit;
+ UINT64 *base;
+} dt_addr_t;
+
+#pragma pack()
+
+extern EFI_STATUS setup_graphics(struct boot_params *buf);
+
+#endif /* __LINUX_BZIMAGE_H__ */
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Library/LoadLinuxLib.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Library/LoadLinuxLib.h
new file mode 100644
index 0000000000..483f8d4b9c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Library/LoadLinuxLib.h
@@ -0,0 +1,205 @@
+/** @file
+ Load/boot UEFI Linux.
+
+ Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __LOAD_LINUX_LIB__
+#define __LOAD_LINUX_LIB__
+
+
+/**
+ Verifies that the kernel setup image is valid and supported.
+ The kernel setup image should be checked before using other library
+ routines which take the kernel setup as an input.
+
+ @param[in] KernelSetup - The kernel setup image
+ @param[in] KernelSetupSize - The kernel setup size
+
+ @retval EFI_SUCCESS - The Linux kernel setup is valid and supported
+ @retval EFI_INVALID_PARAMETER - KernelSetup was NULL
+ @retval EFI_UNSUPPORTED - The Linux kernel is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+LoadLinuxCheckKernelSetup (
+ IN VOID *KernelSetup,
+ IN UINTN KernelSetupSize
+ );
+
+
+/**
+ Gets the initial runtime size of the Linux kernel image by examining
+ the kernel setup image.
+
+ @param[in] KernelSetup - The kernel setup image
+ @param[in] KernelSize - The kernel size on disk.
+
+ @retval 0 An error occurred
+ @retval !0 The initial size required by the kernel to
+ begin execution.
+
+**/
+UINTN
+EFIAPI
+LoadLinuxGetKernelSize (
+ IN VOID *KernelSetup,
+ IN UINTN KernelSize
+ );
+
+
+/**
+ Loads and boots UEFI Linux.
+
+ Note: If successful, then this routine will not return
+
+ @param[in] Kernel - The main kernel image
+ @param[in,out] KernelSetup - The kernel setup image
+
+ @retval EFI_NOT_FOUND - The Linux kernel was not found
+ @retval EFI_INVALID_PARAMETER - Kernel or KernelSetup was NULL
+ @retval EFI_UNSUPPORTED - The Linux kernel version is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+LoadLinux (
+ IN VOID *Kernel,
+ IN OUT VOID *KernelSetup
+ );
+
+
+/**
+ Allocates pages for the kernel setup image.
+
+ @param[in] Pages - The number of pages
+
+ @retval NULL - Unable to allocate pages
+ @retval !NULL - The address of the pages allocated
+
+**/
+VOID*
+EFIAPI
+LoadLinuxAllocateKernelSetupPages (
+ IN UINTN Pages
+ );
+
+
+/**
+ Clears the uninitialised space before and after the struct setup_header
+ in the kernel setup image. The kernel requires that these be zeroed
+ unless explicitly initialised, so this function should be called after
+ the setup_header has been copied in from a bzImage, before setting up
+ anything else.
+
+ @param[in] KernelSetup - The kernel setup image
+
+ @retval EFI_SUCCESS - The Linux kernel setup was successfully initialized
+ @retval EFI_INVALID_PARAMETER - KernelSetup was NULL
+ @retval EFI_UNSUPPORTED - The Linux kernel is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+LoadLinuxInitializeKernelSetup (
+ IN VOID *KernelSetup
+ );
+
+/**
+ Allocates pages for the kernel.
+
+ @param[in] KernelSetup - The kernel setup image
+ @param[in] Pages - The number of pages. (It is recommended to use the
+ size returned from LoadLinuxGetKernelSize.)
+
+ @retval NULL - Unable to allocate pages
+ @retval !NULL - The address of the pages allocated
+
+**/
+VOID*
+EFIAPI
+LoadLinuxAllocateKernelPages (
+ IN VOID *KernelSetup,
+ IN UINTN Pages
+ );
+
+
+/**
+ Allocates pages for the kernel command line.
+
+ @param[in] Pages - The number of pages.
+
+ @retval NULL - Unable to allocate pages
+ @retval !NULL - The address of the pages allocated
+
+**/
+VOID*
+EFIAPI
+LoadLinuxAllocateCommandLinePages (
+ IN UINTN Pages
+ );
+
+
+/**
+ Allocates pages for the initrd image.
+
+ @param[in,out] KernelSetup - The kernel setup image
+ @param[in] Pages - The number of pages.
+
+ @retval NULL - Unable to allocate pages
+ @retval !NULL - The address of the pages allocated
+
+**/
+VOID*
+EFIAPI
+LoadLinuxAllocateInitrdPages (
+ IN VOID *KernelSetup,
+ IN UINTN Pages
+ );
+
+
+/**
+ Sets the kernel command line parameter within the setup image.
+
+ @param[in,out] KernelSetup - The kernel setup image
+ @param[in] CommandLine - The kernel command line
+
+ @retval EFI_SUCCESS - The Linux kernel setup is valid and supported
+ @retval EFI_INVALID_PARAMETER - KernelSetup was NULL
+ @retval EFI_UNSUPPORTED - The Linux kernel is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+LoadLinuxSetCommandLine (
+ IN OUT VOID *KernelSetup,
+ IN CHAR8 *CommandLine
+ );
+
+
+/**
+ Sets the kernel initial ram disk pointer within the setup image.
+
+ @param[in,out] KernelSetup - The kernel setup image
+ @param[in] Initrd - Pointer to the initial ram disk
+ @param[in] InitrdSize - The initial ram disk image size
+
+ @retval EFI_SUCCESS - The Linux kernel setup is valid and supported
+ @retval EFI_INVALID_PARAMETER - KernelSetup was NULL
+ @retval EFI_UNSUPPORTED - The Linux kernel is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+LoadLinuxSetInitrd (
+ IN OUT VOID *KernelSetup,
+ IN VOID *Initrd,
+ IN UINTN InitrdSize
+ );
+
+
+#endif
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Library/SerializeVariablesLib.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Library/SerializeVariablesLib.h
new file mode 100644
index 0000000000..8e74b718f1
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Library/SerializeVariablesLib.h
@@ -0,0 +1,223 @@
+/** @file
+ Serialize & Deserialize UEFI Variables
+
+ Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __SERIALIZE_VARIABLES_LIB__
+#define __SERIALIZE_VARIABLES_LIB__
+
+
+/**
+ Callback function for each variable
+
+ @param[in] Context - Context as sent to the iteration function
+ @param[in] VariableName - Refer to RuntimeServices GetNextVariableName
+ @param[in] VendorGuid - Refer to RuntimeServices GetNextVariableName
+ @param[in] Attributes - Refer to RuntimeServices GetVariable
+ @param[in] DataSize - Refer to RuntimeServices GetVariable
+ @param[in] Data - Refer to RuntimeServices GetVariable
+
+ @retval RETURN_SUCCESS Continue iterating through the variables
+ @return Any RETURN_ERROR Stop iterating through the variables
+
+**/
+typedef
+RETURN_STATUS
+(EFIAPI *VARIABLE_SERIALIZATION_ITERATION_CALLBACK)(
+ IN VOID *Context,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ );
+
+
+/**
+ Creates a new variable serialization instance
+
+ @param[out] Handle - Handle for a variable serialization instance
+
+ @retval RETURN_SUCCESS - The variable serialization instance was
+ successfully created.
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ create the variable serialization instance.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesNewInstance (
+ OUT EFI_HANDLE *Handle
+ );
+
+
+/**
+ Free memory associated with a variable serialization instance
+
+ @param[in] Handle - Handle for a variable serialization instance
+
+ @retval RETURN_SUCCESS - The variable serialization instance was
+ successfully freed.
+ @retval RETURN_INVALID_PARAMETER - Handle was not a valid
+ variable serialization instance.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesFreeInstance (
+ IN EFI_HANDLE Handle
+ );
+
+
+/**
+ Creates a new variable serialization instance using the given
+ binary representation of the variables to fill the new instance
+
+ @param[out] Handle - Handle for a variable serialization instance
+ @param[in] Buffer - A buffer with the serialized representation
+ of the variables. Must be the same format as produced
+ by SerializeVariablesToBuffer.
+ @param[in] Size - This is the size of the binary representation
+ of the variables.
+
+ @retval RETURN_SUCCESS - The binary representation was successfully
+ imported into a new variable serialization instance
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ create the new variable serialization instance
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesNewInstanceFromBuffer (
+ OUT EFI_HANDLE *Handle,
+ IN VOID *Buffer,
+ IN UINTN Size
+ );
+
+
+/**
+ Iterates all variables found with RuntimeServices GetNextVariableName
+
+ @param[in] CallbackFunction - Function called for each variable instance
+ @param[in] Context - Passed to each call of CallbackFunction
+
+ @retval RETURN_SUCCESS - All variables were iterated without the
+ CallbackFunction returning an error
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ iterate through the variables
+ @return Any of RETURN_ERROR indicates an error reading the variable
+ or an error was returned from CallbackFunction
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesIterateSystemVariables (
+ IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
+ IN VOID *Context
+ );
+
+
+/**
+ Iterates all variables found in the variable serialization instance
+
+ @param[in] Handle - Handle for a variable serialization instance
+ @param[in] CallbackFunction - Function called for each variable instance
+ @param[in] Context - Passed to each call of CallbackFunction
+
+ @retval RETURN_SUCCESS - All variables were iterated without the
+ CallbackFunction returning an error
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ iterate through the variables
+ @return Any of RETURN_ERROR indicates an error reading the variable
+ or an error was returned from CallbackFunction
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesIterateInstanceVariables (
+ IN EFI_HANDLE Handle,
+ IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
+ IN VOID *Context
+ );
+
+
+/**
+ Sets all variables found in the variable serialization instance
+
+ @param[in] Handle - Handle for a variable serialization instance
+
+ @retval RETURN_SUCCESS - All variables were set successfully
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ set all the variables
+ @return Any of RETURN_ERROR indicates an error reading the variables
+ or in attempting to set a variable
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesSetSerializedVariables (
+ IN EFI_HANDLE Handle
+ );
+
+
+/**
+ Adds a variable to the variable serialization instance
+
+ @param[in] Handle - Handle for a variable serialization instance
+ @param[in] VariableName - Refer to RuntimeServices GetVariable
+ @param[in] VendorGuid - Refer to RuntimeServices GetVariable
+ @param[in] Attributes - Refer to RuntimeServices GetVariable
+ @param[in] DataSize - Refer to RuntimeServices GetVariable
+ @param[in] Data - Refer to RuntimeServices GetVariable
+
+ @retval RETURN_SUCCESS - All variables were set successfully
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ add the variable
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesAddVariable (
+ IN EFI_HANDLE Handle,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ );
+
+
+/**
+ Serializes the variables known to this instance into the
+ provided buffer.
+
+ @param[in] Handle - Handle for a variable serialization instance
+ @param[out] Buffer - A buffer to store the binary representation
+ of the variables.
+ @param[in,out] Size - On input this is the size of the buffer.
+ On output this is the size of the binary representation
+ of the variables.
+
+ @retval RETURN_SUCCESS - The binary representation was successfully
+ completed and returned in the buffer.
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ save the variables to the buffer.
+ @retval RETURN_INVALID_PARAMETER - Handle was not a valid
+ variable serialization instance or
+ Size or Buffer were NULL.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesToBuffer (
+ IN EFI_HANDLE Handle,
+ OUT VOID *Buffer,
+ IN OUT UINTN *Size
+ );
+
+
+#endif
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
new file mode 100644
index 0000000000..67bb3af584
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
@@ -0,0 +1,55 @@
+/** @file
+ Simics Platform definitions
+
+ Copyright (C) 2015, Red Hat, Inc.
+ Copyright (c) 2014, Gabriel L. Somlo <somlo@cmu.edu>
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __SIMICS_PLATFORMS_H__
+#define __SIMICS_PLATFORMS_H__
+
+#include <Library/PciLib.h>
+#include <IndustryStandard/Pci22.h>
+#include <Register/X58Ich10.h>
+#include <IndustryStandard/I440FxPiix4.h>
+
+//
+// Simics Host Bridge DID Address
+//
+#define SIMICS_HOSTBRIDGE_DID \
+ PCI_LIB_ADDRESS (0, 0, 0, PCI_DEVICE_ID_OFFSET)
+
+//
+// Simics SideBand PCI device registers
+//
+#define SIMICS_SIDEBANDPCI_DEV 0
+#define SIMICS_SIDEBANDPCI_FUNC 7
+#define SIMICS_SIDEBANDPCI_SVID \
+ PCI_LIB_ADDRESS (0, 0, 7, PCI_SVID_OFFSET)
+#define SIMICS_SIDEBANDPCI_SDID \
+ PCI_LIB_ADDRESS (0, 0, 7, PCI_SID_OFFSET)
+#define SIMICS_SIDEBANDPCI_CAP \
+ PCI_LIB_ADDRESS (0, 0, 7, PCI_CAPBILITY_POINTER_OFFSET)
+#define SIMICS_SIDEBANDPCI_CAP_Offset 0x40
+#define SIMICS_SIDEBANDPCI_CAP_ID 0xFF
+
+//
+// Values we program into the PM base address registers
+//
+#define PIIX4_PMBA_VALUE 0xB000
+#define ICH10_PMBASE_VALUE 0x0400
+
+//
+// Common bits in same-purpose registers
+//
+#define PMBA_RTE BIT0
+
+//
+// Common IO ports relative to the Power Management Base Address
+//
+#define ACPI_TIMER_OFFSET 0x8
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/DxeLogoLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/DxeLogoLib.inf
new file mode 100644
index 0000000000..1cf91f02c2
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/DxeLogoLib.inf
@@ -0,0 +1,55 @@
+### @file
+# Module that show progress bar and title above it.
+#
+# General BDS defines and produce general interfaces for platform BDS driver including:
+# 1) BDS boot policy interface;
+# 2) BDS boot device connect interface;
+# 3) BDS Misc interfaces for mainting boot variable, ouput string, etc.
+#
+# Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = DxeLogoLib
+ FILE_GUID = F5AE5B5C-42E8-4A9B-829D-5B631CD5367A
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_DRIVER
+ LIBRARY_CLASS = LogoLib|DXE_DRIVER UEFI_APPLICATION
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+ BaseLib
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ UefiLib
+ BaseMemoryLib
+ DebugLib
+ PrintLib
+ PcdLib
+ DxeServicesLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+
+[FeaturePcd]
+ gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport
+
+[Sources]
+ Logo.c
+
+[Protocols]
+ gEfiGraphicsOutputProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiUgaDrawProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiBootLogoProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiUserManagerProtocolGuid ## CONSUMES
+ gEfiOEMBadgingProtocolGuid ## CONSUMES
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/OEMBadging.h b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/OEMBadging.h
new file mode 100644
index 0000000000..4f06bae5d1
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/OEMBadging.h
@@ -0,0 +1,83 @@
+/** @file
+ The OEM Badging Protocol defines the interface to get the OEM badging
+ image with the display attribute. This protocol can be produced based on OEM badging images.
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EFI_OEM_BADGING_H__
+#define __EFI_OEM_BADGING_H__
+
+//
+// GUID for EFI OEM Badging Protocol
+//
+#define EFI_OEM_BADGING_PROTOCOL_GUID \
+ { 0x170e13c0, 0xbf1b, 0x4218, {0x87, 0x1d, 0x2a, 0xbd, 0xc6, 0xf8, 0x87, 0xbc } }
+
+
+typedef struct _EFI_OEM_BADGING_PROTOCOL EFI_OEM_BADGING_PROTOCOL;
+
+typedef enum {
+ EfiBadgingFormatBMP,
+ EfiBadgingFormatJPEG,
+ EfiBadgingFormatTIFF,
+ EfiBadgingFormatGIF,
+ EfiBadgingFormatUnknown
+} EFI_BADGING_FORMAT;
+
+typedef enum {
+ EfiBadgingDisplayAttributeLeftTop,
+ EfiBadgingDisplayAttributeCenterTop,
+ EfiBadgingDisplayAttributeRightTop,
+ EfiBadgingDisplayAttributeCenterRight,
+ EfiBadgingDisplayAttributeRightBottom,
+ EfiBadgingDisplayAttributeCenterBottom,
+ EfiBadgingDisplayAttributeLeftBottom,
+ EfiBadgingDisplayAttributeCenterLeft,
+ EfiBadgingDisplayAttributeCenter,
+ EfiBadgingDisplayAttributeCustomized
+} EFI_BADGING_DISPLAY_ATTRIBUTE;
+
+/**
+
+ Load an OEM badge image and return its data and attributes.
+
+ @param This The pointer to this protocol instance.
+ @param Instance The visible image instance is found.
+ @param Format The format of the image. Examples: BMP, JPEG.
+ @param ImageData The image data for the badge file. Currently only
+ supports the .bmp file format.
+ @param ImageSize The size of the image returned.
+ @param Attribute The display attributes of the image returned.
+ @param CoordinateX The X coordinate of the image.
+ @param CoordinateY The Y coordinate of the image.
+
+ @retval EFI_SUCCESS The image was fetched successfully.
+ @retval EFI_NOT_FOUND The specified image could not be found.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_BADGING_GET_IMAGE)(
+ IN EFI_OEM_BADGING_PROTOCOL *This,
+ IN OUT UINT32 *Instance,
+ OUT EFI_BADGING_FORMAT *Format,
+ OUT UINT8 **ImageData,
+ OUT UINTN *ImageSize,
+ OUT EFI_BADGING_DISPLAY_ATTRIBUTE *Attribute,
+ OUT UINTN *CoordinateX,
+ OUT UINTN *CoordinateY
+);
+
+
+struct _EFI_OEM_BADGING_PROTOCOL {
+ EFI_BADGING_GET_IMAGE GetImage;
+};
+
+
+extern EFI_GUID gEfiOEMBadgingProtocolGuid;
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/DxeLoadLinuxLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/DxeLoadLinuxLib.inf
new file mode 100644
index 0000000000..cdefeebbdd
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/DxeLoadLinuxLib.inf
@@ -0,0 +1,42 @@
+## @file
+#
+# Copyright (c) 2008 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxeLoadLinuxLib
+ FILE_GUID = 63CC8497-C9D0-46A8-AC08-49DF92A2FF62
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = DxeLoadLinuxLib|DXE_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.common]
+ Linux.c
+ LinuxGdt.c
+
+[Sources.IA32]
+ Ia32/JumpToKernel.nasm
+
+[Sources.X64]
+ X64/JumpToKernel.nasm
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ MemoryAllocationLib
+ BaseMemoryLib
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.nasm b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.nasm
new file mode 100644
index 0000000000..c6f1c31a59
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.nasm
@@ -0,0 +1,41 @@
+; @file
+; Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; JumpToKernel (
+; VOID *KernelStart,
+; VOID *KernelBootParams
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(JumpToKernel)
+ASM_PFX(JumpToKernel):
+
+ mov esi, [esp + 8]
+ call DWORD [esp + 4]
+ ret
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; JumpToUefiKernel (
+; EFI_HANDLE ImageHandle,
+; EFI_SYSTEM_TABLE *SystemTable,
+; VOID *KernelBootParams,
+; VOID *KernelStart
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(JumpToUefiKernel)
+ASM_PFX(JumpToUefiKernel):
+
+ mov eax, [esp + 12]
+ mov eax, [eax + 0x264]
+ add eax, [esp + 16]
+ jmp eax
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
new file mode 100644
index 0000000000..9c0ab80904
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
@@ -0,0 +1,52 @@
+/** @file
+ Boot UEFI Linux.
+
+ Copyright (c) 2008 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _LOAD_LINUX_LIB_INCLUDED_
+#define _LOAD_LINUX_LIB_INCLUDED_
+
+#include <Uefi.h>
+#include <Library/LoadLinuxLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#include <IndustryStandard/LinuxBzImage.h>
+
+#include <Protocol/GraphicsOutput.h>
+
+VOID
+EFIAPI
+JumpToKernel (
+ VOID *KernelStart,
+ VOID *KernelBootParams
+ );
+
+VOID
+EFIAPI
+JumpToUefiKernel (
+ EFI_HANDLE ImageHandle,
+ EFI_SYSTEM_TABLE *SystemTable,
+ VOID *KernelBootParams,
+ VOID *KernelStart
+ );
+
+VOID
+InitLinuxDescriptorTables (
+ VOID
+ );
+
+VOID
+SetLinuxDescriptorTables (
+ VOID
+ );
+
+#endif
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel.nasm b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel.nasm
new file mode 100644
index 0000000000..2b5395f6f8
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel.nasm
@@ -0,0 +1,85 @@
+; @file
+; Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+
+ DEFAULT REL
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; JumpToKernel (
+; VOID *KernelStart, // rcx
+; VOID *KernelBootParams // rdx
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(JumpToKernel)
+ASM_PFX(JumpToKernel):
+
+ ; Set up for executing kernel. BP in %esi, entry point on the stack
+ ; (64-bit when the 'ret' will use it as 32-bit, but we're little-endian)
+ mov rsi, rdx
+ push rcx
+
+ ; Jump into the compatibility mode CS
+ push 0x10
+ lea rax, [.0]
+ push rax
+ DB 0x48, 0xcb ; retfq
+
+.0:
+ ; Now in compatibility mode.
+
+ DB 0xb8, 0x18, 0x0, 0x0, 0x0 ; movl $0x18, %eax
+ DB 0x8e, 0xd8 ; movl %eax, %ds
+ DB 0x8e, 0xc0 ; movl %eax, %es
+ DB 0x8e, 0xe0 ; movl %eax, %fs
+ DB 0x8e, 0xe8 ; movl %eax, %gs
+ DB 0x8e, 0xd0 ; movl %eax, %ss
+
+ ; Disable paging
+ DB 0xf, 0x20, 0xc0 ; movl %cr0, %eax
+ DB 0xf, 0xba, 0xf8, 0x1f ; btcl $31, %eax
+ DB 0xf, 0x22, 0xc0 ; movl %eax, %cr0
+
+ ; Disable long mode in EFER
+ DB 0xb9, 0x80, 0x0, 0x0, 0xc0 ; movl $0x0c0000080, %ecx
+ DB 0xf, 0x32 ; rdmsr
+ DB 0xf, 0xba, 0xf8, 0x8 ; btcl $8, %eax
+ DB 0xf, 0x30 ; wrmsr
+
+ ; Disable PAE
+ DB 0xf, 0x20, 0xe0 ; movl %cr4, %eax
+ DB 0xf, 0xba, 0xf8, 0x5 ; btcl $5, %eax
+ DB 0xf, 0x22, 0xe0 ; movl %eax, %cr4
+
+ DB 0x31, 0xed ; xor %ebp, %ebp
+ DB 0x31, 0xff ; xor %edi, %edi
+ DB 0x31, 0xdb ; xor %ebx, %ebx
+ DB 0xc3 ; ret
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; JumpToUefiKernel (
+; EFI_HANDLE ImageHandle, // rcx
+; EFI_SYSTEM_TABLE *SystemTable, // rdx
+; VOID *KernelBootParams // r8
+; VOID *KernelStart, // r9
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(JumpToUefiKernel)
+ASM_PFX(JumpToUefiKernel):
+
+ mov rdi, rcx
+ mov rsi, rdx
+ mov rdx, r8
+ xor rax, rax
+ mov eax, [r8 + 0x264]
+ add r9, rax
+ add r9, 0x200
+ call r9
+ ret
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h
new file mode 100644
index 0000000000..80776fd003
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h
@@ -0,0 +1,55 @@
+/** @file
+ Save Non-Volatile Variables to a file system.
+
+ Copyright (c) 2009 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __NV_VARS_FILE_LIB_INSTANCE__
+#define __NV_VARS_FILE_LIB_INSTANCE__
+
+#include <Uefi.h>
+
+#include <Guid/FileInfo.h>
+
+#include <Protocol/SimpleFileSystem.h>
+
+#include <Library/BaseLib.h>
+#include <Library/FileHandleLib.h>
+#include <Library/SerializeVariablesLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+/**
+ Loads the non-volatile variables from the NvVars file on the
+ given file system.
+
+ @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
+
+ @return EFI_STATUS based on the success or failure of load operation
+
+**/
+EFI_STATUS
+LoadNvVarsFromFs (
+ EFI_HANDLE FsHandle
+ );
+
+
+/**
+ Saves the non-volatile variables into the NvVars file on the
+ given file system.
+
+ @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
+
+ @return EFI_STATUS based on the success or failure of load operation
+
+**/
+EFI_STATUS
+SaveNvVarsToFs (
+ EFI_HANDLE FsHandle
+ );
+
+#endif
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
new file mode 100644
index 0000000000..4731e77865
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
@@ -0,0 +1,53 @@
+## @file
+# NvVarsFileLib
+#
+# This library saves and restores non-volatile variables in a
+# file within a file system.
+#
+# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = NvVarsFileLib
+ FILE_GUID = 8ECD4CC0-1772-4583-8A74-83633A15FAA0
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = NvVarsFileLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ FsAccess.c
+ NvVarsFileLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ShellPkg/ShellPkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ FileHandleLib
+ MemoryAllocationLib
+ SerializeVariablesLib
+
+[Protocols]
+ gEfiSimpleFileSystemProtocolGuid ## CONSUMES
+
+[Guids]
+ gEfiFileInfoGuid
+
+[Depex]
+ gEfiVariableWriteArchProtocolGuid
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridge.h b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridge.h
new file mode 100644
index 0000000000..0c75430260
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridge.h
@@ -0,0 +1,68 @@
+/** @file
+ Header file of OVMF instance of PciHostBridgeLib.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+PCI_ROOT_BRIDGE *
+ScanForRootBridges (
+ UINTN *NumberOfRootBridges
+);
+
+/**
+ Initialize a PCI_ROOT_BRIDGE structure.
+
+ @param[in] Supports Supported attributes.
+
+ @param[in] Attributes Initial attributes.
+
+ @param[in] AllocAttributes Allocation attributes.
+
+ @param[in] RootBusNumber The bus number to store in RootBus.
+
+ @param[in] MaxSubBusNumber The inclusive maximum bus number that can be
+ assigned to any subordinate bus found behind any
+ PCI bridge hanging off this root bus.
+
+ The caller is repsonsible for ensuring that
+ RootBusNumber <= MaxSubBusNumber. If
+ RootBusNumber equals MaxSubBusNumber, then the
+ root bus has no room for subordinate buses.
+
+ @param[in] Io IO aperture.
+
+ @param[in] Mem MMIO aperture.
+
+ @param[in] MemAbove4G MMIO aperture above 4G.
+
+ @param[in] PMem Prefetchable MMIO aperture.
+
+ @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G.
+
+ @param[out] RootBus The PCI_ROOT_BRIDGE structure (allocated by the
+ caller) that should be filled in by this
+ function.
+
+ @retval EFI_SUCCESS Initialization successful. A device path
+ consisting of an ACPI device path node, with
+ UID = RootBusNumber, has been allocated and
+ linked into RootBus.
+
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
+**/
+EFI_STATUS
+InitRootBridge (
+ IN UINT64 Supports,
+ IN UINT64 Attributes,
+ IN UINT64 AllocAttributes,
+ IN UINT8 RootBusNumber,
+ IN UINT8 MaxSubBusNumber,
+ IN PCI_ROOT_BRIDGE_APERTURE *Io,
+ IN PCI_ROOT_BRIDGE_APERTURE *Mem,
+ IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,
+ IN PCI_ROOT_BRIDGE_APERTURE *PMem,
+ IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G,
+ OUT PCI_ROOT_BRIDGE *RootBus
+ );
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
new file mode 100644
index 0000000000..b22531bb56
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
@@ -0,0 +1,51 @@
+## @file
+# OVMF's instance of the PCI Host Bridge Library.
+#
+# Copyright (C) 2016, Red Hat, Inc.
+# Copyright (c) 2016 - 2018 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PciHostBridgeLib
+ FILE_GUID = 2F04EC41-C3A0-43EB-AC6A-409F973F4439
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PciHostBridgeLib
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ PciHostBridgeLib.c
+ PciHostBridge.h
+
+[Packages]
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ DevicePathLib
+ MemoryAllocationLib
+ PciLib
+
+[Pcd]
+ gBoardModuleTokenSpaceGuid.PcdPciIoBase
+ gBoardModuleTokenSpaceGuid.PcdPciIoSize
+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Base
+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Size
+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Base
+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Size
+ gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf
new file mode 100644
index 0000000000..6465f39fb4
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf
@@ -0,0 +1,56 @@
+### @file
+# Component information file for the Report Firmware Volume (FV) library.
+#
+# Copyright (c) 2018, 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
+ PcdLib
+ IoLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+ SimicsX58SktPkg/SktPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[Sources]
+ PeiReportFvLib.c
+ Fv.c
+
+[Pcd]
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## 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.PcdFlashFvAdvancedBase ## CONSUMES
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize ## CONSUMES
+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize
+ gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize
+ gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatform.h b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatform.h
new file mode 100644
index 0000000000..01ba20d2da
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatform.h
@@ -0,0 +1,172 @@
+/** @file
+ Platform BDS customizations include file.
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
+#define _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
+
+
+#include <PiDxe.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/SmBios.h>
+#include <IndustryStandard/PeImage.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/UefiBootManagerLib.h>
+#include <Library/BootLogoLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/NvVarsFileLib.h>
+
+#include <Protocol/Decompress.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/S3SaveState.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Protocol/LoadedImage.h>
+
+#include <Guid/Acpi.h>
+#include <Guid/SmBios.h>
+#include <Guid/Mps.h>
+#include <Guid/HobList.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/EventGroup.h>
+
+#include <SimicsPlatforms.h>
+
+extern EFI_DEVICE_PATH_PROTOCOL *gPlatformConnectSequence[];
+extern ACPI_HID_DEVICE_PATH gPnpPs2KeyboardDeviceNode;
+extern ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode;
+extern UART_DEVICE_PATH gUartDeviceNode;
+extern VENDOR_DEVICE_PATH gTerminalTypeDeviceNode;
+
+#define PCI_DEVICE_PATH_NODE(Func, Dev) \
+ { \
+ { \
+ HARDWARE_DEVICE_PATH, \
+ HW_PCI_DP, \
+ { \
+ (UINT8) (sizeof (PCI_DEVICE_PATH)), \
+ (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \
+ } \
+ }, \
+ (Func), \
+ (Dev) \
+ }
+
+#define PNPID_DEVICE_PATH_NODE(PnpId) \
+ { \
+ { \
+ ACPI_DEVICE_PATH, \
+ ACPI_DP, \
+ { \
+ (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
+ (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
+ }, \
+ }, \
+ EISA_PNP_ID((PnpId)), \
+ 0 \
+ }
+
+#define gPciIsaBridge \
+ PCI_DEVICE_PATH_NODE(0, 0x1f)
+
+#define gP2PBridge \
+ PCI_DEVICE_PATH_NODE(0, 0x1e)
+
+#define gPnpPs2Keyboard \
+ PNPID_DEVICE_PATH_NODE(0x0303)
+
+#define gPnp16550ComPort \
+ PNPID_DEVICE_PATH_NODE(0x0501)
+
+#define gUart \
+ { \
+ { \
+ MESSAGING_DEVICE_PATH, \
+ MSG_UART_DP, \
+ { \
+ (UINT8) (sizeof (UART_DEVICE_PATH)), \
+ (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8) \
+ } \
+ }, \
+ 0, \
+ 115200, \
+ 8, \
+ 1, \
+ 1 \
+ }
+
+#define gPcAnsiTerminal \
+ { \
+ { \
+ MESSAGING_DEVICE_PATH, \
+ MSG_VENDOR_DP, \
+ { \
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \
+ } \
+ }, \
+ DEVICE_PATH_MESSAGING_PC_ANSI \
+ }
+
+#define PCI_CLASS_SCC 0x07
+#define PCI_SUBCLASS_SERIAL 0x00
+#define PCI_IF_16550 0x02
+#define IS_PCI_16550SERIAL(_p) IS_CLASS3 (_p, PCI_CLASS_SCC, PCI_SUBCLASS_SERIAL, PCI_IF_16550)
+#define IS_PCI_ISA_PDECODE(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA_PDECODE, 0)
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ UINTN ConnectType;
+} PLATFORM_CONSOLE_CONNECT_ENTRY;
+
+#define CONSOLE_OUT BIT0
+#define CONSOLE_IN BIT1
+#define STD_ERROR BIT2
+extern PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[];
+
+//
+// Platform BDS Functions
+//
+
+VOID
+PlatformInitializeConsole (
+ IN PLATFORM_CONSOLE_CONNECT_ENTRY *PlatformConsole
+ );
+
+/**
+ Use SystemTable ConOut to stop video based Simple Text Out consoles from going
+ to the video device. Put up LogoFile on every video device that is a console.
+
+ @param[in] LogoFile The file name of logo to display on the center of the screen.
+
+ @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed.
+ @retval EFI_UNSUPPORTED Logo not found.
+
+**/
+EFI_STATUS
+EFIAPI
+EnableBootLogo(
+ IN EFI_GUID *LogoFile
+);
+
+#endif // _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
new file mode 100644
index 0000000000..cdb6e242e8
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
@@ -0,0 +1,72 @@
+## @file
+# Platform BDS customizations library.
+#
+# Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformBootManagerLib
+ FILE_GUID = 8AE4756F-0C71-4C06-84D4-4C71F204D514
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PlatformBootManagerLib|DXE_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ BdsPlatform.c
+ PlatformData.c
+ BdsPlatform.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+ OvmfPkg/OvmfPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[LibraryClasses]
+ BaseLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ BaseMemoryLib
+ DebugLib
+ PcdLib
+ UefiBootManagerLib
+ BootLogoLib
+ DevicePathLib
+ PciLib
+ NvVarsFileLib
+ DxeLoadLinuxLib
+ UefiLib
+ LogoLib
+
+[Pcd]
+ gBoardModuleTokenSpaceGuid.PcdEmuVariableEvent
+ gBoardModuleTokenSpaceGuid.PcdOvmfFlashVariablesEnable
+ gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
+ gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
+ gBoardModuleTokenSpaceGuid.PcdShellFile
+ gBoardModuleTokenSpaceGuid.PcdLogoFile
+
+[Pcd.IA32, Pcd.X64]
+ gEfiMdePkgTokenSpaceGuid.PcdFSBClock
+
+[Protocols]
+ gEfiDecompressProtocolGuid
+ gEfiPciRootBridgeIoProtocolGuid
+ gEfiS3SaveStateProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
+ gEfiDxeSmmReadyToLockProtocolGuid # PROTOCOL SOMETIMES_PRODUCED
+ gEfiLoadedImageProtocolGuid # PROTOCOL SOMETIMES_PRODUCED
+ gEfiFirmwareVolume2ProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
+
+[Guids]
+ gEfiEndOfDxeEventGroupGuid
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h
new file mode 100644
index 0000000000..9b4c2a629a
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h
@@ -0,0 +1,33 @@
+/** @file
+ Serialize Variables Library implementation
+
+ Copyright (c) 2009 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __SERIALIZE_VARIABLES_LIB_INSTANCE__
+#define __SERIALIZE_VARIABLES_LIB_INSTANCE__
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/SerializeVariablesLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#define SV_FROM_HANDLE(a) CR (a, SV_INSTANCE, Signature, SV_SIGNATURE)
+#define SV_SIGNATURE SIGNATURE_32 ('S', 'V', 'A', 'R')
+
+typedef struct {
+ UINT32 Signature;
+ VOID *BufferPtr;
+ UINTN BufferSize;
+ UINTN DataSize;
+} SV_INSTANCE;
+
+#endif
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
new file mode 100644
index 0000000000..08c561f586
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
@@ -0,0 +1,36 @@
+## @file
+# Serialize Variables Library implementation
+#
+# This library serializes and deserializes UEFI variables
+#
+# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxeSerializeVariablesLib
+ FILE_GUID = 266A1434-6B22-441F-A8D2-D54AA8FDF95C
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = SerializeVariablesLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER
+
+[Sources]
+ SerializeVariablesLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ShellPkg/ShellPkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf
new file mode 100644
index 0000000000..6be3b301ad
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf
@@ -0,0 +1,38 @@
+## @file
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SiliconPolicyInitLib
+ FILE_GUID = B494DF39-A5F8-48A1-B2D0-EF523AD91C55
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = SiliconPolicyInitLib
+
+[Sources]
+ SiliconPolicyInitLib.c
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+# this module.
+#
+################################################################################
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ BaseLib
+ DebugLib
+ DebugPrintErrorLevelLib
+ HobLib
+ IoLib
+ MemoryAllocationLib
+ PeiServicesLib
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf
new file mode 100644
index 0000000000..4fde3c75a6
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf
@@ -0,0 +1,35 @@
+## @file
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SiliconPolicyUpdateLib
+ FILE_GUID = 6EA9585C-3C15-47da-9FFC-25E9E4EA4D0C
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = SiliconPolicyUpdateLib
+
+[Sources]
+ SiliconPolicyUpdateLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ HobLib
+ IoLib
+ PcdLib
+
+[Pcd]
+
+[FixedPcd]
+
+[Ppis]
+
+[Guids]
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm b/Platform/Intel/SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm
new file mode 100644
index 0000000000..adb87de943
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm
@@ -0,0 +1,45 @@
+; @file
+; Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+
+#include <Base.h>
+
+ SECTION .text
+
+extern ASM_PFX(SecCoreStartupWithStack)
+
+;
+; SecCore Entry Point
+;
+; Processor is in flat protected mode
+;
+; @param[in] EAX Initial value of the EAX register (BIST: Built-in Self Test)
+; @param[in] DI 'BP': boot-strap processor, or 'AP': application processor
+; @param[in] EBP Pointer to the start of the Boot Firmware Volume
+;
+; @return None This routine does not return
+;
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+
+ ;
+ ; Load temporary RAM stack based on PCDs
+ ;
+ %define SEC_TOP_OF_STACK (FixedPcdGet32 (PcdSimicsSecPeiTempRamBase) + \
+ FixedPcdGet32 (PcdSimicsSecPeiTempRamSize))
+ mov eax, SEC_TOP_OF_STACK
+ mov esp, eax
+ nop
+
+ ;
+ ; Setup parameters and call SecCoreStartupWithStack
+ ; [esp] return address for call
+ ; [esp+4] BootFirmwareVolumePtr
+ ; [esp+8] TopOfCurrentStack
+ ;
+ push eax
+ push ebp
+ call ASM_PFX(SecCoreStartupWithStack)
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf b/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf
new file mode 100644
index 0000000000..b1d319c5ea
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf
@@ -0,0 +1,73 @@
+## @file
+# SEC Driver
+#
+# Copyright (c) 2008 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SecMain
+ FILE_GUID = e67f156f-54c5-47f3-a35d-07c045881e14
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SecMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ SecMain.c
+
+[Sources.IA32]
+ Ia32/SecEntry.nasm
+
+[Sources.X64]
+ X64/SecEntry.nasm
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ SimicsX58SktPkg/SktPkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ BaseMemoryLib
+ PeiServicesLib
+ PcdLib
+ UefiCpuLib
+ DebugAgentLib
+ IoLib
+ PeCoffLib
+ PeCoffGetEntryPointLib
+ PeCoffExtraActionLib
+ ExtractGuidedSectionLib
+ LocalApicLib
+ PciCf8Lib
+
+[Ppis]
+ gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
+
+[Pcd]
+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize
+ gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
+ gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
+ gBoardModuleTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+ gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
+
+[FeaturePcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm b/Platform/Intel/SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm
new file mode 100644
index 0000000000..2e6d8f618c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm
@@ -0,0 +1,45 @@
+; @file
+; Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+
+#include <Base.h>
+
+DEFAULT REL
+SECTION .text
+
+extern ASM_PFX(SecCoreStartupWithStack)
+
+;
+; SecCore Entry Point
+;
+; Processor is in flat protected mode
+;
+; @param[in] RAX Initial value of the EAX register (BIST: Built-in Self Test)
+; @param[in] DI 'BP': boot-strap processor, or 'AP': application processor
+; @param[in] RBP Pointer to the start of the Boot Firmware Volume
+;
+; @return None This routine does not return
+;
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+
+ ;
+ ; Load temporary RAM stack based on PCDs
+ ;
+ %define SEC_TOP_OF_STACK (FixedPcdGet32 (PcdSimicsSecPeiTempRamBase) + \
+ FixedPcdGet32 (PcdSimicsSecPeiTempRamSize))
+ mov rsp, SEC_TOP_OF_STACK
+ nop
+
+ ;
+ ; Setup parameters and call SecCoreStartupWithStack
+ ; rcx: BootFirmwareVolumePtr
+ ; rdx: TopOfCurrentStack
+ ;
+ mov rcx, rbp
+ mov rdx, rsp
+ sub rsp, 0x20
+ call ASM_PFX(SecCoreStartupWithStack)
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h
new file mode 100644
index 0000000000..bef801bd64
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h
@@ -0,0 +1,37 @@
+/** @file
+ This driver effectuates QSP platform configuration settings and exposes
+ them via HII.
+
+ Copyright (C) 2014, Red Hat, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_H_
+#define _PLATFORM_H_
+
+//
+// Macro and type definitions that connect the form with the HII driver code.
+//
+#define FORMSTATEID_MAIN_FORM 1
+#define FORMID_MAIN_FORM 1
+
+#define QUESTION_RES_CUR 1
+#define MAXSIZE_RES_CUR 16
+
+#define LABEL_RES_NEXT 1
+#define QUESTION_RES_NEXT 2
+
+#define QUESTION_SAVE_EXIT 3
+#define QUESTION_DISCARD_EXIT 4
+
+//
+// This structure describes the form state. Its fields relate strictly to the
+// visual widgets on the form.
+//
+typedef struct {
+ UINT16 CurrentPreferredResolution[MAXSIZE_RES_CUR];
+ UINT32 NextPreferredResolution;
+} MAIN_FORM_STATE;
+
+#endif // _PLATFORM_H_
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.uni b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.uni
new file mode 100644
index 0000000000..6d68cbeb4f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.uni
@@ -0,0 +1,31 @@
+// *++
+//
+// Copyright (C) 2014, Red Hat, Inc.
+// Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Module Name:
+//
+// Platform.uni
+//
+// Abstract:
+//
+// String definitions for PlatformForms.vfr
+//
+// --*/
+
+/=#
+
+#langdef en-US "English"
+
+#string STR_FORMSET_TITLE #language en-US "QSP Platform Configuration"
+#string STR_FORMSET_HELP #language en-US "Change various QSP platform settings."
+#string STR_MAIN_FORM_TITLE #language en-US "QSP Settings"
+#string STR_RES_CUR #language en-US "Preferred Resolution at Next Boot"
+#string STR_RES_CUR_HELP #language en-US "The preferred resolution of the Graphics Console at next boot. It might be unset, or even invalid (hence ignored) wrt. the video RAM size."
+#string STR_RES_NEXT #language en-US "Change Preferred Resolution for Next Boot"
+#string STR_RES_NEXT_HELP #language en-US "You can specify a new preference for the Graphics Console here. The list is filtered against the video RAM size."
+#string STR_SAVE_EXIT #language en-US "Commit Changes and Exit"
+#string STR_DISCARD_EXIT #language en-US "Discard Changes and Exit"
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h
new file mode 100644
index 0000000000..d3f041ddea
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h
@@ -0,0 +1,51 @@
+/** @file
+ Utility functions for serializing (persistently storing) and deserializing
+ OVMF's platform configuration.
+
+ Copyright (C) 2014, Red Hat, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_CONFIG_H_
+#define _PLATFORM_CONFIG_H_
+
+#include <Base.h>
+
+//
+// This structure participates in driver configuration. It does not
+// (necessarily) reflect the wire format in the persistent store.
+//
+#pragma pack(1)
+typedef struct {
+ //
+ // preferred graphics console resolution when booting
+ //
+ UINT32 HorizontalResolution;
+ UINT32 VerticalResolution;
+} PLATFORM_CONFIG;
+#pragma pack()
+
+//
+// Please see the API documentation near the function definitions.
+//
+EFI_STATUS
+EFIAPI
+PlatformConfigSave (
+ IN PLATFORM_CONFIG *PlatformConfig
+ );
+
+EFI_STATUS
+EFIAPI
+PlatformConfigLoad (
+ OUT PLATFORM_CONFIG *PlatformConfig,
+ OUT UINT64 *OptionalElements
+ );
+
+//
+// Feature flags for OptionalElements.
+//
+#define PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION BIT0
+#define PLATFORM_CONFIG_F_DOWNGRADE BIT63
+
+#endif // _PLATFORM_CONFIG_H_
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr
new file mode 100644
index 0000000000..21bf9f5854
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr
@@ -0,0 +1,67 @@
+// *++
+//
+// Copyright (C) 2014, Red Hat, Inc.
+// Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Module Name:
+//
+// PlatformForms.vfr
+//
+// Abstract:
+//
+// Form definitions for exposing some of OVMF's platform knobs via HII.
+//
+// --*/
+
+#include <Guid/SimicsBoardConfig.h>
+#include "Platform.h"
+
+formset
+ guid = SIMICS_BOARD_CONFIG_GUID,
+ title = STRING_TOKEN(STR_FORMSET_TITLE),
+ help = STRING_TOKEN(STR_FORMSET_HELP),
+
+ varstore MAIN_FORM_STATE,
+ varid = FORMSTATEID_MAIN_FORM,
+ name = MainFormState,
+ guid = SIMICS_BOARD_CONFIG_GUID;
+
+ form
+ formid = FORMID_MAIN_FORM,
+ title = STRING_TOKEN(STR_MAIN_FORM_TITLE);
+
+ //
+ // Display the current preference in a read-only string field.
+ //
+ string
+ varid = MainFormState.CurrentPreferredResolution,
+ questionid = QUESTION_RES_CUR,
+ prompt = STRING_TOKEN(STR_RES_CUR),
+ help = STRING_TOKEN(STR_RES_CUR_HELP),
+ flags = READ_ONLY,
+ minsize = 0,
+ maxsize = MAXSIZE_RES_CUR,
+ endstring;
+
+ //
+ // We'll dynamically generate a one-of-many selection at this label.
+ //
+ label LABEL_RES_NEXT;
+
+ text
+ help = STRING_TOKEN(STR_SAVE_EXIT),
+ text = STRING_TOKEN(STR_SAVE_EXIT),
+ flags = INTERACTIVE,
+ key = QUESTION_SAVE_EXIT;
+
+ text
+ help = STRING_TOKEN(STR_DISCARD_EXIT),
+ text = STRING_TOKEN(STR_DISCARD_EXIT),
+ flags = INTERACTIVE,
+ key = QUESTION_DISCARD_EXIT;
+
+ endform;
+
+endformset;
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf
new file mode 100644
index 0000000000..39028e1a70
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf
@@ -0,0 +1,65 @@
+## @file
+# This driver effectuates Simics X58 platform configuration settings and exposes
+# them via HII.
+#
+# Copyright (C) 2014, Red Hat, Inc.
+# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SimicsDxe
+ FILE_GUID = 74B64DC1-B0B6-4853-A6BD-C6426059AB1E
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PlatformInit
+ UNLOAD_IMAGE = PlatformUnload
+
+[Sources]
+ Platform.c
+ Platform.uni
+ PlatformConfig.c
+ PlatformForms.vfr
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ DevicePathLib
+ HiiLib
+ MemoryAllocationLib
+ PrintLib
+ UefiBootServicesTableLib
+ UefiHiiServicesLib
+ UefiLib
+ UefiRuntimeServicesTableLib
+ UefiDriverEntryPoint
+ DxeServicesTableLib
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution
+
+[Protocols]
+ gEfiDevicePathProtocolGuid ## PRODUCES
+ gEfiGraphicsOutputProtocolGuid ## CONSUMES
+ gEfiHiiConfigAccessProtocolGuid ## PRODUCES
+
+[Guids]
+ gEfiIfrTianoGuid
+ gSimicsBoardConfigGuid
+
+[Depex]
+ gEfiHiiConfigRoutingProtocolGuid AND
+ gEfiHiiDatabaseProtocolGuid AND
+ gEfiVariableArchProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h
new file mode 100644
index 0000000000..07fa2e2d11
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h
@@ -0,0 +1,50 @@
+/** @file
+ PC/AT CMOS access routines
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __CMOS_H__
+#define __CMOS_H__
+
+/**
+ Reads 8-bits of CMOS data.
+
+ Reads the 8-bits of CMOS data at the location specified by Index.
+ The 8-bit read value is returned.
+
+ @param Index The CMOS location to read.
+
+ @return The value read.
+
+**/
+UINT8
+EFIAPI
+CmosRead8 (
+ IN UINTN Index
+ );
+
+/**
+ Writes 8-bits of CMOS data.
+
+ Writes 8-bits of CMOS data to the location specified by Index
+ with the value specified by Value and returns Value.
+
+ @param Index The CMOS location to write.
+ @param Value The value to write to CMOS.
+
+ @return The value written to CMOS.
+
+**/
+UINT8
+EFIAPI
+CmosWrite8 (
+ IN UINTN Index,
+ IN UINT8 Value
+ );
+
+
+#endif
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h
new file mode 100644
index 0000000000..102d21cd64
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h
@@ -0,0 +1,88 @@
+/** @file
+ Platform PEI module include file.
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_PEI_H_INCLUDED_
+#define _PLATFORM_PEI_H_INCLUDED_
+
+VOID
+AddIoMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize
+ );
+
+VOID
+AddIoMemoryRangeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ EFI_PHYSICAL_ADDRESS MemoryLimit
+ );
+
+VOID
+AddMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize
+ );
+
+VOID
+AddMemoryRangeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ EFI_PHYSICAL_ADDRESS MemoryLimit
+ );
+
+VOID
+AddUntestedMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize
+ );
+
+VOID
+AddReservedMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize,
+ BOOLEAN Cacheable
+ );
+
+VOID
+AddressWidthInitialization (
+ VOID
+ );
+
+VOID
+X58TsegMbytesInitialization (
+ VOID
+ );
+
+EFI_STATUS
+PublishPeiMemory (
+ VOID
+ );
+
+UINT32
+GetSystemMemorySizeBelow4gb (
+ VOID
+ );
+
+VOID
+InitializeRamRegions (
+ VOID
+ );
+
+VOID
+InstallFeatureControlCallback (
+ VOID
+ );
+
+extern EFI_BOOT_MODE mBootMode;
+
+extern BOOLEAN mS3Supported;
+
+extern UINT8 mPhysMemAddressWidth;
+
+extern UINT32 mMaxCpuCount;
+
+extern UINT16 mHostBridgeDevId;
+#endif // _PLATFORM_PEI_H_INCLUDED_
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf
new file mode 100644
index 0000000000..ccc7037d75
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf
@@ -0,0 +1,104 @@
+## @file
+# Platform PEI driver
+#
+# This module provides platform specific function to detect boot mode.
+# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SimicsPei
+ FILE_GUID = 05116218-f9f1-41f8-8d17-c2207006ffff
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializePlatform
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ Cmos.c
+ FeatureControl.c
+ MemDetect.c
+ Platform.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ SimicsX58SktPkg/SktPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[Guids]
+ gEfiMemoryTypeInformationGuid
+ gEfiSmmPeiSmramMemoryReserveGuid ## CONSUMES
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ HobLib
+ IoLib
+ PciLib
+ PeiResourcePublicationLib
+ PeiServicesLib
+ PeiServicesTablePointerLib
+ PeimEntryPoint
+ MtrrLib
+ PcdLib
+
+[Pcd]
+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize
+ gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize
+ gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageSize
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
+ gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
+ gBoardModuleTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+ gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
+ gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
+ gBoardModuleTokenSpaceGuid.PcdPciIoBase
+ gBoardModuleTokenSpaceGuid.PcdPciIoSize
+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Base
+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Size
+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Base
+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Size
+ gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
+ gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
+ gMinPlatformPkgTokenSpaceGuid.PcdIoApicId
+
+[FixedPcd]
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+
+[Ppis]
+ gEfiPeiMasterBootModePpiGuid
+ gEfiPeiMpServicesPpiGuid
+
+[Depex]
+ TRUE
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h
new file mode 100644
index 0000000000..d679bcd631
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h
@@ -0,0 +1,38 @@
+/** @file
+ This driver installs SMBIOS information for QSP
+
+ Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>
+ Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SMBIOS_PLATFORM_DXE_H_
+#define _SMBIOS_PLATFORM_DXE_H_
+
+#include <PiDxe.h>
+
+#include <Protocol/Smbios.h>
+#include <IndustryStandard/SmBios.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/IoLib.h>
+
+/**
+ Validates the SMBIOS entry point structure
+
+ @param EntryPointStructure SMBIOS entry point structure
+
+ @retval TRUE The entry point structure is valid
+ @retval FALSE The entry point structure is not valid
+
+**/
+BOOLEAN
+IsEntryPointStructureValid (
+ IN SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure
+ );
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
new file mode 100644
index 0000000000..c5986049f1
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
@@ -0,0 +1,51 @@
+## @file
+# This driver installs SMBIOS information for QSP
+#
+# Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmbiosPlatformDxe
+ FILE_GUID = 4b18323d-2d42-4afa-b9e5-91516a6fe505
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = SmbiosTablePublishEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64
+#
+
+[Sources]
+ SmbiosPlatformDxe.h
+ SmbiosPlatformDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+ AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ BaseMemoryLib
+ BaseLib
+ UefiDriverEntryPoint
+ DebugLib
+ HobLib
+ MemoryAllocationLib
+ IoLib
+
+[Protocols]
+ gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+
+[Depex]
+ gEfiSmbiosProtocolGuid
+
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [edk2-platforms PATCH v2 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio
2019-08-28 0:40 [edk2-platforms PATCH v2 0/7] Add Initial QSP MinPlatform Pkg for SIMICS David Wei
` (2 preceding siblings ...)
2019-08-28 0:40 ` [edk2-platforms PATCH v2 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules David Wei
@ 2019-08-28 0:40 ` David Wei
2019-08-28 22:56 ` Nate DeSimone
2019-08-28 0:40 ` [edk2-platforms PATCH v2 5/7] SimicsOpenBoardPkg: Add Overrides modules and Logo image for SIMICS QSP Platform David Wei
` (2 subsequent siblings)
6 siblings, 1 reply; 16+ messages in thread
From: David Wei @ 2019-08-28 0:40 UTC (permalink / raw)
To: devel
Cc: Hao Wu, Liming Gao, Ankit Sinha, Agyeman Prince,
Kubacki Michael A, Nate DeSimone, Michael D Kinney
Add DXE driver for Legacy Sio support
Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../LegacySioDxe/ComponentName.c | 173 ++++++
.../SimicsOpenBoardPkg/LegacySioDxe/SioChip.c | 272 ++++++++++
.../SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c | 600 +++++++++++++++++++++
.../SimicsOpenBoardPkg/LegacySioDxe/SioService.c | 249 +++++++++
.../LegacySioDxe/ComponentName.h | 87 +++
.../LegacySioDxe/LegacySioDxe.inf | 54 ++
.../SimicsOpenBoardPkg/LegacySioDxe/Register.h | 15 +
.../SimicsOpenBoardPkg/LegacySioDxe/SioChip.h | 195 +++++++
.../SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h | 134 +++++
.../SimicsOpenBoardPkg/LegacySioDxe/SioService.h | 143 +++++
10 files changed, 1922 insertions(+)
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/LegacySioDxe.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.c b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.c
new file mode 100644
index 0000000000..4ba02f92c0
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.c
@@ -0,0 +1,173 @@
+/** @file
+ Install Base and Size Info Ppi for Firmware Volume Recovery.
+
+ Copyright (c) 2013 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SioDriver.h"
+
+///
+/// Component Name Protocol instance
+///
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL mSioComponentName = {
+ SioComponentNameGetDriverName,
+ SioComponentNameGetControllerName,
+ "eng"
+};
+
+///
+/// Component Name 2 Protocol instance
+///
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL mSioComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) SioComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)SioComponentNameGetControllerName,
+ "en"
+};
+
+///
+/// Table of driver names
+///
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSioDriverNameTable[] = {
+ {
+ "eng;en",
+ L"Super I/O Driver"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+///
+/// Table of Controller names
+///
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSioControllerNameTable[] = {
+ {
+ "eng;en",
+ L"Super I/O Controller"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+/**
+ Retrieves a Unicode string that is the user-readable name of the EFI Driver.
+
+ @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param Language A pointer to a three-character ISO 639-2 language identifier.
+ This is the language of the driver name that that the caller
+ is requesting, and it must match one of the languages specified
+ in SupportedLanguages. The number of languages supported by a
+ driver is up to the driver writer.
+ @param DriverName A pointer to the Unicode string to return. This Unicode string
+ is the name of the driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the
+ language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+SioComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mSioDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &mSioComponentName)
+ );
+}
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param ControllerHandle The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ @param ChildHandle The handle of the child controller to retrieve the name
+ of. This is an optional parameter that may be NULL. It
+ will be NULL for device drivers. It will also be NULL
+ for a bus drivers that wish to retrieve the name of the
+ bus controller. It will not be NULL for a bus driver
+ that wishes to retrieve the name of a child controller.
+ @param Language A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that the caller is requesting, and it must match one
+ of the languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up to the
+ driver writer.
+ @param ControllerName A pointer to the Unicode string to return. This Unicode
+ string is the name of the controller specified by
+ ControllerHandle and ChildHandle in the language specified
+ by Language, from the point of view of the driver specified
+ by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user-readable name in the
+ language specified by Language for the driver
+ specified by This was returned in DriverName.
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently managing
+ the controller specified by ControllerHandle and
+ ChildHandle.
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the
+ language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+SioComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Make sure this driver is currently managing ControllHandle
+ //
+ Status = EfiTestManagedDevice (
+ ControllerHandle,
+ mSioDriver.DriverBindingHandle,
+ &gEfiPciIoProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // ChildHandle must be NULL for a Device Driver
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mSioControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &mSioComponentName)
+ );
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c
new file mode 100644
index 0000000000..b9a7b9cd24
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c
@@ -0,0 +1,272 @@
+/** @file
+ Super I/O specific implementation.
+
+ Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SioDriver.h"
+#include <Library/S3IoLib.h>
+
+LOCAL_IO_WRITE8 mIoWrite8 = IoWrite8;
+//
+// System configuration (setup) information
+//
+// SYSTEM_CONFIGURATION mSystemConfiguration;
+
+//
+// COM 1 UART Controller
+//
+ACPI_SIO_RESOURCES_IO_IRQ mCom1Resources = {
+ {
+ { ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR },
+ 0x3f8,
+ 8
+ },
+ {
+ { ACPI_IRQ_NOFLAG_DESCRIPTOR },
+ BIT4 // IRQ4
+ },
+ {
+ ACPI_END_TAG_DESCRIPTOR,
+ 0
+ }
+};
+
+//
+// PS/2 Keyboard Controller
+//
+ACPI_SIO_RESOURCES_IO_IRQ mKeyboardResources = {
+ {
+ { ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR },
+ 0x60,
+ 5
+ },
+ {
+ { ACPI_IRQ_NOFLAG_DESCRIPTOR },
+ BIT1
+ },
+ {
+ ACPI_END_TAG_DESCRIPTOR,
+ 0
+ }
+};
+
+//
+// PS/2 Mouse Controller
+//
+ACPI_SIO_RESOURCES_IO_IRQ mMouseResources = {
+ {
+ { ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR },
+ 0x60,
+ 5
+ },
+ {
+ { ACPI_IRQ_NOFLAG_DESCRIPTOR },
+ BIT12
+ },
+ {
+ ACPI_END_TAG_DESCRIPTOR,
+ 0
+ }
+};
+
+//
+// Table of SIO Controllers
+//
+DEVICE_INFO mDeviceInfo[] = {
+ {
+ {
+ EISA_PNP_ID(0x501),
+ 0
+ },
+ 0,
+ RESOURCE_IO | RESOURCE_IRQ,
+ { (ACPI_SMALL_RESOURCE_HEADER *) &mCom1Resources },
+ { (ACPI_SMALL_RESOURCE_HEADER *) &mCom1Resources }
+ }, // COM 1 UART Controller
+ {
+ {
+ EISA_PNP_ID(0x303),
+ 0
+ },
+ 0,
+ 0, // Cannot change resource
+ { (ACPI_SMALL_RESOURCE_HEADER *) &mKeyboardResources },
+ { (ACPI_SMALL_RESOURCE_HEADER *) &mKeyboardResources }
+ }, // PS/2 Keyboard Controller
+ {
+ {
+ EISA_PNP_ID(0xF03),
+ 0
+ },
+ 0,
+ 0, // Cannot change resource
+ { (ACPI_SMALL_RESOURCE_HEADER *) &mMouseResources },
+ { (ACPI_SMALL_RESOURCE_HEADER *) &mMouseResources }
+ } // PS/2 Mouse Controller
+};
+
+
+/**
+ Return the supported devices.
+
+ @param[out] Devices Pointer to pointer of EFI_SIO_ACPI_DEVICE_ID.
+ Caller is responsible to free the buffer.
+ @param[out] Count Pointer to UINTN holding the device count.
+**/
+VOID
+DeviceGetList (
+ OUT EFI_SIO_ACPI_DEVICE_ID **Devices,
+ OUT UINTN *Count
+ )
+{
+ EFI_SIO_ACPI_DEVICE_ID *LocalDevices;
+ UINTN LocalCount;
+ UINTN DeviceCount;
+ UINTN Index;
+
+ //
+ // Allocate enough memory for simplicity
+ //
+ DeviceCount = sizeof (mDeviceInfo) / sizeof (mDeviceInfo[0]);
+ LocalDevices = AllocatePool (sizeof (EFI_SIO_ACPI_DEVICE_ID) * DeviceCount);
+ ASSERT (LocalDevices != NULL);
+ if (LocalDevices == NULL) {
+ return;
+ }
+ LocalCount = 0;
+
+ for (Index = 0; Index < DeviceCount; Index++) {
+ CopyMem (&LocalDevices[LocalCount], &mDeviceInfo[Index].Device, sizeof (EFI_SIO_ACPI_DEVICE_ID));
+ LocalCount++;
+ }
+
+ *Devices = LocalDevices;
+ *Count = LocalCount;
+}
+
+
+/**
+ Super I/O controller initialization.
+
+ @retval EFI_SUCCESS The super I/O controller is found and initialized.
+ @retval EFI_UNSUPPORTED The super I/O controller is not found.
+**/
+EFI_STATUS
+SioInit (
+ VOID
+ )
+{
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Find the DEVICE_INFO for specified Device.
+
+ @param[in] Device Pointer to the EFI_SIO_ACPI_DEVICE_ID.
+
+ @retval DEVICE_INFO* Pointer to the DEVICE_INFO.
+**/
+DEVICE_INFO *
+DeviceSearch (
+ IN EFI_SIO_ACPI_DEVICE_ID *Device
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < sizeof (mDeviceInfo) / sizeof (mDeviceInfo[0]); Index++) {
+ if (CompareMem (Device, &mDeviceInfo[Index].Device, sizeof (*Device)) == 0) {
+ return &mDeviceInfo[Index];
+ }
+ }
+
+ ASSERT (FALSE);
+ return NULL;
+}
+
+
+/**
+ Program the SIO chip to enable the specified device using the default resource.
+
+ @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID.
+**/
+VOID
+DeviceEnable (
+ IN EFI_SIO_ACPI_DEVICE_ID *Device
+ )
+{
+}
+
+
+/**
+ Get the ACPI resources for specified device.
+
+ @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID.
+ @param[out] Resources Pointer to ACPI_RESOURCE_HEADER_PTR.
+
+ @retval EFI_SUCCESS The resources are returned successfully.
+**/
+EFI_STATUS
+DeviceGetResources (
+ IN EFI_SIO_ACPI_DEVICE_ID *Device,
+ OUT ACPI_RESOURCE_HEADER_PTR *Resources
+ )
+{
+ DEVICE_INFO *DeviceInfo;
+
+ DeviceInfo = DeviceSearch (Device);
+
+ *Resources = DeviceInfo->Resources;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Set the ACPI resources for specified device.
+
+ The SIO chip is programmed to use the new resources and the
+ resources setting are saved. The function assumes the resources
+ are valid.
+
+ @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID.
+ @param[in] Resources ACPI_RESOURCE_HEADER_PTR.
+
+ @retval EFI_UNSUPPORTED
+**/
+EFI_STATUS
+DeviceSetResources (
+ IN EFI_SIO_ACPI_DEVICE_ID *Device,
+ IN ACPI_RESOURCE_HEADER_PTR Resources
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+/**
+ Get the possible ACPI resources for specified device.
+
+ @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID.
+ @param[out] Resources Pointer to ACPI_RESOURCE_HEADER_PTR.
+
+ @retval EFI_SUCCESS The resources are returned successfully.
+**/
+EFI_STATUS
+DevicePossibleResources (
+ IN EFI_SIO_ACPI_DEVICE_ID *Device,
+ OUT ACPI_RESOURCE_HEADER_PTR *Resources
+ )
+{
+ DEVICE_INFO *DeviceInfo;
+
+ DeviceInfo = DeviceSearch (Device);
+
+ *Resources = DeviceInfo->PossibleResources;
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c
new file mode 100644
index 0000000000..408c6ff301
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c
@@ -0,0 +1,600 @@
+/** @file
+ EFI Driver following Driver Binding Protocol.
+
+ Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SioDriver.h"
+
+
+//
+// This driver is for ACPI(PNP0A03,0)/PCI(0x1f,0)
+//
+//
+// Sio Driver Global Variables
+//
+EFI_DRIVER_BINDING_PROTOCOL mSioDriver = {
+ SioDriverSupported,
+ SioDriverStart,
+ SioDriverStop,
+ 1,
+ NULL,
+ NULL
+};
+
+//
+// The list of the created SIO_DEV
+//
+LIST_ENTRY mSioDevPool = INITIALIZE_LIST_HEAD_VARIABLE (mSioDevPool);
+
+//
+// Template structure to create SIO_DEV
+//
+SIO_DEV mSioDevTemplate = {
+ SIO_DEV_SIGNATURE, // Signature
+ NULL, // PciHandle
+ {
+ 0x00000000, // HID
+ 0x00000000 // UID
+ },
+ NULL, // Handle
+ { // Sio Instance
+ SioRegisterAccess,
+ SioGetResources,
+ SioSetResources,
+ SioPossibleResources,
+ SioModify
+ },
+ NULL, // DevicePath
+ {
+ NULL, // ForwardLink
+ NULL, // BackLink
+ }
+};
+
+//
+// Template ACPI_HID_DEVICE_PATH structure to create device path
+//
+ACPI_HID_DEVICE_PATH mAcpiNodeTemplate = {
+ {
+ ACPI_DEVICE_PATH, // Type
+ ACPI_DP, // SubType
+ {
+ sizeof (ACPI_HID_DEVICE_PATH), // Length[0]
+ 0 // Length[1]
+ }
+ },
+ 0x00000000, // HID
+ 0x00000000 // UID
+};
+
+
+/**
+ The user Entry Point for module Lpc47m17x. The user code starts with this function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+**/
+EFI_STATUS
+EFIAPI
+SioDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ if (EFI_ERROR (SioInit())) {
+ return EFI_UNSUPPORTED;
+ } else {
+
+ //
+ // Install protocols
+ //
+ return EfiLibInstallDriverBindingComponentName2 (
+ ImageHandle,
+ SystemTable,
+ &mSioDriver,
+ ImageHandle,
+ &mSioComponentName,
+ &mSioComponentName2
+ );
+ }
+}
+
+
+/**
+ Test to see if this driver supports Controller Handle.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] Controller Handle of device to test
+ @param[in] RemainingDevicePath Optional parameter use to pick a specific child
+ device to start.
+
+ @retval EFI_SUCCESS This driver supports this device
+ @retval EFI_ALREADY_STARTED This driver is already running on this device
+ @retval other This driver does not support this device
+**/
+EFI_STATUS
+EFIAPI
+SioDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ ACPI_HID_DEVICE_PATH *AcpiNode;
+ PCI_TYPE00 Pci;
+ UINTN Index;
+ EFI_SIO_ACPI_DEVICE_ID *Devices;
+ UINTN Count;
+ UINTN SegmentNumber;
+ UINTN BusNumber;
+ UINTN DeviceNumber;
+ UINTN FunctionNumber;
+
+ //
+ // If RemainingDevicePath is not NULL, it should verify that the first device
+ // path node in RemainingDevicePath is an ACPI Device path node which is a
+ // legal Device Path Node for this bus driver's children.
+ //
+ if (RemainingDevicePath != NULL) {
+ if (!IsDevicePathEnd (RemainingDevicePath)) {
+ if ((RemainingDevicePath->Type != ACPI_DEVICE_PATH) ||
+ (((RemainingDevicePath->SubType != ACPI_DP) || (DevicePathNodeLength (RemainingDevicePath) != sizeof (ACPI_HID_DEVICE_PATH))) &&
+ ((RemainingDevicePath->SubType != ACPI_EXTENDED_DP) || (DevicePathNodeLength (RemainingDevicePath) != sizeof (ACPI_EXTENDED_HID_DEVICE_PATH))))
+ ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ DeviceGetList (&Devices, &Count);
+ if (Devices == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ AcpiNode = (ACPI_HID_DEVICE_PATH *) RemainingDevicePath;
+ for (Index = 0; Index < Count; Index++) {
+ if ((AcpiNode->HID == Devices[Index].HID) &&
+ (AcpiNode->UID == Devices[Index].UID)) {
+ break;
+ }
+ }
+ FreePool (Devices);
+ if (Index == Count) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+ }
+
+ //
+ // See if the parent device path can be opened BY_DRIVER
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &ParentDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
+ return Status;
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ //
+ // Get PciIo protocol instance
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (!EFI_ERROR (Status)) {
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ sizeof (Pci) / sizeof (UINT32),
+ &Pci
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = EFI_UNSUPPORTED;
+ if ((Pci.Hdr.Command & (EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_MEMORY_SPACE))
+ == (EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_MEMORY_SPACE)
+ ) {
+ if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {
+ //
+ // See if this is a standard PCI to ISA Bridge from the Base Code and Class Code
+ //
+ if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA) {
+ Status = EFI_SUCCESS;
+ }
+
+ //
+ // See if this is an Intel PCI to ISA Bridge in Positive Decode Mode
+ //
+ if ((Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE) &&
+ (Pci.Hdr.VendorId == 0x8086)) {
+ //
+ // See if this is on Function #0 to avoid false positive on
+ // PCI_CLASS_BRIDGE_OTHER that has the same value as
+ // PCI_CLASS_BRIDGE_ISA_PDECODE
+ //
+ Status = PciIo->GetLocation (
+ PciIo,
+ &SegmentNumber,
+ &BusNumber,
+ &DeviceNumber,
+ &FunctionNumber
+ );
+ if (!EFI_ERROR (Status) && (FunctionNumber == 0)) {
+ Status = EFI_SUCCESS;
+ } else {
+ Status = EFI_UNSUPPORTED;
+ }
+ }
+ }
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ }
+ if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Destroy the SIO controller handle.
+
+ @param[in] ChildHandle The SIO controller handle.
+
+ @retval EFI_SUCCESS The SIO controller handle is destroyed successfully.
+**/
+EFI_STATUS
+SioDestroyDevice (
+ IN EFI_HANDLE ChildHandle
+ )
+{
+ EFI_STATUS Status;
+ SIO_DEV *SioDev;
+ EFI_SIO_PROTOCOL *Sio;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+
+ Status = gBS->HandleProtocol (
+ ChildHandle,
+ &gEfiSioProtocolGuid,
+ (VOID **) &Sio
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ SioDev = SIO_DEV_FROM_THIS (Sio);
+
+ Status = gBS->CloseProtocol (
+ SioDev->PciHandle,
+ &gEfiPciIoProtocolGuid,
+ mSioDriver.DriverBindingHandle,
+ ChildHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ ChildHandle,
+ &gEfiDevicePathProtocolGuid,
+ SioDev->DevicePath,
+ &gEfiSioProtocolGuid,
+ &SioDev->Sio,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->OpenProtocol (
+ SioDev->PciHandle,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ mSioDriver.DriverBindingHandle,
+ ChildHandle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ return Status;
+ }
+
+ RemoveEntryList (&SioDev->Link);
+ FreePool (SioDev->DevicePath);
+ FreePool (SioDev);
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Create the SIO controller handle.
+
+ @param[in] Controller The parent PCI controller handle.
+ @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID.
+ @param[in] ParentDevicePath The device path of the parent controller.
+ @param[out] PciIo The PciIo instance of the parent controller.
+**/
+VOID
+SioCreateDevice (
+ IN EFI_HANDLE Controller,
+ IN EFI_SIO_ACPI_DEVICE_ID *Device,
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
+ OUT EFI_PCI_IO_PROTOCOL *PciIo
+ )
+{
+ EFI_STATUS Status;
+ SIO_DEV *SioDev;
+
+ DeviceEnable (Device);
+ SioDev = AllocateCopyPool (sizeof (SIO_DEV), &mSioDevTemplate);
+ ASSERT (SioDev != NULL);
+ if (SioDev == NULL) {
+ return;
+ }
+ InsertHeadList (&mSioDevPool, &SioDev->Link);
+
+ SioDev->PciHandle = Controller;
+
+ CopyMem (&SioDev->Device, Device, sizeof (*Device));
+
+ mAcpiNodeTemplate.HID = Device->HID;
+ mAcpiNodeTemplate.UID = Device->UID;
+ SioDev->DevicePath = AppendDevicePathNode (ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &mAcpiNodeTemplate);
+ ASSERT (SioDev->DevicePath != NULL);
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &SioDev->Handle,
+ &gEfiSioProtocolGuid, &SioDev->Sio,
+ &gEfiDevicePathProtocolGuid, SioDev->DevicePath,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ mSioDriver.DriverBindingHandle,
+ SioDev->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
+
+/**
+ Start this driver on ControllerHandle.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] Controller Handle of device to bind driver to
+ @param[in] RemainingDevicePath Optional parameter use to pick a specific child
+ device to start.
+
+ @retval EFI_SUCCESS This driver is added to ControllerHandle
+ @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
+ @retval other This driver does not support this device
+**/
+EFI_STATUS
+EFIAPI
+SioDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_SIO_ACPI_DEVICE_ID *Devices;
+ SIO_DEV *SioDev;
+ UINTN Count;
+ UINTN Index;
+ ACPI_HID_DEVICE_PATH *AcpiNode;
+ BOOLEAN *HasCreated;
+ BOOLEAN *RequestCreate;
+ LIST_ENTRY *Node;
+
+ HasCreated = NULL;
+ RequestCreate = NULL;
+ //
+ // Get the ISA bridge's Device Path
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &ParentDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+ return Status;
+ }
+
+ //
+ // Get Pci IO
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ return Status;
+ }
+
+ if ((RemainingDevicePath != NULL) && IsDevicePathEnd (RemainingDevicePath)) {
+ return EFI_SUCCESS;
+ }
+
+ DeviceGetList (&Devices, &Count);
+ if (Devices == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit_Start;
+ }
+ HasCreated = AllocatePool (sizeof (BOOLEAN) * Count);
+ ASSERT (HasCreated != NULL);
+ if (HasCreated == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit_Start;
+ }
+ RequestCreate = AllocatePool (sizeof (BOOLEAN) * Count);
+ ASSERT (RequestCreate != NULL);
+ if (RequestCreate == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit_Start;
+ }
+
+ //
+ // Assume no children has been created.
+ // Assume the SIO interface hasn't been initialized.
+ //
+ ZeroMem (HasCreated, sizeof (BOOLEAN) * Count);
+
+ if (Status == EFI_ALREADY_STARTED) {
+ for (Node = GetFirstNode (&mSioDevPool);
+ !IsNull (&mSioDevPool, Node);
+ Node = GetNextNode (&mSioDevPool, Node)
+ ) {
+ SioDev = CR (Node, SIO_DEV, Link, SIO_DEV_SIGNATURE);
+ Status = gBS->HandleProtocol (
+ SioDev->PciHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &DevicePath
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // See if they are under the same PCI to ISA Bridge
+ //
+ if (CompareMem (DevicePath, ParentDevicePath, GetDevicePathSize (DevicePath)) == 0) {
+ for (Index = 0; Index < Count; Index++) {
+ if (CompareMem (&SioDev->Device, &Devices[Index], sizeof (EFI_SIO_ACPI_DEVICE_ID)) == 0) {
+ HasCreated[Index] = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ AcpiNode = (ACPI_HID_DEVICE_PATH *) RemainingDevicePath;
+ for (Index = 0; Index < Count; Index++) {
+ if ((AcpiNode == NULL) ||
+ ((AcpiNode->HID == Devices[Index].HID) && (AcpiNode->UID == Devices[Index].UID))
+ ) {
+ RequestCreate[Index] = TRUE;
+ } else {
+ RequestCreate[Index] = FALSE;
+ }
+ }
+
+ for (Index = 0; Index < Count; Index++) {
+ if (RequestCreate[Index] && !HasCreated[Index]) {
+ SioCreateDevice (Controller, &Devices[Index], ParentDevicePath, PciIo);
+ }
+ }
+Exit_Start:
+ if (Devices != NULL) {
+ FreePool (Devices);
+ }
+ if (HasCreated != NULL) {
+ FreePool (HasCreated);
+ }
+ if (RequestCreate != NULL) {
+ FreePool (RequestCreate);
+ }
+
+ return Status;
+}
+
+
+/**
+ Stop this driver on ControllerHandle.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] Controller Handle of device to stop driver on
+ @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
+ children is zero stop the entire bus driver.
+ @param[in] ChildHandleBuffer List of Child Handles to Stop.
+
+ @retval EFI_SUCCESS This driver is removed ControllerHandle
+ @retval other This driver was not removed from this device
+**/
+EFI_STATUS
+EFIAPI
+SioDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ BOOLEAN AllChildrenStopped;
+
+ if (NumberOfChildren == 0) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ return EFI_SUCCESS;
+ }
+
+ AllChildrenStopped = TRUE;
+ for (Index = 0; Index < NumberOfChildren; Index++) {
+ Status = SioDestroyDevice (ChildHandleBuffer[Index]);
+ if (EFI_ERROR (Status)) {
+ AllChildrenStopped = FALSE;
+ }
+ }
+
+ if (AllChildrenStopped) {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_DEVICE_ERROR;
+ }
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c
new file mode 100644
index 0000000000..379002b833
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c
@@ -0,0 +1,249 @@
+/** @file
+ Super I/O Interface implementation.
+
+ Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SioDriver.h"
+
+
+/**
+ Provides an interface to get a list of the current resources consumed by the device in the ACPI
+ Resource Descriptor format.
+
+ GetResources() returns a list of resources currently consumed by the device. The
+ ResourceList is a pointer to the buffer containing resource descriptors for the device. The
+ descriptors are in the format of Small or Large ACPI resource descriptor as defined by ACPI
+ specification (2.0 & 3.0). The buffer of resource descriptors is terminated with the 'End tag'
+ resource descriptor.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[out] ResourceList A pointer to an ACPI resource descriptor list that defines the current resources
+ used by the device. Type ACPI_RESOURCE_HEADER_PTR is defined in the "Related
+ Definitions" below.
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER ResourceList is NULL
+**/
+EFI_STATUS
+EFIAPI
+SioGetResources (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ OUT ACPI_RESOURCE_HEADER_PTR *ResourceList
+ )
+{
+ SIO_DEV *SioDev;
+
+ if (ResourceList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SioDev = SIO_DEV_FROM_THIS (This);
+
+ return DeviceGetResources (&SioDev->Device, ResourceList);
+}
+
+
+/**
+ Provides a collection of resource descriptor lists. Each resource descriptor list in the collection
+ defines a combination of resources that can potentially be used by the device.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[out] ResourceCollection Collection of the resource descriptor lists.
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER ResourceCollection is NULL
+**/
+EFI_STATUS
+EFIAPI
+SioPossibleResources (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ OUT ACPI_RESOURCE_HEADER_PTR *ResourceCollection
+ )
+{
+ SIO_DEV *SioDev;
+
+ if (ResourceCollection == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SioDev = SIO_DEV_FROM_THIS (This);
+
+ return DevicePossibleResources (&SioDev->Device, ResourceCollection);
+}
+
+
+/**
+ Sets the resources for the device.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] ResourceList Pointer to the ACPI resource descriptor list. Type ACPI_RESOURCE_HEADER_PTR
+ is defined in the "Related Definitions" section of
+ EFI_SIO_PROTOCOL.GetResources().
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER ResourceList is invalid
+ @retval EFI_ACCESS_DENIED Some of the resources in ResourceList are in use
+**/
+EFI_STATUS
+EFIAPI
+SioSetResources (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ IN ACPI_RESOURCE_HEADER_PTR ResourceList
+ )
+{
+ SIO_DEV *SioDev;
+ ACPI_RESOURCE_HEADER_PTR ResourcePtr;
+ ACPI_RESOURCE_HEADER_PTR ResourceCollection;
+ ACPI_RESOURCE_HEADER_PTR ResourcePtr2;
+ BOOLEAN Found;
+
+ ResourcePtr = ResourceList;
+ SioDev = SIO_DEV_FROM_THIS (This);
+
+ //
+ // Check whether the resource is in the possible resource collection
+ //
+ DevicePossibleResources (&SioDev->Device, &ResourceCollection);
+
+ while (ResourcePtr.SmallHeader->Byte != ACPI_END_TAG_DESCRIPTOR) {
+
+ Found = FALSE;
+ ResourcePtr2 = ResourceCollection;
+ while (ResourcePtr2.SmallHeader->Byte != ACPI_END_TAG_DESCRIPTOR) {
+ if (ResourcePtr2.SmallHeader->Bits.Type == 0) {
+ //
+ // Small Header
+ //
+ if (CompareMem (
+ ResourcePtr2.SmallHeader,
+ ResourcePtr.SmallHeader,
+ ResourcePtr2.SmallHeader->Bits.Length + sizeof (*ResourcePtr2.SmallHeader)
+ ) == 0) {
+ Found = TRUE;
+ break;
+ }
+
+ ResourcePtr2.SmallHeader = (ACPI_SMALL_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr2.SmallHeader
+ + ResourcePtr2.SmallHeader->Bits.Length
+ + sizeof (*ResourcePtr2.SmallHeader));
+
+ } else {
+ //
+ // Large Header
+ //
+ if (CompareMem (
+ ResourcePtr2.LargeHeader,
+ ResourcePtr.LargeHeader,
+ ResourcePtr2.LargeHeader->Length + sizeof (*ResourcePtr2.LargeHeader)
+ ) == 0) {
+ Found = TRUE;
+ break;
+ }
+
+ ResourcePtr2.LargeHeader = (ACPI_LARGE_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr2.LargeHeader
+ + ResourcePtr2.LargeHeader->Length
+ + sizeof (*ResourcePtr2.LargeHeader));
+ }
+ }
+
+ if (!Found) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ if (ResourcePtr.SmallHeader->Bits.Type == 0) {
+ ResourcePtr.SmallHeader = (ACPI_SMALL_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr.SmallHeader
+ + ResourcePtr.SmallHeader->Bits.Length
+ + sizeof (*ResourcePtr.SmallHeader));
+ } else {
+ ResourcePtr.LargeHeader = (ACPI_LARGE_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr.LargeHeader
+ + ResourcePtr.LargeHeader->Length
+ + sizeof (*ResourcePtr.LargeHeader));
+ }
+ }
+
+ //
+ // ResourceList can be set
+ //
+ return DeviceSetResources (&SioDev->Device, ResourceList);
+}
+
+
+/**
+ Provides a low level access to the registers for the Super I/O.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] Write Specifies the type of the register operation. If this parameter is TRUE,
+ Value is interpreted as an input parameter and the operation is a register write.
+ If this parameter is FALSE, Value is interpreted as an output parameter and the
+ operation is a register read.
+ @param[in] ExitCfgMode Exit Configuration Mode Indicator. If this parameter is set to TRUE, the
+ Super I/O driver will turn off configuration mode of the Super I/O prior to returning
+ from this function. If this parameter is set to FALSE, the Super I/O driver will
+ leave Super I/O in the configuration mode.
+ The Super I/O driver must track the current state of the Super I/O and enable the
+ configuration mode of Super I/O if necessary prior to register access.
+ @param[in] Register Register number.
+ @param[in, out] Value If Write is TRUE, Value is a pointer to the buffer containing the byte of data to be
+ written to the Super I/O register. If Write is FALSE, Value is a pointer to the
+ destination buffer for the byte of data to be read from the Super I/O register.
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER The Value is NULL
+ @retval EFI_INVALID_PARAMETER Invalid Register number
+**/
+EFI_STATUS
+EFIAPI
+SioRegisterAccess (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ IN BOOLEAN Write,
+ IN BOOLEAN ExitCfgMode,
+ IN UINT8 Register,
+ IN OUT UINT8 *Value
+ )
+{
+ if (Value == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Provides an interface for a table based programming of the Super I/O registers.
+
+ The Modify() function provides an interface for table based programming of the Super I/O
+ registers. This function can be used to perform programming of multiple Super I/O registers with a
+ single function call. For each table entry, the Register is read, its content is bitwise ANDed with
+ AndMask, and then ORed with OrMask before being written back to the Register. The Super
+ I/O driver must track the current state of the Super I/O and enable the configuration mode of Super I/
+ O if necessary prior to table processing. Once the table is processed, the Super I/O device has to be
+ returned to the original state.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] Command A pointer to an array of NumberOfCommands EFI_SIO_REGISTER_MODIFY
+ structures. Each structure specifies a single Super I/O register modify operation.
+ Type EFI_SIO_REGISTER_MODIFY is defined in the "Related Definitions" below.
+ @param[in] NumberOfCommands Number of elements in the Command array.
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER Command is NULL
+**/
+EFI_STATUS
+EFIAPI
+SioModify (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ IN CONST EFI_SIO_REGISTER_MODIFY *Command,
+ IN UINTN NumberOfCommands
+ )
+{
+
+ if (Command == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.h b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.h
new file mode 100644
index 0000000000..5368f94bcd
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.h
@@ -0,0 +1,87 @@
+/** @file
+ Install Base and Size Info Ppi for Firmware Volume Recovery.
+
+ Copyright (c) 2013 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+/**
+ Retrieves a Unicode string that is the user-readable name of the EFI Driver.
+
+ @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param Language A pointer to a three-character ISO 639-2 language identifier.
+ This is the language of the driver name that that the caller
+ is requesting, and it must match one of the languages specified
+ in SupportedLanguages. The number of languages supported by a
+ driver is up to the driver writer.
+ @param DriverName A pointer to the Unicode string to return. This Unicode string
+ is the name of the driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the
+ language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+SioComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param ControllerHandle The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ @param ChildHandle The handle of the child controller to retrieve the name
+ of. This is an optional parameter that may be NULL. It
+ will be NULL for device drivers. It will also be NULL
+ for a bus drivers that wish to retrieve the name of the
+ bus controller. It will not be NULL for a bus driver
+ that wishes to retrieve the name of a child controller.
+ @param Language A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that the caller is requesting, and it must match one
+ of the languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up to the
+ driver writer.
+ @param ControllerName A pointer to the Unicode string to return. This Unicode
+ string is the name of the controller specified by
+ ControllerHandle and ChildHandle in the language specified
+ by Language, from the point of view of the driver specified
+ by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user-readable name in the
+ language specified by Language for the driver
+ specified by This was returned in DriverName.
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently managing
+ the controller specified by ControllerHandle and
+ ChildHandle.
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the
+ language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+SioComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/LegacySioDxe.inf b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/LegacySioDxe.inf
new file mode 100644
index 0000000000..275f36ca47
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/LegacySioDxe.inf
@@ -0,0 +1,54 @@
+## @file
+# Module information that produces the
+# EFI_SIO_PROTOCOL.
+#
+# Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = HitachiH8s2113Dxe
+ FILE_GUID = 7807E404-8281-4FF1-8457-0B54BABE263F
+ VERSION_STRING = 1.0
+ MODULE_TYPE = UEFI_DRIVER
+ ENTRY_POINT = SioDriverEntryPoint
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+ BaseLib
+ UefiLib
+ DebugLib
+ MemoryAllocationLib
+ PcdLib
+ DevicePathLib
+ IoLib
+ UefiDriverEntryPoint
+ UefiBootServicesTableLib
+ S3BootScriptLib
+ S3IoLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[Sources]
+ SioChip.c
+ SioChip.h
+ SioService.c
+ SioService.h
+ SioDriver.c
+ SioDriver.h
+ ComponentName.c
+
+[Protocols]
+ gEfiPciIoProtocolGuid ## CONSUMES
+ gEfiDevicePathProtocolGuid ## PRODUCES
+ gEfiSioProtocolGuid ## PRODUCES
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register.h b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register.h
new file mode 100644
index 0000000000..f61f713cf2
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register.h
@@ -0,0 +1,15 @@
+/** @file
+ Super I/O register definitions
+
+ Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _REGISTER_H_
+#define _REGISTER_H_
+
+#define EC_COMMAND_PORT 0x66
+#define EC_DATA_PORT 0x62
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h
new file mode 100644
index 0000000000..48e28c44b0
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h
@@ -0,0 +1,195 @@
+/** @file
+ Super I/O specific header.
+
+ Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SIO_H_
+#define _SIO_H_
+
+
+#include "Register.h"
+
+typedef
+UINT8
+(EFIAPI *LOCAL_IO_WRITE8) (
+ IN UINTN Port,
+ IN UINT8 Value
+ );
+
+#define RESOURCE_IO BIT0
+#define RESOURCE_IRQ BIT1
+#define RESOURCE_DMA BIT2
+#define RESOURCE_MEM BIT3
+
+#pragma pack(1)
+
+typedef struct {
+ EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR Io;
+ EFI_ACPI_IRQ_NOFLAG_DESCRIPTOR Irq;
+ EFI_ACPI_END_TAG_DESCRIPTOR End;
+} ACPI_SIO_RESOURCES_IO_IRQ;
+#pragma pack()
+
+typedef struct {
+ UINT32 HID;
+ UINT32 UID;
+} EFI_SIO_ACPI_DEVICE_ID;
+
+typedef struct {
+ EFI_SIO_ACPI_DEVICE_ID Device;
+ UINT8 DeviceId;
+ UINT8 ResourceMask;
+ ACPI_RESOURCE_HEADER_PTR Resources;
+ ACPI_RESOURCE_HEADER_PTR PossibleResources;
+} DEVICE_INFO;
+
+
+/**
+ Initialize the SIO chip for S3.
+**/
+VOID
+SioInitForS3 (
+ VOID
+ );
+
+
+/**
+ Return the supported devices.
+
+ @param[out] Devices Pointer to pointer of EFI_SIO_ACPI_DEVICE_ID.
+ Caller is responsible to free the buffer.
+ @param[out] Count Pointer to UINTN holding the device count.
+**/
+VOID
+DeviceGetList (
+ OUT EFI_SIO_ACPI_DEVICE_ID **Devices,
+ OUT UINTN *Count
+ );
+
+
+/**
+ Program the SIO chip to enable the specified device using the default resource.
+
+ @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID.
+**/
+VOID
+DeviceEnable (
+ IN EFI_SIO_ACPI_DEVICE_ID *Device
+ );
+
+
+/**
+ Get the possible ACPI resources for specified device.
+
+ @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID.
+ @param[out] Resources Pointer to ACPI_RESOURCE_HEADER_PTR.
+
+ @retval EFI_SUCCESS The resources are returned successfully.
+**/
+EFI_STATUS
+DevicePossibleResources (
+ IN EFI_SIO_ACPI_DEVICE_ID *Device,
+ OUT ACPI_RESOURCE_HEADER_PTR *Resources
+ );
+
+
+/**
+ Set the ACPI resources for specified device.
+
+ The SIO chip is programmed to use the new resources and the
+ resources setting are saved. The function assumes the resources
+ are valid.
+
+ @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID.
+ @param[in] Resources ACPI_RESOURCE_HEADER_PTR.
+
+ @retval EFI_SUCCESS The resources are set successfully.
+**/
+EFI_STATUS
+DeviceSetResources (
+ IN EFI_SIO_ACPI_DEVICE_ID *Device,
+ IN ACPI_RESOURCE_HEADER_PTR Resources
+ );
+
+
+/**
+ Get the ACPI resources for specified device.
+
+ @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID.
+ @param[out] Resources Pointer to ACPI_RESOURCE_HEADER_PTR.
+
+ @retval EFI_SUCCESS The resources are returned successfully.
+**/
+EFI_STATUS
+DeviceGetResources (
+ IN EFI_SIO_ACPI_DEVICE_ID *Device,
+ OUT ACPI_RESOURCE_HEADER_PTR *Resources
+ );
+
+
+/**
+ Program the SIO chip to enter the configure mode.
+**/
+VOID
+EnterConfigMode (
+ VOID
+ );
+
+
+/**
+ Program the SIO chip to exit the configure mode.
+**/
+VOID
+ExitConfigMode (
+ VOID
+ );
+
+
+/**
+ Perform a 8-bit I/O write to SIO register.
+
+ @param[in] Index The register index.
+ @param[in] Data The value to write to register.
+**/
+VOID
+WriteRegister (
+ IN UINT8 Index,
+ IN UINT8 Data
+ );
+
+
+/**
+ Perform a 8-bit I/O read from SIO register.
+
+ @param[in] Index The register index.
+
+ @retval Value The value written to the register.
+**/
+UINT8
+ReadRegister (
+ IN UINT8 Index
+ );
+
+//
+// Prototypes for the sio internal function
+//
+//
+// Internal function
+//
+
+
+/**
+ Find Super I/O controller.
+
+ @retval EFI_SUCCESS Super I/O controller exists.
+ @retval EFI_UNSUPPORTED Super I/O controller does not exist.
+**/
+EFI_STATUS
+SioInit (
+ VOID
+ );
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h
new file mode 100644
index 0000000000..2e75871f7f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h
@@ -0,0 +1,134 @@
+/** @file
+ Header file for Driver Binding Protocol.
+
+ Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SIO_DRIVER_H_
+#define _SIO_DRIVER_H_
+
+#include <PiDxe.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/PciLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+
+//
+// Driver Consumed Protocol Prototypes
+//
+#include <Protocol/DriverBinding.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/DevicePath.h>
+
+//
+// Driver Produced Protocol Prototypes
+//
+#include <Protocol/SuperIo.h>
+
+
+#include "SioChip.h"
+#include "SioService.h"
+#include "ComponentName.h"
+
+//
+// Global Variables definitions
+//
+extern EFI_DRIVER_BINDING_PROTOCOL mSioDriver;
+extern EFI_COMPONENT_NAME_PROTOCOL mSioComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL mSioComponentName2;
+
+//
+// SIO device private data structure
+//
+#define SIO_DEV_SIGNATURE SIGNATURE_32 ('_', 'S', 'I', 'O')
+
+typedef struct _SIO_DEV {
+ UINT32 Signature;
+ EFI_HANDLE PciHandle;
+ EFI_SIO_ACPI_DEVICE_ID Device;
+ EFI_HANDLE Handle;
+ EFI_SIO_PROTOCOL Sio;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ LIST_ENTRY Link;
+} SIO_DEV;
+
+#define SIO_DEV_FROM_THIS(a) CR (a, SIO_DEV, Sio, SIO_DEV_SIGNATURE)
+
+//
+// Prototypes for Driver model protocol interface
+//
+
+
+/**
+ Test to see if this driver supports Controller Handle.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] Controller Handle of device to test
+ @param[in] RemainingDevicePath Optional parameter use to pick a specific child
+ device to start.
+
+ @retval EFI_SUCCESS This driver supports this device
+ @retval EFI_ALREADY_STARTED This driver is already running on this device
+ @retval other This driver does not support this device
+**/
+EFI_STATUS
+EFIAPI
+SioDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+
+/**
+ Start this driver on ControllerHandle.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] Controller Handle of device to bind driver to
+ @param[in] RemainingDevicePath Optional parameter use to pick a specific child
+ device to start.
+
+ @retval EFI_SUCCESS This driver is added to ControllerHandle
+ @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
+ @retval other This driver does not support this device
+**/
+EFI_STATUS
+EFIAPI
+SioDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+
+/**
+ Stop this driver on ControllerHandle.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] Controller Handle of device to stop driver on
+ @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
+ children is zero stop the entire bus driver.
+ @param[in] ChildHandleBuffer List of Child Handles to Stop.
+
+ @retval EFI_SUCCESS This driver is removed ControllerHandle
+ @retval other This driver was not removed from this device
+**/
+EFI_STATUS
+EFIAPI
+SioDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h
new file mode 100644
index 0000000000..6a8081dc6e
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h
@@ -0,0 +1,143 @@
+/** @file
+ Super I/O Interface function declarations.
+
+ Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SIO_ACPI_H_
+#define _SIO_ACPI_H_
+
+//
+// Prototypes for the SIO protocol interface
+//
+
+
+/**
+ Provides an interface to get a list of the current resources consumed by the device in the ACPI
+ Resource Descriptor format.
+
+ GetResources() returns a list of resources currently consumed by the device. The
+ ResourceList is a pointer to the buffer containing resource descriptors for the device. The
+ descriptors are in the format of Small or Large ACPI resource descriptor as defined by ACPI
+ specification (2.0 & 3.0). The buffer of resource descriptors is terminated with the 'End tag'
+ resource descriptor.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[out] ResourceList A pointer to an ACPI resource descriptor list that defines the current resources
+ used by the device. Type ACPI_RESOURCE_HEADER_PTR is defined in the "Related
+ Definitions" below.
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER ResourceList is NULL
+**/
+EFI_STATUS
+EFIAPI
+SioGetResources (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ OUT ACPI_RESOURCE_HEADER_PTR *ResourceList
+ );
+
+
+/**
+ Sets the resources for the device.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] ResourceList Pointer to the ACPI resource descriptor list. Type ACPI_RESOURCE_HEADER_PTR
+ is defined in the "Related Definitions" section of
+ EFI_SIO_PROTOCOL.GetResources().
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER ResourceList is invalid
+ @retval EFI_ACCESS_DENIED Some of the resources in ResourceList are in use
+**/
+EFI_STATUS
+EFIAPI
+SioSetResources (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ IN ACPI_RESOURCE_HEADER_PTR ResourceList
+ );
+
+
+/**
+ Provides a collection of resource descriptor lists. Each resource descriptor list in the collection
+ defines a combination of resources that can potentially be used by the device.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[out] ResourceCollection Collection of the resource descriptor lists.
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER ResourceCollection is NULL
+**/
+EFI_STATUS
+EFIAPI
+SioPossibleResources (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ OUT ACPI_RESOURCE_HEADER_PTR *ResourceCollection
+ );
+
+
+/**
+ Provides a low level access to the registers for the Super I/O.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] Write Specifies the type of the register operation. If this parameter is TRUE,
+ Value is interpreted as an input parameter and the operation is a register write.
+ If this parameter is FALSE, Value is interpreted as an output parameter and the
+ operation is a register read.
+ @param[in] ExitCfgMode Exit Configuration Mode Indicator. If this parameter is set to TRUE, the
+ Super I/O driver will turn off configuration mode of the Super I/O prior to returning
+ from this function. If this parameter is set to FALSE, the Super I/O driver will
+ leave Super I/O in the configuration mode.
+ The Super I/O driver must track the current state of the Super I/O and enable the
+ configuration mode of Super I/O if necessary prior to register access.
+ @param[in] Register Register number.
+ @param[in, out] Value If Write is TRUE, Value is a pointer to the buffer containing the byte of data to be
+ written to the Super I/O register. If Write is FALSE, Value is a pointer to the
+ destination buffer for the byte of data to be read from the Super I/O register.
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER The Value is NULL
+ @retval EFI_INVALID_PARAMETER Invalid Register number
+**/
+EFI_STATUS
+EFIAPI
+SioRegisterAccess (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ IN BOOLEAN Write,
+ IN BOOLEAN ExitCfgMode,
+ IN UINT8 Register,
+ IN OUT UINT8 *Value
+ );
+
+
+/**
+ Provides an interface for a table based programming of the Super I/O registers.
+
+ The Modify() function provides an interface for table based programming of the Super I/O
+ registers. This function can be used to perform programming of multiple Super I/O registers with a
+ single function call. For each table entry, the Register is read, its content is bitwise ANDed with
+ AndMask, and then ORed with OrMask before being written back to the Register. The Super
+ I/O driver must track the current state of the Super I/O and enable the configuration mode of Super I/
+ O if necessary prior to table processing. Once the table is processed, the Super I/O device has to be
+ returned to the original state.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] Command A pointer to an array of NumberOfCommands EFI_SIO_REGISTER_MODIFY
+ structures. Each structure specifies a single Super I/O register modify operation.
+ Type EFI_SIO_REGISTER_MODIFY is defined in the "Related Definitions" below.
+ @param[in] NumberOfCommands Number of elements in the Command array.
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER Command is NULL
+**/
+EFI_STATUS
+EFIAPI
+SioModify (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ IN CONST EFI_SIO_REGISTER_MODIFY *Command,
+ IN UINTN NumberOfCommands
+ );
+
+#endif
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [edk2-platforms PATCH v2 5/7] SimicsOpenBoardPkg: Add Overrides modules and Logo image for SIMICS QSP Platform
2019-08-28 0:40 [edk2-platforms PATCH v2 0/7] Add Initial QSP MinPlatform Pkg for SIMICS David Wei
` (3 preceding siblings ...)
2019-08-28 0:40 ` [edk2-platforms PATCH v2 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio David Wei
@ 2019-08-28 0:40 ` David Wei
2019-08-28 3:01 ` Liming Gao
2019-08-28 23:02 ` Nate DeSimone
2019-08-28 0:40 ` [edk2-platforms PATCH v2 6/7] SimicsOpenBoardPkg/BoardX58Ich10: Add board module for QSP Build tip David Wei
2019-08-28 0:40 ` [edk2-platforms PATCH v2 7/7] Platform/Intel: Add build option for SIMICS QSP Platform David Wei
6 siblings, 2 replies; 16+ messages in thread
From: David Wei @ 2019-08-28 0:40 UTC (permalink / raw)
To: devel
Cc: Hao Wu, Liming Gao, Ankit Sinha, Agyeman Prince,
Kubacki Michael A, Nate DeSimone, Michael D Kinney
Add overridden modules specific for SIMICS support.
Add SIMICS customized Logo image
Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c | 1579 ++++++++++++++++++++
.../MinPlatformPkg/Acpi/AcpiTables/Facs/Facs.c | 84 ++
.../MinPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.c | 359 +++++
.../MinPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.c | 78 +
.../MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c | 46 +
.../Overrides/OvmfPkg/QemuVideoDxe/ComponentName.c | 205 +++
.../Overrides/OvmfPkg/QemuVideoDxe/Driver.c | 1011 +++++++++++++
.../QemuVideoDxe/DriverSupportedEfiVersion.c | 15 +
.../Overrides/OvmfPkg/QemuVideoDxe/Gop.c | 416 ++++++
.../Overrides/OvmfPkg/QemuVideoDxe/Initialize.c | 341 +++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c | 302 ++++
Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp | Bin 0 -> 141078 bytes
Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec | 152 ++
.../MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h | 45 +
.../Acpi/AcpiTables/AcpiPlatform.inf | 105 ++
.../Overrides/OvmfPkg/QemuVideoDxe/Qemu.h | 507 +++++++
.../OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | 74 +
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm | 279 ++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h | 701 +++++++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh | 79 +
20 files changed, 6378 insertions(+)
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Facs/Facs.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/ComponentName.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driver.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/DriverSupportedEfiVersion.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Initialize.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qemu.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c
new file mode 100644
index 0000000000..f050d8afc0
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c
@@ -0,0 +1,1579 @@
+/** @file
+ ACPI Platform Driver
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "AcpiPlatform.h"
+
+#define MAX_CPU_NUM (FixedPcdGet32(PcdMaxCpuThreadCount) * FixedPcdGet32(PcdMaxCpuCoreCount) * FixedPcdGet32(PcdMaxCpuSocketCount))
+
+#pragma pack(1)
+
+typedef struct {
+ UINT32 AcpiProcessorId;
+ UINT32 ApicId;
+ UINT32 Flags;
+ UINT32 SwProcApicId;
+ UINT32 SocketNum;
+} EFI_CPU_ID_ORDER_MAP;
+
+//
+// Private Driver Data
+//
+//
+// Define Union of IO APIC & Local APIC structure;
+//
+typedef union {
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE AcpiLocalApic;
+ EFI_ACPI_4_0_IO_APIC_STRUCTURE AcpiIoApic;
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE AcpiLocalx2Apic;
+ struct {
+ UINT8 Type;
+ UINT8 Length;
+ } AcpiApicCommon;
+} ACPI_APIC_STRUCTURE_PTR;
+
+#pragma pack()
+
+extern EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE Facs;
+extern EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE Fadt;
+extern EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER Hpet;
+extern EFI_ACPI_WSMT_TABLE Wsmt;
+
+VOID *mLocalTable[] = {
+ &Facs,
+ &Fadt,
+ &Hpet,
+ &Wsmt,
+};
+
+EFI_ACPI_TABLE_PROTOCOL *mAcpiTable;
+
+UINT32 mNumOfBitShift = 6;
+BOOLEAN mForceX2ApicId;
+BOOLEAN mX2ApicEnabled;
+
+EFI_MP_SERVICES_PROTOCOL *mMpService;
+BOOLEAN mCpuOrderSorted;
+EFI_CPU_ID_ORDER_MAP mCpuApicIdOrderTable[MAX_CPU_NUM];
+UINTN mNumberOfCPUs = 0;
+UINTN mNumberOfEnabledCPUs = 0;
+//
+// following are possible APICID Map for SKX
+//
+static const UINT32 ApicIdMapA[] = { //for SKUs have number of core > 16
+ //it is 14 + 14 + 14 + 14 format
+ 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007,
+ 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x00000010, 0x00000011,
+ 0x00000012, 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, 0x00000018, 0x00000019,
+ 0x0000001A, 0x0000001B, 0x0000001C, 0x0000001D, 0x00000020, 0x00000021, 0x00000022, 0x00000023,
+ 0x00000024, 0x00000025, 0x00000026, 0x00000027, 0x00000028, 0x00000029, 0x0000002A, 0x0000002B,
+ 0x0000002C, 0x0000002D, 0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, 0x00000035,
+ 0x00000036, 0x00000037, 0x00000038, 0x00000039, 0x0000003A, 0x0000003B, 0x0000003C, 0x0000003D
+};
+
+static const UINT32 ApicIdMapB[] = { //for SKUs have number of cores <= 16 use 32 ID space
+ //
+ //it is 16+16 format
+ //
+ 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007,
+ 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F,
+ 0x00000010, 0x00000011, 0x00000012, 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017,
+ 0x00000018, 0x00000019, 0x0000001A, 0x0000001B, 0x0000001C, 0x0000001D, 0x0000001E, 0x0000001F,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+
+static const UINT32 ApicIdMapC[] = { //for SKUs have number of cores <= 16 use 64 ID space
+ //
+ //it is 16+0+16+0 format
+ //
+ 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007,
+ 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F,
+ 0x00000020, 0x00000021, 0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000026, 0x00000027,
+ 0x00000028, 0x00000029, 0x0000002A, 0x0000002B, 0x0000002C, 0x0000002D, 0x0000002E, 0x0000002F,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+static const UINT32 ApicIdMapD[] = { //for SKUs have number of cores <= 8 use 16 ID space
+ //
+ //it is 16 format
+ //
+ 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007,
+ 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+const UINT32 *mApicIdMap = NULL;
+
+/**
+ This function detect the APICID map and update ApicID Map pointer
+
+ @param None
+
+ @retval VOID
+
+**/
+VOID DetectApicIdMap(VOID)
+{
+ UINTN CoreCount;
+
+ CoreCount = 0;
+
+ if(mApicIdMap != NULL) {
+ return; //aleady initialized
+ }
+
+ mApicIdMap = ApicIdMapA; // default to > 16C SKUs
+
+ CoreCount = mNumberOfEnabledCPUs / 2;
+ DEBUG ((DEBUG_INFO, "CoreCount - %d\n", CoreCount));
+
+ if(CoreCount <= 16) {
+
+ if(mNumOfBitShift == 4) {
+ mApicIdMap = ApicIdMapD;
+ }
+
+ if(mNumOfBitShift == 5) {
+ mApicIdMap = ApicIdMapB;
+ }
+
+ if(mNumOfBitShift == 6) {
+ mApicIdMap = ApicIdMapC;
+ }
+
+ }
+
+ return;
+}
+
+/**
+ This function return the CoreThreadId of ApicId from ACPI ApicId Map array
+
+ @param ApicId
+
+ @retval Index of ACPI ApicId Map array
+
+**/
+UINT32
+GetIndexFromApicId (
+ UINT32 ApicId
+ )
+{
+ UINT32 CoreThreadId;
+ UINT32 i;
+
+ ASSERT (mApicIdMap != NULL);
+
+ CoreThreadId = ApicId & ((1 << mNumOfBitShift) - 1);
+
+ for(i = 0; i < (FixedPcdGet32(PcdMaxCpuCoreCount) * FixedPcdGet32(PcdMaxCpuThreadCount)); i++) {
+ if(mApicIdMap[i] == CoreThreadId) {
+ break;
+ }
+ }
+
+ ASSERT (i <= (FixedPcdGet32(PcdMaxCpuCoreCount) * FixedPcdGet32(PcdMaxCpuThreadCount)));
+
+ return i;
+}
+
+UINT32
+ApicId2SwProcApicId (
+ UINT32 ApicId
+ )
+{
+ UINT32 Index;
+
+ for (Index = 0; Index < MAX_CPU_NUM; Index++) {
+ if ((mCpuApicIdOrderTable[Index].Flags == 1) && (mCpuApicIdOrderTable[Index].ApicId == ApicId)) {
+ return Index;
+ }
+ }
+
+ return (UINT32) -1;
+
+}
+
+VOID
+DebugDisplayReOrderTable(
+ VOID
+ )
+{
+ UINT32 Index;
+
+ DEBUG ((EFI_D_ERROR, "Index AcpiProcId ApicId Flags SwApicId Skt\n"));
+ for (Index=0; Index<MAX_CPU_NUM; Index++) {
+ DEBUG ((EFI_D_ERROR, " %02d 0x%02X 0x%02X %d 0x%02X %d\n",
+ Index, mCpuApicIdOrderTable[Index].AcpiProcessorId,
+ mCpuApicIdOrderTable[Index].ApicId,
+ mCpuApicIdOrderTable[Index].Flags,
+ mCpuApicIdOrderTable[Index].SwProcApicId,
+ mCpuApicIdOrderTable[Index].SocketNum));
+ }
+}
+
+EFI_STATUS
+AppendCpuMapTableEntry (
+ IN VOID *ApicPtr,
+ IN UINT32 LocalApicCounter
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *LocalApicPtr;
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE *LocalX2ApicPtr;
+ UINT8 Type;
+
+ Status = EFI_SUCCESS;
+ Type = ((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiApicCommon.Type;
+ LocalApicPtr = (EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *)(&((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiLocalApic);
+ LocalX2ApicPtr = (EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE *)(&((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiLocalx2Apic);
+
+ if(Type == EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC) {
+ if(!mX2ApicEnabled) {
+ LocalApicPtr->Flags = (UINT8)mCpuApicIdOrderTable[LocalApicCounter].Flags;
+ LocalApicPtr->ApicId = (UINT8)mCpuApicIdOrderTable[LocalApicCounter].ApicId;
+ LocalApicPtr->AcpiProcessorId = (UINT8)mCpuApicIdOrderTable[LocalApicCounter].AcpiProcessorId;
+ } else {
+ LocalApicPtr->Flags = 0;
+ LocalApicPtr->ApicId = 0xFF;
+ LocalApicPtr->AcpiProcessorId = (UINT8)0xFF;
+ Status = EFI_UNSUPPORTED;
+ }
+ } else if(Type == EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC) {
+ if(mX2ApicEnabled) {
+ LocalX2ApicPtr->Flags = (UINT8)mCpuApicIdOrderTable[LocalApicCounter].Flags;
+ LocalX2ApicPtr->X2ApicId = mCpuApicIdOrderTable[LocalApicCounter].ApicId;
+ LocalX2ApicPtr->AcpiProcessorUid = mCpuApicIdOrderTable[LocalApicCounter].AcpiProcessorId;
+ } else {
+ LocalX2ApicPtr->Flags = 0;
+ LocalX2ApicPtr->X2ApicId = (UINT32)-1;
+ LocalX2ApicPtr->AcpiProcessorUid = (UINT32)-1;
+ Status = EFI_UNSUPPORTED;
+ }
+ } else {
+ Status = EFI_UNSUPPORTED;
+ }
+
+ return Status;
+
+}
+
+EFI_STATUS
+SortCpuLocalApicInTable (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;
+ UINT32 Index;
+ UINT32 CurrProcessor;
+ UINT32 BspApicId;
+ UINT32 TempVal = 0;
+ EFI_CPU_ID_ORDER_MAP *CpuIdMapPtr;
+ UINT32 CoreThreadMask;
+
+ Index = 0;
+ Status = EFI_SUCCESS;
+
+ CoreThreadMask = (UINT32) ((1 << mNumOfBitShift) - 1);
+
+ if(!mCpuOrderSorted) {
+
+ Index = 0;
+
+ for (CurrProcessor = 0; CurrProcessor < mNumberOfCPUs; CurrProcessor++) {
+ Status = mMpService->GetProcessorInfo (
+ mMpService,
+ CurrProcessor,
+ &ProcessorInfoBuffer
+ );
+
+ if ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) != 0) {
+ if(ProcessorInfoBuffer.ProcessorId & 1) { //is 2nd thread
+ CpuIdMapPtr = (EFI_CPU_ID_ORDER_MAP *)&mCpuApicIdOrderTable[(Index - 1) + MAX_CPU_NUM / 2];
+ } else { //is primary thread
+ CpuIdMapPtr = (EFI_CPU_ID_ORDER_MAP *)&mCpuApicIdOrderTable[Index];
+ Index++;
+ }
+ CpuIdMapPtr->ApicId = (UINT32)ProcessorInfoBuffer.ProcessorId;
+ CpuIdMapPtr->Flags = ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) != 0);
+ CpuIdMapPtr->SocketNum = (UINT32)ProcessorInfoBuffer.Location.Package;
+ CpuIdMapPtr->AcpiProcessorId = (CpuIdMapPtr->SocketNum * FixedPcdGet32(PcdMaxCpuCoreCount) * FixedPcdGet32(PcdMaxCpuThreadCount)) + GetIndexFromApicId(CpuIdMapPtr->ApicId); //CpuIdMapPtr->ApicId;
+ CpuIdMapPtr->SwProcApicId = ((UINT32)(ProcessorInfoBuffer.Location.Package << mNumOfBitShift) + (((UINT32)ProcessorInfoBuffer.ProcessorId) & CoreThreadMask));
+ if(mX2ApicEnabled) { //if X2Apic, re-order the socket # so it starts from base 0 and contiguous
+ //may not necessory!!!!!
+ }
+
+ //update processorbitMask
+ if (CpuIdMapPtr->Flags == 1) {
+
+ if(mForceX2ApicId) {
+ CpuIdMapPtr->SocketNum &= 0x7;
+ CpuIdMapPtr->AcpiProcessorId &= 0xFF; //keep lower 8bit due to use Proc obj in dsdt
+ CpuIdMapPtr->SwProcApicId &= 0xFF;
+ }
+ }
+ } else { //not enabled
+ CpuIdMapPtr = (EFI_CPU_ID_ORDER_MAP *)&mCpuApicIdOrderTable[Index];
+ CpuIdMapPtr->ApicId = (UINT32)-1;
+ CpuIdMapPtr->Flags = 0;
+ CpuIdMapPtr->AcpiProcessorId = (UINT32)-1;
+ CpuIdMapPtr->SwProcApicId = (UINT32)-1;
+ CpuIdMapPtr->SocketNum = (UINT32)-1;
+ } //end if PROC ENABLE
+ } //end for CurrentProcessor
+ //
+ //keep for debug purpose
+ //
+ DEBUG(( EFI_D_ERROR, "::ACPI:: APIC ID Order Table Init. CoreThreadMask = %x, mNumOfBitShift = %x\n", CoreThreadMask, mNumOfBitShift));
+ DebugDisplayReOrderTable();
+ //
+ //make sure 1st entry is BSP
+ //
+ if(mX2ApicEnabled) {
+ BspApicId = (UINT32)AsmReadMsr64(0x802);
+ } else {
+ BspApicId = (*(volatile UINT32 *)(UINTN)0xFEE00020) >> 24;
+ }
+ DEBUG ((EFI_D_INFO, "BspApicId - 0x%x\n", BspApicId));
+
+ if(mCpuApicIdOrderTable[0].ApicId != BspApicId) {
+ //
+ //check to see if 1st entry is BSP, if not swap it
+ //
+ Index = ApicId2SwProcApicId(BspApicId);
+
+ if(MAX_CPU_NUM <= Index) {
+ DEBUG ((EFI_D_ERROR, "Asserting the SortCpuLocalApicInTable Index Bufferflow\n"));
+ ASSERT_EFI_ERROR(EFI_INVALID_PARAMETER);
+ }
+
+ TempVal = mCpuApicIdOrderTable[Index].ApicId;
+ mCpuApicIdOrderTable[Index].ApicId = mCpuApicIdOrderTable[0].ApicId;
+ mCpuApicIdOrderTable[0].ApicId = TempVal;
+ mCpuApicIdOrderTable[Index].Flags = mCpuApicIdOrderTable[0].Flags;
+ mCpuApicIdOrderTable[0].Flags = 1;
+ TempVal = mCpuApicIdOrderTable[Index].SwProcApicId;
+ mCpuApicIdOrderTable[Index].SwProcApicId = mCpuApicIdOrderTable[0].SwProcApicId;
+ mCpuApicIdOrderTable[0].SwProcApicId = TempVal;
+ //
+ //swap AcpiProcId
+ //
+ TempVal = mCpuApicIdOrderTable[Index].AcpiProcessorId;
+ mCpuApicIdOrderTable[Index].AcpiProcessorId = mCpuApicIdOrderTable[0].AcpiProcessorId;
+ mCpuApicIdOrderTable[0].AcpiProcessorId = TempVal;
+
+ }
+ //
+ //Make sure no holes between enabled threads
+ //
+ for(CurrProcessor = 0; CurrProcessor < MAX_CPU_NUM; CurrProcessor++) {
+
+ if(mCpuApicIdOrderTable[CurrProcessor].Flags == 0) {
+ //
+ //make sure disabled entry has ProcId set to FFs
+ //
+ mCpuApicIdOrderTable[CurrProcessor].ApicId = (UINT32)-1;
+ mCpuApicIdOrderTable[CurrProcessor].AcpiProcessorId = (UINT32)-1;
+ mCpuApicIdOrderTable[CurrProcessor].SwProcApicId = (UINT32)-1;
+
+ for(Index = CurrProcessor+1; Index < MAX_CPU_NUM; Index++) {
+ if(mCpuApicIdOrderTable[Index].Flags == 1) {
+ //
+ //move enabled entry up
+ //
+ mCpuApicIdOrderTable[CurrProcessor].Flags = 1;
+ mCpuApicIdOrderTable[CurrProcessor].ApicId = mCpuApicIdOrderTable[Index].ApicId;
+ mCpuApicIdOrderTable[CurrProcessor].AcpiProcessorId = mCpuApicIdOrderTable[Index].AcpiProcessorId;
+ mCpuApicIdOrderTable[CurrProcessor].SwProcApicId = mCpuApicIdOrderTable[Index].SwProcApicId;
+ mCpuApicIdOrderTable[CurrProcessor].SocketNum = mCpuApicIdOrderTable[Index].SocketNum;
+ //
+ //disable moved entry
+ //
+ mCpuApicIdOrderTable[Index].Flags = 0;
+ mCpuApicIdOrderTable[Index].ApicId = (UINT32)-1;
+ mCpuApicIdOrderTable[Index].AcpiProcessorId = (UINT32)-1;
+ mCpuApicIdOrderTable[Index].SwProcApicId = (UINT32)-1;
+ break;
+ }
+ }
+ }
+ }
+ //
+ //keep for debug purpose
+ //
+ DEBUG ((EFI_D_ERROR, "APIC ID Order Table ReOrdered\n"));
+ DebugDisplayReOrderTable();
+
+ mCpuOrderSorted = TRUE;
+ }
+
+ return Status;
+}
+
+
+/** Structure of a sub-structure of the ACPI header.
+
+ This structure contains the type and length fields, which are common to every
+ sub-structure of the ACPI tables. A pointer to any structure can be cast as this.
+**/
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+} STRUCTURE_HEADER;
+
+STRUCTURE_HEADER mMadtStructureTable[] = {
+ {EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC, sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE)},
+ {EFI_ACPI_4_0_IO_APIC, sizeof (EFI_ACPI_4_0_IO_APIC_STRUCTURE)},
+ {EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE, sizeof (EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE)},
+ {EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE, sizeof (EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE)},
+ {EFI_ACPI_4_0_LOCAL_APIC_NMI, sizeof (EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE)},
+ {EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE, sizeof (EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE)},
+ {EFI_ACPI_4_0_IO_SAPIC, sizeof (EFI_ACPI_4_0_IO_SAPIC_STRUCTURE)},
+ {EFI_ACPI_4_0_LOCAL_SAPIC, sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE)},
+ {EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES, sizeof (EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE)},
+ {EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC, sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE)},
+ {EFI_ACPI_4_0_LOCAL_X2APIC_NMI, sizeof (EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE)}
+};
+
+/**
+ Get the size of the ACPI table.
+
+ This function calculates the size needed for the ACPI Table based on the number and
+ size of the sub-structures that will compose it.
+
+ @param[in] TableSpecificHdrLength Size of the table specific header, not the ACPI standard header size.
+ @param[in] Structures Pointer to an array of sub-structure pointers.
+ @param[in] StructureCount Number of structure pointers in the array.
+
+ @return Total size needed for the ACPI table.
+**/
+UINT32
+GetTableSize (
+ IN UINTN TableSpecificHdrLength,
+ IN STRUCTURE_HEADER **Structures,
+ IN UINTN StructureCount
+ )
+{
+ UINT32 TableLength;
+ UINT32 Index;
+
+ //
+ // Compute size of the ACPI table; header plus all structures needed.
+ //
+ TableLength = (UINT32) TableSpecificHdrLength;
+
+ for (Index = 0; Index < StructureCount; Index++) {
+ ASSERT (Structures[Index] != NULL);
+ if (Structures[Index] == NULL) {
+ return 0;
+ }
+
+ TableLength += Structures[Index]->Length;
+ }
+
+ return TableLength;
+}
+
+/**
+ Allocate the ACPI Table.
+
+ This function allocates space for the ACPI table based on the number and size of
+ the sub-structures that will compose it.
+
+ @param[in] TableSpecificHdrLength Size of the table specific header, not the ACPI standard header size.
+ @param[in] Structures Pointer to an array of sub-structure pointers.
+ @param[in] StructureCount Number of structure pointers in the array.
+ @param[out] Table Newly allocated ACPI Table pointer.
+
+ @retval EFI_SUCCESS Successfully allocated the Table.
+ @retval EFI_OUT_OF_RESOURCES Space for the Table could not be allocated.
+**/
+EFI_STATUS
+AllocateTable (
+ IN UINTN TableSpecificHdrLength,
+ IN STRUCTURE_HEADER **Structures,
+ IN UINTN StructureCount,
+ OUT EFI_ACPI_DESCRIPTION_HEADER **Table
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Size;
+ EFI_ACPI_DESCRIPTION_HEADER *InternalTable;
+
+ //
+ // Get the size of the ACPI table and allocate memory.
+ //
+ Size = GetTableSize (TableSpecificHdrLength, Structures, StructureCount);
+ InternalTable = (EFI_ACPI_DESCRIPTION_HEADER *) AllocatePool (Size);
+
+ if (InternalTable == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ DEBUG ((
+ DEBUG_ERROR,
+ "Failed to allocate %d bytes for ACPI Table\n",
+ Size
+ ));
+ } else {
+ Status = EFI_SUCCESS;
+ DEBUG ((
+ DEBUG_INFO,
+ "Successfully allocated %d bytes for ACPI Table at 0x%p\n",
+ Size,
+ InternalTable
+ ));
+ *Table = InternalTable;
+ }
+
+ return Status;
+}
+
+/**
+ Initialize the header.
+
+ This function fills in the standard table header with correct values,
+ except for the length and checksum fields, which are filled in later.
+
+ @param[in,out] Header Pointer to the header structure.
+
+ @retval EFI_SUCCESS Successfully initialized the header.
+ @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+**/
+EFI_STATUS
+InitializeHeader (
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER *Header,
+ IN UINT32 Signature,
+ IN UINT8 Revision,
+ IN UINT32 OemRevision
+ )
+{
+ UINT64 AcpiTableOemId;
+
+ if (Header == NULL) {
+ DEBUG ((DEBUG_ERROR, "Header pointer is NULL\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Header->Signature = Signature;
+ Header->Length = 0; // filled in by Build function
+ Header->Revision = Revision;
+ Header->Checksum = 0; // filled in by InstallAcpiTable
+
+ CopyMem (
+ (VOID *) &Header->OemId,
+ PcdGetPtr (PcdAcpiDefaultOemId),
+ sizeof (Header->OemId)
+ );
+
+ AcpiTableOemId = PcdGet64 (PcdAcpiDefaultOemTableId);
+ CopyMem (
+ (VOID *) &Header->OemTableId,
+ (VOID *) &AcpiTableOemId,
+ sizeof (Header->OemTableId)
+ );
+
+ Header->OemRevision = OemRevision;
+ Header->CreatorId = 0;
+ Header->CreatorRevision = 0;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initialize the MADT header.
+
+ This function fills in the MADT's standard table header with correct values,
+ except for the length and checksum fields, which are filled in later.
+
+ @param[in,out] MadtHeader Pointer to the MADT header structure.
+
+ @retval EFI_SUCCESS Successfully initialized the MADT header.
+ @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+**/
+EFI_STATUS
+InitializeMadtHeader (
+ IN OUT EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *MadtHeader
+ )
+{
+ EFI_STATUS Status;
+
+ if (MadtHeader == NULL) {
+ DEBUG ((DEBUG_ERROR, "MADT header pointer is NULL\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = InitializeHeader (
+ &MadtHeader->Header,
+ EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
+ EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ MadtHeader->LocalApicAddress = PcdGet32(PcdLocalApicAddress);
+ MadtHeader->Flags = EFI_ACPI_4_0_PCAT_COMPAT;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Copy an ACPI sub-structure; MADT and SRAT supported
+
+ This function validates the structure type and size of a sub-structure
+ and returns a newly allocated copy of it.
+
+ @param[in] Header Pointer to the header of the table.
+ @param[in] Structure Pointer to the structure to copy.
+ @param[in] NewStructure Newly allocated copy of the structure.
+
+ @retval EFI_SUCCESS Successfully copied the structure.
+ @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+ @retval EFI_INVALID_PARAMETER Structure type was unknown.
+ @retval EFI_INVALID_PARAMETER Structure length was wrong for its type.
+ @retval EFI_UNSUPPORTED Header passed in is not supported.
+**/
+EFI_STATUS
+CopyStructure (
+ IN EFI_ACPI_DESCRIPTION_HEADER *Header,
+ IN STRUCTURE_HEADER *Structure,
+ OUT STRUCTURE_HEADER **NewStructure
+ )
+{
+ STRUCTURE_HEADER *NewStructureInternal;
+ STRUCTURE_HEADER *StructureTable;
+ UINTN TableNumEntries;
+ BOOLEAN EntryFound;
+ UINT8 Index;
+
+ //
+ // Initialize the number of table entries and the table based on the table header passed in.
+ //
+ if (Header->Signature == EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
+ TableNumEntries = sizeof (mMadtStructureTable) / sizeof (STRUCTURE_HEADER);
+ StructureTable = mMadtStructureTable;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Check the incoming structure against the table of supported structures.
+ //
+ EntryFound = FALSE;
+ for (Index = 0; Index < TableNumEntries; Index++) {
+ if (Structure->Type == StructureTable[Index].Type) {
+ if (Structure->Length == StructureTable[Index].Length) {
+ EntryFound = TRUE;
+ } else {
+ DEBUG ((
+ DEBUG_ERROR,
+ "Invalid length for structure type %d: expected %d, actually %d\n",
+ Structure->Type,
+ StructureTable[Index].Length,
+ Structure->Length
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ }
+
+ //
+ // If no entry in the table matches the structure type and length passed in
+ // then return invalid parameter.
+ //
+ if (!EntryFound) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "Unknown structure type: %d\n",
+ Structure->Type
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ NewStructureInternal = (STRUCTURE_HEADER *) AllocatePool (Structure->Length);
+ if (NewStructureInternal == NULL) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "Failed to allocate %d bytes for type %d structure\n",
+ Structure->Length,
+ Structure->Type
+ ));
+ return EFI_OUT_OF_RESOURCES;
+ } else {
+ DEBUG ((
+ DEBUG_INFO,
+ "Successfully allocated %d bytes for type %d structure at 0x%p\n",
+ Structure->Length,
+ Structure->Type,
+ NewStructureInternal
+ ));
+ }
+
+ CopyMem (
+ (VOID *) NewStructureInternal,
+ (VOID *) Structure,
+ Structure->Length
+ );
+
+ *NewStructure = NewStructureInternal;
+ return EFI_SUCCESS;
+}
+
+/**
+ Build ACPI Table. MADT tables supported.
+
+ This function builds the ACPI table from the header plus the list of sub-structures
+ passed in. The table returned by this function is ready to be installed using
+ the ACPI table protocol's InstallAcpiTable function, which copies it into
+ ACPI memory. After that, the caller should free the memory returned by this
+ function.
+
+ @param[in] AcpiHeader Pointer to the header structure.
+ @param[in] TableSpecificHdrLength Size of the table specific header, not the ACPI standard header size.
+ @param[in] Structures Pointer to an array of sub-structure pointers.
+ @param[in] StructureCount Number of structure pointers in the array.
+ @param[out] NewTable Newly allocated and initialized pointer to the ACPI Table.
+
+ @retval EFI_SUCCESS Successfully built the ACPI table.
+ @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+ @retval EFI_INVALID_PARAMETER Header parameter had the wrong signature.
+ @retval EFI_OUT_OF_RESOURCES Space for the ACPI Table could not be allocated.
+**/
+EFI_STATUS
+BuildAcpiTable (
+ IN EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader,
+ IN UINTN TableSpecificHdrLength,
+ IN STRUCTURE_HEADER **Structures,
+ IN UINTN StructureCount,
+ OUT UINT8 **NewTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_DESCRIPTION_HEADER *InternalTable;
+ UINTN Index;
+ UINT8 *CurrPtr;
+ UINT8 *EndOfTablePtr;
+
+ if (AcpiHeader == NULL) {
+ DEBUG ((DEBUG_ERROR, "AcpiHeader pointer is NULL\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (AcpiHeader->Signature != EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "MADT header signature is expected, actually 0x%08x\n",
+ AcpiHeader->Signature
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Structures == NULL) {
+ DEBUG ((DEBUG_ERROR, "Structure array pointer is NULL\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (Index = 0; Index < StructureCount; Index++) {
+ if (Structures[Index] == NULL) {
+ DEBUG ((DEBUG_ERROR, "Structure pointer %d is NULL\n", Index));
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
+ // Allocate the memory needed for the table.
+ //
+ Status = AllocateTable (
+ TableSpecificHdrLength,
+ Structures,
+ StructureCount,
+ &InternalTable
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Copy Header and patch in structure length, checksum is programmed later
+ // after all structures are populated.
+ //
+ CopyMem (
+ (VOID *) InternalTable,
+ (VOID *) AcpiHeader,
+ TableSpecificHdrLength
+ );
+
+ InternalTable->Length = GetTableSize (TableSpecificHdrLength, Structures, StructureCount);
+
+ //
+ // Copy all the sub structures to the table.
+ //
+ CurrPtr = ((UINT8 *) InternalTable) + TableSpecificHdrLength;
+ EndOfTablePtr = ((UINT8 *) InternalTable) + InternalTable->Length;
+
+ for (Index = 0; Index < StructureCount; Index++) {
+ ASSERT (Structures[Index] != NULL);
+ if (Structures[Index] == NULL) {
+ break;
+ }
+
+ CopyMem (
+ (VOID *) CurrPtr,
+ (VOID *) Structures[Index],
+ Structures[Index]->Length
+ );
+
+ CurrPtr += Structures[Index]->Length;
+ ASSERT (CurrPtr <= EndOfTablePtr);
+ if (CurrPtr > EndOfTablePtr) {
+ break;
+ }
+ }
+
+ //
+ // Update the return pointer.
+ //
+ *NewTable = (UINT8 *) InternalTable;
+ return EFI_SUCCESS;
+}
+
+/**
+ Build from scratch and install the MADT.
+
+ @retval EFI_SUCCESS The MADT was installed successfully.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate required structures.
+**/
+EFI_STATUS
+InstallMadtFromScratch (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *NewMadtTable;
+ UINTN TableHandle;
+ EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER MadtTableHeader;
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE ProcLocalApicStruct;
+ EFI_ACPI_4_0_IO_APIC_STRUCTURE IoApicStruct;
+ EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE IntSrcOverrideStruct;
+ EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE LocalApciNmiStruct;
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE ProcLocalX2ApicStruct;
+ EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE LocalX2ApicNmiStruct;
+ STRUCTURE_HEADER **MadtStructs;
+ UINTN MaxMadtStructCount;
+ UINTN MadtStructsIndex;
+ UINT32 CurrentIoApicAddress = (UINT32)(PcdGet32(PcdPcIoApicAddressBase));
+ UINT32 PcIoApicEnable;
+ UINT32 PcIoApicMask;
+ UINTN PcIoApicIndex;
+
+ DetectApicIdMap();
+
+ // Call for Local APIC ID Reorder
+ SortCpuLocalApicInTable ();
+
+ NewMadtTable = NULL;
+
+ MaxMadtStructCount = (UINT32) (
+ MAX_CPU_NUM + // processor local APIC structures
+ MAX_CPU_NUM + // processor local x2APIC structures
+ 1 + PcdGet8(PcdPcIoApicCount) + // I/O APIC structures
+ 2 + // interrupt source override structures
+ 1 + // local APIC NMI structures
+ 1 // local x2APIC NMI structures
+ ); // other structures are not used
+
+ MadtStructs = (STRUCTURE_HEADER **) AllocateZeroPool (MaxMadtStructCount * sizeof (STRUCTURE_HEADER *));
+ if (MadtStructs == NULL) {
+ DEBUG ((DEBUG_ERROR, "Could not allocate MADT structure pointer array\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initialize the next index into the structure pointer array. It is
+ // incremented every time a structure of any type is copied to the array.
+ //
+ MadtStructsIndex = 0;
+
+ //
+ // Initialize MADT Header Structure
+ //
+ Status = InitializeMadtHeader (&MadtTableHeader);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "InitializeMadtHeader failed: %r\n", Status));
+ goto Done;
+ }
+
+ DEBUG ((EFI_D_INFO, "Number of CPUs detected = %d \n", mNumberOfCPUs));
+
+ //
+ // Build Processor Local APIC Structures and Processor Local X2APIC Structures
+ //
+ ProcLocalApicStruct.Type = EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC;
+ ProcLocalApicStruct.Length = sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE);
+
+ ProcLocalX2ApicStruct.Type = EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC;
+ ProcLocalX2ApicStruct.Length = sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE);
+ ProcLocalX2ApicStruct.Reserved[0] = 0;
+ ProcLocalX2ApicStruct.Reserved[1] = 0;
+
+ for (Index = 0; Index < MAX_CPU_NUM; Index++) {
+ //
+ // If x2APIC mode is not enabled, and if it is possible to express the
+ // APIC ID as a UINT8, use a processor local APIC structure. Otherwise,
+ // use a processor local x2APIC structure.
+ //
+ if (!mX2ApicEnabled && mCpuApicIdOrderTable[Index].ApicId < MAX_UINT8) {
+ ProcLocalApicStruct.Flags = (UINT8) mCpuApicIdOrderTable[Index].Flags;
+ ProcLocalApicStruct.ApicId = (UINT8) mCpuApicIdOrderTable[Index].ApicId;
+ ProcLocalApicStruct.AcpiProcessorId = (UINT8) mCpuApicIdOrderTable[Index].AcpiProcessorId;
+
+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
+ Status = CopyStructure (
+ &MadtTableHeader.Header,
+ (STRUCTURE_HEADER *) &ProcLocalApicStruct,
+ &MadtStructs[MadtStructsIndex++]
+ );
+ } else if (mCpuApicIdOrderTable[Index].ApicId != 0xFFFFFFFF) {
+ ProcLocalX2ApicStruct.Flags = (UINT8) mCpuApicIdOrderTable[Index].Flags;
+ ProcLocalX2ApicStruct.X2ApicId = mCpuApicIdOrderTable[Index].ApicId;
+ ProcLocalX2ApicStruct.AcpiProcessorUid = mCpuApicIdOrderTable[Index].AcpiProcessorId;
+
+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
+ Status = CopyStructure (
+ &MadtTableHeader.Header,
+ (STRUCTURE_HEADER *) &ProcLocalX2ApicStruct,
+ &MadtStructs[MadtStructsIndex++]
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (local APIC/x2APIC) failed: %r\n", Status));
+ goto Done;
+ }
+ }
+
+ //
+ // Build I/O APIC Structures
+ //
+ IoApicStruct.Type = EFI_ACPI_4_0_IO_APIC;
+ IoApicStruct.Length = sizeof (EFI_ACPI_4_0_IO_APIC_STRUCTURE);
+ IoApicStruct.Reserved = 0;
+
+ PcIoApicEnable = PcdGet32(PcdPcIoApicEnable);
+
+ if (FixedPcdGet32(PcdMaxCpuSocketCount) <= 4) {
+ IoApicStruct.IoApicId = PcdGet8(PcdIoApicId);
+ IoApicStruct.IoApicAddress = PcdGet32(PcdIoApicAddress);
+ IoApicStruct.GlobalSystemInterruptBase = 0;
+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
+ Status = CopyStructure (
+ &MadtTableHeader.Header,
+ (STRUCTURE_HEADER *) &IoApicStruct,
+ &MadtStructs[MadtStructsIndex++]
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (I/O APIC) failed: %r\n", Status));
+ goto Done;
+ }
+ }
+
+ for (PcIoApicIndex = 0; PcIoApicIndex < PcdGet8(PcdPcIoApicCount); PcIoApicIndex++) {
+ PcIoApicMask = (1 << PcIoApicIndex);
+ if ((PcIoApicEnable & PcIoApicMask) == 0) {
+ continue;
+ }
+
+ IoApicStruct.IoApicId = (UINT8)(PcdGet8(PcdPcIoApicIdBase) + PcIoApicIndex);
+ IoApicStruct.IoApicAddress = CurrentIoApicAddress;
+ CurrentIoApicAddress = (CurrentIoApicAddress & 0xFFFF8000) + 0x8000;
+ IoApicStruct.GlobalSystemInterruptBase = (UINT32)(24 + (PcIoApicIndex * 8));
+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
+ Status = CopyStructure (
+ &MadtTableHeader.Header,
+ (STRUCTURE_HEADER *) &IoApicStruct,
+ &MadtStructs[MadtStructsIndex++]
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (I/O APIC) failed: %r\n", Status));
+ goto Done;
+ }
+ }
+
+ //
+ // Build Interrupt Source Override Structures
+ //
+ IntSrcOverrideStruct.Type = EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE;
+ IntSrcOverrideStruct.Length = sizeof (EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE);
+
+ //
+ // IRQ0=>IRQ2 Interrupt Source Override Structure
+ //
+ IntSrcOverrideStruct.Bus = 0x0; // Bus - ISA
+ IntSrcOverrideStruct.Source = 0x0; // Source - IRQ0
+ IntSrcOverrideStruct.GlobalSystemInterrupt = 0x2; // Global System Interrupt - IRQ2
+ IntSrcOverrideStruct.Flags = 0x0; // Flags - Conforms to specifications of the bus
+
+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
+ Status = CopyStructure (
+ &MadtTableHeader.Header,
+ (STRUCTURE_HEADER *) &IntSrcOverrideStruct,
+ &MadtStructs[MadtStructsIndex++]
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (IRQ2 source override) failed: %r\n", Status));
+ goto Done;
+ }
+
+ //
+ // IRQ9 (SCI Active High) Interrupt Source Override Structure
+ //
+ IntSrcOverrideStruct.Bus = 0x0; // Bus - ISA
+ IntSrcOverrideStruct.Source = 0x9; // Source - IRQ9
+ IntSrcOverrideStruct.GlobalSystemInterrupt = 0x9; // Global System Interrupt - IRQ9
+ IntSrcOverrideStruct.Flags = 0xD; // Flags - Level-tiggered, Active High
+
+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
+ Status = CopyStructure (
+ &MadtTableHeader.Header,
+ (STRUCTURE_HEADER *) &IntSrcOverrideStruct,
+ &MadtStructs[MadtStructsIndex++]
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (IRQ9 source override) failed: %r\n", Status));
+ goto Done;
+ }
+
+ //
+ // Build Local APIC NMI Structures
+ //
+ LocalApciNmiStruct.Type = EFI_ACPI_4_0_LOCAL_APIC_NMI;
+ LocalApciNmiStruct.Length = sizeof (EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE);
+ LocalApciNmiStruct.AcpiProcessorId = 0xFF; // Applies to all processors
+ LocalApciNmiStruct.Flags = 0x000D; // Flags - Level-tiggered, Active High
+ LocalApciNmiStruct.LocalApicLint = 0x1;
+
+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
+ Status = CopyStructure (
+ &MadtTableHeader.Header,
+ (STRUCTURE_HEADER *) &LocalApciNmiStruct,
+ &MadtStructs[MadtStructsIndex++]
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (APIC NMI) failed: %r\n", Status));
+ goto Done;
+ }
+
+ //
+ // Build Local x2APIC NMI Structure
+ //
+ LocalX2ApicNmiStruct.Type = EFI_ACPI_4_0_LOCAL_X2APIC_NMI;
+ LocalX2ApicNmiStruct.Length = sizeof (EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE);
+ LocalX2ApicNmiStruct.Flags = 0x000D; // Flags - Level-tiggered, Active High
+ LocalX2ApicNmiStruct.AcpiProcessorUid = 0xFFFFFFFF; // Applies to all processors
+ LocalX2ApicNmiStruct.LocalX2ApicLint = 0x01;
+ LocalX2ApicNmiStruct.Reserved[0] = 0x00;
+ LocalX2ApicNmiStruct.Reserved[1] = 0x00;
+ LocalX2ApicNmiStruct.Reserved[2] = 0x00;
+
+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
+ Status = CopyStructure (
+ &MadtTableHeader.Header,
+ (STRUCTURE_HEADER *) &LocalX2ApicNmiStruct,
+ &MadtStructs[MadtStructsIndex++]
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (x2APIC NMI) failed: %r\n", Status));
+ goto Done;
+ }
+
+ //
+ // Build Madt Structure from the Madt Header and collection of pointers in MadtStructs[]
+ //
+ Status = BuildAcpiTable (
+ (EFI_ACPI_DESCRIPTION_HEADER *) &MadtTableHeader,
+ sizeof (EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER),
+ MadtStructs,
+ MadtStructsIndex,
+ (UINT8 **)&NewMadtTable
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "BuildAcpiTable failed: %r\n", Status));
+ goto Done;
+ }
+
+ //
+ // Publish Madt Structure to ACPI
+ //
+ Status = mAcpiTable->InstallAcpiTable (
+ mAcpiTable,
+ NewMadtTable,
+ NewMadtTable->Header.Length,
+ &TableHandle
+ );
+
+Done:
+ //
+ // Free memory
+ //
+ for (MadtStructsIndex = 0; MadtStructsIndex < MaxMadtStructCount; MadtStructsIndex++) {
+ if (MadtStructs[MadtStructsIndex] != NULL) {
+ FreePool (MadtStructs[MadtStructsIndex]);
+ }
+ }
+
+ FreePool (MadtStructs);
+
+ if (NewMadtTable != NULL) {
+ FreePool (NewMadtTable);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+InstallMcfgFromScratch (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER *McfgTable;
+ EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *Segment;
+ UINTN Index;
+ UINTN SegmentCount;
+ PCI_SEGMENT_INFO *PciSegmentInfo;
+ UINTN TableHandle;
+
+ PciSegmentInfo = GetPciSegmentInfo (&SegmentCount);
+
+ McfgTable = AllocateZeroPool (
+ sizeof(EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER) +
+ sizeof(EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE) * SegmentCount
+ );
+ if (McfgTable == NULL) {
+ DEBUG ((DEBUG_ERROR, "Could not allocate MCFG structure\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = InitializeHeader (
+ &McfgTable->Header,
+ EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
+ EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Set MCFG table "Length" field based on the number of PCIe segments enumerated so far
+ //
+ McfgTable->Header.Length = (UINT32)(sizeof (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER) +
+ sizeof (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE) * SegmentCount);
+
+ Segment = (VOID *)(McfgTable + 1);
+
+ for (Index = 0; Index < SegmentCount; Index++) {
+ Segment[Index].PciSegmentGroupNumber = PciSegmentInfo[Index].SegmentNumber;
+ Segment[Index].BaseAddress = PciSegmentInfo[Index].BaseAddress;
+ Segment[Index].StartBusNumber = PciSegmentInfo[Index].StartBusNumber;
+ Segment[Index].EndBusNumber = PciSegmentInfo[Index].EndBusNumber;
+ }
+
+ //
+ // Publish Madt Structure to ACPI
+ //
+ Status = mAcpiTable->InstallAcpiTable (
+ mAcpiTable,
+ McfgTable,
+ McfgTable->Header.Length,
+ &TableHandle
+ );
+
+ return Status;
+}
+
+/**
+ This function will update any runtime platform specific information.
+ This currently includes:
+ Setting OEM table values, ID, table ID, creator ID and creator revision.
+ Enabling the proper processor entries in the APIC tables
+ It also indicates with which ACPI table version the table belongs.
+
+ @param[in] Table The table to update
+ @param[in] Version Where to install this table
+
+ @retval EFI_SUCCESS Updated tables commplete.
+**/
+EFI_STATUS
+PlatformUpdateTables (
+ IN OUT EFI_ACPI_COMMON_HEADER *Table,
+ IN OUT EFI_ACPI_TABLE_VERSION *Version
+ )
+{
+ EFI_ACPI_DESCRIPTION_HEADER *TableHeader;
+ UINT8 *TempOemId;
+ UINT64 TempOemTableId;
+ EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader;
+ EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *HpetTable;
+ UINT32 HpetBaseAddress;
+ EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_BLOCK_ID HpetBlockId;
+ UINT32 HpetCapabilitiesData;
+ HPET_GENERAL_CAPABILITIES_ID_REGISTER HpetCapabilities;
+
+ TableHeader = NULL;
+
+ //
+ // By default, a table belongs in all ACPI table versions published.
+ // Some tables will override this because they have different versions of the table.
+ //
+ TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
+
+ //
+ // Update the OEM and creator information for every table except FACS.
+ //
+ if (Table->Signature != EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {
+ TempOemId = (UINT8 *)PcdGetPtr(PcdAcpiDefaultOemId);
+ CopyMem (&TableHeader->OemId, TempOemId, 6);
+
+ //
+ // Skip OEM table ID and creator information for DSDT, SSDT and PSDT tables, since these are
+ // created by an ASL compiler and the creator information is useful.
+ //
+ if (Table->Signature != EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE &&
+ Table->Signature != EFI_ACPI_1_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE &&
+ Table->Signature != EFI_ACPI_1_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
+ ) {
+ TempOemTableId = PcdGet64(PcdAcpiDefaultOemTableId);
+ CopyMem (&TableHeader->OemTableId, &TempOemTableId, 8);
+
+ //
+ // Update the creator ID
+ //
+ TableHeader->CreatorId = PcdGet32(PcdAcpiDefaultCreatorId);
+
+ //
+ // Update the creator revision
+ //
+ TableHeader->CreatorRevision = PcdGet32(PcdAcpiDefaultCreatorRevision);
+ }
+ }
+
+
+ //
+ // By default, a table belongs in all ACPI table versions published.
+ // Some tables will override this because they have different versions of the table.
+ //
+ *Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0;
+
+ //
+ // Update the various table types with the necessary updates
+ //
+ switch (Table->Signature) {
+
+ case EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
+ ASSERT(FALSE);
+ break;
+
+ case EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
+ FadtHeader = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *) Table;
+
+ FadtHeader->PreferredPmProfile = PcdGet8 (PcdFadtPreferredPmProfile);
+ FadtHeader->IaPcBootArch = PcdGet16 (PcdFadtIaPcBootArch);
+ FadtHeader->Flags = PcdGet32 (PcdFadtFlags);
+
+ FadtHeader->AcpiEnable = PcdGet8 (PcdAcpiEnableSwSmi);
+ FadtHeader->AcpiDisable = PcdGet8 (PcdAcpiDisableSwSmi);
+
+ FadtHeader->Pm1aEvtBlk = PcdGet16 (PcdAcpiPm1AEventBlockAddress);
+ FadtHeader->Pm1bEvtBlk = PcdGet16 (PcdAcpiPm1BEventBlockAddress);
+ FadtHeader->Pm1aCntBlk = PcdGet16 (PcdAcpiPm1AControlBlockAddress);
+ FadtHeader->Pm1bCntBlk = PcdGet16 (PcdAcpiPm1BControlBlockAddress);
+ FadtHeader->Pm2CntBlk = PcdGet16 (PcdAcpiPm2ControlBlockAddress);
+ FadtHeader->PmTmrBlk = PcdGet16 (PcdAcpiPmTimerBlockAddress);
+ FadtHeader->Gpe0Blk = PcdGet16 (PcdAcpiGpe0BlockAddress);
+ FadtHeader->Gpe1Blk = PcdGet16 (PcdAcpiGpe1BlockAddress);
+
+ FadtHeader->XPm1aEvtBlk.Address = PcdGet16 (PcdAcpiPm1AEventBlockAddress);
+ FadtHeader->XPm1bEvtBlk.Address = PcdGet16 (PcdAcpiPm1BEventBlockAddress);
+ if (FadtHeader->XPm1bEvtBlk.Address == 0) {
+ FadtHeader->XPm1bEvtBlk.AccessSize = 0;
+ }
+ FadtHeader->XPm1aCntBlk.Address = PcdGet16 (PcdAcpiPm1AControlBlockAddress);
+ FadtHeader->XPm1bCntBlk.Address = PcdGet16 (PcdAcpiPm1BControlBlockAddress);
+ if (FadtHeader->XPm1bCntBlk.Address == 0) {
+ FadtHeader->XPm1bCntBlk.AccessSize = 0;
+ }
+ FadtHeader->XPm2CntBlk.Address = PcdGet16 (PcdAcpiPm2ControlBlockAddress);
+ //if (FadtHeader->XPm2CntBlk.Address == 0) {
+ FadtHeader->XPm2CntBlk.AccessSize = 0;
+ //}
+ FadtHeader->XPmTmrBlk.Address = PcdGet16 (PcdAcpiPmTimerBlockAddress);
+ FadtHeader->XGpe0Blk.Address = PcdGet16 (PcdAcpiGpe0BlockAddress);
+ FadtHeader->XGpe1Blk.Address = PcdGet16 (PcdAcpiGpe1BlockAddress);
+ if (FadtHeader->XGpe1Blk.Address == 0) {
+ FadtHeader->XGpe1Blk.AccessSize = 0;
+ }
+
+ DEBUG(( EFI_D_ERROR, "ACPI FADT table @ address 0x%x\n", Table ));
+ DEBUG(( EFI_D_ERROR, " IaPcBootArch 0x%x\n", FadtHeader->IaPcBootArch ));
+ DEBUG(( EFI_D_ERROR, " Flags 0x%x\n", FadtHeader->Flags ));
+ break;
+
+ case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE:
+ HpetTable = (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *)Table;
+ HpetBaseAddress = PcdGet32 (PcdHpetBaseAddress);
+ HpetTable->BaseAddressLower32Bit.Address = HpetBaseAddress;
+ HpetTable->BaseAddressLower32Bit.RegisterBitWidth = 0;
+ HpetCapabilitiesData = MmioRead32 (HpetBaseAddress + HPET_GENERAL_CAPABILITIES_ID_OFFSET);
+ HpetCapabilities.Uint64 = HpetCapabilitiesData;
+ HpetCapabilitiesData = MmioRead32 (HpetBaseAddress + HPET_GENERAL_CAPABILITIES_ID_OFFSET + 4);
+ HpetCapabilities.Uint64 |= LShiftU64 (HpetCapabilitiesData, 32);
+ HpetBlockId.Bits.Revision = HpetCapabilities.Bits.Revision;
+ HpetBlockId.Bits.NumberOfTimers = HpetCapabilities.Bits.NumberOfTimers;
+ HpetBlockId.Bits.CounterSize = HpetCapabilities.Bits.CounterSize;
+ HpetBlockId.Bits.Reserved = 0;
+ HpetBlockId.Bits.LegacyRoute = HpetCapabilities.Bits.LegacyRoute;
+ HpetBlockId.Bits.VendorId = HpetCapabilities.Bits.VendorId;
+ HpetTable->EventTimerBlockId = HpetBlockId.Uint32;
+ HpetTable->MainCounterMinimumClockTickInPeriodicMode = (UINT16)HpetCapabilities.Bits.CounterClockPeriod;
+ DEBUG(( EFI_D_ERROR, "ACPI HPET table @ address 0x%x\n", Table ));
+ DEBUG(( EFI_D_ERROR, " HPET base 0x%x\n", PcdGet32 (PcdHpetBaseAddress) ));
+ break;
+
+ case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:
+ ASSERT(FALSE);
+ break;
+
+ default:
+ break;
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ This function calculates RCR based on PCI Device ID and Vendor ID from the devices
+ available on the platform.
+ It also includes other instances of BIOS change to calculate CRC and provides as
+ HWSignature filed in FADT table.
+**/
+VOID
+IsHardwareChange (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT32 CRC;
+ UINT32 *HWChange;
+ UINTN HWChangeSize;
+ UINT32 PciId;
+ UINTN Handle;
+ EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *FacsPtr;
+ EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *pFADT;
+
+ HandleCount = 0;
+ HandleBuffer = NULL;
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiPciIoProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return; // PciIO protocol not installed yet!
+ }
+
+ //
+ // Allocate memory for HWChange and add additional entrie for
+ // pFADT->XDsdt
+ //
+ HWChangeSize = HandleCount + 1;
+ HWChange = AllocateZeroPool( sizeof(UINT32) * HWChangeSize );
+ ASSERT( HWChange != NULL );
+
+ if (HWChange == NULL) return;
+
+ //
+ // add HWChange inputs: PCI devices
+ //
+ for (Index = 0; HandleCount > 0; HandleCount--) {
+ PciId = 0;
+ Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID **) &PciIo);
+ if (!EFI_ERROR (Status)) {
+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0, 1, &PciId);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+ HWChange[Index++] = PciId;
+ }
+ }
+
+ //
+ // Locate FACP Table
+ //
+ Handle = 0;
+ Status = LocateAcpiTableBySignature (
+ EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
+ (EFI_ACPI_DESCRIPTION_HEADER **) &pFADT,
+ &Handle
+ );
+ if (EFI_ERROR (Status) || (pFADT == NULL)) {
+ return; //Table not found or out of memory resource for pFADT table
+ }
+
+ //
+ // add HWChange inputs: others
+ //
+ HWChange[Index++] = (UINT32)pFADT->XDsdt;
+
+ //
+ // Calculate CRC value with HWChange data.
+ //
+ Status = gBS->CalculateCrc32(HWChange, HWChangeSize, &CRC);
+ DEBUG((DEBUG_INFO, "CRC = %x and Status = %r\n", CRC, Status));
+
+ //
+ // Set HardwareSignature value based on CRC value.
+ //
+ FacsPtr = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)pFADT->FirmwareCtrl;
+ FacsPtr->HardwareSignature = CRC;
+ FreePool( HWChange );
+}
+
+VOID
+UpdateLocalTable (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_COMMON_HEADER *CurrentTable;
+ EFI_ACPI_TABLE_VERSION Version;
+ UINTN TableHandle;
+ UINTN Index;
+
+ for (Index = 0; Index < sizeof(mLocalTable)/sizeof(mLocalTable[0]); Index++) {
+ CurrentTable = mLocalTable[Index];
+
+ PlatformUpdateTables (CurrentTable, &Version);
+
+ TableHandle = 0;
+
+ if (Version != EFI_ACPI_TABLE_VERSION_NONE) {
+ Status = mAcpiTable->InstallAcpiTable (
+ mAcpiTable,
+ CurrentTable,
+ CurrentTable->Length,
+ &TableHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+}
+
+
+VOID
+EFIAPI
+AcpiEndOfDxeEvent (
+ EFI_EVENT Event,
+ VOID *ParentImageHandle
+ )
+{
+
+ if (Event != NULL) {
+ gBS->CloseEvent(Event);
+ }
+
+
+ //
+ // Calculate Hardware Signature value based on current platform configurations
+ //
+ IsHardwareChange();
+}
+
+/**
+ ACPI Platform driver installation function.
+
+ @param[in] ImageHandle Handle for this drivers loaded image protocol.
+ @param[in] SystemTable EFI system table.
+
+ @retval EFI_SUCCESS The driver installed without error.
+ @retval EFI_ABORTED The driver encountered an error and could not complete installation of
+ the ACPI tables.
+
+**/
+EFI_STATUS
+EFIAPI
+InstallAcpiPlatform (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT EndOfDxeEvent;
+
+
+ Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&mMpService);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&mAcpiTable);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Create an End of DXE event.
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ AcpiEndOfDxeEvent,
+ NULL,
+ &gEfiEndOfDxeEventGroupGuid,
+ &EndOfDxeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Determine the number of processors
+ //
+ mMpService->GetNumberOfProcessors (
+ mMpService,
+ &mNumberOfCPUs,
+ &mNumberOfEnabledCPUs
+ );
+ ASSERT (mNumberOfCPUs <= MAX_CPU_NUM && mNumberOfEnabledCPUs >= 1);
+ DEBUG ((DEBUG_INFO, "mNumberOfCPUs - %d\n", mNumberOfCPUs));
+ DEBUG ((DEBUG_INFO, "mNumberOfEnabledCPUs - %d\n", mNumberOfEnabledCPUs));
+
+ DEBUG ((DEBUG_INFO, "mX2ApicEnabled - 0x%x\n", mX2ApicEnabled));
+ DEBUG ((DEBUG_INFO, "mForceX2ApicId - 0x%x\n", mForceX2ApicId));
+
+ // support up to 64 threads/socket
+ AsmCpuidEx(CPUID_EXTENDED_TOPOLOGY, 1, &mNumOfBitShift, NULL, NULL, NULL);
+ mNumOfBitShift &= 0x1F;
+ DEBUG ((DEBUG_INFO, "mNumOfBitShift - 0x%x\n", mNumOfBitShift));
+
+ UpdateLocalTable ();
+
+ InstallMadtFromScratch ();
+ InstallMcfgFromScratch ();
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Facs/Facs.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Facs/Facs.c
new file mode 100644
index 0000000000..e649b5b89c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Facs/Facs.c
@@ -0,0 +1,84 @@
+/** @file
+ This file contains a structure definition for the ACPI 5.0 Firmware ACPI
+ Control Structure (FACS). The contents of this file should only be modified
+ for bug fixes, no porting is required.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+
+//
+// FACS Definitions
+//
+#define EFI_ACPI_FIRMWARE_WAKING_VECTOR 0x00000000
+#define EFI_ACPI_GLOBAL_LOCK 0x00000000
+
+//
+// Firmware Control Structure Feature Flags are defined in AcpiX.0.h
+//
+#define EFI_ACPI_FIRMWARE_CONTROL_STRUCTURE_FLAGS 0x00000000
+
+#define EFI_ACPI_X_FIRMWARE_WAKING_VECTOR 0x0000000000000000
+
+#define EFI_ACPI_OSPM_FLAGS 0x00000000
+
+
+//
+// Firmware ACPI Control Structure
+// Please modify all values in Facs.h only.
+//
+
+EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE Facs = {
+ EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE,
+ sizeof (EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE),
+
+ //
+ // Hardware Signature will be updated at runtime
+ //
+ 0x00000000,
+
+ EFI_ACPI_FIRMWARE_WAKING_VECTOR,
+ EFI_ACPI_GLOBAL_LOCK,
+ EFI_ACPI_FIRMWARE_CONTROL_STRUCTURE_FLAGS,
+ EFI_ACPI_X_FIRMWARE_WAKING_VECTOR,
+ EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION,
+ {
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE
+ },
+ EFI_ACPI_OSPM_FLAGS,
+ {
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE
+ }
+};
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.c
new file mode 100644
index 0000000000..d1fe98e24b
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.c
@@ -0,0 +1,359 @@
+/** @file
+ This file contains a structure definition for the ACPI 5.0 Fixed ACPI
+ Description Table (FADT). The contents of this file should only be modified
+ for bug fixes, no porting is required.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include <IndustryStandard/Acpi.h>
+
+//
+// FADT Definitions
+//
+#define EFI_ACPI_OEM_FADT_REVISION 0x00000000
+
+#define EFI_ACPI_PREFERRED_PM_PROFILE 0x00 // To be fixed
+
+#define EFI_ACPI_SCI_INT 0x0009
+#define EFI_ACPI_SMI_CMD 0x000000B2
+
+#define EFI_ACPI_ACPI_ENABLE 0 // To be fixed
+#define EFI_ACPI_ACPI_DISABLE 0 // To be fixed
+#define EFI_ACPI_S4_BIOS_REQ 0x00
+#define EFI_ACPI_CST_CNT 0x00
+
+#define EFI_ACPI_PSTATE_CNT 0x00
+#define EFI_ACPI_GPE1_BASE (EFI_ACPI_GPE1_BLK_BIT_WIDTH / 2)
+#define EFI_ACPI_P_LVL2_LAT 0x0065 // 101
+#define EFI_ACPI_P_LVL3_LAT 0x03E9 // 1001
+#define EFI_ACPI_FLUSH_SIZE 0x0000
+#define EFI_ACPI_FLUSH_STRIDE 0x0000
+#define EFI_ACPI_DUTY_OFFSET 0x01
+#define EFI_ACPI_DUTY_WIDTH 0x00
+
+#define EFI_ACPI_DAY_ALRM 0x0D
+#define EFI_ACPI_MON_ALRM 0x00
+#define EFI_ACPI_CENTURY 0x32
+
+//
+// IA-PC Boot Architecture Flags
+//
+
+#define EFI_ACPI_IAPC_BOOT_ARCH 0 // To be fixed
+
+//
+// Fixed Feature Flags
+//
+#define EFI_ACPI_FIXED_FEATURE_FLAGS 0 // To be fixed
+
+//
+// PM1A Event Register Block Generic Address Information
+//
+#define EFI_ACPI_PM1A_EVT_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO
+#define EFI_ACPI_PM1A_EVT_BLK_BIT_WIDTH 0x20
+#define EFI_ACPI_PM1A_EVT_BLK_BIT_OFFSET 0x00
+#define EFI_ACPI_PM1A_EVT_BLK_ADDRESS 0 // To be fixed
+
+//
+// PM1B Event Register Block Generic Address Information
+//
+#define EFI_ACPI_PM1B_EVT_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO
+#define EFI_ACPI_PM1B_EVT_BLK_BIT_WIDTH 0x00
+#define EFI_ACPI_PM1B_EVT_BLK_BIT_OFFSET 0x00
+#define EFI_ACPI_PM1B_EVT_BLK_ADDRESS 0 // To be fixed
+
+//
+// PM1A Control Register Block Generic Address Information
+//
+#define EFI_ACPI_PM1A_CNT_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO
+#define EFI_ACPI_PM1A_CNT_BLK_BIT_WIDTH 0x10
+#define EFI_ACPI_PM1A_CNT_BLK_BIT_OFFSET 0x00
+#define EFI_ACPI_PM1A_CNT_BLK_ADDRESS 0 // To be fixed
+
+//
+// PM1B Control Register Block Generic Address Information
+//
+#define EFI_ACPI_PM1B_CNT_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO
+#define EFI_ACPI_PM1B_CNT_BLK_BIT_WIDTH 0x00
+#define EFI_ACPI_PM1B_CNT_BLK_BIT_OFFSET 0x00
+#define EFI_ACPI_PM1B_CNT_BLK_ADDRESS 0 // To be fixed
+
+//
+// PM2 Control Register Block Generic Address Information
+//
+#define EFI_ACPI_PM2_CNT_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO
+#define EFI_ACPI_PM2_CNT_BLK_BIT_WIDTH 0x08
+#define EFI_ACPI_PM2_CNT_BLK_BIT_OFFSET 0x00
+#define EFI_ACPI_PM2_CNT_BLK_ADDRESS 0 // To be fixed
+
+//
+// Power Management Timer Control Register Block Generic Address
+// Information
+//
+#define EFI_ACPI_PM_TMR_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO
+#define EFI_ACPI_PM_TMR_BLK_BIT_WIDTH 0x20
+#define EFI_ACPI_PM_TMR_BLK_BIT_OFFSET 0x00
+#define EFI_ACPI_PM_TMR_BLK_ADDRESS 0 // To be fixed
+
+//
+// General Purpose Event 0 Register Block Generic Address
+// Information
+//
+#define EFI_ACPI_GPE0_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO
+#define EFI_ACPI_GPE0_BLK_BIT_WIDTH 0 // size of R_PCH_ACPI_GPE0_STS_127_96 + R_PCH_ACPI_GPE0_EN_127_96
+#define EFI_ACPI_GPE0_BLK_BIT_OFFSET 0x00
+#define EFI_ACPI_GPE0_BLK_ADDRESS 0 // To be fixed
+
+//
+// General Purpose Event 1 Register Block Generic Address
+// Information
+//
+#define EFI_ACPI_GPE1_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO
+#define EFI_ACPI_GPE1_BLK_BIT_WIDTH 0x0
+#define EFI_ACPI_GPE1_BLK_BIT_OFFSET 0x0
+#define EFI_ACPI_GPE1_BLK_ADDRESS 0 // To be fixed
+//
+// Reset Register Generic Address Information
+//
+#define EFI_ACPI_RESET_REG_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO
+#define EFI_ACPI_RESET_REG_BIT_WIDTH 0x08
+#define EFI_ACPI_RESET_REG_BIT_OFFSET 0x00
+#define EFI_ACPI_RESET_REG_ADDRESS 0x00000CF9
+#define EFI_ACPI_RESET_VALUE 0x06
+
+//
+// Number of bytes decoded by PM1 event blocks (a and b)
+//
+#define EFI_ACPI_PM1_EVT_LEN ((EFI_ACPI_PM1A_EVT_BLK_BIT_WIDTH + EFI_ACPI_PM1B_EVT_BLK_BIT_WIDTH) / 8)
+
+//
+// Number of bytes decoded by PM1 control blocks (a and b)
+//
+#define EFI_ACPI_PM1_CNT_LEN ((EFI_ACPI_PM1A_CNT_BLK_BIT_WIDTH + EFI_ACPI_PM1B_CNT_BLK_BIT_WIDTH) / 8)
+
+//
+// Number of bytes decoded by PM2 control block
+//
+#define EFI_ACPI_PM2_CNT_LEN (EFI_ACPI_PM2_CNT_BLK_BIT_WIDTH / 8)
+
+//
+// Number of bytes decoded by PM timer block
+//
+#define EFI_ACPI_PM_TMR_LEN (EFI_ACPI_PM_TMR_BLK_BIT_WIDTH / 8)
+
+//
+// Number of bytes decoded by GPE0 block
+//
+#define EFI_ACPI_GPE0_BLK_LEN (EFI_ACPI_GPE0_BLK_BIT_WIDTH / 8)
+
+//
+// Number of bytes decoded by GPE1 block
+//
+#define EFI_ACPI_GPE1_BLK_LEN (EFI_ACPI_GPE1_BLK_BIT_WIDTH / 8)
+
+//
+// Fixed ACPI Description Table
+// Please modify all values in Fadt.h only.
+//
+
+EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE Fadt = {
+ {
+ EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
+ sizeof (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE),
+ EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,
+
+ //
+ // Checksum will be updated at runtime
+ //
+ 0x00,
+
+ //
+ // It is expected that these values will be updated at runtime
+ //
+ { ' ', ' ', ' ', ' ', ' ', ' ' },
+
+ 0,
+ EFI_ACPI_OEM_FADT_REVISION,
+ 0,
+ 0
+ },
+
+ //
+ // These addresses will be updated at runtime
+ //
+ 0x00000000,
+ 0x00000000,
+
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_PREFERRED_PM_PROFILE,
+ EFI_ACPI_SCI_INT,
+ EFI_ACPI_SMI_CMD,
+ EFI_ACPI_ACPI_ENABLE,
+ EFI_ACPI_ACPI_DISABLE,
+ EFI_ACPI_S4_BIOS_REQ,
+ EFI_ACPI_PSTATE_CNT,
+
+ EFI_ACPI_PM1A_EVT_BLK_ADDRESS,
+ EFI_ACPI_PM1B_EVT_BLK_ADDRESS,
+ EFI_ACPI_PM1A_CNT_BLK_ADDRESS,
+ EFI_ACPI_PM1B_CNT_BLK_ADDRESS,
+ EFI_ACPI_PM2_CNT_BLK_ADDRESS,
+ EFI_ACPI_PM_TMR_BLK_ADDRESS,
+ EFI_ACPI_GPE0_BLK_ADDRESS,
+ EFI_ACPI_GPE1_BLK_ADDRESS,
+ EFI_ACPI_PM1_EVT_LEN,
+ EFI_ACPI_PM1_CNT_LEN,
+ EFI_ACPI_PM2_CNT_LEN,
+ EFI_ACPI_PM_TMR_LEN,
+ EFI_ACPI_GPE0_BLK_LEN,
+ EFI_ACPI_GPE1_BLK_LEN,
+ EFI_ACPI_GPE1_BASE,
+
+ //
+ // Latest OS have C-State capability and CST_CNT SMI doesn't need to be defined.
+ // CST_CNT SMI is not handled in BIOS and it can be removed safely.
+ //
+ EFI_ACPI_CST_CNT,
+ EFI_ACPI_P_LVL2_LAT,
+ EFI_ACPI_P_LVL3_LAT,
+ EFI_ACPI_FLUSH_SIZE,
+ EFI_ACPI_FLUSH_STRIDE,
+ EFI_ACPI_DUTY_OFFSET,
+ EFI_ACPI_DUTY_WIDTH,
+ EFI_ACPI_DAY_ALRM,
+ EFI_ACPI_MON_ALRM,
+ EFI_ACPI_CENTURY,
+ EFI_ACPI_IAPC_BOOT_ARCH,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_FIXED_FEATURE_FLAGS,
+
+ //
+ // Reset Register Block
+ //
+ {
+ EFI_ACPI_RESET_REG_ADDRESS_SPACE_ID,
+ EFI_ACPI_RESET_REG_BIT_WIDTH,
+ EFI_ACPI_RESET_REG_BIT_OFFSET,
+ EFI_ACPI_5_0_BYTE,
+ EFI_ACPI_RESET_REG_ADDRESS
+ },
+ EFI_ACPI_RESET_VALUE,
+ {
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE
+ },
+
+ //
+ // These addresses will be updated at runtime
+ //
+ 0x0000000000000000, // X_FIRMWARE_CTRL
+ 0x0000000000000000, // X_DSDT
+
+ {
+ //
+ // X_PM1a Event Register Block
+ //
+ EFI_ACPI_PM1A_EVT_BLK_ADDRESS_SPACE_ID,
+ EFI_ACPI_PM1A_EVT_BLK_BIT_WIDTH,
+ EFI_ACPI_PM1A_EVT_BLK_BIT_OFFSET,
+ EFI_ACPI_5_0_WORD,
+ EFI_ACPI_PM1A_EVT_BLK_ADDRESS
+ },
+ {
+ //
+ // X_PM1b Event Register Block
+ //
+ EFI_ACPI_PM1B_EVT_BLK_ADDRESS_SPACE_ID,
+ EFI_ACPI_PM1B_EVT_BLK_BIT_WIDTH,
+ EFI_ACPI_PM1B_EVT_BLK_BIT_OFFSET,
+ EFI_ACPI_5_0_WORD,
+ EFI_ACPI_PM1B_EVT_BLK_ADDRESS
+ },
+ {
+ //
+ // X_PM1a Control Register Block
+ //
+ EFI_ACPI_PM1A_CNT_BLK_ADDRESS_SPACE_ID,
+ EFI_ACPI_PM1A_CNT_BLK_BIT_WIDTH,
+ EFI_ACPI_PM1A_CNT_BLK_BIT_OFFSET,
+ EFI_ACPI_5_0_WORD,
+ EFI_ACPI_PM1A_CNT_BLK_ADDRESS
+ },
+ {
+ //
+ // X_PM1b Control Register Block
+ //
+ EFI_ACPI_PM1B_CNT_BLK_ADDRESS_SPACE_ID,
+ EFI_ACPI_PM1B_CNT_BLK_BIT_WIDTH,
+ EFI_ACPI_PM1B_CNT_BLK_BIT_OFFSET,
+ EFI_ACPI_5_0_WORD,
+ EFI_ACPI_PM1B_CNT_BLK_ADDRESS
+ },
+ {
+ //
+ // X_PM2 Control Register Block
+ //
+ EFI_ACPI_PM2_CNT_BLK_ADDRESS_SPACE_ID,
+ EFI_ACPI_PM2_CNT_BLK_BIT_WIDTH,
+ EFI_ACPI_PM2_CNT_BLK_BIT_OFFSET,
+ EFI_ACPI_5_0_BYTE,
+ EFI_ACPI_PM2_CNT_BLK_ADDRESS
+ },
+ {
+ //
+ // X_PM Timer Control Register Block
+ //
+ EFI_ACPI_PM_TMR_BLK_ADDRESS_SPACE_ID,
+ EFI_ACPI_PM_TMR_BLK_BIT_WIDTH,
+ EFI_ACPI_PM_TMR_BLK_BIT_OFFSET,
+ EFI_ACPI_5_0_DWORD,
+ EFI_ACPI_PM_TMR_BLK_ADDRESS
+ },
+ {
+ //
+ // X_General Purpose Event 0 Register Block
+ //
+ EFI_ACPI_GPE0_BLK_ADDRESS_SPACE_ID,
+ EFI_ACPI_GPE0_BLK_BIT_WIDTH,
+ EFI_ACPI_GPE0_BLK_BIT_OFFSET,
+ EFI_ACPI_5_0_BYTE,
+ EFI_ACPI_GPE0_BLK_ADDRESS
+ },
+ {
+ //
+ // X_General Purpose Event 1 Register Block
+ //
+ EFI_ACPI_GPE1_BLK_ADDRESS_SPACE_ID,
+ EFI_ACPI_GPE1_BLK_BIT_WIDTH,
+ EFI_ACPI_GPE1_BLK_BIT_OFFSET,
+ EFI_ACPI_5_0_BYTE,
+ EFI_ACPI_GPE1_BLK_ADDRESS
+ },
+ {
+ //
+ // Sleep Control Reg - update in DXE driver
+ //
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ },
+ {
+ //
+ // Sleep Status Reg - update in DXE driver
+ //
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }
+};
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.c
new file mode 100644
index 0000000000..e9528b0ec3
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.c
@@ -0,0 +1,78 @@
+/** @file
+ This file contains a structure definition for the ACPI 1.0 High Precision Event Timer
+ Description Table (HPET). The contents of this file should only be modified
+ for bug fixes, no porting is required.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+
+//
+// HPET Definitions
+//
+#define EFI_ACPI_OEM_HPET_REVISION 0x00000001
+
+#define EFI_ACPI_EVENT_TIMER_BLOCK_ID 0x0 // To be filled
+
+//
+// Event Timer Block Base Address Information
+//
+#define EFI_ACPI_EVENT_TIMER_BLOCK_ADDRESS_SPACE_ID EFI_ACPI_3_0_SYSTEM_MEMORY
+#define EFI_ACPI_EVENT_TIMER_BLOCK_BIT_WIDTH 0x40
+#define EFI_ACPI_EVENT_TIMER_BLOCK_BIT_OFFSET 0x00
+#define EFI_ACPI_EVENT_TIMER_ACCESS_SIZE 0x00
+#define EFI_ACPI_EVENT_TIMER_BLOCK_ADDRESS 0x0 // To be filled
+
+#define EFI_ACPI_HPET_NUMBER 0x00
+
+#define EFI_ACPI_MIN_CLOCK_TICK 0x0080
+
+#define EFI_ACPI_HPET_ATTRIBUTES 0x00
+
+//
+// High Precision Event Timer Table
+// Please modify all values in Hpet.h only.
+//
+
+EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER Hpet = {
+ {
+ EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE,
+ sizeof (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER),
+ EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_REVISION,
+
+ //
+ // Checksum will be updated at runtime
+ //
+ 0x00,
+
+ //
+ // It is expected that these values will be updated at runtime
+ //
+ { ' ', ' ', ' ', ' ', ' ', ' ' },
+
+ 0,
+ EFI_ACPI_OEM_HPET_REVISION,
+ 0,
+ 0
+ },
+
+ EFI_ACPI_EVENT_TIMER_BLOCK_ID,
+ {
+ EFI_ACPI_EVENT_TIMER_BLOCK_ADDRESS_SPACE_ID,
+ EFI_ACPI_EVENT_TIMER_BLOCK_BIT_WIDTH,
+ EFI_ACPI_EVENT_TIMER_BLOCK_BIT_OFFSET,
+ EFI_ACPI_EVENT_TIMER_ACCESS_SIZE,
+ EFI_ACPI_EVENT_TIMER_BLOCK_ADDRESS
+ },
+ EFI_ACPI_HPET_NUMBER,
+ EFI_ACPI_MIN_CLOCK_TICK,
+ EFI_ACPI_HPET_ATTRIBUTES
+};
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c
new file mode 100644
index 0000000000..625b7560bb
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c
@@ -0,0 +1,46 @@
+/** @file
+ ACPI WSMT table
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
+#include <Library/PcdLib.h>
+
+//
+// WSMT Definitions
+//
+
+#define EFI_ACPI_OEM_WSMT_REVISION 0x00000001
+
+EFI_ACPI_WSMT_TABLE Wsmt = {
+ {
+ EFI_ACPI_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE,
+ sizeof (EFI_ACPI_WSMT_TABLE),
+ EFI_WSMT_TABLE_REVISION,
+
+ //
+ // Checksum will be updated at runtime
+ //
+ 0x00,
+
+ //
+ // It is expected that these values will be updated at runtime
+ //
+ { ' ', ' ', ' ', ' ', ' ', ' ' },
+
+ 0,
+ EFI_ACPI_OEM_WSMT_REVISION,
+ 0,
+ 0
+ },
+
+ FixedPcdGet32(PcdWsmtProtectionFlags)
+};
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/ComponentName.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/ComponentName.c
new file mode 100644
index 0000000000..d6d1d451df
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/ComponentName.c
@@ -0,0 +1,205 @@
+/** @file
+ Component name for the QEMU video controller.
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Qemu.h"
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gQemuVideoComponentName = {
+ QemuVideoComponentNameGetDriverName,
+ QemuVideoComponentNameGetControllerName,
+ "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gQemuVideoComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) QemuVideoComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) QemuVideoComponentNameGetControllerName,
+ "en"
+};
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mQemuVideoDriverNameTable[] = {
+ { "eng;en", L"QEMU Video Driver" },
+ { NULL , NULL }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mQemuVideoControllerNameTable[] = {
+ { "eng;en", L"QEMU Video PCI Adapter" },
+ { NULL , NULL }
+};
+
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mQemuVideoDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &gQemuVideoComponentName)
+ );
+}
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // This is a device driver, so ChildHandle must be NULL.
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver is currently managing ControllHandle
+ //
+ Status = EfiTestManagedDevice (
+ ControllerHandle,
+ gQemuVideoDriverBinding.DriverBindingHandle,
+ &gEfiPciIoProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get the QEMU Video's Device structure
+ //
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mQemuVideoControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gQemuVideoComponentName)
+ );
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driver.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driver.c
new file mode 100644
index 0000000000..e49e7a465c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driver.c
@@ -0,0 +1,1011 @@
+/** @file
+ This driver is a sample implementation of the Graphics Output Protocol for
+ the QEMU (Cirrus Logic 5446) video controller.
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Qemu.h"
+#include <IndustryStandard/Acpi.h>
+
+EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding = {
+ QemuVideoControllerDriverSupported,
+ QemuVideoControllerDriverStart,
+ QemuVideoControllerDriverStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+QEMU_VIDEO_CARD gQemuVideoCardList[] = {
+ {
+ PCI_CLASS_DISPLAY_VGA,
+ CIRRUS_LOGIC_VENDOR_ID,
+ CIRRUS_LOGIC_5430_DEVICE_ID,
+ QEMU_VIDEO_CIRRUS_5430,
+ L"Cirrus 5430"
+ },{
+ PCI_CLASS_DISPLAY_VGA,
+ CIRRUS_LOGIC_VENDOR_ID,
+ CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID,
+ QEMU_VIDEO_CIRRUS_5430,
+ L"Cirrus 5430"
+ },{
+ PCI_CLASS_DISPLAY_VGA,
+ CIRRUS_LOGIC_VENDOR_ID,
+ CIRRUS_LOGIC_5446_DEVICE_ID,
+ QEMU_VIDEO_CIRRUS_5446,
+ L"Cirrus 5446"
+ },{
+ PCI_CLASS_DISPLAY_VGA,
+ 0x4321,
+ 0x1111,
+ QEMU_VIDEO_BOCHS_MMIO,
+ L"QEMU Standard VGA"
+ },{
+ PCI_CLASS_DISPLAY_OTHER,
+ 0x1234,
+ 0x1111,
+ QEMU_VIDEO_BOCHS_MMIO,
+ L"QEMU Standard VGA (secondary)"
+ },{
+ PCI_CLASS_DISPLAY_VGA,
+ 0x1b36,
+ 0x0100,
+ QEMU_VIDEO_BOCHS,
+ L"QEMU QXL VGA"
+ },{
+ PCI_CLASS_DISPLAY_VGA,
+ 0x1af4,
+ 0x1050,
+ QEMU_VIDEO_BOCHS_MMIO,
+ L"QEMU VirtIO VGA"
+ },{
+ 0 /* end of list */
+ }
+};
+
+static QEMU_VIDEO_CARD*
+QemuVideoDetect(
+ IN UINT8 SubClass,
+ IN UINT16 VendorId,
+ IN UINT16 DeviceId
+ )
+{
+ UINTN Index = 0;
+
+ while (gQemuVideoCardList[Index].VendorId != 0) {
+ if (gQemuVideoCardList[Index].SubClass == SubClass &&
+ gQemuVideoCardList[Index].VendorId == VendorId &&
+ gQemuVideoCardList[Index].DeviceId == DeviceId) {
+ return gQemuVideoCardList + Index;
+ }
+ Index++;
+ }
+ return NULL;
+}
+
+/**
+ Check if this device is supported.
+
+ @param This The driver binding protocol.
+ @param Controller The controller handle to check.
+ @param RemainingDevicePath The remaining device path.
+
+ @retval EFI_SUCCESS The bus supports this controller.
+ @retval EFI_UNSUPPORTED This device isn't supported.
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoControllerDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ PCI_TYPE00 Pci;
+ QEMU_VIDEO_CARD *Card;
+
+ //
+ // Open the PCI I/O Protocol
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Read the PCI Configuration Header from the PCI Device
+ //
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ sizeof (Pci) / sizeof (UINT32),
+ &Pci
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ Status = EFI_UNSUPPORTED;
+ if (!IS_PCI_DISPLAY (&Pci)) {
+ goto Done;
+ }
+ Card = QemuVideoDetect(Pci.Hdr.ClassCode[1], Pci.Hdr.VendorId, Pci.Hdr.DeviceId);
+ if (Card != NULL) {
+ DEBUG ((EFI_D_INFO, "QemuVideo: %s detected\n", Card->Name));
+ Status = EFI_SUCCESS;
+ }
+
+Done:
+ //
+ // Close the PCI I/O Protocol
+ //
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ return Status;
+}
+
+/**
+ Start to process the controller.
+
+ @param This The USB bus driver binding instance.
+ @param Controller The controller to check.
+ @param RemainingDevicePath The remaining device patch.
+
+ @retval EFI_SUCCESS The controller is controlled by the usb bus.
+ @retval EFI_ALREADY_STARTED The controller is already controlled by the usb
+ bus.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoControllerDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_TPL OldTpl;
+ EFI_STATUS Status;
+ QEMU_VIDEO_PRIVATE_DATA *Private;
+ BOOLEAN IsQxl;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ ACPI_ADR_DEVICE_PATH AcpiDeviceNode;
+ PCI_TYPE00 Pci;
+ QEMU_VIDEO_CARD *Card;
+ EFI_PCI_IO_PROTOCOL *ChildPciIo;
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ //
+ // Allocate Private context data for GOP inteface.
+ //
+ Private = AllocateZeroPool (sizeof (QEMU_VIDEO_PRIVATE_DATA));
+ if (Private == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RestoreTpl;
+ }
+
+ //
+ // Set up context record
+ //
+ Private->Signature = QEMU_VIDEO_PRIVATE_DATA_SIGNATURE;
+
+ //
+ // Open PCI I/O Protocol
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &Private->PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreePrivate;
+ }
+
+ //
+ // Read the PCI Configuration Header from the PCI Device
+ //
+ Status = Private->PciIo->Pci.Read (
+ Private->PciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ sizeof (Pci) / sizeof (UINT32),
+ &Pci
+ );
+ if (EFI_ERROR (Status)) {
+ goto ClosePciIo;
+ }
+
+ //
+ // Determine card variant.
+ //
+ Card = QemuVideoDetect(Pci.Hdr.ClassCode[1], Pci.Hdr.VendorId, Pci.Hdr.DeviceId);
+ if (Card == NULL) {
+ Status = EFI_DEVICE_ERROR;
+ goto ClosePciIo;
+ }
+ Private->Variant = Card->Variant;
+
+ //
+ // IsQxl is based on the detected Card->Variant, which at a later point might
+ // not match Private->Variant.
+ //
+ IsQxl = (BOOLEAN)(Card->Variant == QEMU_VIDEO_BOCHS);
+
+ //
+ // Save original PCI attributes
+ //
+ Status = Private->PciIo->Attributes (
+ Private->PciIo,
+ EfiPciIoAttributeOperationGet,
+ 0,
+ &Private->OriginalPciAttributes
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto ClosePciIo;
+ }
+
+ //
+ // Set new PCI attributes
+ //
+ Status = Private->PciIo->Attributes (
+ Private->PciIo,
+ EfiPciIoAttributeOperationEnable,
+ EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto ClosePciIo;
+ }
+
+ //
+ // Check whenever the qemu stdvga mmio bar is present (qemu 1.3+).
+ //
+ if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *MmioDesc;
+
+ Status = Private->PciIo->GetBarAttributes (
+ Private->PciIo,
+ PCI_BAR_IDX2,
+ NULL,
+ (VOID**) &MmioDesc
+ );
+ if (EFI_ERROR (Status) ||
+ MmioDesc->ResType != ACPI_ADDRESS_SPACE_TYPE_MEM) {
+ DEBUG ((EFI_D_INFO, "QemuVideo: No mmio bar, fallback to port io\n"));
+ Private->Variant = QEMU_VIDEO_BOCHS;
+ } else {
+ DEBUG ((EFI_D_INFO, "QemuVideo: Using mmio bar @ 0x%lx\n",
+ MmioDesc->AddrRangeMin));
+ }
+
+ if (!EFI_ERROR (Status)) {
+ FreePool (MmioDesc);
+ }
+ }
+
+ //
+ // Check if accessing the bochs interface works.
+ //
+ if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO ||
+ Private->Variant == QEMU_VIDEO_BOCHS) {
+ UINT16 BochsId;
+ BochsId = BochsRead(Private, VBE_DISPI_INDEX_ID);
+ if ((BochsId & 0xFFF0) != VBE_DISPI_ID0) {
+ DEBUG ((EFI_D_INFO, "QemuVideo: BochsID mismatch (got 0x%x)\n", BochsId));
+ Status = EFI_DEVICE_ERROR;
+ goto RestoreAttributes;
+ }
+ }
+
+ //
+ // Get ParentDevicePath
+ //
+ Status = gBS->HandleProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &ParentDevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ goto RestoreAttributes;
+ }
+
+ //
+ // Set Gop Device Path
+ //
+ ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));
+ AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;
+ AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;
+ AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);
+ SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH));
+
+ Private->GopDevicePath = AppendDevicePathNode (
+ ParentDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode
+ );
+ if (Private->GopDevicePath == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RestoreAttributes;
+ }
+
+ //
+ // Create new child handle and install the device path protocol on it.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Private->Handle,
+ &gEfiDevicePathProtocolGuid,
+ Private->GopDevicePath,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreeGopDevicePath;
+ }
+
+ //
+ // Construct video mode buffer
+ //
+ switch (Private->Variant) {
+ case QEMU_VIDEO_CIRRUS_5430:
+ case QEMU_VIDEO_CIRRUS_5446:
+ Status = QemuVideoCirrusModeSetup (Private);
+ break;
+ case QEMU_VIDEO_BOCHS_MMIO:
+ case QEMU_VIDEO_BOCHS:
+ Status = QemuVideoBochsModeSetup (Private, IsQxl);
+ break;
+ default:
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ break;
+ }
+ if (EFI_ERROR (Status)) {
+ goto UninstallGopDevicePath;
+ }
+
+ //
+ // Start the GOP software stack.
+ //
+ Status = QemuVideoGraphicsOutputConstructor (Private);
+ if (EFI_ERROR (Status)) {
+ goto FreeModeData;
+ }
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Private->Handle,
+ &gEfiGraphicsOutputProtocolGuid,
+ &Private->GraphicsOutput,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto DestructQemuVideoGraphics;
+ }
+
+ //
+ // Reference parent handle from child handle.
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &ChildPciIo,
+ This->DriverBindingHandle,
+ Private->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ goto UninstallGop;
+ }
+
+#if defined MDE_CPU_IA32 || defined MDE_CPU_X64
+ if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO ||
+ Private->Variant == QEMU_VIDEO_BOCHS) {
+ InstallVbeShim (Card->Name, Private->GraphicsOutput.Mode->FrameBufferBase);
+ }
+#endif
+
+ gBS->RestoreTPL (OldTpl);
+ return EFI_SUCCESS;
+
+UninstallGop:
+ gBS->UninstallProtocolInterface (Private->Handle,
+ &gEfiGraphicsOutputProtocolGuid, &Private->GraphicsOutput);
+
+DestructQemuVideoGraphics:
+ QemuVideoGraphicsOutputDestructor (Private);
+
+FreeModeData:
+ FreePool (Private->ModeData);
+
+UninstallGopDevicePath:
+ gBS->UninstallProtocolInterface (Private->Handle,
+ &gEfiDevicePathProtocolGuid, Private->GopDevicePath);
+
+FreeGopDevicePath:
+ FreePool (Private->GopDevicePath);
+
+RestoreAttributes:
+ Private->PciIo->Attributes (Private->PciIo, EfiPciIoAttributeOperationSet,
+ Private->OriginalPciAttributes, NULL);
+
+ClosePciIo:
+ gBS->CloseProtocol (Controller, &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle, Controller);
+
+FreePrivate:
+ FreePool (Private);
+
+RestoreTpl:
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+/**
+ Stop this device
+
+ @param This The USB bus driver binding protocol.
+ @param Controller The controller to release.
+ @param NumberOfChildren The number of children of this device that
+ opened the controller BY_CHILD.
+ @param ChildHandleBuffer The array of child handle.
+
+ @retval EFI_SUCCESS The controller or children are stopped.
+ @retval EFI_DEVICE_ERROR Failed to stop the driver.
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoControllerDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+
+ EFI_STATUS Status;
+ QEMU_VIDEO_PRIVATE_DATA *Private;
+
+ if (NumberOfChildren == 0) {
+ //
+ // Close the PCI I/O Protocol
+ //
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ return EFI_SUCCESS;
+ }
+
+ //
+ // free all resources for whose access we need the child handle, because the
+ // child handle is going away
+ //
+ ASSERT (NumberOfChildren == 1);
+ Status = gBS->OpenProtocol (
+ ChildHandleBuffer[0],
+ &gEfiGraphicsOutputProtocolGuid,
+ (VOID **) &GraphicsOutput,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get our private context information
+ //
+ Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput);
+ ASSERT (Private->Handle == ChildHandleBuffer[0]);
+
+ QemuVideoGraphicsOutputDestructor (Private);
+ //
+ // Remove the GOP protocol interface from the system
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ Private->Handle,
+ &gEfiGraphicsOutputProtocolGuid,
+ &Private->GraphicsOutput,
+ NULL
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Restore original PCI attributes
+ //
+ Private->PciIo->Attributes (
+ Private->PciIo,
+ EfiPciIoAttributeOperationSet,
+ Private->OriginalPciAttributes,
+ NULL
+ );
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Private->Handle
+ );
+
+ FreePool (Private->ModeData);
+ gBS->UninstallProtocolInterface (Private->Handle,
+ &gEfiDevicePathProtocolGuid, Private->GopDevicePath);
+ FreePool (Private->GopDevicePath);
+
+ //
+ // Free our instance data
+ //
+ gBS->FreePool (Private);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+ @param Address TODO: add argument description
+ @param Data TODO: add argument description
+
+ TODO: add return values
+
+**/
+VOID
+outb (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Address,
+ UINT8 Data
+ )
+{
+ EFI_STATUS Status;
+ VOID *Interface;
+ Private->PciIo->Io.Write (
+ Private->PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Address,
+ 1,
+ &Data
+ );
+ Status = gBS->LocateProtocol(&gEfiDxeSmmReadyToLockProtocolGuid, NULL, &Interface);
+ if (!EFI_ERROR(Status)) {
+ return;
+ }
+
+ Status = S3BootScriptSaveIoWrite(
+ S3BootScriptWidthUint8,
+ Address,
+ (UINTN)1,
+ &Data
+ );
+}
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+ @param Address TODO: add argument description
+ @param Data TODO: add argument description
+
+ TODO: add return values
+
+**/
+VOID
+outw (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Address,
+ UINT16 Data
+ )
+{
+ EFI_STATUS Status;
+ VOID *Interface;
+
+ Private->PciIo->Io.Write (
+ Private->PciIo,
+ EfiPciIoWidthUint16,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Address,
+ 1,
+ &Data
+ );
+
+ Status = gBS->LocateProtocol(&gEfiDxeSmmReadyToLockProtocolGuid, NULL, &Interface);
+ if (!EFI_ERROR(Status)) {
+ return;
+ }
+ Status = S3BootScriptSaveIoWrite(
+ S3BootScriptWidthUint16,
+ Address,
+ 1,
+ &Data
+ );
+}
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+ @param Address TODO: add argument description
+
+ TODO: add return values
+
+**/
+UINT8
+inb (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Address
+ )
+{
+ UINT8 Data;
+
+ Private->PciIo->Io.Read (
+ Private->PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Address,
+ 1,
+ &Data
+ );
+ return Data;
+}
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+ @param Address TODO: add argument description
+
+ TODO: add return values
+
+**/
+UINT16
+inw (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Address
+ )
+{
+ UINT16 Data;
+
+ Private->PciIo->Io.Read (
+ Private->PciIo,
+ EfiPciIoWidthUint16,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Address,
+ 1,
+ &Data
+ );
+ return Data;
+}
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+ @param Index TODO: add argument description
+ @param Red TODO: add argument description
+ @param Green TODO: add argument description
+ @param Blue TODO: add argument description
+
+ TODO: add return values
+
+**/
+VOID
+SetPaletteColor (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Index,
+ UINT8 Red,
+ UINT8 Green,
+ UINT8 Blue
+ )
+{
+ VgaOutb (Private, PALETTE_INDEX_REGISTER, (UINT8) Index);
+ VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8) (Red >> 2));
+ VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8) (Green >> 2));
+ VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8) (Blue >> 2));
+}
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+
+ TODO: add return values
+
+**/
+VOID
+SetDefaultPalette (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ )
+{
+ UINTN Index;
+ UINTN RedIndex;
+ UINTN GreenIndex;
+ UINTN BlueIndex;
+
+ Index = 0;
+ for (RedIndex = 0; RedIndex < 8; RedIndex++) {
+ for (GreenIndex = 0; GreenIndex < 8; GreenIndex++) {
+ for (BlueIndex = 0; BlueIndex < 4; BlueIndex++) {
+ SetPaletteColor (Private, Index, (UINT8) (RedIndex << 5), (UINT8) (GreenIndex << 5), (UINT8) (BlueIndex << 6));
+ Index++;
+ }
+ }
+ }
+}
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+
+ TODO: add return values
+
+**/
+VOID
+ClearScreen (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ )
+{
+ UINT32 Color;
+
+ Color = 0;
+ Private->PciIo->Mem.Write (
+ Private->PciIo,
+ EfiPciIoWidthFillUint32,
+ 0,
+ 0,
+ 0x400000 >> 2,
+ &Color
+ );
+}
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+
+ TODO: add return values
+
+**/
+VOID
+DrawLogo (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN ScreenWidth,
+ UINTN ScreenHeight
+ )
+{
+}
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+ @param ModeData TODO: add argument description
+
+ TODO: add return values
+
+**/
+VOID
+InitializeCirrusGraphicsMode (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ QEMU_VIDEO_CIRRUS_MODES *ModeData
+ )
+{
+ UINT8 Byte;
+ UINTN Index;
+
+ outw (Private, SEQ_ADDRESS_REGISTER, 0x1206);
+ outw (Private, SEQ_ADDRESS_REGISTER, 0x0012);
+
+ for (Index = 0; Index < 15; Index++) {
+ outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]);
+ }
+
+ if (Private->Variant == QEMU_VIDEO_CIRRUS_5430) {
+ outb (Private, SEQ_ADDRESS_REGISTER, 0x0f);
+ Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30);
+ outb (Private, SEQ_DATA_REGISTER, Byte);
+ }
+
+ outb (Private, MISC_OUTPUT_REGISTER, ModeData->MiscSetting);
+ outw (Private, GRAPH_ADDRESS_REGISTER, 0x0506);
+ outw (Private, SEQ_ADDRESS_REGISTER, 0x0300);
+ outw (Private, CRTC_ADDRESS_REGISTER, 0x2011);
+
+ for (Index = 0; Index < 28; Index++) {
+ outw (Private, CRTC_ADDRESS_REGISTER, (UINT16) ((ModeData->CrtcSettings[Index] << 8) | Index));
+ }
+
+ for (Index = 0; Index < 9; Index++) {
+ outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((GraphicsController[Index] << 8) | Index));
+ }
+
+ inb (Private, INPUT_STATUS_1_REGISTER);
+
+ for (Index = 0; Index < 21; Index++) {
+ outb (Private, ATT_ADDRESS_REGISTER, (UINT8) Index);
+ outb (Private, ATT_ADDRESS_REGISTER, AttributeController[Index]);
+ }
+
+ outb (Private, ATT_ADDRESS_REGISTER, 0x20);
+
+ outw (Private, GRAPH_ADDRESS_REGISTER, 0x0009);
+ outw (Private, GRAPH_ADDRESS_REGISTER, 0x000a);
+ outw (Private, GRAPH_ADDRESS_REGISTER, 0x000b);
+ outb (Private, DAC_PIXEL_MASK_REGISTER, 0xff);
+
+ SetDefaultPalette (Private);
+ ClearScreen (Private);
+}
+
+VOID
+BochsWrite (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINT16 Reg,
+ UINT16 Data
+ )
+{
+ EFI_STATUS Status;
+
+ if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
+ Status = Private->PciIo->Mem.Write (
+ Private->PciIo,
+ EfiPciIoWidthUint16,
+ PCI_BAR_IDX2,
+ 0x500 + (Reg << 1),
+ 1,
+ &Data
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ outw (Private, VBE_DISPI_IOPORT_INDEX, Reg);
+ outw (Private, VBE_DISPI_IOPORT_DATA, Data);
+ }
+}
+
+UINT16
+BochsRead (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINT16 Reg
+ )
+{
+ EFI_STATUS Status;
+ UINT16 Data;
+
+ if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
+ Status = Private->PciIo->Mem.Read (
+ Private->PciIo,
+ EfiPciIoWidthUint16,
+ PCI_BAR_IDX2,
+ 0x500 + (Reg << 1),
+ 1,
+ &Data
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ outw (Private, VBE_DISPI_IOPORT_INDEX, Reg);
+ Data = inw (Private, VBE_DISPI_IOPORT_DATA);
+ }
+ return Data;
+}
+
+VOID
+VgaOutb (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Reg,
+ UINT8 Data
+ )
+{
+ EFI_STATUS Status;
+
+ if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
+ Status = Private->PciIo->Mem.Write (
+ Private->PciIo,
+ EfiPciIoWidthUint8,
+ PCI_BAR_IDX2,
+ 0x400 - 0x3c0 + Reg,
+ 1,
+ &Data
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ outb (Private, Reg, Data);
+ }
+}
+
+VOID
+InitializeBochsGraphicsMode (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ QEMU_VIDEO_BOCHS_MODES *ModeData
+ )
+{
+ DEBUG ((EFI_D_INFO, "InitializeBochsGraphicsMode: %dx%d @ %d\n",
+ ModeData->Width, ModeData->Height, ModeData->ColorDepth));
+
+ /* unblank */
+ VgaOutb (Private, ATT_ADDRESS_REGISTER, 0x20);
+
+ BochsWrite (Private, VBE_DISPI_INDEX_ENABLE, 0);
+ BochsWrite (Private, VBE_DISPI_INDEX_BANK, 0);
+ BochsWrite (Private, VBE_DISPI_INDEX_X_OFFSET, 0);
+ BochsWrite (Private, VBE_DISPI_INDEX_Y_OFFSET, 0);
+
+ BochsWrite (Private, VBE_DISPI_INDEX_BPP, (UINT16) ModeData->ColorDepth);
+ BochsWrite (Private, VBE_DISPI_INDEX_XRES, (UINT16) ModeData->Width);
+ BochsWrite (Private, VBE_DISPI_INDEX_VIRT_WIDTH, (UINT16) ModeData->Width);
+ BochsWrite (Private, VBE_DISPI_INDEX_YRES, (UINT16) ModeData->Height);
+ BochsWrite (Private, VBE_DISPI_INDEX_VIRT_HEIGHT, (UINT16) ModeData->Height);
+
+ BochsWrite (Private, VBE_DISPI_INDEX_ENABLE,
+ VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
+
+ SetDefaultPalette (Private);
+ ClearScreen (Private);
+}
+
+EFI_STATUS
+EFIAPI
+InitializeQemuVideo (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EfiLibInstallDriverBindingComponentName2 (
+ ImageHandle,
+ SystemTable,
+ &gQemuVideoDriverBinding,
+ ImageHandle,
+ &gQemuVideoComponentName,
+ &gQemuVideoComponentName2
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Install EFI Driver Supported EFI Version Protocol required for
+ // EFI drivers that are on PCI and other plug in cards.
+ //
+ gQemuVideoDriverSupportedEfiVersion.FirmwareVersion = PcdGet32 (PcdDriverSupportedEfiVersion);
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &gEfiDriverSupportedEfiVersionProtocolGuid,
+ &gQemuVideoDriverSupportedEfiVersion,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/DriverSupportedEfiVersion.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/DriverSupportedEfiVersion.c
new file mode 100644
index 0000000000..af658f9f60
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/DriverSupportedEfiVersion.c
@@ -0,0 +1,15 @@
+/** @file
+ Driver supported version protocol for the QEMU video driver.
+
+ Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Qemu.h"
+
+EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gQemuVideoDriverSupportedEfiVersion = {
+ sizeof (EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL), // Size of Protocol structure.
+ 0 // Version number to be filled at start up.
+};
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.c
new file mode 100644
index 0000000000..5158e4851e
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.c
@@ -0,0 +1,416 @@
+/** @file
+ Graphics Output Protocol functions for the QEMU video controller.
+
+ Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Qemu.h"
+
+STATIC
+VOID
+QemuVideoCompleteModeInfo (
+ IN QEMU_VIDEO_MODE_DATA *ModeData,
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info
+ )
+{
+ Info->Version = 0;
+ if (ModeData->ColorDepth == 8) {
+ Info->PixelFormat = PixelBitMask;
+ Info->PixelInformation.RedMask = PIXEL_RED_MASK;
+ Info->PixelInformation.GreenMask = PIXEL_GREEN_MASK;
+ Info->PixelInformation.BlueMask = PIXEL_BLUE_MASK;
+ Info->PixelInformation.ReservedMask = 0;
+ } else if (ModeData->ColorDepth == 24) {
+ Info->PixelFormat = PixelBitMask;
+ Info->PixelInformation.RedMask = PIXEL24_RED_MASK;
+ Info->PixelInformation.GreenMask = PIXEL24_GREEN_MASK;
+ Info->PixelInformation.BlueMask = PIXEL24_BLUE_MASK;
+ Info->PixelInformation.ReservedMask = 0;
+ } else if (ModeData->ColorDepth == 32) {
+ DEBUG ((EFI_D_INFO, "PixelBlueGreenRedReserved8BitPerColor\n"));
+ Info->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
+ }
+ Info->PixelsPerScanLine = Info->HorizontalResolution;
+}
+
+
+STATIC
+EFI_STATUS
+QemuVideoCompleteModeData (
+ IN QEMU_VIDEO_PRIVATE_DATA *Private,
+ OUT EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode
+ )
+{
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *FrameBufDesc;
+ QEMU_VIDEO_MODE_DATA *ModeData;
+
+ ModeData = &Private->ModeData[Mode->Mode];
+ Info = Mode->Info;
+ QemuVideoCompleteModeInfo (ModeData, Info);
+
+ Private->PciIo->GetBarAttributes (
+ Private->PciIo,
+ 0,
+ NULL,
+ (VOID**) &FrameBufDesc
+ );
+
+ Mode->FrameBufferBase = FrameBufDesc->AddrRangeMin;
+ Mode->FrameBufferSize = Info->HorizontalResolution * Info->VerticalResolution;
+ Mode->FrameBufferSize = Mode->FrameBufferSize * ((ModeData->ColorDepth + 7) / 8);
+ Mode->FrameBufferSize = EFI_PAGES_TO_SIZE (
+ EFI_SIZE_TO_PAGES (Mode->FrameBufferSize)
+ );
+ DEBUG ((EFI_D_INFO, "FrameBufferBase: 0x%Lx, FrameBufferSize: 0x%Lx\n",
+ Mode->FrameBufferBase, (UINT64)Mode->FrameBufferSize));
+
+ FreePool (FrameBufDesc);
+ return EFI_SUCCESS;
+}
+
+//
+// Graphics Output Protocol Member Functions
+//
+EFI_STATUS
+EFIAPI
+QemuVideoGraphicsOutputQueryMode (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN UINT32 ModeNumber,
+ OUT UINTN *SizeOfInfo,
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
+ )
+/*++
+
+Routine Description:
+
+ Graphics Output protocol interface to query video mode
+
+ Arguments:
+ This - Protocol instance pointer.
+ ModeNumber - The mode number to return information on.
+ Info - Caller allocated buffer that returns information about ModeNumber.
+ SizeOfInfo - A pointer to the size, in bytes, of the Info buffer.
+
+ Returns:
+ EFI_SUCCESS - Mode information returned.
+ EFI_BUFFER_TOO_SMALL - The Info buffer was too small.
+ EFI_DEVICE_ERROR - A hardware error occurred trying to retrieve the video mode.
+ EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()
+ EFI_INVALID_PARAMETER - One of the input args was NULL.
+
+--*/
+{
+ QEMU_VIDEO_PRIVATE_DATA *Private;
+ QEMU_VIDEO_MODE_DATA *ModeData;
+
+ Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
+
+ if (Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
+ if (*Info == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
+
+ ModeData = &Private->ModeData[ModeNumber];
+ (*Info)->HorizontalResolution = ModeData->HorizontalResolution;
+ (*Info)->VerticalResolution = ModeData->VerticalResolution;
+ QemuVideoCompleteModeInfo (ModeData, *Info);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+QemuVideoGraphicsOutputSetMode (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN UINT32 ModeNumber
+ )
+/*++
+
+Routine Description:
+
+ Graphics Output protocol interface to set video mode
+
+ Arguments:
+ This - Protocol instance pointer.
+ ModeNumber - The mode number to be set.
+
+ Returns:
+ EFI_SUCCESS - Graphics mode was changed.
+ EFI_DEVICE_ERROR - The device had an error and could not complete the request.
+ EFI_UNSUPPORTED - ModeNumber is not supported by this device.
+
+--*/
+{
+ QEMU_VIDEO_PRIVATE_DATA *Private;
+ QEMU_VIDEO_MODE_DATA *ModeData;
+ RETURN_STATUS Status;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black;
+
+ Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
+
+ if (ModeNumber >= This->Mode->MaxMode) {
+ return EFI_UNSUPPORTED;
+ }
+
+ ModeData = &Private->ModeData[ModeNumber];
+
+ switch (Private->Variant) {
+ case QEMU_VIDEO_CIRRUS_5430:
+ case QEMU_VIDEO_CIRRUS_5446:
+ InitializeCirrusGraphicsMode (Private, &QemuVideoCirrusModes[ModeData->InternalModeIndex]);
+ break;
+ case QEMU_VIDEO_BOCHS_MMIO:
+ case QEMU_VIDEO_BOCHS:
+ InitializeBochsGraphicsMode (Private, &QemuVideoBochsModes[ModeData->InternalModeIndex]);
+ break;
+ default:
+ ASSERT (FALSE);
+ return EFI_DEVICE_ERROR;
+ }
+
+ This->Mode->Mode = ModeNumber;
+ This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;
+ This->Mode->Info->VerticalResolution = ModeData->VerticalResolution;
+ This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
+
+ QemuVideoCompleteModeData (Private, This->Mode);
+
+ //
+ // Re-initialize the frame buffer configure when mode changes.
+ //
+ Status = FrameBufferBltConfigure (
+ (VOID*) (UINTN) This->Mode->FrameBufferBase,
+ This->Mode->Info,
+ Private->FrameBufferBltConfigure,
+ &Private->FrameBufferBltConfigureSize
+ );
+ if (Status == RETURN_BUFFER_TOO_SMALL) {
+ //
+ // Frame buffer configure may be larger in new mode.
+ //
+ if (Private->FrameBufferBltConfigure != NULL) {
+ FreePool (Private->FrameBufferBltConfigure);
+ }
+ Private->FrameBufferBltConfigure =
+ AllocatePool (Private->FrameBufferBltConfigureSize);
+ ASSERT (Private->FrameBufferBltConfigure != NULL);
+
+ //
+ // Create the configuration for FrameBufferBltLib
+ //
+ Status = FrameBufferBltConfigure (
+ (VOID*) (UINTN) This->Mode->FrameBufferBase,
+ This->Mode->Info,
+ Private->FrameBufferBltConfigure,
+ &Private->FrameBufferBltConfigureSize
+ );
+ }
+ ASSERT (Status == RETURN_SUCCESS);
+
+ //
+ // Per UEFI Spec, need to clear the visible portions of the output display to black.
+ //
+ ZeroMem (&Black, sizeof (Black));
+ Status = FrameBufferBlt (
+ Private->FrameBufferBltConfigure,
+ &Black,
+ EfiBltVideoFill,
+ 0, 0,
+ 0, 0,
+ This->Mode->Info->HorizontalResolution, This->Mode->Info->VerticalResolution,
+ 0
+ );
+ ASSERT_RETURN_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+QemuVideoGraphicsOutputBlt (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta
+ )
+/*++
+
+Routine Description:
+
+ Graphics Output protocol instance to block transfer for CirrusLogic device
+
+Arguments:
+
+ This - Pointer to Graphics Output protocol instance
+ BltBuffer - The data to transfer to screen
+ BltOperation - The operation to perform
+ SourceX - The X coordinate of the source for BltOperation
+ SourceY - The Y coordinate of the source for BltOperation
+ DestinationX - The X coordinate of the destination for BltOperation
+ DestinationY - The Y coordinate of the destination for BltOperation
+ Width - The width of a rectangle in the blt rectangle in pixels
+ Height - The height of a rectangle in the blt rectangle in pixels
+ Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
+ If a Delta of 0 is used, the entire BltBuffer will be operated on.
+ If a subrectangle of the BltBuffer is used, then Delta represents
+ the number of bytes in a row of the BltBuffer.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter passed in
+ EFI_SUCCESS - Blt operation success
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_TPL OriginalTPL;
+ QEMU_VIDEO_PRIVATE_DATA *Private;
+
+ Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
+ //
+ // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
+ // We would not want a timer based event (Cursor, ...) to come in while we are
+ // doing this operation.
+ //
+ OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);
+
+ switch (BltOperation) {
+ case EfiBltVideoToBltBuffer:
+ case EfiBltBufferToVideo:
+ case EfiBltVideoFill:
+ case EfiBltVideoToVideo:
+ Status = FrameBufferBlt (
+ Private->FrameBufferBltConfigure,
+ BltBuffer,
+ BltOperation,
+ SourceX,
+ SourceY,
+ DestinationX,
+ DestinationY,
+ Width,
+ Height,
+ Delta
+ );
+ break;
+
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ gBS->RestoreTPL (OriginalTPL);
+
+ return Status;
+}
+
+EFI_STATUS
+QemuVideoGraphicsOutputConstructor (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+
+
+ GraphicsOutput = &Private->GraphicsOutput;
+ GraphicsOutput->QueryMode = QemuVideoGraphicsOutputQueryMode;
+ GraphicsOutput->SetMode = QemuVideoGraphicsOutputSetMode;
+ GraphicsOutput->Blt = QemuVideoGraphicsOutputBlt;
+
+ //
+ // Initialize the private data
+ //
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE),
+ (VOID **) &Private->GraphicsOutput.Mode
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
+ (VOID **) &Private->GraphicsOutput.Mode->Info
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreeMode;
+ }
+ Private->GraphicsOutput.Mode->MaxMode = (UINT32) Private->MaxMode;
+ Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;
+ Private->FrameBufferBltConfigure = NULL;
+ Private->FrameBufferBltConfigureSize = 0;
+
+ //
+ // Initialize the hardware
+ //
+ Status = GraphicsOutput->SetMode (GraphicsOutput, 0);
+ if (EFI_ERROR (Status)) {
+ goto FreeInfo;
+ }
+
+ DrawLogo (
+ Private,
+ Private->ModeData[Private->GraphicsOutput.Mode->Mode].HorizontalResolution,
+ Private->ModeData[Private->GraphicsOutput.Mode->Mode].VerticalResolution
+ );
+
+ return EFI_SUCCESS;
+
+FreeInfo:
+ FreePool (Private->GraphicsOutput.Mode->Info);
+
+FreeMode:
+ FreePool (Private->GraphicsOutput.Mode);
+ Private->GraphicsOutput.Mode = NULL;
+
+ return Status;
+}
+
+EFI_STATUS
+QemuVideoGraphicsOutputDestructor (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+{
+ if (Private->FrameBufferBltConfigure != NULL) {
+ FreePool (Private->FrameBufferBltConfigure);
+ }
+
+ if (Private->GraphicsOutput.Mode != NULL) {
+ if (Private->GraphicsOutput.Mode->Info != NULL) {
+ gBS->FreePool (Private->GraphicsOutput.Mode->Info);
+ }
+ gBS->FreePool (Private->GraphicsOutput.Mode);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Initialize.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Initialize.c
new file mode 100644
index 0000000000..543d360861
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Initialize.c
@@ -0,0 +1,341 @@
+/** @file
+ Graphics Output Protocol functions for the QEMU video controller.
+
+ Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Qemu.h"
+
+
+///
+/// Generic Attribute Controller Register Settings
+///
+UINT8 AttributeController[21] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x41, 0x00, 0x0F, 0x00, 0x00
+};
+
+///
+/// Generic Graphics Controller Register Settings
+///
+UINT8 GraphicsController[9] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF
+};
+
+//
+// 640 x 480 x 256 color @ 60 Hertz
+//
+UINT8 Crtc_640_480_256_60[28] = {
+ 0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xe1, 0x83, 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3,
+ 0xff, 0x00, 0x00, 0x22
+};
+
+UINT8 Crtc_640_480_32bpp_60[28] = {
+ 0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xe1, 0x83, 0xdf, 0x40, 0x00, 0xe7, 0x04, 0xe3,
+ 0xff, 0x00, 0x00, 0x32
+};
+
+UINT16 Seq_640_480_256_60[15] = {
+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
+ 0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e
+};
+
+UINT16 Seq_640_480_32bpp_60[15] = {
+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,
+ 0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e
+};
+
+//
+// 800 x 600 x 256 color @ 60 Hertz
+//
+UINT8 Crtc_800_600_256_60[28] = {
+ 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x58, 0x8C, 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3,
+ 0xFF, 0x00, 0x00, 0x22
+};
+
+UINT8 Crtc_800_600_32bpp_60[28] = {
+ 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x58, 0x8C, 0x57, 0x90, 0x00, 0x5F, 0x91, 0xE3,
+ 0xFF, 0x00, 0x00, 0x32
+};
+
+UINT16 Seq_800_600_256_60[15] = {
+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
+ 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e
+};
+
+UINT16 Seq_800_600_32bpp_60[15] = {
+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,
+ 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e
+};
+
+UINT8 Crtc_960_720_32bpp_60[28] = {
+ 0xA3, 0x77, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x88, 0xCF, 0xe0, 0x00, 0x00, 0x64, 0xE3,
+ 0xFF, 0x4A, 0x00, 0x32
+};
+
+UINT16 Seq_960_720_32bpp_60[15] = {
+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,
+ 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
+};
+
+//
+// 1024 x 768 x 256 color @ 60 Hertz
+//
+UINT8 Crtc_1024_768_256_60[28] = {
+ 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,
+ 0xFF, 0x4A, 0x00, 0x22
+};
+
+UINT16 Seq_1024_768_256_60[15] = {
+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
+ 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
+};
+
+//
+// 1024 x 768 x 24-bit color @ 60 Hertz
+//
+UINT8 Crtc_1024_768_24bpp_60[28] = {
+ 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,
+ 0xFF, 0x4A, 0x00, 0x32
+};
+
+UINT16 Seq_1024_768_24bpp_60[15] = {
+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1507, 0x0008, 0x4a0b,
+ 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
+};
+
+UINT8 Crtc_1024_768_32bpp_60[28] = {
+ 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x88, 0xFF, 0xe0, 0x00, 0x00, 0x64, 0xE3,
+ 0xFF, 0x4A, 0x00, 0x32
+};
+
+UINT16 Seq_1024_768_32bpp_60[15] = {
+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,
+ 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
+};
+
+///
+/// Table of supported video modes
+///
+QEMU_VIDEO_CIRRUS_MODES QemuVideoCirrusModes[] = {
+// { 640, 480, 8, Crtc_640_480_256_60, Seq_640_480_256_60, 0xe3 },
+// { 800, 600, 8, Crtc_800_600_256_60, Seq_800_600_256_60, 0xef },
+ { 640, 480, 32, Crtc_640_480_32bpp_60, Seq_640_480_32bpp_60, 0xef },
+ { 800, 600, 32, Crtc_800_600_32bpp_60, Seq_800_600_32bpp_60, 0xef },
+// { 1024, 768, 8, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef }
+ { 1024, 768, 24, Crtc_1024_768_24bpp_60, Seq_1024_768_24bpp_60, 0xef }
+// { 1024, 768, 32, Crtc_1024_768_32bpp_60, Seq_1024_768_32bpp_60, 0xef }
+// { 960, 720, 32, Crtc_960_720_32bpp_60, Seq_1024_768_32bpp_60, 0xef }
+};
+
+#define QEMU_VIDEO_CIRRUS_MODE_COUNT \
+ (ARRAY_SIZE (QemuVideoCirrusModes))
+
+/**
+ Construct the valid video modes for QemuVideo.
+
+**/
+EFI_STATUS
+QemuVideoCirrusModeSetup (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ )
+{
+ UINT32 Index;
+ QEMU_VIDEO_MODE_DATA *ModeData;
+ QEMU_VIDEO_CIRRUS_MODES *VideoMode;
+
+ //
+ // Setup Video Modes
+ //
+ Private->ModeData = AllocatePool (
+ sizeof (Private->ModeData[0]) * QEMU_VIDEO_CIRRUS_MODE_COUNT
+ );
+ if (Private->ModeData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ ModeData = Private->ModeData;
+ VideoMode = &QemuVideoCirrusModes[0];
+ for (Index = 0; Index < QEMU_VIDEO_CIRRUS_MODE_COUNT; Index ++) {
+ ModeData->InternalModeIndex = Index;
+ ModeData->HorizontalResolution = VideoMode->Width;
+ ModeData->VerticalResolution = VideoMode->Height;
+ ModeData->ColorDepth = VideoMode->ColorDepth;
+ DEBUG ((EFI_D_INFO,
+ "Adding Mode %d as Cirrus Internal Mode %d: %dx%d, %d-bit\n",
+ (INT32) (ModeData - Private->ModeData),
+ ModeData->InternalModeIndex,
+ ModeData->HorizontalResolution,
+ ModeData->VerticalResolution,
+ ModeData->ColorDepth
+ ));
+
+ ModeData ++ ;
+ VideoMode ++;
+ }
+ Private->MaxMode = ModeData - Private->ModeData;
+
+ return EFI_SUCCESS;
+}
+
+///
+/// Table of supported video modes
+///
+QEMU_VIDEO_BOCHS_MODES QemuVideoBochsModes[] = {
+ { 640, 480, 32 },
+ { 800, 480, 32 },
+ { 800, 600, 32 },
+ { 832, 624, 32 },
+ { 960, 640, 32 },
+ { 1024, 600, 32 },
+ { 1024, 768, 32 },
+ { 1152, 864, 32 },
+ { 1152, 870, 32 },
+ { 1280, 720, 32 },
+ { 1280, 760, 32 },
+ { 1280, 768, 32 },
+ { 1280, 800, 32 },
+ { 1280, 960, 32 },
+ { 1280, 1024, 32 },
+ { 1360, 768, 32 },
+ { 1366, 768, 32 },
+ { 1400, 1050, 32 },
+ { 1440, 900, 32 },
+ { 1600, 900, 32 },
+ { 1600, 1200, 32 },
+ { 1680, 1050, 32 },
+ { 1920, 1080, 32 },
+ { 1920, 1200, 32 },
+ { 1920, 1440, 32 },
+ { 2000, 2000, 32 },
+ { 2048, 1536, 32 },
+ { 2048, 2048, 32 },
+ { 2560, 1440, 32 },
+ { 2560, 1600, 32 },
+ { 2560, 2048, 32 },
+ { 2800, 2100, 32 },
+ { 3200, 2400, 32 },
+ { 3840, 2160, 32 },
+ { 4096, 2160, 32 },
+ { 7680, 4320, 32 },
+ { 8192, 4320, 32 }
+};
+
+#define QEMU_VIDEO_BOCHS_MODE_COUNT \
+ (ARRAY_SIZE (QemuVideoBochsModes))
+
+EFI_STATUS
+QemuVideoBochsModeSetup (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ BOOLEAN IsQxl
+ )
+{
+ UINT32 AvailableFbSize;
+ UINT32 Index;
+ QEMU_VIDEO_MODE_DATA *ModeData;
+ QEMU_VIDEO_BOCHS_MODES *VideoMode;
+
+ //
+ // Fetch the available framebuffer size.
+ //
+ // VBE_DISPI_INDEX_VIDEO_MEMORY_64K is expected to return the size of the
+ // drawable framebuffer. Up to and including qemu-2.1 however it used to
+ // return the size of PCI BAR 0 (ie. the full video RAM size).
+ //
+ // On stdvga the two concepts coincide with each other; the full memory size
+ // is usable for drawing.
+ //
+ // On QXL however, only a leading segment, "surface 0", can be used for
+ // drawing; the rest of the video memory is used for the QXL guest-host
+ // protocol. VBE_DISPI_INDEX_VIDEO_MEMORY_64K should report the size of
+ // "surface 0", but since it doesn't (up to and including qemu-2.1), we
+ // retrieve the size of the drawable portion from a field in the QXL ROM BAR,
+ // where it is also available.
+ //
+ if (IsQxl) {
+ UINT32 Signature;
+ UINT32 DrawStart;
+
+ Signature = 0;
+ DrawStart = 0xFFFFFFFF;
+ AvailableFbSize = 0;
+ if (EFI_ERROR (
+ Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32,
+ PCI_BAR_IDX2, 0, 1, &Signature)) ||
+ Signature != SIGNATURE_32 ('Q', 'X', 'R', 'O') ||
+ EFI_ERROR (
+ Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32,
+ PCI_BAR_IDX2, 36, 1, &DrawStart)) ||
+ DrawStart != 0 ||
+ EFI_ERROR (
+ Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32,
+ PCI_BAR_IDX2, 40, 1, &AvailableFbSize))) {
+ DEBUG ((EFI_D_ERROR, "%a: can't read size of drawable buffer from QXL "
+ "ROM\n", __FUNCTION__));
+ return EFI_NOT_FOUND;
+ }
+ } else {
+ AvailableFbSize = BochsRead (Private, VBE_DISPI_INDEX_VIDEO_MEMORY_64K);
+ AvailableFbSize *= SIZE_64KB;
+ }
+ DEBUG ((EFI_D_INFO, "%a: AvailableFbSize=0x%x\n", __FUNCTION__,
+ AvailableFbSize));
+
+ //
+ // Setup Video Modes
+ //
+ Private->ModeData = AllocatePool (
+ sizeof (Private->ModeData[0]) * QEMU_VIDEO_BOCHS_MODE_COUNT
+ );
+ if (Private->ModeData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ ModeData = Private->ModeData;
+ VideoMode = &QemuVideoBochsModes[0];
+ for (Index = 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index ++) {
+ UINTN RequiredFbSize;
+
+ ASSERT (VideoMode->ColorDepth % 8 == 0);
+ RequiredFbSize = (UINTN) VideoMode->Width * VideoMode->Height *
+ (VideoMode->ColorDepth / 8);
+ if (RequiredFbSize <= AvailableFbSize) {
+ ModeData->InternalModeIndex = Index;
+ ModeData->HorizontalResolution = VideoMode->Width;
+ ModeData->VerticalResolution = VideoMode->Height;
+ ModeData->ColorDepth = VideoMode->ColorDepth;
+ DEBUG ((EFI_D_INFO,
+ "Adding Mode %d as Bochs Internal Mode %d: %dx%d, %d-bit\n",
+ (INT32) (ModeData - Private->ModeData),
+ ModeData->InternalModeIndex,
+ ModeData->HorizontalResolution,
+ ModeData->VerticalResolution,
+ ModeData->ColorDepth
+ ));
+
+ ModeData ++ ;
+ }
+ VideoMode ++;
+ }
+ Private->MaxMode = ModeData - Private->ModeData;
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c
new file mode 100644
index 0000000000..aa4648f813
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c
@@ -0,0 +1,302 @@
+/** @file
+ Install a fake VGABIOS service handler (real mode Int10h) for the buggy
+ Windows 2008 R2 SP1 UEFI guest.
+
+ The handler is never meant to be directly executed by a VCPU; it's there for
+ the internal real mode emulator of Windows 2008 R2 SP1.
+
+ The code is based on Ralf Brown's Interrupt List:
+ <http://www.cs.cmu.edu/~ralf/files.html>
+ <http://www.ctyme.com/rbrown.htm>
+
+ Copyright (C) 2014, Red Hat, Inc.
+ Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <IndustryStandard/LegacyVgaBios.h>
+#include <Library/DebugLib.h>
+#include <Library/PciLib.h>
+#include <Library/PrintLib.h>
+#include <SimicsPlatforms.h>
+
+#include "Qemu.h"
+#include "VbeShim.h"
+
+#pragma pack (1)
+typedef struct {
+ UINT16 Offset;
+ UINT16 Segment;
+} IVT_ENTRY;
+#pragma pack ()
+
+//
+// This string is displayed by Windows 2008 R2 SP1 in the Screen Resolution,
+// Advanced Settings dialog. It should be short.
+//
+STATIC CONST CHAR8 mProductRevision[] = "OVMF Int10h (fake)";
+
+/**
+ Install the VBE Info and VBE Mode Info structures, and the VBE service
+ handler routine in the C segment. Point the real-mode Int10h interrupt vector
+ to the handler. The only advertised mode is 1024x768x32.
+
+ @param[in] CardName Name of the video card to be exposed in the
+ Product Name field of the VBE Info structure. The
+ parameter must originate from a
+ QEMU_VIDEO_CARD.Name field.
+ @param[in] FrameBufferBase Guest-physical base address of the video card's
+ frame buffer.
+**/
+VOID
+InstallVbeShim (
+ IN CONST CHAR16 *CardName,
+ IN EFI_PHYSICAL_ADDRESS FrameBufferBase
+ )
+{
+ EFI_PHYSICAL_ADDRESS Segment0, SegmentC, SegmentF;
+ UINTN Segment0Pages;
+ IVT_ENTRY *Int0x10;
+ EFI_STATUS Segment0AllocationStatus;
+ UINT16 HostBridgeDevId;
+ UINTN SegmentCPages;
+ VBE_INFO *VbeInfoFull;
+ VBE_INFO_BASE *VbeInfo;
+ UINT8 *Ptr;
+ UINTN Printed;
+ VBE_MODE_INFO *VbeModeInfo;
+
+ if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT0|BIT7)) == BIT0) {
+ DEBUG ((
+ DEBUG_WARN,
+ "%a: page 0 protected, not installing VBE shim\n",
+ __FUNCTION__
+ ));
+ DEBUG ((
+ DEBUG_WARN,
+ "%a: page 0 protection prevents Windows 7 from booting anyway\n",
+ __FUNCTION__
+ ));
+ return;
+ }
+
+ Segment0 = 0x00000;
+ SegmentC = 0xC0000;
+ SegmentF = 0xF0000;
+
+ //
+ // Attempt to cover the real mode IVT with an allocation. This is a UEFI
+ // driver, hence the arch protocols have been installed previously. Among
+ // those, the CPU arch protocol has configured the IDT, so we can overwrite
+ // the IVT used in real mode.
+ //
+ // The allocation request may fail, eg. if LegacyBiosDxe has already run.
+ //
+ Segment0Pages = 1;
+ Int0x10 = (IVT_ENTRY *)(UINTN)Segment0 + 0x10;
+ Segment0AllocationStatus = gBS->AllocatePages (
+ AllocateAddress,
+ EfiBootServicesCode,
+ Segment0Pages,
+ &Segment0
+ );
+
+ if (EFI_ERROR (Segment0AllocationStatus)) {
+ EFI_PHYSICAL_ADDRESS Handler;
+
+ //
+ // Check if a video BIOS handler has been installed previously -- we
+ // shouldn't override a real video BIOS with our shim, nor our own shim if
+ // it's already present.
+ //
+ Handler = (Int0x10->Segment << 4) + Int0x10->Offset;
+ if (Handler >= SegmentC && Handler < SegmentF) {
+ DEBUG ((EFI_D_INFO, "%a: Video BIOS handler found at %04x:%04x\n",
+ __FUNCTION__, Int0x10->Segment, Int0x10->Offset));
+ return;
+ }
+
+ //
+ // Otherwise we'll overwrite the Int10h vector, even though we may not own
+ // the page at zero.
+ //
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: failed to allocate page at zero: %r\n",
+ __FUNCTION__,
+ Segment0AllocationStatus
+ ));
+ } else {
+ //
+ // We managed to allocate the page at zero. SVN r14218 guarantees that it
+ // is NUL-filled.
+ //
+ ASSERT (Int0x10->Segment == 0x0000);
+ ASSERT (Int0x10->Offset == 0x0000);
+ }
+
+ HostBridgeDevId = PcdGet16(PcdSimicsX58HostBridgePciDevId);
+ switch (HostBridgeDevId) {
+ case INTEL_ICH10_DEVICE_ID:
+ break;
+ default:
+ DEBUG((
+ DEBUG_ERROR,
+ "%a: unknown host bridge device ID: 0x%04x\n",
+ __FUNCTION__,
+ HostBridgeDevId
+ ));
+ ASSERT (FALSE);
+
+ if (!EFI_ERROR(Segment0AllocationStatus)) {
+ gBS->FreePages(Segment0, Segment0Pages);
+ }
+ return;
+ }
+ //
+ // low nibble covers 0xC0000 to 0xC3FFF
+ // high nibble covers 0xC4000 to 0xC7FFF
+ // bit1 in each nibble is Write Enable
+ // bit0 in each nibble is Read Enable
+ //
+
+ //
+ // We never added memory space during PEI or DXE for the C segment, so we
+ // don't need to (and can't) allocate from there. Also, guest operating
+ // systems will see a hole in the UEFI memory map there.
+ //
+ SegmentCPages = 4;
+
+ ASSERT (sizeof mVbeShim <= EFI_PAGES_TO_SIZE (SegmentCPages));
+ CopyMem ((VOID *)(UINTN)SegmentC, mVbeShim, sizeof mVbeShim);
+
+ //
+ // Fill in the VBE INFO structure.
+ //
+ VbeInfoFull = (VBE_INFO *)(UINTN)SegmentC;
+ VbeInfo = &VbeInfoFull->Base;
+ Ptr = VbeInfoFull->Buffer;
+
+ CopyMem (VbeInfo->Signature, "VESA", 4);
+ VbeInfo->VesaVersion = 0x0300;
+
+ VbeInfo->OemNameAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr;
+ CopyMem (Ptr, "QEMU", 5);
+ Ptr += 5;
+
+ VbeInfo->Capabilities = BIT0; // DAC can be switched into 8-bit mode
+
+ VbeInfo->ModeListAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr;
+ *(UINT16*)Ptr = 0x00f1; // mode number
+ Ptr += 2;
+ *(UINT16*)Ptr = 0xFFFF; // mode list terminator
+ Ptr += 2;
+
+ VbeInfo->VideoMem64K = (UINT16)((1024 * 768 * 4 + 65535) / 65536);
+ VbeInfo->OemSoftwareVersion = 0x0000;
+
+ VbeInfo->VendorNameAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr;
+ CopyMem (Ptr, "OVMF", 5);
+ Ptr += 5;
+
+ VbeInfo->ProductNameAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr;
+ Printed = AsciiSPrint ((CHAR8 *)Ptr,
+ sizeof VbeInfoFull->Buffer - (Ptr - VbeInfoFull->Buffer), "%s",
+ CardName);
+ Ptr += Printed + 1;
+
+ VbeInfo->ProductRevAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr;
+ CopyMem (Ptr, mProductRevision, sizeof mProductRevision);
+ Ptr += sizeof mProductRevision;
+
+ ASSERT (sizeof VbeInfoFull->Buffer >= Ptr - VbeInfoFull->Buffer);
+ ZeroMem (Ptr, sizeof VbeInfoFull->Buffer - (Ptr - VbeInfoFull->Buffer));
+
+ //
+ // Fil in the VBE MODE INFO structure.
+ //
+ VbeModeInfo = (VBE_MODE_INFO *)(VbeInfoFull + 1);
+
+ //
+ // bit0: mode supported by present hardware configuration
+ // bit1: optional information available (must be =1 for VBE v1.2+)
+ // bit3: set if color, clear if monochrome
+ // bit4: set if graphics mode, clear if text mode
+ // bit5: mode is not VGA-compatible
+ // bit7: linear framebuffer mode supported
+ //
+ VbeModeInfo->ModeAttr = BIT7 | BIT5 | BIT4 | BIT3 | BIT1 | BIT0;
+
+ //
+ // bit0: exists
+ // bit1: bit1: readable
+ // bit2: writeable
+ //
+ VbeModeInfo->WindowAAttr = BIT2 | BIT1 | BIT0;
+
+ VbeModeInfo->WindowBAttr = 0x00;
+ VbeModeInfo->WindowGranularityKB = 0x0040;
+ VbeModeInfo->WindowSizeKB = 0x0040;
+ VbeModeInfo->WindowAStartSegment = 0xA000;
+ VbeModeInfo->WindowBStartSegment = 0x0000;
+ VbeModeInfo->WindowPositioningAddress = 0x0000;
+ VbeModeInfo->BytesPerScanLine = 1024 * 4;
+
+ VbeModeInfo->Width = 1024;
+ VbeModeInfo->Height = 768;
+ VbeModeInfo->CharCellWidth = 8;
+ VbeModeInfo->CharCellHeight = 16;
+ VbeModeInfo->NumPlanes = 1;
+ VbeModeInfo->BitsPerPixel = 32;
+ VbeModeInfo->NumBanks = 1;
+ VbeModeInfo->MemoryModel = 6; // direct color
+ VbeModeInfo->BankSizeKB = 0;
+ VbeModeInfo->NumImagePagesLessOne = 0;
+ VbeModeInfo->Vbe3 = 0x01;
+
+ VbeModeInfo->RedMaskSize = 8;
+ VbeModeInfo->RedMaskPos = 16;
+ VbeModeInfo->GreenMaskSize = 8;
+ VbeModeInfo->GreenMaskPos = 8;
+ VbeModeInfo->BlueMaskSize = 8;
+ VbeModeInfo->BlueMaskPos = 0;
+ VbeModeInfo->ReservedMaskSize = 8;
+ VbeModeInfo->ReservedMaskPos = 24;
+
+ //
+ // bit1: Bytes in reserved field may be used by application
+ //
+ VbeModeInfo->DirectColorModeInfo = BIT1;
+
+ VbeModeInfo->LfbAddress = (UINT32)FrameBufferBase;
+ VbeModeInfo->OffScreenAddress = 0;
+ VbeModeInfo->OffScreenSizeKB = 0;
+
+ VbeModeInfo->BytesPerScanLineLinear = 1024 * 4;
+ VbeModeInfo->NumImagesLessOneBanked = 0;
+ VbeModeInfo->NumImagesLessOneLinear = 0;
+ VbeModeInfo->RedMaskSizeLinear = 8;
+ VbeModeInfo->RedMaskPosLinear = 16;
+ VbeModeInfo->GreenMaskSizeLinear = 8;
+ VbeModeInfo->GreenMaskPosLinear = 8;
+ VbeModeInfo->BlueMaskSizeLinear = 8;
+ VbeModeInfo->BlueMaskPosLinear = 0;
+ VbeModeInfo->ReservedMaskSizeLinear = 8;
+ VbeModeInfo->ReservedMaskPosLinear = 24;
+ VbeModeInfo->MaxPixelClockHz = 0;
+
+ ZeroMem (VbeModeInfo->Reserved, sizeof VbeModeInfo->Reserved);
+
+ //
+ // Clear Write Enable (bit1), keep Read Enable (bit0) set
+ //
+
+ //
+ // Second, point the Int10h vector at the shim.
+ //
+ Int0x10->Segment = (UINT16) ((UINT32)SegmentC >> 4);
+ Int0x10->Offset = (UINT16) ((UINTN) (VbeModeInfo + 1) - SegmentC);
+
+ DEBUG ((EFI_D_INFO, "%a: VBE shim installed\n", __FUNCTION__));
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp b/Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..86d7030833a096f545393735d931d9f4f2fbf8c0
GIT binary patch
literal 141078
zcmeHwJ9Hz-kzh@gFoN)Qu|weq&F~F*XbyPdaEHTfE*dKcjU5ohf-&!%BU8pXGG)q?
zD^tc9GS`(UQ>MIoGG)r#cb?2OW$Gd_vnu0Pg~E?y>sT{Q)F&%4G9u%Xk&#)e|2h0&
zn&2`0PLf>1@BjWNN&Xl7`zYzU`~UYcP5w_masS+n@=v#$bm8A8pL~*ZKm9cM6#l(=
z^C_Iaf!{aDCtrS<d<p+Pc?<u(e4D(*e{bKy^(^^xHcMvkZ-xI>tK`$wx5>BPew+N{
zCqGF({r0EHo1gqN`6>SUDV+cGXUUiF?`J>zS@QFr|2+Bf=f6mP@rz$1Z-4R2<d?tv
zW%A`Oeg)^hN`Cb#`2FRtlefS6b@J<9|2p~dSHDSq^PAr!Z-4zC$qfGe$A7@@Z+@Hn
z_P4)H-u~uyaQ?gGcfW(*-~K-N{qKLDtbX^0<PU%NLo)l_AL0Cu$shj+zrX)e@~1!j
zDf#vfe@_1V=RYT_KmKR(E&Th>|AgN^{U!O!U;dK(*MI$2^6j7hn*8;ze@*`Ox4)It
zdHsE*z$*n_Dey{xR|>pR;FSWe6nLe;D+OLD@JfMK3cOO_l>)C6c%=ZLK$`j}9J%#+
z`g{~f-@JKc$n%k3)||b2c=-M+LnK+A>$>;;@$vEfKfY?L=VAb__wxr}$K&JI&mkaS
zw~kS*1G~9@9j0;vimRVfxy_Y(?c(tf7y|!~-77nSYEzvqlcpIQf^ZIl@W;O*3M7fT
z!9kZ0_+7Z-@1+@3FK$(@q_Qx*CNCLHfLrh%DN_M$JaLeE@0@S|JKldEOG8tTLJSzc
zYJ|Dn!`@e*DIXr+U-e-^H5^DwWD+9bE5=`ek8z`XKS_FDqrkua>L0^f)%(?nEBo=A
z_fYpY?}i^&&`AMu>PnMqa+)M3U!$^re1FlY5cqf;0Cy_D)w70^J`w{D#QyQ|9Rf@{
z8kVb`(W3$AHjlEeUB&Ltb>`mu&NuNEoIQM&cK+Snc~b#~A`kH2n~2dD(13?{J;ulG
z|Id&fV>kskN%9G{)3wsUdQ;W(-n%jm@Z%%a^j$>b;a#Vy<Dc-|$FJd0z%bzRz4!P4
z{sCjp0*YfS>J9)L?rr`_zY37>O@Q{_-78}U2meqcS?f20ZdoD)$&5I7LUsP#5!2mA
zEIv!W^NqXXbtyvT1i?FFELrj6Q@p|h8in*2V;#tu|Ax1|Dk=1pD}m+Uwxe4Bj5U1+
zJNV<fsLOyKaN}*L9!@<z9mh8h<ni$wkx9P7lK%h4Z%*B<7Jsrp4EO5e<5xcS!ohMF
zJ_0O6y=;Bij258V7V**nn0p+qQDwP~>Dq?`cmO&E`M9W{0!H{GGAQ{1E-QX`E<5s}
zixRkn@-arZCEI?0@4(@!dEW!@f%90CZ#9t*CtDBKkZs|re|+@#d>x=TP>&8u37Fif
zP;WRXRfWgu@yZqbfd>-qeS<tg%t&h+Aa47}cR8#P>jS!=`3l7Lc);J!$~z?;OIihj
zxJtjk;$;D^S?~^kMG7IeoW6RCcaSk~q(8<IzH0o9OmK=1x&^#M_~DWL3Z%@l%Bx4@
zQb6AQ0u=1$cz8ZPP&8e|HGe+wWG;a{KAZ!dmCOWS0ZA+r)prfR?Qf3}ZHIRt%l`lv
zzO}JApCzUJ@O1P=5WkZCa0l!MTn7vs`QQIzf_!;+1fA~c0XAemf*X$MP!igY&BDW#
zd-rkbYJv*{4EhQVuCL$*Dm%m{luAOUt{}bp7>!hUi69=~R-0q&3OmUD4Bta0ky`-E
zBMCQ&c4z~>MVXJ@dBmalpL?R*f<qBnTQ#X(J_tX?h<1tLTfD%Bj#$v8##j&Vqk}Yl
z@AY!xHNnH@N%pU<a<nu~HUmE#yNG;vNkH|7S}oL&{>V4s^ECYzID`MbpMsHs!vn@!
z&V+3w2Pj#D`tZXJ_M-sGAqlrXPlBcONaEABVz;s4SiqS=@9#jn@OTgGC#?-dgT$2G
z--!^SMEK$C2MRMB*}oyW&Rm32W4K0r<wWA0cjG*hKmZaaM^HJ~Vp3Cse}#_#BI4uv
z?}PKYf)sz2zQKnMuroQOk$1S&{|Qw)?8fju9MHeU6|8@9k`j?5-ef({?Vfmz{NTul
z6~lkvK)7~A<pUsHuchXjkS)~s1>zt017ZiRi1VxPE@+rB{(^ty{I0;Y<X_;P2a4d3
zzTPsx848;6ue=%x{w`7+O9gX_Fu@+d-G_0CQt1Jgj02h4c>L1?!h9HEL8Lugef_t;
zp{PGRq8g8|BDz@ifQQ!rNT?+7E-FwFyj#SjQa(^$Ab&|ne*?-yfnolYlQqW=01AB<
z`2nRtKFVKgL(mTh)C&}X`>xkSc+-}ThiiC5@cGo?>P&AiC2xWXLl_@<ZAS2fn>B~y
zEP9hpAtG3)%foU#Ho^kTkU&H`)PUUf_74!O_alHGC?AjDQv~}Fsb9)RL?Ea%Qe=$y
zhXSsny77dg7WC*bJj9k_&vlFfOrd>PIjS`$P>+v5YSQ(Be8ll!kPo0&7$ISGu3jg5
zXsxgbZ_sH7fPv9?AP+Yl!AUOpf$xFw@~#>p8DWL)(2C0&tEB~kMLm!50Ugba{s5Us
z{jxvCJA`Zj-WP~}DDcsbfH{urt^(i(j^2?UIN(APg@+Rg<Px4DH&KuPFrJR#rf;?B
zU-?Il{bQ^byA-_PT`lAX@&y408LS4N0a^3MwID!3+5?Pt9q;bCP7`5;K~m|xn9z2*
z>AQp%c031C0MSbO0qqHgqY^dWo@^!kv6Qptfgi3X1$_k|p?4zHpiv*AdsRkDKJvp4
zCm;S4$mS{S0Q*XVe}%Ys?dtt2B$q2SM)p<m;qHcx>;OAaaYNG3l=>gnf&eMdp2>%o
z=g?`O9Y^r5u=@fRaNGm>3J*Lli5*cdsZ`zZu8ix(;hvL#HxLPh>lAxe&{qJ{*>j-T
zxp#cZ&g$A6<iop~AV{7GB|qS0Cm%j|=!XJm&x4gg_WNFq-6+ThAcfEZU}xf;_f_Fu
zcj6*&ffzxTI(}$a&VJDDSqF04`;~k^V}kt%@&V){;uxqD?;wMq2+^Qppxxuh6E6KR
zJo^TR`e2}fJ;%pzH=2)NKVbCl)CxWd_5;oku&)D1;=FPgmV0jy`9Z251JJTdy~Wyq
zmtH6;zz^;0#~4uv^5JwTigFn02i=EN5hSti9rSSO-H;DQIAW}^{cyxP!JbD3d3}ZN
zfu3>%iSkkUSMU%B1_L+W2G?fj#&8u}NoPMCO%bpc0?=+K7Y}~e4JT-u0UxXixi*Gh
zIGlXAVJO)1f5UnLVAmAXaT^aO;V4#6*vZF3u;&2GBU!=<_5-pV%C>9--mZXie*!<6
z><6ePY@xE}kwK;20D^trTk6uDd-;H-I6}j3nY4jg4Jiqz_FYR+BAt^PLs>wQ%xgJd
zuaCaq3@Yg#m6nMlC-M;iZzf34d`@{+@&UT97RiyDq}mL)eTmB7g~n9&qa1%k>X+@0
zcN~L|v{hZf8oJ;_91jwI*R>1&c*9b?=T1I#{CK$doA3Fa^Iix*K76-7`y2AZhl_)F
zV)bLZ7vzHj#VZ61{a}RWn-1Rs@HzmhX9EppR<NKCVs~(WK^wdqVOaV=2iI4w0|Ppt
zIwy`^BB_8n5%nFE+Vim|sk0j(?EnkM=Z?wf@8XTm(ykMU(x6w32r*QA!#fI&(Y}s%
z8JG`j{I%nUleUr|jvrWW&@vUk@+4?~he~;`_IK<^?429bS8y4eJNHTn%Lg#9*7CTH
zvy!#I+dZi4ITWwt!;Q9}E-#LbA)Yjk7k)|_=v=X^s>ew?VhMH}q}|yOjAp>C;O~NF
z#yA9O<?1bWQch96hj1!!U7!wN;=4}JIqyD>^5IJP;pZ5tf&&e%Iy_*QiUz=&53jF0
zKcc=W-=nYsIgn-8;)nM=tM>BEEq+lx0HzyEMf>5ZgNm>&-%{+g{t9lO2Z{q^IHbM`
z*G@jd_yb-H_8bRQuKSk*!hmQg9d48mnp*l-*hR;_(GTAb;}3X^lo~rkeG_=gQvmFd
zRszWjhAU^!12IrO0P{*dI4txuT(wvTk9HN9wX&Oa@)6pBRUs9z{jO#B2apT|0W}|?
zx!x77g?xYoeuJO@k^{u}k%mMkCs-KkcTFw*D-<T2)WzyQ13`fw?_VJ%&Lj7|+IvM2
z8$1hu(W3DOHCG4;tHHjGEr9ci9~@Rts;<04<eNba%q?$69fkVJH8<D~#0F79&0O_I
zk1z(LgTN4fcZ_8NKb(9-`vJYjJq1WXJ|dcFIfWix4m}?oH-Gx>AH4AdLyq#{`yxJq
z3oJFpli(sous~4&?4EeHm_DjGuOLB#-H@`94++clDgch~-QR~%4a_ZXoBkCN&DZ3r
zLx0rWDes|tkT7hh()H88A0i*fC8w_dRwW<NBk4eD2*QPbo|mDisQBFJ<GTTtz+&%C
zTsa&|c>Ceh<rrRt|D9JvT91IkL4=qT(5IEYf=6Co1^EcD5MYHQ!UiP2hn@=@IBR%-
zqp}|WtFj-y6GJ`zKja7YM?Bmeln-~qyQKjQ=Picuh?5VeC7b|K`+<O>zAE9u%|Nwq
zC-4Jme0K&9zj*_#et6@sD97h`1Bft&$8hRQV5CTJh>=)ChU0VV%=M_?sZo7pB8il!
zkfcqrAh*6}+mGPgx`sl}189H}BH)j}54=Q-!r@vIu8DjAsi=Ioj$OGsp%+4tO2xaH
zJa;@A@7_U0@B0`S{^0}GNyq2N54<P+-O@J=MybTH`PcQRAZcOR1MP=bT~Gx>5=r5@
zkjrj)I8fd-%17C`VCV#OVn=gIzUr~qh_csK4RSY_d;ndlYaC7aVc!^Gdi&u#13!OW
z>MQpSV(@jC!L0-jJGHO$Jr0n+c2gVgoL7OqjDO^YKdv80eFcF15dl}I*Pe{sD?k7!
z5mH}}AO1Exi?Bk6b&}`ncg|!j<kk<Ue0bheN}kTnmhurr9|(d?*7D&5#s@4=uv}xH
z6kzQ<12?5q%15B;<2Rp2goEuu#RszFDuKTj<+Lo4#qq;+9<1JRT*wE$iSJUtWfh-5
zYAM*GfBm$)QT>Abz&1HcgflqsAMgWu5ZvXkLWgzQ+0_rCbC5_DlMk%bIV!X|kFBR1
zizm7UGkyU6V~nr?kub~3X?K_*a#G{4K2QCisvHlxU<y$KSeL7*Qq4#o_y?`^u`9gt
z@pgFNCD>bGZqHp3qyX$2@~O)q!gn7Ovs_On_5%t5KYXrA)Kw*tfR=0h7;!`leFgjd
z4HR)*!k?qKx;|PdpMU`Nmq`9nK4SH*HHaGG<}M)F)eo&fP{!^FfI#fO3U8GJ@RyE}
zUJ`v%LnnY2z<Wud!}_DLA6|mT?yegpIXKuI+&!Qy1?<kDTYNMA2RQxi7(~crlK3+C
zx3V8_j+PB71bzT4#G1kKt@qI)Yy=cIkbFR$0PF&pTggh$&V>5<j-wS*X-?W5y?t*+
z^5G@uhAy<#pTa%35!!~+t5C{iV1mYWhxhGD`EcN%2$~F^=K(K7`{Cr(QSkxhx?BhK
zP<#d{2aFVlA<0*jrTY9EAUEDEk1=8w^c8p{NE+aW8;x2>9z#AVn*ohM`2ZaJpbbx>
zG*rE|M7_Kb{9C;3I=gES_)5-k0$}byaR^Uc4Q02CNerd@0I7Y~b9FnOBLvs^$Bub$
z75GtN2>0>8QLFd09>41N&W(cPMa8}2T1dwt;EN-y>hPM+OPY`GqI~=aiQ=5P2+JWE
z2sFmp52df1Jr61~%15vt1a~D4;RazD_EY~K`mVuIz_vJ7wtNbx|ELV^1)YHTxPg*j
zsy!2&D!@~uh4<7#HX8a`rGMqPR#6e5xEH<--mY6}Hg>%NeE`ho0)ZI2=pyjqGw39h
zn~hBQ!dK@w>v4lgFvl2l*)@{h-^Kc&-G{LsOg@mB&YlAy@H~1`Wv`9m;EDu^#kN!u
zfb_#~5i}0L0Xv*_!b?0J-bKF#@)@v%Zz?`RQio6-_JvRfYVq>Qm5&$L9mc*MFCPxz
zS1yiN(y#>V6f)of{DAElzd<7gfqW_;6=$IWudgt4>gB_Cni5t((h&&ihvPu@Japq=
z&mCm1ukbWdpK5hL77pyY(0C$3{(k)XJ($dffm~Qa5%0${udguri&VnWpkW+fU^Ltd
zr!GDWmwr~N8V^EoS89we2CYAKr(bpaoSvg~1sDOKrW`-K?*e3}G{0t%czhdxxdkLn
z;X?2E*tzb=TLVe&?_&Md92>l_^-;+Oyb0$38r3JDi}FE~k-J01A>1G$v~}HRWUwuj
zd^mL;>PEofG}s1^I4{6hK6rpw%2Uy6eV>2zwHuBKz$sSeE!q2C$%h}XeqDA>Y)NPz
z*bgDZ6iG)QtRKjBD1C(#@x~DCxj!%M2lfen0D8!+$f0n9h)`Ly{jblz^77$5BIt#o
zZUpS=fNDdy%g;t3nX5-w%2Uxd!9y9la7_@a3NS)OsT*S>AAjW3rn4dy!oEY|>IkRG
zuo&<jWi7}@1&b2M^#PcXs=(}X0tf|}K<@(&CLhofJx@Y+!5LhiVFef=_acLKz`~D#
z(T6EBrvRL*$#XuOmcxYdGVr66U`Iv&LZID+2^b-Jeth$<Ujy!V4n9KZd*c<hC@kJ_
zaRg*3z{J}%NJ9Vdfr>KZumc(BD?Z-tJC{q9a<Wpg->t1h7Wl3TjjrxM;}CgF>)ict
z76H4z?}d)NW!+_^q!MpHoIH_IL2Q6>kf(*DgVtDpOMZL-_5&9^;iw3BN%#?h_>S~r
z2MJvo3szZumimR!dJ1|+q5wj0c;&0)!=nV_xt`b8uA^XaXfa7>-mz+U?F)qU`1r$*
zLq-o0CrAMbUMUbI$$|k9<Bzh`=V|ss*BEf`#s=Whet3TuEQsR=b$Ek+@%YupKCa-S
z&K9gtXGtKab}vI3DHw#^Ig9Zes-p+UqPT+#Ze0l!`rVJ9Aga2ML<Dd+#k=mPB!QI*
zNz{(BjzCb}O(c41Ip7{d@UM^)Fcd)z^VV^tYCz~8;YIktG7U%~*Re4CZ8sxa)l_#<
z8bf>@&p{lqqVhk)-%a3`Hy~Rt6xoj-*darET&u!J5351Izz;k{r^p@OaY+?UUxi1m
z`p}O`P&kOO0GHZn3=RTjZ^OF)1*@zMH{>i4!e4}M!3x!55npYEV+Cus6Q{32Kq;O>
zb@YH<;se;#O}C&BuN*;ks~X>ORXUd7AE!G)-3U0GMpfWOG;Dm1K>SdFLoom&yayO{
zj9n|<V~Bsu$L9$w*z(+PML;~9WE!v{fw03oKK{52IUqj!94He2&}ry+4%Ol9@;@gZ
z)fL`7kbF3|3flu9;c(0ibq9VxWkeNteS&?Fl=2!SLh)VIhbk#xcnc^?I}luoevKY@
zfCN9KZPBm@fe`T+quhrV_^#*u<B*@DVju_F4}ND@-k{Cf1(%Qh8R|g}!~Y&usLAoe
zRf;-19NvI9et3LB_1{DN6QBeNYrqKOpC2D0?I4AxjBJ(_B=I#EqLelv-V{h8jUL{O
zOZ!$q`H)Y(`vns7@yGkM>XWyQK@^G!7$nTke{{y6lNCFFkl*`fr>tq54T5S1LGnXp
z)3I>>)M+HAlfq^($ExWSZaWHiQL^UG+r9r<>Xibo6nLe;D+OLD@JfMK3cOO_l>)C6
zc%{HA1zsueN`Y4jyi(wm0<RR<mI7I)+w1jD`u*-+87A9S`&wR7Ano=C!?V%l_3iEb
z{r%+rW;FOa;0S&Q;lpc2);k$qT;EL>t9)G@`ShHvqL2)H`PbdS`Diq{I6oVn4o>>r
zxL^EBMm_EHPe-@YWl=GrI>|@X8kd*cf*Rb?!Obi$)<sd|tHpeBcRe~Aym+Q``opV<
z#S6!j;_Snd^^!a3`J(Dr;iOnhZ!S(>u4T-+gUcz=P!j+3dj7#q>8Hb*hUL?nGZ2%K
zZ7=6H>z?1&;2aq<{7?m?tE3|~s#xBh^<J1YN&A-#7+1I-Zbz=C?TFb$)dc%wc{6xP
z9O>UIZ9K)@`wvuMbtj@B#^sEBl<H}Fi>$3JH`eP9l^?w}!e1;d53|}v(s#S--u1$8
zZjBBEw{AYrAxLj!w@2J97FYf4h<EVPozZNg6^~fEJy;Ho!|?&Ok`HWVKEHZa85vGi
zt%YN~UOX$Vd$6sI{Rq8oH61;hk?dW~x8TNl?e^Q)gDlVX>PG)6s(|%+dH+0aeR?+8
zLRGET#fNG=pd0k(l;RuCi~034n33M)HaNoI{OZ}{cz?M{&)Qk^z^VNH?1_i$>EN~v
zh8TQX%xAON{q^vPG2EXC6hb=MPBkyC4z>3&#iI7Sb2i;%Ir8Ofa(8n%g7`E9sQVu@
zH-HZ5@NTxs^Ss#9?jRz?-RaXcxqH#9tBNHE#7mBS)^@ap2i@W5>iXv9_I@&*v8kOJ
zb259X37@oo)ugNP<@EMq@PUr}8u;NK!FB>L^?81IGnp-6KBVbbUiP0Newv=#*85e(
zYJPX|Bxr1;+>r}(PR?&&3bctK#qG)Qbyhm453Uuf+11HY^ob+Wx-Iz5>D81@N-O3}
zj&4NK;Y`&UZWQ_S#l$$<QgrWf+3<GJptt77o)bN*4Rz+TW7oYm@s0za*W?Q?jvJIX
ztDWeWyA9Kh)8dy7H9N2OH&>TO#QwaF9m~tVSBI({H5)jxx;~mktz$=i_XLhaJHk9y
zskD1p*H@3mkUC{Gzlb06eJ*-Df4$kDZXB?>IfjI!L%RdycZ1`5+0Rez78rETXZ8s3
z7!r~WY|jd2jgP_o7R`ToMY6$-JwRMt9hyezi9PPvkd~Xdyz29d3zzr$;u9=Q7DGPr
z>F_+X0g^<UNDIENIXqj9n%*+2ZM>QG@2z@@`}zTB+QTr<-DEnSFP6(C#@!*${qp>@
z_u;5FNPxY#gb3nnzVL0BO?~QaEmN|ydsAmE&kx$_-i=jDep?qE>71NhL58~?xk4EJ
z{_1@20XP6@_w?fWex}ori+nM?y*#UNDIxLN)LDx|PEmC(tq|hs+D=f&`e#>@hAg0B
zIlVqVdD#P&&fwy9Y7*A#iDGeoHMD1SdRM07GlMUv9_Yv}tQwYArU-TiqkF43*LSPQ
z<!P<Z9|-N8!KA(6b&EWv#ofh;CFq@z>H6H)DU)sSOox_{T3%ZG?hdYMoIcJExLRDl
zOpc_zv)j!b$~7mSURtU*y)YSab0AOj#E7sL%aOs>&fwa_MDfDkSlygj{mTISbhm&T
zn-le8dy4s`Wk}4hYjK#MQuiiSU!7U(NNY4_^^!hW-B_)8I_j&MI;VG*snnRqJ9BFU
zc53y@<slL@(@VpwEiY9|((IzahDY?p*^3%arYE*@Bybj&#mw-X1{N`9Zi`k$x~*=U
z8OCFEr9h;8L#qkI?aS%&<nyT(z~^pky>FvU?-qC3G?)@{zjvlwZ%Qln=eZ6cXQOS!
zJc3<azl>D5{x*gqqVLXDS`}FgDQ--k)aV;Ex6&I;XCw2oZ;wg^(sh@`^gtg5uW3ZP
z+h>-BsY6-aFK$(*vW)t2uW!>Ni6y~zau}GMZI`{L8na%E+R^NIrLt?oOlm~y?-Wxx
z;4|Ic>FGXg=o{K<B0Doo#aPjlden_4%Y6lTpH{-Vy*+eQXil+^=^WWek7J6vJpvP{
zF~u^I=C`+tPoh|o-%F|6lfv7)o(?wVzbb@{8%vop-Z6x3p9ytiMo<MRo6_S9oNI3t
zlV{uFB(;3VT0|QjtZsz=)VtN1V<z=W>z>oqy{5Pl;x=d&bVyj7+~3|p-s|0DzCo=i
z1>73Z{R%cDBRJY)O#03>;eI-AUJ$mrJ>j?**@MO1u0Gb4_N}BXZ)C@EayvSQ<n~^-
z+l6hHPR~X+O>y7#^Nd8YrtI*10h!^$)05DK!Rh&BW84>}AQ(fe*xzbLAFHpe(Ol@1
zLA{@gLG^(M;ifn*QoqB=diD&fL^}1!QxH_Y9QH+s4fX}OxTz1tL#_>DNH)@b+iWLO
zncXSfw-U2lClgg9XxGL4s3tO%^)K#f-Q%a1ka}g6&u-52u-g&4Gq|jsQ^@bQ4e4Gh
z8Wnmx&3I^Dq^AmwTtHqo3M>|P=W29BD(Rfv){VU;(upUp9pe;+PPTo9Re<$#(SS+s
zqE629Ti*SRF~f?>P^*S@_0VI^E9%<Hs#r}fnz(_r!!)y2hK?`?o3&}x$aJV%>Cjl*
z3eBv+bw@Q?E5BtvkCiAjVI?$deJ4Fv{U+xlkB;HX!8=8}HSsWsrsWS`7violJLDb1
z{lRAE(^k3R{TsUtIiESru5?Q|DO)tDukw3}J2oMhT_Wb{$nQ6HtWbOZPFp$vS3Kb^
zKs{T+7i|NaAYR%9#WwKhVn++%wtImYOW>DG2^sQ(yjjU1Y7^^6=72=>t|kC`KFf??
zDGIpzc5^$}HNlC3cglelkc;gGA$>K!m2<CoV0P}sc5-;Cgb;aZ%{{iG&X%RDnYMMY
z-5f<`Cz&sqsZF)U+HUiZY=nei$CNd;XHs&?T|M@Od0{Jz`Cc(lvm)!JnE{(`t1i=l
zNeXVUQ`NoKqisz3iSh!MEb3y;sju&tMzctu?sZL-G251}3T}%Vh64$*dAXe)!FueO
zQ65;*8!#@m@OeARR_C|Wm}euc5Z7xxBh!W|*5c{iLp&{N3`J5aabdZoTKBN}cTAJ`
zi=4$8Qtdfxk!_-rr{}E4+EbC+2w<dJ$6`o+9Sa=k%&JxeuUppLvludG0&t=<R(k=-
zE@k)U3G>#tytvt3S^3s>tz^`F=QTGH(wItE@5&CG&XN=ZKkbIv^z>SJ#;pb9MET3i
zP+Qr&`A*8pQ>|yjk=F}muQrl*+X9v?U&;BsEr41KSuy3;Q+b<hCqi_t2v4^%LOywu
zlbCgTCvep78*FCJPita%TM((fXwOJa$}e}7aIEJ<&lRmX!IgJiwDcYHT8{~pyq=Ex
z7E`7x2_3p8XP4J^um{Uza({Pyc_t(9zNoGdY$A^W5t#d*n(pDw3fJRfjHL=T&hM#U
zc+0dJmCeouXqn>k8s;rb8g&NeFabsMCaj!*FHeXG1$fo;;oEi}v+Bm1S^)t2XZvou
zqPKVlgG9YjmEF+p69e5_>Af*!WDI|n<|YJgcMk~)V|CX<F--*wv2vAGMj9ri^RD0G
z$V^+lU1Wjc5zaGX-3OzbwlVCn0n*)4=3zA=MU9w`Iizh$bzj^JrK(OZh!~YjoHtB{
zz=ti)&QHzt7X(}DG&MBKIyYBOSg+UL>*^6r&P;?-JS(#!^BOX>H0_=m2gNNjLcVE3
z_r<kbTa>D5fh)C>Apn26DvH(gs%93Fw~1Yy7=wj^4R=}bEiR1d(isi?^wc8E7G9}x
zc5}Kmw4)tu!+3OthW}FbdjC5+6T`<$nL8+0vm%ac`efynH<GY>%@M(?Vk(engi!xb
zn-HF`t1L*1P_i=DEFV#c+}c>m+pFC>f{=ncAJE30F}YLNAJw7pgDtl-%B;~RA4=EL
zd()FlkEG_*)lq)r=9%=4k}0YJjhPiT3Uvru3V|@9I-LrS=G2(N<sM3)2lqI*m%oW*
zx(ma~xh*C<n&B&ggEprDO0^20cA!w!Gn8=_7W`HMx1OtU^gxa7D-MX01)sG^jMSJl
zQ@|d{bjX7f+k7^`vgO8VmXaD<|7t&xF<Z?KZ_FN5@oze&$yBJnU@-wizkUNb!40@v
z3MbP@7Y3UyiPE{^khU<!R%o1uu4QFgUS|R~uub=543etI;C-{@Qp;~vRR3M5NkN&f
zn4Bq=apLi-CC?k^7&cumtWZi}V<#(#YNlYY;6qt*=U=TIn1Gzhi6v%VbggRkk*0fO
zDkQcN9egY4K-MfcLzHs|MR;r(P}ZG%(Qb3P)QYjU3|eSX*>}=&Igl#uNlE41ZJ1e5
zLmH}&^e*O9nPIJ`MpTVUguLR*7tBm^No^$`5bRJ&jnJSvwH6mGSV*HPy8DTq3t7-H
zh>8tN<<OW`-BaR3&9x%-QfxWUS0yC*)io?Lpa@t?Sfou?eGHWJq^VV*f>R?+b!j`)
z6s0ZC)1g%A#VrA$I@7XAw$<>03V=>2;d8`EM@g3=zrIo2vZ=?ev4o|Vup;R>_pcCU
zaYL*oX+Ama8^$T8?IUIPIn}}A1wlW%5Xk40Te4mmN~bA_sfshwdH_<YM?;?cun1%}
zt6lve!e4!f1Hcd&nA(6q5gJ91&BANbmQ(9!y|l}{^i&E+ensF6qzanVi*{F)B@-V#
zS<RZKMJD!!e#H_tSb|R+3}FW*V+0P=UhvGWQzO>GZMqo^mcBC~0iLGTxcoRPfI4bJ
zi#Zt+D)DJhSju1%g_Nq4tQBDvwAfC`THc+Pp+nrL#pH-kM>=E)BNaA;HiI5BVazx~
zRMW5{YzXLc2(7PDrPvFCeR|ejVaf3rO?&L9fdya1kf~mQie`GjnAS1Bs>-K>la3zd
z!1r~S2c^3pRAy|FP|`5f=^fxmZ<Uf(f@<-bsR;5t5fGIbJ+B)QW=dT})t0Ip)D^K(
zpbw1YBI}jT+CQ;AtRtd0U7d@uUh`p_8n*&Jiu&AP%i<g_aa+?WC%v*G1I%p5P1$`S
zhcd)Ks2*9|(N`0TK;}jmR`Nn2G8^?w8jzcR56nss$;I-m3PGi_0o?kC3#>C0!XwjN
zs^``Y2~}`~#QS<O_?nAx12&N#xt(BiqNh;S`85$}AfwJ#1<-V8nk1${kl_N)k<4(A
z*9#F{u9$a#6J;aTGoq8U*Hq)H%hB8-0!hy}tzim>;jQ!G*ZEaVH7bS!pmRQRnVw2f
z#WH;Q*7B~Wqz6U(tk2a6V6pH)&N8)<f;bzQR9HFF{1pNnNdvNn1)p+o1gzeJ6B%-a
z0`*Z>^XqY9NnI+3O#o5Y^u${EuHu`3oa#%69p^u7%R$c7B2J?E(^G5=ISTIZmk11n
zBeo{euhu>j*@5>@q&8cxx%`xMxL=*F4ajkTNouWz<0@Z!d_ZTR_^>{+voM4Xf6<eD
zn=Xjz3Tm;4V}(m9d74M>Dmy3a#8W=XH(K1d-o&)86K+CM6-<U|d3eLJ>BjW2l5J47
zysnA{hdWWh8KOxu8R=MB=%~r2N!0(UNlQ8{l4!!L$Oy=2r0IVWk;Yf7uPTcSGHdcx
zrwC~7^K5+szx{8iusa=ED`U(CSE2H*5V3+pgp|L-I+)f!o95ii-T9@vYQ<mpd`V_a
zXz+kBG)|$nA+)kTGXO$Y&U;VE5Tqw9196AT+S8#>NkwFu^50h1<!kt>Qx-Qaa8eMl
z@+Ehm%$+p(eqPq{D%i}BBBzI{hDzfv9OO#Iy6N~psUkXl54EfH%L}5eq=&|)SoCVC
z7A;oQAw$GCy`v`c!C>?KLDX~tK*@<;=o-iK&_q1>AjCI-sF_wW)1uaQuHwj|1l18?
zRciFrj>v4aqM}LBCgY=H#MKM2)r2)p&siS2nf$pVniiXv(o7<`zew5sL;tF&Ju0>;
zxI~600TJnh<(CmdsmZyzQd5xa7B^XwiMa?t>FfZx<kH-ub-}z1*q$RA{#@s)#C9I^
zOe!q8KCL6?E_mz#@K7-@qVLq|XV%`1^pj;Ys;-r%M(};f*C?ftkf_i6!9T6nQ3;ix
z)P&*#hTJ;}<n!xj73=Ui(0w`ATF}%D846L0UDSRHWPH|>{xX}bR(-ggctEQq#z=0S
z-;iWh>M2hNF$0uJWA;Zk_xE>KL#?O}M1BQE`J}|-O=JXH#oT2SxR}HWB*k+!S*@}P
z`6xPqQD>RN3K=rt9k^%NbY8=WN^v#E>9A~0uLM#!9qxu&;!Ib2$o1$dgw+-1oCbkq
zD3u9-3dFBQt=nX*n1Hw!cUP^&yg7@#r)o+X*ebSkX^qkW3(CO}U81VO<s>%cP>`eH
zRZK%sNsdfkNa0zl@mNC>tyPdKD%bF?m2%6o7qW9{9)TfC5};_n;E0c8Dl|19DjGzy
z))6N;{kM!UU==K3Tlz{PU`6!m8$GmgqIm2zRsI`Ldqs21z{<!0FBI80CauTnFi+GX
zUfR)QxRlWp+$$L{BnCz%WwZ1ZHEqt)RW~<GXUs!fox7`gyb09i@yd>xv4$el;opqN
z;Y+9xHAP6SJP=twGR8wkgHrBT{-){#)M~Y8qiNH{2AoDhB8=r(Otd4X{(&EBdw#M7
zQU@v`J#o5Hg$_{>SDuZKNS&15M4aSOOJ+V)a*h!ii=d1%Su-NXa`fRH#dIvhqau9~
z4Rv4+ottZ*-*iiUcZ&warM+JB*quyAAba+z=|z@&Ao~EVvkBMuOsYeqB=zpFq%j@5
zUi0h)nbw40SePx=_*7?dR)I#$l|kntblG6i5}B~g*1V-M3bjKxLUtphB<T-GJ##*N
z#k!Q4t-6h`cX%!-t48-ali?I<?7_Vf;!b94WH6DDO3KxmgKgEu8h4ewt3o!&G``Bf
z*uNPDGto_C@Sf&Erd&{iE=MO!>!>MzvH)0iU*`SDhdB+>v~6_9bXWPXup?tOzz;Fg
z(UU<TD3b5cKiZ<bxttseP|GXh@oWnv+5M<{C4sVlhICi;^3KgzgS|G0y%rvMSItNx
zwc`{&)MF(Q$=G`vbPiTVuBD`LSUJZ{!@nv8gV<B0msvbRMwfO=;7_e}YH~lBfiZOC
zDY&WZI;hl`I3JAC?Ep!GPJ$kZoF5_ablpM83Q0BKqiF}J4CU>p9#U%uK)HLrlyFCF
zmZEO${U;V+wIk$#N=aY7AcFywQ%W_xoZ=&E61sxq`G_Ffl}Ycrdi;7BBzA4)K*4$+
zBTU6TsGiKw2PiqUq6GIRI8`ZB%)t^d9x|Vs&<!YDw~OH+DRXQkhK#JPSW@pcEzabu
z7NQ~clj$1N7W=&q3@fvuRM-Zm{maUz2z8?5WCK+#(zp;$QifOAeho6zw?_=m*r^7_
z;M~cwQn3ZKr3pp0+WT|uPwmYRq>81!kQ_<Vw#p@MBw0xA06{?}a`ui-6m7<rmgpM^
zi84igXq4egWX*52vpz)YJodTt_-F)6@`}>#ObiD}?xyrvm^PL&$MZS2Y^{u2x~?q@
zlC^}K@9@)+gD?amqNiITwtI0I3!=%Ba_C0p{L>3WIv(`X64HpWbQ>8hp*CszR!C_>
zgyej>M8}n3gK+B`bA^#`wmp8^zae8y#7|OdT*%N(4hLy;SBe00cf};{n)+<pW1q;;
z3=&%e#JX}K2Z|JYQx@X`LF<B|y#r=Dz9Jo7I+rcizmgsD<?IKUagwXfX^b+F8UJ+s
z=PoTUZMsN>v9cFv|ABf3BA*}Gx@Oy{?}FSe@5tDAaTTG+y~Oh9)5-}SG8~lqljSsV
zT_z2SNtIZ4+cW8RBO&EFD`_KL8MdOuOb%8V9Bpyhr<_bZpt12xtlJ~g>oOysY`81)
zPS|2l6{Y9y=?*PX(_27omd*mPcbV>j4B-PGDeqWfEhZgzKyHUu<Xj#Vc4>TL+JH1W
zWJXp7)XBsMC<c*Kzkicc8K88O<n!qr>uVPa7Fq0C^XV-%^W1^r&9BJJ7djx6)-pOn
zGF(F3G8yS3UI6R`ClocyTWm(O?y2Rj7AzJG(Kc)A0dCV}v<}%?Ji~mt9KF#&hIGs$
zdUDE%#6;!V4&o)lnq$Eam8Drn^@jU>Bla#o8ZPm5)aEM(Et@U_lnq!M>X95%(XBz`
z06k6~NFgA@NI7a@!*eN(2hj*}428tz3H6ZtZKRX%&pRY)!5DxM0m?%Wy#bDlHqq`Z
zRdXCn%N#=zzLNZ4={$0y5thc;fMw$&bB{PWkb<{U8Bjo`@sGQii9}*B(}>4G9!kp6
z8A2KPh`m{MH^N1k@Xx{}GL`x;fmAyL#UsaNM&g96YUxV<1z5(vS#uDIHv>_cCk`?a
zN!mEkr}z;A5cMwsBFEuJ(v_ADdp`+rA_=VJRqNOyEYc=97|R{=kfT>(nG<R2<J_v8
zog-F93Ka`qDT{QV)fLkJMt;c8x0%@sm(1&xx)z}<c%IWSd4aH%=Sp06iC#1XiXU-Y
zS8sHnHYp!;N@cH>TI2LWY*%G&PsylVGnk3%RQJNM)ywizcw{7@(l4SED1O9l*2oVz
zQfAa>g>OwE>l@YUl?Xve(Z%l1!@(UH48<a`*)^3P^0t(8nr$w9ujsnU<X$qalOn)O
zwuqPP8%`vINaai?QgY6hbfm^sq+<1n@vSS^>Ld0xQscg-S+@`0EbFi=Zy36YKmp}P
z{m`y~AI&C$Cq0rRx_w)h*xzU2dscO<9ey~q&B4qOV()3^0=|^Bn%@c;mYHQF5~a3L
zh+b_&+(XV0aTCEDvx29C?8%bU$TnOvZvw2P+J_Cp!K{l)qlt1R1~Ypi>Rvx7Cz5kI
z4XzWZ+VNu>`QXA%=1*yI(IJ{B7sMka<@Z@kYL95`sT{L9hVV6`wES-8{g{cwx60m4
zKAQL;LR4HnAcR#$F4}yXYP-hDBnwB$xUA6uvurx`@y*?@z!DwEF%J!5tAW^7R9o?*
z8uB*qL)mjKA4%G~m@HSz*(F!)+flxzw5%H$BEHXJd?5&ij&V2(kj(%k{pLVT?d@-i
z^aHkzb~k%2<}t|Ls*V1xLpkg8dOhh^v~Ns9N#omkFjvlXjqHHPGclhoV@Oy;PC7PV
zvH6kM`h_GvCr#sz2LGy5I*2M9gdb8N2#dNI*?mfM#gr!ECO;%S5c#ZFhEfC<^N8-|
zitL$sL7OEOlhdsfn#Skt`9TC;W^M5h5yk2l=T_HVaR(~3GZHB_nH77NAFrY>Y<VvC
zEuO^)KvVpxemuzBR_HyHAEIwPEkDfI`<x{&Bz8EM#8GQ(I#B{!(q9%o;hE6|<%h_K
zqUKK~X2igOlpHeuQTb0O<Z#5Gm&EEQ*O?suAP%%qP^&e?3)u^?lj>nILXnDZcl-rE
z)`TBY!0G&lbk-wjRg}K+yb}3RWa94lZ}X=4eU^y117+ECSYAaLVg)F35un@#Eml_U
zZ842COPv(Q;AE(Py#tQeDmfob@{gMUGNg`m(c=3oFw@~%ME{EARWbyDMHhU<^sX&P
z2ee)gylI5g)Sc_6mKwYO*|EsfdaU)RXQu|S`FE3(RHh9efyC#!?ZHg!$-B2f?l(>S
zD>>&x^Gl@b8Y6Ei3K>ViGDO7kuXb<47H`&k4TnK6qar+eA(iP)$TKmRVK7@?$i>NY
zF|3@Cp!rvFXcvbPGVPaS1j_ux?e|}3-LATVnbo!Bx2vq>RdGTAL0b!S)klr%aA>+O
zH}9rj;%LfGl%exDm9cC7ZWERVeAcyyExy}ley*FxS_fqe79}GbE4lB~4rphi5}N-d
z+1)aKcTIQJlUV{WA5QMSPV(F3UgO99Fn~!9zJYFNy+|(V8oOhPDc&=q$N|0w*+f0D
zaWNrmqE=VLe9`PuaQHfsMfS}Dbf^ft?U|T}^w^5oVHp&~LgI7XQbS-7F_>wK5h*9N
zJz3--H#5vf<UP5PCFWC$03~ch5&aG+RWXZ>fIjxA+Km<|DL<)VnHl1_1CH4ZA4ww=
z8m!x`8Op>)Z%8^y#4slf>kZU`39`IPdI3)xFexb{dyJzb|K^%j0FK%$9Be7R;+9P)
zmNmBjmATu?7^{&3J34)?*5i;=AUX9zjHMj4aHpj`)_ayz+e9F-<A~Nlx0Y9l&vncA
z1wz^Pd-P;-5W&Hhsj9Zh(KJ<#awP{@uclUbk#*!vAgg+x;Kckkx=^0hIGu-s%>X5x
z)ZV@&ayUpQALVe6c4oO>GTl%{j>3uBm2G7EGi;Cj?r-#s{bWQ4%BD682WQrNI$PAT
zEryv`oV+IAv5}S0>}MI?rJ*gkDF)GVQsw5+T5XH@p5^6g6Q>*a`t(d%J1j$$1PlwM
z!w4k`qMx@$Qts?c=Fio4C8&=sXO^h)l@U_1fKU!V<X42Z#((D*GRs}%-)BiWMvh!T
zwFJzkiz#hn**-R1c35JL<R)qb{RE(#Nr>Sq>@<i~JjjHn=CR0V*qOdtzu38nX*DIT
z;`=O+y`WuM{<-edvgtY53295b<fm~-c9)FPvaJqfE^AyK1&+BG^0N?(AOi1gTOz+-
zaeFU!-ao92M4r811}Il@1NF9;rt&j^#286mh?s#Sk;_x!@EoT6&&&Q6e#r(V(nsLx
zxGma;DR*ilEiPl+2P-jcI(I_M0OgD)2e-yo#x~Z(7Rj*!Rj!$s$>n=n$nTTR<B9_*
z-gJ!F8tX$9lr6;W!@s%K?sMH*sloS!V^CrXbmb77s+LQ!O%F5KVk<YYJp<G(l_1IK
zQWfs5YPV=+O;OXPlj(kZt;O;x8RBqSK@4VUFp#%pE(kH_$`zvSm0Y{O<bediEn<{p
zOiV6Rk_aC6+Wf*DSs#J5%O2#Y9cO#6i0pq@B<J5s!eX0`RDL^}*a*4JIotb1dhdKM
z1-YRCU0^JiVmzZk2l|{yJBXCzd$}jp2c6fP+QXGrS-X5EQhKH|S4x_5_R&(gaTFaY
z>I@~S1tllxnybwn=-?$}a+2%X{0n!fjK{e$d^v>F?O24`+m?7s>$<*+(MdTtWuB1q
z%j4`I)-2~7*Ru##R+(S6#PvwUWdHEQW|f)YU>YET(tIru0)bD4#84oESAQW>AIa88
zYDp0_=c&xnkh3{Le3#L|l7sj4z5(j`*0p+~0!B#56(5D9<`yT6+A`jaP}aPcZbnD$
zj6}Cz7HQTTxZJ8rd~YI=A2=ubDrHxKS5KW2C&{98Hd2y*pCvJuS8)$Y23QfwYD?!)
z1_i-uuCSHQ*eAy1{wi|ou&$6FI@2p<a=-X=h41bsG7f>16yImr^>f|CJ!*lU%2z1J
zOt&;2WS&Yd73c017<3`vG>J(136xhYkUl~Yt80sIqpQuJkY{{8-5ktpWz%K)I*d)L
z)~ZjVFtsALcBYA02tq04c{J$CpXYl`RTv!QBpaNM&Ie+BSvnL!HAie7f=aFVbWUya
z1Jcy$ZfcRLf~YIGU*(!<OPPBl(?nzv>UtH&i)#Bj5;EI_@t)5+XLs|(ayh>jskSlz
ziu{1@v#^MVNp1PLZebb$3jf$-BmV09(=>1?-N1r2K`mAl>!e{&D|%c`rq$%`M#QOW
z#CPw9z3Vb%YQcIJ>Q_xk`Gvclu|8d_N4AoK+uL+$A*gqy(yQqFcp~G4dbdsK{?QSk
zoX&l!?S<*=QXyQ?p0RU&E|?}qPAEi6rWvwxu~ZL>5F^moqvT8!+w-O)H4<C@BVE=x
zch{j>xmE0X9)(|f*-@D_V!Yo&z8_4^KJ@{cX&UqCOTMHdHL1;}c+JmsivVR^E7W`?
zUGuFLIIw8}*_p)0fS^X1rM=FhC!Jmh<?u8LORORgQA4$#7k2GAXIdsFMX?NDGSQXu
zbWoxoX1R_TxW5)cqX&)b$#nXHdK(?Fs(;PnJ+98apgGOdm7|w}<WSTjyyp}7!2`Kn
zjro0+DW6vAT2s87+SXvE%}03kYHYfDgxtD&O=grpwgs)%9BW6oOlne+G^#vaGC#5>
z)oWkZi=C;1g0FRq5R~}l8f*wAn=U=5R1UAO#}^`;WMC=%CoXu(A*XX6Y8WY^J+3yn
zQ~P=qM<B|*Bnb}&s)x8`d@zR_2dJbk)i6*p7k1yW>HKruH5*<>^JzAxC++o`?eD8*
z1*p1G-;T1>jY{IBLNpNGFpdA3=<a({&GP`Mb)P*|L_r6NQL@$Ny2ZRIN(h+-x7w0v
z*`%W~HNGJ6S(w3;_0c?_sy1CJ3W)rw7i`v6y?2b0RIaf{645ReDkb|1VF`B#cQupq
zX;_GnC+Wz^2rMGCBWtF$UmA6w<hrOeQ&&TTPY!7rLsim&oW&@G3a8Nc7Q^%~7b+YL
z*z-@G`+C&Z5wVrzW3O1MML3vk&=UwHrb~FcWRee}N22+uw8gA1soZd48E7>!ld>Q+
zsP9>?qB~4s9Ohh!BhrWs<jQ(v925%{BKEGwZBU3$@yh4~f+4$9l(mK5^i(?uRGaGM
zD$Cfl!4DC8UeE=(v?e)-Uy~Fq^{rwWS*Ab^aV}SYA$8V7T4^0B#0o{p3O-k~#quhn
z!>{RZf>vopGwJ@osY*$uo6D<EVKJi6<9W6eY$qcyHC$XXmPa55I5YQuS=DW@Wx1<7
zd8X!b-OL=N#(a9gqrqj%%oKUHS)o!UYZ}kUu3Z0$e{}FFR3&}&oCHj@MmNTkCCYpK
z+WR9h>QVTX16AD662@!-5`%|>4Tou6%y?3Y18VKy0qTz^Bo%t%-l+PhDTz#RwB>RI
zs<3n=2j29qLPf_Rz$BQ)!@tte4iw#D#}%^7j0gu?8(y!Mw_@a+of$!6?rWrS?i)sz
z#06Kzg)C60Xy8wJ!qBXV!b)U3WrIg3K)1iNGSmzDogW3t_&&=ry6V2TwHts42g?N+
zPNC$}t3ia-J-aO@0HV5qGxk+2mC?Ii(&(+4O{yO{q)K6toF$b2e4MW=c4eX%G`C<=
zor)i7mvk6kL>h+TC(@e-xGOf|x56)2Xm)dP+J`*}PtGpy=5izl1pq&4u66Ds*Pe3S
z;9AGps}`yVGTly8&Pufj@>G!9o@65_qtITme9nZE%2bZ^T$i)DKMx068#p*}FK3hc
zyZh-}1}X3%90mI>km~>ZV`J%1u#`?TNvu_(C0W>+WU7bJrxMg|*Xfx^B*yk`{vNOl
zLGd2xQ8B~8lejh+rW~x%J|eK;-~oJ@C=Jq0tcM<*Hmw)X3X4wOXuHYeeK!v9x8#Ct
zq{NB}DKB1KiE%nhttkt2WKIXb=HcMXnl9PEjCH~DXLU4yrR}QEr1C&~iEH_*5+>;K
z|E`Jxh#l@rC_Ddlb(9YFzi$%>$Y?+{zok90!lpkFssc#OZMyBtHgjY#sw#jJ{bdFo
zEl_dN!p1eg>`QgApm9UFcLt<DQqO_nwbMDBFE5EuOycH&O+b5**g2nYif@_WU=oCY
ztPVM?SE5n-%je^bwGL!$EMTHmlQyX<V6TdF(x|1}83J_40k^RQ{Vk_4feJI)AtGt@
zS?_M)x_`d7C2==i&N2{udDXTI5$woRV0X>G`k<!OX`F>4>#o#-FuEgVqE{0iWQVnY
zhqZ6<W?No0B86NnNY%RKQ|Q%WJTWs8dG^9q3@MgOx?mz!&8c(oP?0$qYGdfag<R9a
z$Cg?^ng-4i_J(V1p1|Hx@!aq}JkEMuHSl0>nV;*PkXQ#UcN0;(T2%$Za_a6tMMfBa
z4yl1(${xf7Q-)}Dq0%i_{-hqPiP@hD&ekWXG5IRKn6@=c{eqRfAo{2oFEp8=;*Bcc
zwC3WGs!#9ozM%0<RJfEaVpoI91MLY3h{)L&q(EK7+rYc+E!94#CLgi4&Ch=t3{iGU
zYpXR+bykxDWc4RQAzr9Op*-xSQY0Z*z{EX5+UhKoiyE-~$H-!lLq|vF6&)4=-exwc
z;K<@!w%hmurO+Nqe)v$*q?qzS$XZ*_t}?_0!{?C+XRDj3N|=Dw%Z$XWAl4Snl+HlT
zi!n}S?L0sklHc^Dr7{8l1r5U+3x5kfOKIY)XE*6iC+e$`fMjcz)U40lRO23O`*yax
z9=LeY6PvX-GD|(4b}x**AY4)Sli!_6;Yh4}Nw$I$N=Sdc&B`X7I>FvDzSAo<&=JjV
zb19cwyLPu4m$!i~%P1`l)#;v^^)But{TyD!{ASqI0RST!DV7N7R`Ny863=k0c4R5o
z;vMxEyUTvVbn^=Z)4B=T8noNrHtlt;v%9k1@akU7cjWWC(ZJw_nVTn;>nibBwVGnp
z-%e&0glC<*9;1>1+tUV1c2v|1pt9u>+risd+O+9QYaH3>4==9oCbRisv6#>9Z?Dcz
zd(v*W>a55cANeQR+_!Wel}pG2{9R)y4Bw@2BSBb!j`ARY9V;=?VsGqyp}QPZIah0x
zTs>*0H#i**&xXUnNiWlS$`vx#Vu`r4YG&K9bVrR)dC<#nv%$$SyG;wqnM-2w>zanQ
z0NAF8`MK_?&5#!GOoht^(w1l1!rAq8tLZkL&6=GX6J<-Se_J#JLLAnb8E&y!!P&Bq
znZ2+pLpnyX&|2<>qDF3oke~V%7;`Et<JZ~~a=kKgW9q9YpV;i6du^5_5BzI=u6w;3
zL%J3_a^bDZ1^%07p-F>vq?PBy%Kb>4RTrDD5^(jWoeMR`g_?X*kgXnI`zKa#e?7B|
z`UaRiJuL)nkS?c={Lu{)H&meogim9o*5>u=;%eJ1);i_{=^+OE8ybj@_2dC|g~qgY
z18UkAJ1Mxn$+D~QEuFHuRWL{{P=hfB3-M%fMWM&ycDpfyJw2M!k7O7WIMglkbKS6f
zM31~1YD}%cB~VMGQ>J?EeygcfHE#kvhj~0YUD0u5dYZCg4J}F16Dz_F0b>zMYJ#!X
zGc!no^YyKpkYw_EfWBX<Z(R@6%)Ll4-qaA4^9WNz3{9OL=TPA(W{tI|;i_*-%Ry2j
z=#~%FK+9vWDcvhVw*?%sR$>u%rq_e4TRT@ClumkF)8!ygNUmb=ZGmi~miY%XAtbzu
zKOzJt8g}4IH9PGQX}e{{&{!@95Q-`5xsa8hL&|c0rHu{K`Rrn5-Y`+FHO2C}HlLuX
z6%4sOD>^@9f<#qa-H8?Z!A2B|7Ne<?Te}U#Oh)tc`U9G&UWXjNueL}AEX5dHd&Q0+
z>wJFMYy!F$Go?@ct8zk`<8=5dGr<8-Sxq)LTK#L4uIZZq>lg%{nf?T|oNp0tSeJ4`
z6GW1vSHmmj#@i05)$Cg2>Bkz<{^iuz+|#|c>mWZu-}cPfFT<fytR@$=hCMyKu`{dT
z)fp!eL?E=bTJI8_Q_I)XlDf1;{{mL4`R&Dt4r!(Rv)fr6Hy}}WD_?V4+MDIAe0s-_
zb+MdYpBXI4PDb~&+<?hBX*~4UL27;zF?Cbt#=%@USB+-0!?y;Tb9;Gq(hVWeH0$<<
zqnoKuS_@_P&vUQ?^LvbFTtF<JPjIn8Cv>bd>kZDX?q;^#z;}w7ib?AERxy@Sgs;1y
zv#nH+Dm%Ab4Bwt&HJ`$q!R6&>ba{1iKbhAz1YT%kL+eo8=YChMvhdi4HZ13pyBlo7
z<>mG5{d7?)-B7-mO6jn^2F_z0TcB>t6Uj+}?5ts$IkYHWt@6CafXAk99jVx&A<acQ
z)|!)u7@p;>4Yo@dOBVOic0l-A&-wCLU^8y)srA9K30dQbh0~$Ape`cW@@)2`jxK8^
zY#wPvHCrMci{)~$AyCH{a^@pm`xaM5P`XfQ1}C@m3OFL$e3r9?F<W4Gn4+)@Xj9*B
z#vh+9Z}hn9M6E=J0rMVCi=kTiiV37g?@G($X7p)^l}hzH44vCU8SE|Pi%ah7VBOY4
z(Y$TKzJ<J=gNJ^gBA_sfu}}9Z=354HEKK*k*S!&$B(%S5KF_V06KimjU+smdwE?Gg
zgdpm?(O%cKDWC4sWA<tteL1ZS8q{JQAFM=bj{|J2N93s?wEmXoYT6f&Frpd|c-T!u
ziY5O_c}uj8QS9VyM?+Yct5nP{S?!(6X?_!#tzrwL>F*>WhR1#kQn!PdHjbvEG>Eg6
za&cUBIx7Ui7Nd5UG?cPdOsvfXtY_O>k;TDR=r**Z#iOn{fh_3HFQG@7fUP~|*Nyv3
zm|*nHp<L60_?QgY)~+u%#DO&~N57Ny&1rSc0&-Q%YU02qI}S3}mKsA$V2IT#(%waT
zM}Bc>r(PbN=FJskC)cgr_hNEx<?=!Wa<f{;!UIk2=zK+l&cEGIwlV9Sx3Y>kM6-4H
zw}kS%zn%W5Rj*p!4(paHTDzry@i<V6jSX~=AvXB5dkPaAu0PcM$!Ax?7t0Oo3y|4f
zJKYo-wVK#@?yf6Ydzq`?_#U0kPHI`!4dXif)4Hv2U@CNSb=I$u@;y*I@T+O}<m`G<
z6OYD42dBN-u!rgB?((s)+BT)uun@ero7#M<PVe;m@)jcOc{wa8^5uMb2MPQAj+n8j
zt@e2zq%dIviwz*cUbdkqR<P9%%<2r9q`PKPNbF?3U)$2583E1jPa9NXr+0EXJcp@|
z>+9>Q%hCDS=}GSc;YCTUw9_A)o?VQt$~Fv7s~NVkjQH)^(R(>jA>P{d(sr`!9R@k<
zG|f7lEUQ~N!3)38t2A?MXp!p&{<7(vEo<E3og190wYuK0Ev{;H*3NZ(xG!d>#tub5
zsDrsyku<3hdq<Y!cf(rC7T^B=<E&c~aLKP4)cUTZN$aLLU|{!QSm<3_-txV)Uqd1J
zz2lbfHWf>4)d(UoIn#47o1p#OJ@1^^`QebEeFW)1^3_TR?9hGkK^yG-J4aSy$f36$
ziygp_`taxKx_0sD{*8U{5Ympd4AOZ#Ir#$j;oD(5*REpVNDGJX@F=|ih%jC*hrNyz
z<j)bM!!`WO*dMp7KEES-IlllhJrN2u(F;eFV=vrJlA+p?u4D(~=jGGO|KElqo%34R
zfS7B;zVip_E$Kj~&qt1|^X25yNTfbc<u46PI=GsZ(JexR@^o?NQMuKA2njSMlN77P
z^ycE^1B+ByE!}Vr6Wtrq!(r*c4y&g()M-Ah37M6>0)F%5Vs>{kIv);TC;D!gA8rEs
zFmI-P*!ySRoKvH-d5_iBY&apruQ@I9)nYN5&8E}I-AJw(Iu>R}hnse~C&P;?48zyC
zRGuEIYmw=EOw`hW@gdS0zQAo<Z1jPLR62tTSaEQ5eS0^Vl3AVFHZMj`JLd*#0Bdov
z9*EC09<#F?1NQ07bcxF*ie{lGTV71mx}0NRMPa6=w`QcjL`nXx)KV1+?PZ^DoBzJN
zc|u)Pk*+(6d)Q0r8`o+Xa0Te4pXiSk7|n~fis>_~gLE_;)GsrQ=v8MQtbp{kQO(8T
zw%v{h$LNLdxv`oYjEW2K<RBX-AEOl;U}opB4I9rkE?nPG*}jiE=aUVNU)2P@clN#&
zKi&K0*ITPru@lHFYu*as39#;5wB!i;?9~$>cBm@UX8;)s$VIWZc@g8R>}=8y#HkSG
zn`a-2TE~aeYv)H6>f@2eN3E`gba1;_YduA9tq#F`?ziK|>REi;`gV0Lrj237_3GI*
zYd!LfPr5CFLoYC=BhC7a1CmyoV>c4!nI2}NO6A%o`Q6#ejAmz@{`pPKUP^~p8uUyI
zX;fH{=>C#3k~7#|`{H`C5GxMaeAMxosJ*$`^sFXoRV?l<26bydHp6|Y62Oy_!TIP4
zwqJ2O(J!Xg#`iLw3Y!DelNp=!uI6`Far>eJRB~hxu)$Kd-#<ASz|sHE)8(?^UDz%F
zXLVrB!PUiwm#lwehCeO%9!x@A!K#T1ST+HZo_~i^o=;29{cD3o2Os#diT!Et3gMLk
TuM~Ktz$*n_Dey{xHWc`O(cS1K
literal 0
HcmV?d00001
diff --git a/Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec b/Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec
new file mode 100644
index 0000000000..ea070a10cd
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec
@@ -0,0 +1,152 @@
+## @file
+# EFI/Framework Simics platform
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = SimicsOpenBoardPkg
+ PACKAGE_GUID = E6A03E0D-5944-4dc6-9292-090D609EDD3A
+ PACKAGE_VERSION = 0.1
+
+[Includes]
+ Include
+
+[Guids]
+ gBoardModuleTokenSpaceGuid = {0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a, 0xea, 0x71, 0x5f, 0xd3, 0x59, 0xa5}}
+ gSimicsBoardConfigGuid = {0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a, 0xea, 0x71, 0x5f, 0xd3, 0x59, 0xa5}}
+
+[PcdsFixedAtBuild]
+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase|0x0|UINT32|0
+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize|0x0|UINT32|1
+ gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase|0x0|UINT32|0x15
+ gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize|0x0|UINT32|0x16
+
+ #TODO: Remove these two when we integrate new PlatformPei
+ gBoardModuleTokenSpaceGuid.PcdSimicsMemFvBase|0x00800000|UINT32|2
+ gBoardModuleTokenSpaceGuid.PcdSimicsMemFvSize|0x00500000|UINT32|3
+
+ gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase|0x0|UINT32|0x8
+ gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize|0x0|UINT32|0x9
+ gBoardModuleTokenSpaceGuid.PcdSimicsFirmwareFdSize|0x0|UINT32|0xa
+ gBoardModuleTokenSpaceGuid.PcdSimicsFirmwareBlockSize|0|UINT32|0xb
+ gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase|0x0|UINT32|0xc
+ gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase|0x0|UINT32|0xd
+ gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase|0x0|UINT32|0xe
+ gBoardModuleTokenSpaceGuid.PcdSimicsFdBaseAddress|0x0|UINT32|0xf
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesBase|0x0|UINT32|0x11
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesSize|0x0|UINT32|0x12
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|0x0|UINT32|0x13
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamSize|0x0|UINT32|0x14
+ gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageBase|0x0|UINT32|0x18
+ gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageSize|0x0|UINT32|0x19
+ gBoardModuleTokenSpaceGuid.PcdGuidedExtractHandlerTableSize|0x0|UINT32|0x1a
+ gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd|0x0|UINT32|0x1f
+
+[PcdsDynamic, PcdsDynamicEx]
+
+ # TODO: investigate whether next two Pcds are needed
+ gBoardModuleTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|0x28
+ gBoardModuleTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
+ gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0|UINT16|0x1b
+
+ ## The IO port aperture shared by all PCI root bridges.
+ #
+ gBoardModuleTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x22
+ gBoardModuleTokenSpaceGuid.PcdPciIoSize|0x0|UINT64|0x23
+
+ ## The 32-bit MMIO aperture shared by all PCI root bridges.
+ #
+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Base|0x0|UINT64|0x24
+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Size|0x0|UINT64|0x25
+
+ ## The 64-bit MMIO aperture shared by all PCI root bridges.
+ #
+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Base|0x0|UINT64|0x26
+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Size|0x0|UINT64|0x27
+
+[PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx, PcdsPatchableInModule]
+ ## Pcd8259LegacyModeMask defines the default mask value for platform. This value is determined<BR><BR>
+ # 1) If platform only support pure UEFI, value should be set to 0xFFFF or 0xFFFE;
+ # Because only clock interrupt is allowed in legacy mode in pure UEFI platform.<BR>
+ # 2) If platform install CSM and use thunk module:<BR>
+ # a) If thunk call provided by CSM binary requires some legacy interrupt support, the corresponding bit
+ # should be opened as 0.<BR>
+ # For example, if keyboard interfaces provided CSM binary use legacy keyboard interrupt in 8259 bit 1, then
+ # the value should be set to 0xFFFC.<BR>
+ # b) If all thunk call provied by CSM binary do not require legacy interrupt support, value should be set
+ # to 0xFFFF or 0xFFFE.<BR>
+ #
+ # The default value of legacy mode mask could be changed by EFI_LEGACY_8259_PROTOCOL->SetMask(). But it is rarely
+ # need change it except some special cases such as when initializing the CSM binary, it should be set to 0xFFFF to
+ # mask all legacy interrupt. Please restore the original legacy mask value if changing is made for these special case.<BR>
+ # @Prompt 8259 Legacy Mode mask.
+ gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeMask|0xFFFF|UINT16|0x00000001
+
+ ## Pcd8259LegacyModeEdgeLevel defines the default edge level for legacy mode's interrrupt controller.
+ # For the corresponding bits, 0 = Edge triggered and 1 = Level triggered.
+ # @Prompt 8259 Legacy Mode edge level.
+ gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel|0x0000|UINT16|0x00000002
+
+ ## Indicates if we need enable IsaAcpiCom1 device.<BR><BR>
+ # TRUE - Enables IsaAcpiCom1 device.<BR>
+ # FALSE - Doesn't enable IsaAcpiCom1 device.<BR>
+ # @Prompt Enable IsaAcpiCom1 device.
+ gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiCom1Enable|TRUE|BOOLEAN|0x00000003
+
+ ## Indicates if we need enable IsaAcpiCom2 device.<BR><BR>
+ # TRUE - Enables IsaAcpiCom2 device.<BR>
+ # FALSE - Doesn't enable IsaAcpiCom2 device.<BR>
+ # @Prompt Enable IsaAcpiCom12 device.
+ gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiCom2Enable|TRUE|BOOLEAN|0x00000004
+
+ ## Indicates if we need enable IsaAcpiPs2Keyboard device.<BR><BR>
+ # TRUE - Enables IsaAcpiPs2Keyboard device.<BR>
+ # FALSE - Doesn't enable IsaAcpiPs2Keyboard device.<BR>
+ # @Prompt Enable IsaAcpiPs2Keyboard device.
+ gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiPs2KeyboardEnable|TRUE|BOOLEAN|0x00000005
+
+ ## Indicates if we need enable IsaAcpiPs2Mouse device.<BR><BR>
+ # TRUE - Enables IsaAcpiPs2Mouse device.<BR>
+ # FALSE - Doesn't enable IsaAcpiPs2Mouse device.<BR>
+ # @Prompt Enable IsaAcpiPs2Mouse device.
+ gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiPs2MouseEnable|TRUE|BOOLEAN|0x00000006
+
+ ## Indicates if we need enable IsaAcpiFloppyA device.<BR><BR>
+ # TRUE - Enables IsaAcpiFloppyA device.<BR>
+ # FALSE - Doesn't enable IsaAcpiFloppyA device.<BR>
+ # @Prompt Enable IsaAcpiFloppyA device.
+ gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiFloppyAEnable|TRUE|BOOLEAN|0x00000007
+
+ ## Indicates if we need enable IsaAcpiFloppyB device.<BR><BR>
+ # TRUE - Enables IsaAcpiFloppyB device.<BR>
+ # FALSE - Doesn't enable IsaAcpiFloppyB device.<BR>
+ # @Prompt Enable IsaAcpiFloppyB device.
+ gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiFloppyBEnable|TRUE|BOOLEAN|0x00000008
+
+[PcdsFixedAtBuild, PcdsPatchableInModule]
+ ## FFS filename to find the shell application.
+ # @Prompt FFS Name of Shell Application
+ gBoardModuleTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }|VOID*|0x40000004
+
+ ## ISA Bus features to support DMA, SlaveDMA and ISA Memory. <BR><BR>
+ # BIT0 indicates if DMA is supported<BR>
+ # BIT1 indicates if only slave DMA is supported<BR>
+ # BIT2 indicates if ISA memory is supported<BR>
+ # Other BITs are reseved and must be zero.
+ # If more than one features are supported, the different BIT will be enabled at the same time.
+ # @Prompt ISA Bus Features
+ # @Expression 0x80000002 | (gBoardModuleTokenSpaceGuid.PcdIsaBusSupportedFeatures & 0xF8) == 0
+ gBoardModuleTokenSpaceGuid.PcdIsaBusSupportedFeatures|0x05|UINT8|0x00010040
+
+ gBoardModuleTokenSpaceGuid.PcdLogoFile |{ 0x99, 0x8b, 0xB2, 0x7B, 0xBB, 0x61, 0xD5, 0x11, 0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }|VOID*|0x00010037
+
+[Protocols]
+ ##
+ ## IntelFrameworkModulePkg
+ ##
+ gEfiOEMBadgingProtocolGuid = { 0x170E13C0, 0xBF1B, 0x4218, { 0x87, 0x1D, 0x2A, 0xBD, 0xC6, 0xF8, 0x87, 0xBC }}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h
new file mode 100644
index 0000000000..e98aac4676
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h
@@ -0,0 +1,45 @@
+/** @file
+ This is an implementation of the ACPI platform driver.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ACPI_PLATFORM_H_
+#define _ACPI_PLATFORM_H_
+
+//
+// Statements that include other header files
+//
+
+#include <Base.h>
+#include <Uefi.h>
+#include <IndustryStandard/Pci30.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
+#include <Register/Hpet.h>
+#include <Guid/EventGroup.h>
+#include <Guid/GlobalVariable.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BoardAcpiTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/AslUpdateLib.h>
+#include <Library/PciSegmentInfoLib.h>
+
+#include <Protocol/AcpiTable.h>
+#include <Protocol/MpService.h>
+#include <Protocol/PciIo.h>
+
+#include <Register/Cpuid.h>
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.inf
new file mode 100644
index 0000000000..7dfd0832a3
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.inf
@@ -0,0 +1,105 @@
+## @file
+# Component information file for AcpiPlatform module
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = AcpiPlatform
+ FILE_GUID = FC90EB7A-3E0A-483C-A26C-484D36593FF4
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InstallAcpiPlatform
+
+[Sources.common]
+ AcpiPlatform.h
+ AcpiPlatform.c
+ Fadt/Fadt.c
+ Facs/Facs.c
+ Hpet/Hpet.c
+ Wsmt/Wsmt.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ PcAtChipsetPkg/PcAtChipsetPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ BaseLib
+ DebugLib
+ IoLib
+ PcdLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ BaseMemoryLib
+ HobLib
+ PciSegmentInfoLib
+ AslUpdateLib
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
+
+ gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicEnable
+ gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicCount
+ gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicIdBase
+ gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicAddressBase
+ gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicInterruptBase
+ gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuThreadCount
+ gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuCoreCount
+ gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuSocketCount
+
+ gMinPlatformPkgTokenSpaceGuid.PcdFadtPreferredPmProfile
+ gMinPlatformPkgTokenSpaceGuid.PcdFadtIaPcBootArch
+ gMinPlatformPkgTokenSpaceGuid.PcdFadtFlags
+
+ gPcAtChipsetPkgTokenSpaceGuid.PcdHpetBaseAddress
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiEnableSwSmi
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiDisableSwSmi
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1AEventBlockAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1BEventBlockAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1AControlBlockAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1BControlBlockAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm2ControlBlockAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPmTimerBlockAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiGpe0BlockAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiGpe1BlockAddress
+
+ gMinPlatformPkgTokenSpaceGuid.PcdLocalApicAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdIoApicAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdIoApicId
+
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
+ gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuSocketCount
+
+ gMinPlatformPkgTokenSpaceGuid.PcdWsmtProtectionFlags
+
+[Protocols]
+ gEfiAcpiTableProtocolGuid ## CONSUMES
+ gEfiMpServiceProtocolGuid ## CONSUMES
+ gEfiPciIoProtocolGuid ## CONSUMES
+
+[Guids]
+ gEfiGlobalVariableGuid ## CONSUMES
+ gEfiHobListGuid ## CONSUMES
+ gEfiEndOfDxeEventGroupGuid ## CONSUMES
+
+[Depex]
+ gEfiAcpiTableProtocolGuid AND
+ gEfiMpServiceProtocolGuid AND
+ gEfiPciRootBridgeIoProtocolGuid AND
+ gEfiVariableArchProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid
+
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qemu.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qemu.h
new file mode 100644
index 0000000000..f6ef44a14f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qemu.h
@@ -0,0 +1,507 @@
+/** @file
+ QEMU Video Controller Driver
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// QEMU Video Controller Driver
+//
+
+#ifndef _QEMU_H_
+#define _QEMU_H_
+
+
+#include <Uefi.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/DriverSupportedEfiVersion.h>
+#include <Protocol/DevicePath.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/TimerLib.h>
+#include <Library/FrameBufferBltLib.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Acpi.h>
+
+#include <Library/S3BootScriptLib.h>
+
+//
+// QEMU Video PCI Configuration Header values
+//
+#define CIRRUS_LOGIC_VENDOR_ID 0x1013
+#define CIRRUS_LOGIC_5430_DEVICE_ID 0x00a8
+#define CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID 0x00a0
+#define CIRRUS_LOGIC_5446_DEVICE_ID 0x00b8
+
+//
+// QEMU Vide Graphical Mode Data
+//
+typedef struct {
+ UINT32 InternalModeIndex; // points into card-specific mode table
+ UINT32 HorizontalResolution;
+ UINT32 VerticalResolution;
+ UINT32 ColorDepth;
+} QEMU_VIDEO_MODE_DATA;
+
+#define PIXEL_RED_SHIFT 0
+#define PIXEL_GREEN_SHIFT 3
+#define PIXEL_BLUE_SHIFT 6
+
+#define PIXEL_RED_MASK (BIT7 | BIT6 | BIT5)
+#define PIXEL_GREEN_MASK (BIT4 | BIT3 | BIT2)
+#define PIXEL_BLUE_MASK (BIT1 | BIT0)
+
+#define PIXEL_TO_COLOR_BYTE(pixel, mask, shift) ((UINT8) ((pixel & mask) << shift))
+#define PIXEL_TO_RED_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel, PIXEL_RED_MASK, PIXEL_RED_SHIFT)
+#define PIXEL_TO_GREEN_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel, PIXEL_GREEN_MASK, PIXEL_GREEN_SHIFT)
+#define PIXEL_TO_BLUE_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel, PIXEL_BLUE_MASK, PIXEL_BLUE_SHIFT)
+
+#define RGB_BYTES_TO_PIXEL(Red, Green, Blue) \
+ (UINT8) ( (((Red) >> PIXEL_RED_SHIFT) & PIXEL_RED_MASK) | \
+ (((Green) >> PIXEL_GREEN_SHIFT) & PIXEL_GREEN_MASK) | \
+ (((Blue) >> PIXEL_BLUE_SHIFT) & PIXEL_BLUE_MASK) )
+
+#define PIXEL24_RED_MASK 0x00ff0000
+#define PIXEL24_GREEN_MASK 0x0000ff00
+#define PIXEL24_BLUE_MASK 0x000000ff
+
+#define GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER 0xffff
+
+//
+// QEMU Video Private Data Structure
+//
+#define QEMU_VIDEO_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('Q', 'V', 'I', 'D')
+
+typedef enum {
+ QEMU_VIDEO_CIRRUS_5430 = 1,
+ QEMU_VIDEO_CIRRUS_5446,
+ QEMU_VIDEO_BOCHS,
+ QEMU_VIDEO_BOCHS_MMIO,
+} QEMU_VIDEO_VARIANT;
+
+typedef struct {
+ UINT8 SubClass;
+ UINT16 VendorId;
+ UINT16 DeviceId;
+ QEMU_VIDEO_VARIANT Variant;
+ CHAR16 *Name;
+} QEMU_VIDEO_CARD;
+
+typedef struct {
+ UINT64 Signature;
+ EFI_HANDLE Handle;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT64 OriginalPciAttributes;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL GraphicsOutput;
+ EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;
+
+ //
+ // The next two fields match the client-visible
+ // EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.MaxMode field.
+ //
+ UINTN MaxMode;
+ QEMU_VIDEO_MODE_DATA *ModeData;
+
+ QEMU_VIDEO_VARIANT Variant;
+ FRAME_BUFFER_CONFIGURE *FrameBufferBltConfigure;
+ UINTN FrameBufferBltConfigureSize;
+} QEMU_VIDEO_PRIVATE_DATA;
+
+///
+/// Card-specific Video Mode structures
+///
+typedef struct {
+ UINT32 Width;
+ UINT32 Height;
+ UINT32 ColorDepth;
+ UINT8 *CrtcSettings;
+ UINT16 *SeqSettings;
+ UINT8 MiscSetting;
+} QEMU_VIDEO_CIRRUS_MODES;
+
+typedef struct {
+ UINT32 Width;
+ UINT32 Height;
+ UINT32 ColorDepth;
+} QEMU_VIDEO_BOCHS_MODES;
+
+#define QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS(a) \
+ CR(a, QEMU_VIDEO_PRIVATE_DATA, GraphicsOutput, QEMU_VIDEO_PRIVATE_DATA_SIGNATURE)
+
+
+//
+// Global Variables
+//
+extern UINT8 AttributeController[];
+extern UINT8 GraphicsController[];
+extern UINT8 Crtc_640_480_256_60[];
+extern UINT16 Seq_640_480_256_60[];
+extern UINT8 Crtc_800_600_256_60[];
+extern UINT16 Seq_800_600_256_60[];
+extern UINT8 Crtc_1024_768_256_60[];
+extern UINT16 Seq_1024_768_256_60[];
+extern QEMU_VIDEO_CIRRUS_MODES QemuVideoCirrusModes[];
+extern QEMU_VIDEO_BOCHS_MODES QemuVideoBochsModes[];
+extern EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gQemuVideoComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gQemuVideoComponentName2;
+extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gQemuVideoDriverSupportedEfiVersion;
+
+//
+// Io Registers defined by VGA
+//
+#define CRTC_ADDRESS_REGISTER 0x3d4
+#define CRTC_DATA_REGISTER 0x3d5
+#define SEQ_ADDRESS_REGISTER 0x3c4
+#define SEQ_DATA_REGISTER 0x3c5
+#define GRAPH_ADDRESS_REGISTER 0x3ce
+#define GRAPH_DATA_REGISTER 0x3cf
+#define ATT_ADDRESS_REGISTER 0x3c0
+#define MISC_OUTPUT_REGISTER 0x3c2
+#define INPUT_STATUS_1_REGISTER 0x3da
+#define DAC_PIXEL_MASK_REGISTER 0x3c6
+#define PALETTE_INDEX_REGISTER 0x3c8
+#define PALETTE_DATA_REGISTER 0x3c9
+
+#define VBE_DISPI_IOPORT_INDEX 0x01CE
+#define VBE_DISPI_IOPORT_DATA 0x01D0
+
+#define VBE_DISPI_INDEX_ID 0x0
+#define VBE_DISPI_INDEX_XRES 0x1
+#define VBE_DISPI_INDEX_YRES 0x2
+#define VBE_DISPI_INDEX_BPP 0x3
+#define VBE_DISPI_INDEX_ENABLE 0x4
+#define VBE_DISPI_INDEX_BANK 0x5
+#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
+#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
+#define VBE_DISPI_INDEX_X_OFFSET 0x8
+#define VBE_DISPI_INDEX_Y_OFFSET 0x9
+#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa
+
+#define VBE_DISPI_ID0 0xB0C0
+#define VBE_DISPI_ID1 0xB0C1
+#define VBE_DISPI_ID2 0xB0C2
+#define VBE_DISPI_ID3 0xB0C3
+#define VBE_DISPI_ID4 0xB0C4
+#define VBE_DISPI_ID5 0xB0C5
+
+#define VBE_DISPI_DISABLED 0x00
+#define VBE_DISPI_ENABLED 0x01
+#define VBE_DISPI_GETCAPS 0x02
+#define VBE_DISPI_8BIT_DAC 0x20
+#define VBE_DISPI_LFB_ENABLED 0x40
+#define VBE_DISPI_NOCLEARMEM 0x80
+
+//
+// Graphics Output Hardware abstraction internal worker functions
+//
+EFI_STATUS
+QemuVideoGraphicsOutputConstructor (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ );
+
+EFI_STATUS
+QemuVideoGraphicsOutputDestructor (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ );
+
+
+//
+// EFI_DRIVER_BINDING_PROTOCOL Protocol Interface
+//
+/**
+ TODO: Add function description
+
+ @param This TODO: add argument description
+ @param Controller TODO: add argument description
+ @param RemainingDevicePath TODO: add argument description
+
+ TODO: add return values
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoControllerDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ TODO: Add function description
+
+ @param This TODO: add argument description
+ @param Controller TODO: add argument description
+ @param RemainingDevicePath TODO: add argument description
+
+ TODO: add return values
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoControllerDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ TODO: Add function description
+
+ @param This TODO: add argument description
+ @param Controller TODO: add argument description
+ @param NumberOfChildren TODO: add argument description
+ @param ChildHandleBuffer TODO: add argument description
+
+ TODO: add return values
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoControllerDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+//
+// EFI Component Name Functions
+//
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+
+//
+// Local Function Prototypes
+//
+VOID
+InitializeCirrusGraphicsMode (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ QEMU_VIDEO_CIRRUS_MODES *ModeData
+ );
+
+VOID
+InitializeBochsGraphicsMode (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ QEMU_VIDEO_BOCHS_MODES *ModeData
+ );
+
+VOID
+SetPaletteColor (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Index,
+ UINT8 Red,
+ UINT8 Green,
+ UINT8 Blue
+ );
+
+VOID
+SetDefaultPalette (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ );
+
+VOID
+DrawLogo (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN ScreenWidth,
+ UINTN ScreenHeight
+ );
+
+VOID
+outb (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Address,
+ UINT8 Data
+ );
+
+VOID
+outw (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Address,
+ UINT16 Data
+ );
+
+UINT8
+inb (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Address
+ );
+
+UINT16
+inw (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Address
+ );
+
+VOID
+BochsWrite (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINT16 Reg,
+ UINT16 Data
+ );
+
+UINT16
+BochsRead (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINT16 Reg
+ );
+
+VOID
+VgaOutb (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Reg,
+ UINT8 Data
+ );
+
+EFI_STATUS
+QemuVideoCirrusModeSetup (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ );
+
+EFI_STATUS
+QemuVideoBochsModeSetup (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ BOOLEAN IsQxl
+ );
+
+VOID
+InstallVbeShim (
+ IN CONST CHAR16 *CardName,
+ IN EFI_PHYSICAL_ADDRESS FrameBufferBase
+ );
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
new file mode 100644
index 0000000000..4143487366
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
@@ -0,0 +1,74 @@
+## @file
+# This driver is a sample implementation of the Graphics Output Protocol for
+# the QEMU (Cirrus Logic 5446) video controller.
+#
+# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = QemuVideoDxe
+ FILE_GUID = e3752948-b9a1-4770-90c4-df41c38986be
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializeQemuVideo
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+# DRIVER_BINDING = gQemuVideoDriverBinding
+# COMPONENT_NAME = gQemuVideoComponentName
+#
+
+[Sources.common]
+ ComponentName.c
+ Driver.c
+ DriverSupportedEfiVersion.c
+ Gop.c
+ Initialize.c
+ Qemu.h
+
+[Sources.Ia32, Sources.X64]
+ VbeShim.c
+ VbeShim.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ OptionRomPkg/OptionRomPkg.dec
+ OvmfPkg/OvmfPkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ FrameBufferBltLib
+ DebugLib
+ DevicePathLib
+ MemoryAllocationLib
+ PcdLib
+ PciLib
+ PrintLib
+ TimerLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+ S3BootScriptLib
+
+[Protocols]
+ gEfiDriverSupportedEfiVersionProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+ gEfiGraphicsOutputProtocolGuid # PROTOCOL BY_START
+ gEfiDevicePathProtocolGuid # PROTOCOL BY_START
+ gEfiPciIoProtocolGuid # PROTOCOL TO_START
+ gEfiDxeSmmReadyToLockProtocolGuid
+
+[Pcd]
+ gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion
+ gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
+ gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm
new file mode 100644
index 0000000000..a82077e2d9
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm
@@ -0,0 +1,279 @@
+; @file
+; A minimal Int10h stub that allows the Windows 2008 R2 SP1 UEFI guest's buggy,
+; default VGA driver to switch to 1024x768x32, on the stdvga and QXL video
+; cards of QEMU.
+;
+; Copyright (C) 2014, Red Hat, Inc.
+; Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+
+; enable this macro for debug messages
+;%define DEBUG
+
+%macro DebugLog 1
+%ifdef DEBUG
+ push si
+ mov si, %1
+ call PrintStringSi
+ pop si
+%endif
+%endmacro
+
+
+BITS 16
+ORG 0
+
+VbeInfo:
+TIMES 256 nop
+
+VbeModeInfo:
+TIMES 256 nop
+
+
+Handler:
+ cmp ax, 0x4f00
+ je GetInfo
+ cmp ax, 0x4f01
+ je GetModeInfo
+ cmp ax, 0x4f02
+ je SetMode
+ cmp ax, 0x4f03
+ je GetMode
+ cmp ax, 0x4f10
+ je GetPmCapabilities
+ cmp ax, 0x4f15
+ je ReadEdid
+ cmp ah, 0x00
+ je SetModeLegacy
+ DebugLog StrUnkownFunction
+Hang:
+ jmp Hang
+
+
+GetInfo:
+ push es
+ push di
+ push ds
+ push si
+ push cx
+
+ DebugLog StrEnterGetInfo
+
+ ; target (es:di) set on input
+ push cs
+ pop ds
+ mov si, VbeInfo
+ ; source (ds:si) set now
+
+ mov cx, 256
+ cld
+ rep movsb
+
+ pop cx
+ pop si
+ pop ds
+ pop di
+ pop es
+ jmp Success
+
+
+GetModeInfo:
+ push es
+ push di
+ push ds
+ push si
+ push cx
+
+ DebugLog StrEnterGetModeInfo
+
+ and cx, ~0x4000 ; clear potentially set LFB bit in mode number
+ cmp cx, 0x00f1
+ je KnownMode1
+ DebugLog StrUnkownMode
+ jmp Hang
+KnownMode1:
+ ; target (es:di) set on input
+ push cs
+ pop ds
+ mov si, VbeModeInfo
+ ; source (ds:si) set now
+
+ mov cx, 256
+ cld
+ rep movsb
+
+ pop cx
+ pop si
+ pop ds
+ pop di
+ pop es
+ jmp Success
+
+
+%define ATT_ADDRESS_REGISTER 0x03c0
+%define VBE_DISPI_IOPORT_INDEX 0x01ce
+%define VBE_DISPI_IOPORT_DATA 0x01d0
+
+%define VBE_DISPI_INDEX_XRES 0x1
+%define VBE_DISPI_INDEX_YRES 0x2
+%define VBE_DISPI_INDEX_BPP 0x3
+%define VBE_DISPI_INDEX_ENABLE 0x4
+%define VBE_DISPI_INDEX_BANK 0x5
+%define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
+%define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
+%define VBE_DISPI_INDEX_X_OFFSET 0x8
+%define VBE_DISPI_INDEX_Y_OFFSET 0x9
+
+%define VBE_DISPI_ENABLED 0x01
+%define VBE_DISPI_LFB_ENABLED 0x40
+
+%macro BochsWrite 2
+ push dx
+ push ax
+
+ mov dx, VBE_DISPI_IOPORT_INDEX
+ mov ax, %1
+ out dx, ax
+
+ mov dx, VBE_DISPI_IOPORT_DATA
+ mov ax, %2
+ out dx, ax
+
+ pop ax
+ pop dx
+%endmacro
+
+SetMode:
+ push dx
+ push ax
+
+ DebugLog StrEnterSetMode
+
+ cmp bx, 0x40f1
+ je KnownMode2
+ DebugLog StrUnkownMode
+ jmp Hang
+KnownMode2:
+
+ ; unblank
+ mov dx, ATT_ADDRESS_REGISTER
+ mov al, 0x20
+ out dx, al
+
+ BochsWrite VBE_DISPI_INDEX_ENABLE, 0
+ BochsWrite VBE_DISPI_INDEX_BANK, 0
+ BochsWrite VBE_DISPI_INDEX_X_OFFSET, 0
+ BochsWrite VBE_DISPI_INDEX_Y_OFFSET, 0
+ BochsWrite VBE_DISPI_INDEX_BPP, 32
+ BochsWrite VBE_DISPI_INDEX_XRES, 1024
+ BochsWrite VBE_DISPI_INDEX_VIRT_WIDTH, 1024
+ BochsWrite VBE_DISPI_INDEX_YRES, 768
+ BochsWrite VBE_DISPI_INDEX_VIRT_HEIGHT, 768
+ BochsWrite VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED
+
+ pop ax
+ pop dx
+ jmp Success
+
+
+GetMode:
+ DebugLog StrEnterGetMode
+ mov bx, 0x40f1
+ jmp Success
+
+
+GetPmCapabilities:
+ DebugLog StrGetPmCapabilities
+ jmp Unsupported
+
+
+ReadEdid:
+ DebugLog StrReadEdid
+ jmp Unsupported
+
+
+SetModeLegacy:
+ DebugLog StrEnterSetModeLegacy
+
+ cmp al, 0x03
+ je KnownMode3
+ cmp al, 0x12
+ je KnownMode4
+ DebugLog StrUnkownMode
+ jmp Hang
+KnownMode3:
+ mov al, 0x30
+ jmp SetModeLegacyDone
+KnownMode4:
+ mov al, 0x20
+SetModeLegacyDone:
+ DebugLog StrExitSuccess
+ iret
+
+
+Success:
+ DebugLog StrExitSuccess
+ mov ax, 0x004f
+ iret
+
+
+Unsupported:
+ DebugLog StrExitUnsupported
+ mov ax, 0x014f
+ iret
+
+
+%ifdef DEBUG
+PrintStringSi:
+ pusha
+ push ds ; save original
+ push cs
+ pop ds
+ mov dx, 0x0402
+PrintStringSiLoop:
+ lodsb
+ cmp al, 0
+ je PrintStringSiDone
+ out dx, al
+ jmp PrintStringSiLoop
+PrintStringSiDone:
+ pop ds ; restore original
+ popa
+ ret
+
+
+StrExitSuccess:
+ db 'Exit', 0x0a, 0
+
+StrExitUnsupported:
+ db 'Unsupported', 0x0a, 0
+
+StrUnkownFunction:
+ db 'Unknown Function', 0x0a, 0
+
+StrEnterGetInfo:
+ db 'GetInfo', 0x0a, 0
+
+StrEnterGetModeInfo:
+ db 'GetModeInfo', 0x0a, 0
+
+StrEnterGetMode:
+ db 'GetMode', 0x0a, 0
+
+StrEnterSetMode:
+ db 'SetMode', 0x0a, 0
+
+StrEnterSetModeLegacy:
+ db 'SetModeLegacy', 0x0a, 0
+
+StrUnkownMode:
+ db 'Unkown Mode', 0x0a, 0
+
+StrGetPmCapabilities:
+ db 'GetPmCapabilities', 0x0a, 0
+
+StrReadEdid:
+ db 'ReadEdid', 0x0a, 0
+%endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h
new file mode 100644
index 0000000000..cc9b6e14cd
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h
@@ -0,0 +1,701 @@
+//
+// THIS FILE WAS GENERATED BY "VbeShim.sh". DO NOT EDIT.
+//
+#ifndef _VBE_SHIM_H_
+#define _VBE_SHIM_H_
+STATIC CONST UINT8 mVbeShim[] = {
+ /* 00000000 nop */ 0x90,
+ /* 00000001 nop */ 0x90,
+ /* 00000002 nop */ 0x90,
+ /* 00000003 nop */ 0x90,
+ /* 00000004 nop */ 0x90,
+ /* 00000005 nop */ 0x90,
+ /* 00000006 nop */ 0x90,
+ /* 00000007 nop */ 0x90,
+ /* 00000008 nop */ 0x90,
+ /* 00000009 nop */ 0x90,
+ /* 0000000A nop */ 0x90,
+ /* 0000000B nop */ 0x90,
+ /* 0000000C nop */ 0x90,
+ /* 0000000D nop */ 0x90,
+ /* 0000000E nop */ 0x90,
+ /* 0000000F nop */ 0x90,
+ /* 00000010 nop */ 0x90,
+ /* 00000011 nop */ 0x90,
+ /* 00000012 nop */ 0x90,
+ /* 00000013 nop */ 0x90,
+ /* 00000014 nop */ 0x90,
+ /* 00000015 nop */ 0x90,
+ /* 00000016 nop */ 0x90,
+ /* 00000017 nop */ 0x90,
+ /* 00000018 nop */ 0x90,
+ /* 00000019 nop */ 0x90,
+ /* 0000001A nop */ 0x90,
+ /* 0000001B nop */ 0x90,
+ /* 0000001C nop */ 0x90,
+ /* 0000001D nop */ 0x90,
+ /* 0000001E nop */ 0x90,
+ /* 0000001F nop */ 0x90,
+ /* 00000020 nop */ 0x90,
+ /* 00000021 nop */ 0x90,
+ /* 00000022 nop */ 0x90,
+ /* 00000023 nop */ 0x90,
+ /* 00000024 nop */ 0x90,
+ /* 00000025 nop */ 0x90,
+ /* 00000026 nop */ 0x90,
+ /* 00000027 nop */ 0x90,
+ /* 00000028 nop */ 0x90,
+ /* 00000029 nop */ 0x90,
+ /* 0000002A nop */ 0x90,
+ /* 0000002B nop */ 0x90,
+ /* 0000002C nop */ 0x90,
+ /* 0000002D nop */ 0x90,
+ /* 0000002E nop */ 0x90,
+ /* 0000002F nop */ 0x90,
+ /* 00000030 nop */ 0x90,
+ /* 00000031 nop */ 0x90,
+ /* 00000032 nop */ 0x90,
+ /* 00000033 nop */ 0x90,
+ /* 00000034 nop */ 0x90,
+ /* 00000035 nop */ 0x90,
+ /* 00000036 nop */ 0x90,
+ /* 00000037 nop */ 0x90,
+ /* 00000038 nop */ 0x90,
+ /* 00000039 nop */ 0x90,
+ /* 0000003A nop */ 0x90,
+ /* 0000003B nop */ 0x90,
+ /* 0000003C nop */ 0x90,
+ /* 0000003D nop */ 0x90,
+ /* 0000003E nop */ 0x90,
+ /* 0000003F nop */ 0x90,
+ /* 00000040 nop */ 0x90,
+ /* 00000041 nop */ 0x90,
+ /* 00000042 nop */ 0x90,
+ /* 00000043 nop */ 0x90,
+ /* 00000044 nop */ 0x90,
+ /* 00000045 nop */ 0x90,
+ /* 00000046 nop */ 0x90,
+ /* 00000047 nop */ 0x90,
+ /* 00000048 nop */ 0x90,
+ /* 00000049 nop */ 0x90,
+ /* 0000004A nop */ 0x90,
+ /* 0000004B nop */ 0x90,
+ /* 0000004C nop */ 0x90,
+ /* 0000004D nop */ 0x90,
+ /* 0000004E nop */ 0x90,
+ /* 0000004F nop */ 0x90,
+ /* 00000050 nop */ 0x90,
+ /* 00000051 nop */ 0x90,
+ /* 00000052 nop */ 0x90,
+ /* 00000053 nop */ 0x90,
+ /* 00000054 nop */ 0x90,
+ /* 00000055 nop */ 0x90,
+ /* 00000056 nop */ 0x90,
+ /* 00000057 nop */ 0x90,
+ /* 00000058 nop */ 0x90,
+ /* 00000059 nop */ 0x90,
+ /* 0000005A nop */ 0x90,
+ /* 0000005B nop */ 0x90,
+ /* 0000005C nop */ 0x90,
+ /* 0000005D nop */ 0x90,
+ /* 0000005E nop */ 0x90,
+ /* 0000005F nop */ 0x90,
+ /* 00000060 nop */ 0x90,
+ /* 00000061 nop */ 0x90,
+ /* 00000062 nop */ 0x90,
+ /* 00000063 nop */ 0x90,
+ /* 00000064 nop */ 0x90,
+ /* 00000065 nop */ 0x90,
+ /* 00000066 nop */ 0x90,
+ /* 00000067 nop */ 0x90,
+ /* 00000068 nop */ 0x90,
+ /* 00000069 nop */ 0x90,
+ /* 0000006A nop */ 0x90,
+ /* 0000006B nop */ 0x90,
+ /* 0000006C nop */ 0x90,
+ /* 0000006D nop */ 0x90,
+ /* 0000006E nop */ 0x90,
+ /* 0000006F nop */ 0x90,
+ /* 00000070 nop */ 0x90,
+ /* 00000071 nop */ 0x90,
+ /* 00000072 nop */ 0x90,
+ /* 00000073 nop */ 0x90,
+ /* 00000074 nop */ 0x90,
+ /* 00000075 nop */ 0x90,
+ /* 00000076 nop */ 0x90,
+ /* 00000077 nop */ 0x90,
+ /* 00000078 nop */ 0x90,
+ /* 00000079 nop */ 0x90,
+ /* 0000007A nop */ 0x90,
+ /* 0000007B nop */ 0x90,
+ /* 0000007C nop */ 0x90,
+ /* 0000007D nop */ 0x90,
+ /* 0000007E nop */ 0x90,
+ /* 0000007F nop */ 0x90,
+ /* 00000080 nop */ 0x90,
+ /* 00000081 nop */ 0x90,
+ /* 00000082 nop */ 0x90,
+ /* 00000083 nop */ 0x90,
+ /* 00000084 nop */ 0x90,
+ /* 00000085 nop */ 0x90,
+ /* 00000086 nop */ 0x90,
+ /* 00000087 nop */ 0x90,
+ /* 00000088 nop */ 0x90,
+ /* 00000089 nop */ 0x90,
+ /* 0000008A nop */ 0x90,
+ /* 0000008B nop */ 0x90,
+ /* 0000008C nop */ 0x90,
+ /* 0000008D nop */ 0x90,
+ /* 0000008E nop */ 0x90,
+ /* 0000008F nop */ 0x90,
+ /* 00000090 nop */ 0x90,
+ /* 00000091 nop */ 0x90,
+ /* 00000092 nop */ 0x90,
+ /* 00000093 nop */ 0x90,
+ /* 00000094 nop */ 0x90,
+ /* 00000095 nop */ 0x90,
+ /* 00000096 nop */ 0x90,
+ /* 00000097 nop */ 0x90,
+ /* 00000098 nop */ 0x90,
+ /* 00000099 nop */ 0x90,
+ /* 0000009A nop */ 0x90,
+ /* 0000009B nop */ 0x90,
+ /* 0000009C nop */ 0x90,
+ /* 0000009D nop */ 0x90,
+ /* 0000009E nop */ 0x90,
+ /* 0000009F nop */ 0x90,
+ /* 000000A0 nop */ 0x90,
+ /* 000000A1 nop */ 0x90,
+ /* 000000A2 nop */ 0x90,
+ /* 000000A3 nop */ 0x90,
+ /* 000000A4 nop */ 0x90,
+ /* 000000A5 nop */ 0x90,
+ /* 000000A6 nop */ 0x90,
+ /* 000000A7 nop */ 0x90,
+ /* 000000A8 nop */ 0x90,
+ /* 000000A9 nop */ 0x90,
+ /* 000000AA nop */ 0x90,
+ /* 000000AB nop */ 0x90,
+ /* 000000AC nop */ 0x90,
+ /* 000000AD nop */ 0x90,
+ /* 000000AE nop */ 0x90,
+ /* 000000AF nop */ 0x90,
+ /* 000000B0 nop */ 0x90,
+ /* 000000B1 nop */ 0x90,
+ /* 000000B2 nop */ 0x90,
+ /* 000000B3 nop */ 0x90,
+ /* 000000B4 nop */ 0x90,
+ /* 000000B5 nop */ 0x90,
+ /* 000000B6 nop */ 0x90,
+ /* 000000B7 nop */ 0x90,
+ /* 000000B8 nop */ 0x90,
+ /* 000000B9 nop */ 0x90,
+ /* 000000BA nop */ 0x90,
+ /* 000000BB nop */ 0x90,
+ /* 000000BC nop */ 0x90,
+ /* 000000BD nop */ 0x90,
+ /* 000000BE nop */ 0x90,
+ /* 000000BF nop */ 0x90,
+ /* 000000C0 nop */ 0x90,
+ /* 000000C1 nop */ 0x90,
+ /* 000000C2 nop */ 0x90,
+ /* 000000C3 nop */ 0x90,
+ /* 000000C4 nop */ 0x90,
+ /* 000000C5 nop */ 0x90,
+ /* 000000C6 nop */ 0x90,
+ /* 000000C7 nop */ 0x90,
+ /* 000000C8 nop */ 0x90,
+ /* 000000C9 nop */ 0x90,
+ /* 000000CA nop */ 0x90,
+ /* 000000CB nop */ 0x90,
+ /* 000000CC nop */ 0x90,
+ /* 000000CD nop */ 0x90,
+ /* 000000CE nop */ 0x90,
+ /* 000000CF nop */ 0x90,
+ /* 000000D0 nop */ 0x90,
+ /* 000000D1 nop */ 0x90,
+ /* 000000D2 nop */ 0x90,
+ /* 000000D3 nop */ 0x90,
+ /* 000000D4 nop */ 0x90,
+ /* 000000D5 nop */ 0x90,
+ /* 000000D6 nop */ 0x90,
+ /* 000000D7 nop */ 0x90,
+ /* 000000D8 nop */ 0x90,
+ /* 000000D9 nop */ 0x90,
+ /* 000000DA nop */ 0x90,
+ /* 000000DB nop */ 0x90,
+ /* 000000DC nop */ 0x90,
+ /* 000000DD nop */ 0x90,
+ /* 000000DE nop */ 0x90,
+ /* 000000DF nop */ 0x90,
+ /* 000000E0 nop */ 0x90,
+ /* 000000E1 nop */ 0x90,
+ /* 000000E2 nop */ 0x90,
+ /* 000000E3 nop */ 0x90,
+ /* 000000E4 nop */ 0x90,
+ /* 000000E5 nop */ 0x90,
+ /* 000000E6 nop */ 0x90,
+ /* 000000E7 nop */ 0x90,
+ /* 000000E8 nop */ 0x90,
+ /* 000000E9 nop */ 0x90,
+ /* 000000EA nop */ 0x90,
+ /* 000000EB nop */ 0x90,
+ /* 000000EC nop */ 0x90,
+ /* 000000ED nop */ 0x90,
+ /* 000000EE nop */ 0x90,
+ /* 000000EF nop */ 0x90,
+ /* 000000F0 nop */ 0x90,
+ /* 000000F1 nop */ 0x90,
+ /* 000000F2 nop */ 0x90,
+ /* 000000F3 nop */ 0x90,
+ /* 000000F4 nop */ 0x90,
+ /* 000000F5 nop */ 0x90,
+ /* 000000F6 nop */ 0x90,
+ /* 000000F7 nop */ 0x90,
+ /* 000000F8 nop */ 0x90,
+ /* 000000F9 nop */ 0x90,
+ /* 000000FA nop */ 0x90,
+ /* 000000FB nop */ 0x90,
+ /* 000000FC nop */ 0x90,
+ /* 000000FD nop */ 0x90,
+ /* 000000FE nop */ 0x90,
+ /* 000000FF nop */ 0x90,
+ /* 00000100 nop */ 0x90,
+ /* 00000101 nop */ 0x90,
+ /* 00000102 nop */ 0x90,
+ /* 00000103 nop */ 0x90,
+ /* 00000104 nop */ 0x90,
+ /* 00000105 nop */ 0x90,
+ /* 00000106 nop */ 0x90,
+ /* 00000107 nop */ 0x90,
+ /* 00000108 nop */ 0x90,
+ /* 00000109 nop */ 0x90,
+ /* 0000010A nop */ 0x90,
+ /* 0000010B nop */ 0x90,
+ /* 0000010C nop */ 0x90,
+ /* 0000010D nop */ 0x90,
+ /* 0000010E nop */ 0x90,
+ /* 0000010F nop */ 0x90,
+ /* 00000110 nop */ 0x90,
+ /* 00000111 nop */ 0x90,
+ /* 00000112 nop */ 0x90,
+ /* 00000113 nop */ 0x90,
+ /* 00000114 nop */ 0x90,
+ /* 00000115 nop */ 0x90,
+ /* 00000116 nop */ 0x90,
+ /* 00000117 nop */ 0x90,
+ /* 00000118 nop */ 0x90,
+ /* 00000119 nop */ 0x90,
+ /* 0000011A nop */ 0x90,
+ /* 0000011B nop */ 0x90,
+ /* 0000011C nop */ 0x90,
+ /* 0000011D nop */ 0x90,
+ /* 0000011E nop */ 0x90,
+ /* 0000011F nop */ 0x90,
+ /* 00000120 nop */ 0x90,
+ /* 00000121 nop */ 0x90,
+ /* 00000122 nop */ 0x90,
+ /* 00000123 nop */ 0x90,
+ /* 00000124 nop */ 0x90,
+ /* 00000125 nop */ 0x90,
+ /* 00000126 nop */ 0x90,
+ /* 00000127 nop */ 0x90,
+ /* 00000128 nop */ 0x90,
+ /* 00000129 nop */ 0x90,
+ /* 0000012A nop */ 0x90,
+ /* 0000012B nop */ 0x90,
+ /* 0000012C nop */ 0x90,
+ /* 0000012D nop */ 0x90,
+ /* 0000012E nop */ 0x90,
+ /* 0000012F nop */ 0x90,
+ /* 00000130 nop */ 0x90,
+ /* 00000131 nop */ 0x90,
+ /* 00000132 nop */ 0x90,
+ /* 00000133 nop */ 0x90,
+ /* 00000134 nop */ 0x90,
+ /* 00000135 nop */ 0x90,
+ /* 00000136 nop */ 0x90,
+ /* 00000137 nop */ 0x90,
+ /* 00000138 nop */ 0x90,
+ /* 00000139 nop */ 0x90,
+ /* 0000013A nop */ 0x90,
+ /* 0000013B nop */ 0x90,
+ /* 0000013C nop */ 0x90,
+ /* 0000013D nop */ 0x90,
+ /* 0000013E nop */ 0x90,
+ /* 0000013F nop */ 0x90,
+ /* 00000140 nop */ 0x90,
+ /* 00000141 nop */ 0x90,
+ /* 00000142 nop */ 0x90,
+ /* 00000143 nop */ 0x90,
+ /* 00000144 nop */ 0x90,
+ /* 00000145 nop */ 0x90,
+ /* 00000146 nop */ 0x90,
+ /* 00000147 nop */ 0x90,
+ /* 00000148 nop */ 0x90,
+ /* 00000149 nop */ 0x90,
+ /* 0000014A nop */ 0x90,
+ /* 0000014B nop */ 0x90,
+ /* 0000014C nop */ 0x90,
+ /* 0000014D nop */ 0x90,
+ /* 0000014E nop */ 0x90,
+ /* 0000014F nop */ 0x90,
+ /* 00000150 nop */ 0x90,
+ /* 00000151 nop */ 0x90,
+ /* 00000152 nop */ 0x90,
+ /* 00000153 nop */ 0x90,
+ /* 00000154 nop */ 0x90,
+ /* 00000155 nop */ 0x90,
+ /* 00000156 nop */ 0x90,
+ /* 00000157 nop */ 0x90,
+ /* 00000158 nop */ 0x90,
+ /* 00000159 nop */ 0x90,
+ /* 0000015A nop */ 0x90,
+ /* 0000015B nop */ 0x90,
+ /* 0000015C nop */ 0x90,
+ /* 0000015D nop */ 0x90,
+ /* 0000015E nop */ 0x90,
+ /* 0000015F nop */ 0x90,
+ /* 00000160 nop */ 0x90,
+ /* 00000161 nop */ 0x90,
+ /* 00000162 nop */ 0x90,
+ /* 00000163 nop */ 0x90,
+ /* 00000164 nop */ 0x90,
+ /* 00000165 nop */ 0x90,
+ /* 00000166 nop */ 0x90,
+ /* 00000167 nop */ 0x90,
+ /* 00000168 nop */ 0x90,
+ /* 00000169 nop */ 0x90,
+ /* 0000016A nop */ 0x90,
+ /* 0000016B nop */ 0x90,
+ /* 0000016C nop */ 0x90,
+ /* 0000016D nop */ 0x90,
+ /* 0000016E nop */ 0x90,
+ /* 0000016F nop */ 0x90,
+ /* 00000170 nop */ 0x90,
+ /* 00000171 nop */ 0x90,
+ /* 00000172 nop */ 0x90,
+ /* 00000173 nop */ 0x90,
+ /* 00000174 nop */ 0x90,
+ /* 00000175 nop */ 0x90,
+ /* 00000176 nop */ 0x90,
+ /* 00000177 nop */ 0x90,
+ /* 00000178 nop */ 0x90,
+ /* 00000179 nop */ 0x90,
+ /* 0000017A nop */ 0x90,
+ /* 0000017B nop */ 0x90,
+ /* 0000017C nop */ 0x90,
+ /* 0000017D nop */ 0x90,
+ /* 0000017E nop */ 0x90,
+ /* 0000017F nop */ 0x90,
+ /* 00000180 nop */ 0x90,
+ /* 00000181 nop */ 0x90,
+ /* 00000182 nop */ 0x90,
+ /* 00000183 nop */ 0x90,
+ /* 00000184 nop */ 0x90,
+ /* 00000185 nop */ 0x90,
+ /* 00000186 nop */ 0x90,
+ /* 00000187 nop */ 0x90,
+ /* 00000188 nop */ 0x90,
+ /* 00000189 nop */ 0x90,
+ /* 0000018A nop */ 0x90,
+ /* 0000018B nop */ 0x90,
+ /* 0000018C nop */ 0x90,
+ /* 0000018D nop */ 0x90,
+ /* 0000018E nop */ 0x90,
+ /* 0000018F nop */ 0x90,
+ /* 00000190 nop */ 0x90,
+ /* 00000191 nop */ 0x90,
+ /* 00000192 nop */ 0x90,
+ /* 00000193 nop */ 0x90,
+ /* 00000194 nop */ 0x90,
+ /* 00000195 nop */ 0x90,
+ /* 00000196 nop */ 0x90,
+ /* 00000197 nop */ 0x90,
+ /* 00000198 nop */ 0x90,
+ /* 00000199 nop */ 0x90,
+ /* 0000019A nop */ 0x90,
+ /* 0000019B nop */ 0x90,
+ /* 0000019C nop */ 0x90,
+ /* 0000019D nop */ 0x90,
+ /* 0000019E nop */ 0x90,
+ /* 0000019F nop */ 0x90,
+ /* 000001A0 nop */ 0x90,
+ /* 000001A1 nop */ 0x90,
+ /* 000001A2 nop */ 0x90,
+ /* 000001A3 nop */ 0x90,
+ /* 000001A4 nop */ 0x90,
+ /* 000001A5 nop */ 0x90,
+ /* 000001A6 nop */ 0x90,
+ /* 000001A7 nop */ 0x90,
+ /* 000001A8 nop */ 0x90,
+ /* 000001A9 nop */ 0x90,
+ /* 000001AA nop */ 0x90,
+ /* 000001AB nop */ 0x90,
+ /* 000001AC nop */ 0x90,
+ /* 000001AD nop */ 0x90,
+ /* 000001AE nop */ 0x90,
+ /* 000001AF nop */ 0x90,
+ /* 000001B0 nop */ 0x90,
+ /* 000001B1 nop */ 0x90,
+ /* 000001B2 nop */ 0x90,
+ /* 000001B3 nop */ 0x90,
+ /* 000001B4 nop */ 0x90,
+ /* 000001B5 nop */ 0x90,
+ /* 000001B6 nop */ 0x90,
+ /* 000001B7 nop */ 0x90,
+ /* 000001B8 nop */ 0x90,
+ /* 000001B9 nop */ 0x90,
+ /* 000001BA nop */ 0x90,
+ /* 000001BB nop */ 0x90,
+ /* 000001BC nop */ 0x90,
+ /* 000001BD nop */ 0x90,
+ /* 000001BE nop */ 0x90,
+ /* 000001BF nop */ 0x90,
+ /* 000001C0 nop */ 0x90,
+ /* 000001C1 nop */ 0x90,
+ /* 000001C2 nop */ 0x90,
+ /* 000001C3 nop */ 0x90,
+ /* 000001C4 nop */ 0x90,
+ /* 000001C5 nop */ 0x90,
+ /* 000001C6 nop */ 0x90,
+ /* 000001C7 nop */ 0x90,
+ /* 000001C8 nop */ 0x90,
+ /* 000001C9 nop */ 0x90,
+ /* 000001CA nop */ 0x90,
+ /* 000001CB nop */ 0x90,
+ /* 000001CC nop */ 0x90,
+ /* 000001CD nop */ 0x90,
+ /* 000001CE nop */ 0x90,
+ /* 000001CF nop */ 0x90,
+ /* 000001D0 nop */ 0x90,
+ /* 000001D1 nop */ 0x90,
+ /* 000001D2 nop */ 0x90,
+ /* 000001D3 nop */ 0x90,
+ /* 000001D4 nop */ 0x90,
+ /* 000001D5 nop */ 0x90,
+ /* 000001D6 nop */ 0x90,
+ /* 000001D7 nop */ 0x90,
+ /* 000001D8 nop */ 0x90,
+ /* 000001D9 nop */ 0x90,
+ /* 000001DA nop */ 0x90,
+ /* 000001DB nop */ 0x90,
+ /* 000001DC nop */ 0x90,
+ /* 000001DD nop */ 0x90,
+ /* 000001DE nop */ 0x90,
+ /* 000001DF nop */ 0x90,
+ /* 000001E0 nop */ 0x90,
+ /* 000001E1 nop */ 0x90,
+ /* 000001E2 nop */ 0x90,
+ /* 000001E3 nop */ 0x90,
+ /* 000001E4 nop */ 0x90,
+ /* 000001E5 nop */ 0x90,
+ /* 000001E6 nop */ 0x90,
+ /* 000001E7 nop */ 0x90,
+ /* 000001E8 nop */ 0x90,
+ /* 000001E9 nop */ 0x90,
+ /* 000001EA nop */ 0x90,
+ /* 000001EB nop */ 0x90,
+ /* 000001EC nop */ 0x90,
+ /* 000001ED nop */ 0x90,
+ /* 000001EE nop */ 0x90,
+ /* 000001EF nop */ 0x90,
+ /* 000001F0 nop */ 0x90,
+ /* 000001F1 nop */ 0x90,
+ /* 000001F2 nop */ 0x90,
+ /* 000001F3 nop */ 0x90,
+ /* 000001F4 nop */ 0x90,
+ /* 000001F5 nop */ 0x90,
+ /* 000001F6 nop */ 0x90,
+ /* 000001F7 nop */ 0x90,
+ /* 000001F8 nop */ 0x90,
+ /* 000001F9 nop */ 0x90,
+ /* 000001FA nop */ 0x90,
+ /* 000001FB nop */ 0x90,
+ /* 000001FC nop */ 0x90,
+ /* 000001FD nop */ 0x90,
+ /* 000001FE nop */ 0x90,
+ /* 000001FF nop */ 0x90,
+ /* 00000200 cmp ax,0x4f00 */ 0x3D, 0x00, 0x4F,
+ /* 00000203 jz 0x22d */ 0x74, 0x28,
+ /* 00000205 cmp ax,0x4f01 */ 0x3D, 0x01, 0x4F,
+ /* 00000208 jz 0x245 */ 0x74, 0x3B,
+ /* 0000020A cmp ax,0x4f02 */ 0x3D, 0x02, 0x4F,
+ /* 0000020D jz 0x269 */ 0x74, 0x5A,
+ /* 0000020F cmp ax,0x4f03 */ 0x3D, 0x03, 0x4F,
+ /* 00000212 jz word 0x331 */ 0x0F, 0x84, 0x1B, 0x01,
+ /* 00000216 cmp ax,0x4f10 */ 0x3D, 0x10, 0x4F,
+ /* 00000219 jz word 0x336 */ 0x0F, 0x84, 0x19, 0x01,
+ /* 0000021D cmp ax,0x4f15 */ 0x3D, 0x15, 0x4F,
+ /* 00000220 jz word 0x338 */ 0x0F, 0x84, 0x14, 0x01,
+ /* 00000224 cmp ah,0x0 */ 0x80, 0xFC, 0x00,
+ /* 00000227 jz word 0x33a */ 0x0F, 0x84, 0x0F, 0x01,
+ /* 0000022B jmp short 0x22b */ 0xEB, 0xFE,
+ /* 0000022D push es */ 0x06,
+ /* 0000022E push di */ 0x57,
+ /* 0000022F push ds */ 0x1E,
+ /* 00000230 push si */ 0x56,
+ /* 00000231 push cx */ 0x51,
+ /* 00000232 push cs */ 0x0E,
+ /* 00000233 pop ds */ 0x1F,
+ /* 00000234 mov si,0x0 */ 0xBE, 0x00, 0x00,
+ /* 00000237 mov cx,0x100 */ 0xB9, 0x00, 0x01,
+ /* 0000023A cld */ 0xFC,
+ /* 0000023B rep movsb */ 0xF3, 0xA4,
+ /* 0000023D pop cx */ 0x59,
+ /* 0000023E pop si */ 0x5E,
+ /* 0000023F pop ds */ 0x1F,
+ /* 00000240 pop di */ 0x5F,
+ /* 00000241 pop es */ 0x07,
+ /* 00000242 jmp word 0x34c */ 0xE9, 0x07, 0x01,
+ /* 00000245 push es */ 0x06,
+ /* 00000246 push di */ 0x57,
+ /* 00000247 push ds */ 0x1E,
+ /* 00000248 push si */ 0x56,
+ /* 00000249 push cx */ 0x51,
+ /* 0000024A and cx,0xbfff */ 0x81, 0xE1, 0xFF, 0xBF,
+ /* 0000024E cmp cx,0xf1 */ 0x81, 0xF9, 0xF1, 0x00,
+ /* 00000252 jz 0x256 */ 0x74, 0x02,
+ /* 00000254 jmp short 0x22b */ 0xEB, 0xD5,
+ /* 00000256 push cs */ 0x0E,
+ /* 00000257 pop ds */ 0x1F,
+ /* 00000258 mov si,0x100 */ 0xBE, 0x00, 0x01,
+ /* 0000025B mov cx,0x100 */ 0xB9, 0x00, 0x01,
+ /* 0000025E cld */ 0xFC,
+ /* 0000025F rep movsb */ 0xF3, 0xA4,
+ /* 00000261 pop cx */ 0x59,
+ /* 00000262 pop si */ 0x5E,
+ /* 00000263 pop ds */ 0x1F,
+ /* 00000264 pop di */ 0x5F,
+ /* 00000265 pop es */ 0x07,
+ /* 00000266 jmp word 0x34c */ 0xE9, 0xE3, 0x00,
+ /* 00000269 push dx */ 0x52,
+ /* 0000026A push ax */ 0x50,
+ /* 0000026B cmp bx,0x40f1 */ 0x81, 0xFB, 0xF1, 0x40,
+ /* 0000026F jz 0x273 */ 0x74, 0x02,
+ /* 00000271 jmp short 0x22b */ 0xEB, 0xB8,
+ /* 00000273 mov dx,0x3c0 */ 0xBA, 0xC0, 0x03,
+ /* 00000276 mov al,0x20 */ 0xB0, 0x20,
+ /* 00000278 out dx,al */ 0xEE,
+ /* 00000279 push dx */ 0x52,
+ /* 0000027A push ax */ 0x50,
+ /* 0000027B mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 0000027E mov ax,0x4 */ 0xB8, 0x04, 0x00,
+ /* 00000281 out dx,ax */ 0xEF,
+ /* 00000282 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 00000285 mov ax,0x0 */ 0xB8, 0x00, 0x00,
+ /* 00000288 out dx,ax */ 0xEF,
+ /* 00000289 pop ax */ 0x58,
+ /* 0000028A pop dx */ 0x5A,
+ /* 0000028B push dx */ 0x52,
+ /* 0000028C push ax */ 0x50,
+ /* 0000028D mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 00000290 mov ax,0x5 */ 0xB8, 0x05, 0x00,
+ /* 00000293 out dx,ax */ 0xEF,
+ /* 00000294 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 00000297 mov ax,0x0 */ 0xB8, 0x00, 0x00,
+ /* 0000029A out dx,ax */ 0xEF,
+ /* 0000029B pop ax */ 0x58,
+ /* 0000029C pop dx */ 0x5A,
+ /* 0000029D push dx */ 0x52,
+ /* 0000029E push ax */ 0x50,
+ /* 0000029F mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 000002A2 mov ax,0x8 */ 0xB8, 0x08, 0x00,
+ /* 000002A5 out dx,ax */ 0xEF,
+ /* 000002A6 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 000002A9 mov ax,0x0 */ 0xB8, 0x00, 0x00,
+ /* 000002AC out dx,ax */ 0xEF,
+ /* 000002AD pop ax */ 0x58,
+ /* 000002AE pop dx */ 0x5A,
+ /* 000002AF push dx */ 0x52,
+ /* 000002B0 push ax */ 0x50,
+ /* 000002B1 mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 000002B4 mov ax,0x9 */ 0xB8, 0x09, 0x00,
+ /* 000002B7 out dx,ax */ 0xEF,
+ /* 000002B8 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 000002BB mov ax,0x0 */ 0xB8, 0x00, 0x00,
+ /* 000002BE out dx,ax */ 0xEF,
+ /* 000002BF pop ax */ 0x58,
+ /* 000002C0 pop dx */ 0x5A,
+ /* 000002C1 push dx */ 0x52,
+ /* 000002C2 push ax */ 0x50,
+ /* 000002C3 mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 000002C6 mov ax,0x3 */ 0xB8, 0x03, 0x00,
+ /* 000002C9 out dx,ax */ 0xEF,
+ /* 000002CA mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 000002CD mov ax,0x20 */ 0xB8, 0x20, 0x00,
+ /* 000002D0 out dx,ax */ 0xEF,
+ /* 000002D1 pop ax */ 0x58,
+ /* 000002D2 pop dx */ 0x5A,
+ /* 000002D3 push dx */ 0x52,
+ /* 000002D4 push ax */ 0x50,
+ /* 000002D5 mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 000002D8 mov ax,0x1 */ 0xB8, 0x01, 0x00,
+ /* 000002DB out dx,ax */ 0xEF,
+ /* 000002DC mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 000002DF mov ax,0x400 */ 0xB8, 0x00, 0x04,
+ /* 000002E2 out dx,ax */ 0xEF,
+ /* 000002E3 pop ax */ 0x58,
+ /* 000002E4 pop dx */ 0x5A,
+ /* 000002E5 push dx */ 0x52,
+ /* 000002E6 push ax */ 0x50,
+ /* 000002E7 mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 000002EA mov ax,0x6 */ 0xB8, 0x06, 0x00,
+ /* 000002ED out dx,ax */ 0xEF,
+ /* 000002EE mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 000002F1 mov ax,0x400 */ 0xB8, 0x00, 0x04,
+ /* 000002F4 out dx,ax */ 0xEF,
+ /* 000002F5 pop ax */ 0x58,
+ /* 000002F6 pop dx */ 0x5A,
+ /* 000002F7 push dx */ 0x52,
+ /* 000002F8 push ax */ 0x50,
+ /* 000002F9 mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 000002FC mov ax,0x2 */ 0xB8, 0x02, 0x00,
+ /* 000002FF out dx,ax */ 0xEF,
+ /* 00000300 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 00000303 mov ax,0x300 */ 0xB8, 0x00, 0x03,
+ /* 00000306 out dx,ax */ 0xEF,
+ /* 00000307 pop ax */ 0x58,
+ /* 00000308 pop dx */ 0x5A,
+ /* 00000309 push dx */ 0x52,
+ /* 0000030A push ax */ 0x50,
+ /* 0000030B mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 0000030E mov ax,0x7 */ 0xB8, 0x07, 0x00,
+ /* 00000311 out dx,ax */ 0xEF,
+ /* 00000312 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 00000315 mov ax,0x300 */ 0xB8, 0x00, 0x03,
+ /* 00000318 out dx,ax */ 0xEF,
+ /* 00000319 pop ax */ 0x58,
+ /* 0000031A pop dx */ 0x5A,
+ /* 0000031B push dx */ 0x52,
+ /* 0000031C push ax */ 0x50,
+ /* 0000031D mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 00000320 mov ax,0x4 */ 0xB8, 0x04, 0x00,
+ /* 00000323 out dx,ax */ 0xEF,
+ /* 00000324 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 00000327 mov ax,0x41 */ 0xB8, 0x41, 0x00,
+ /* 0000032A out dx,ax */ 0xEF,
+ /* 0000032B pop ax */ 0x58,
+ /* 0000032C pop dx */ 0x5A,
+ /* 0000032D pop ax */ 0x58,
+ /* 0000032E pop dx */ 0x5A,
+ /* 0000032F jmp short 0x34c */ 0xEB, 0x1B,
+ /* 00000331 mov bx,0x40f1 */ 0xBB, 0xF1, 0x40,
+ /* 00000334 jmp short 0x34c */ 0xEB, 0x16,
+ /* 00000336 jmp short 0x350 */ 0xEB, 0x18,
+ /* 00000338 jmp short 0x350 */ 0xEB, 0x16,
+ /* 0000033A cmp al,0x3 */ 0x3C, 0x03,
+ /* 0000033C jz 0x345 */ 0x74, 0x07,
+ /* 0000033E cmp al,0x12 */ 0x3C, 0x12,
+ /* 00000340 jz 0x349 */ 0x74, 0x07,
+ /* 00000342 jmp word 0x22b */ 0xE9, 0xE6, 0xFE,
+ /* 00000345 mov al,0x30 */ 0xB0, 0x30,
+ /* 00000347 jmp short 0x34b */ 0xEB, 0x02,
+ /* 00000349 mov al,0x20 */ 0xB0, 0x20,
+ /* 0000034B iretw */ 0xCF,
+ /* 0000034C mov ax,0x4f */ 0xB8, 0x4F, 0x00,
+ /* 0000034F iretw */ 0xCF,
+ /* 00000350 mov ax,0x14f */ 0xB8, 0x4F, 0x01,
+ /* 00000353 iretw */ 0xCF,
+};
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh
new file mode 100644
index 0000000000..7669f8a219
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+###
+# @file
+# Shell script to assemble and dump the fake Int10h handler from NASM source to
+# a C array.
+#
+# Copyright (C) 2014, Red Hat, Inc.
+# Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+###
+
+set -e -u
+
+STEM=$(dirname -- "$0")/$(basename -- "$0" .sh)
+
+#
+# Install exit handler -- remove temporary files.
+#
+exit_handler()
+{
+ rm -f -- "$STEM".bin "$STEM".disasm "$STEM".offsets "$STEM".insns \
+ "$STEM".bytes
+}
+trap exit_handler EXIT
+
+#
+# Assemble the source file.
+#
+nasm -o "$STEM".bin -- "$STEM".asm
+
+#
+# Disassemble it, in order to get a binary dump associated with the source.
+# (ndisasm doesn't recognize the "--" end-of-options delimiter.)
+#
+ndisasm "$STEM".bin >"$STEM".disasm
+
+#
+# Create three files, each with one column of the disassembly.
+#
+# The first column contains the offsets, and it starts the comment.
+#
+cut -c 1-8 -- "$STEM".disasm \
+| sed -e 's,^, /* ,' >"$STEM".offsets
+
+#
+# The second column contains the assembly-language instructions, and it closes
+# the comment. We first pad it to 30 characters.
+#
+cut -c 29- -- "$STEM".disasm \
+| sed -e 's,$, ,' \
+ -e 's,^\(.\{30\}\).*$,\1 */,' >"$STEM".insns
+
+#
+# The third column contains the bytes corresponding to the instruction,
+# represented as C integer constants. First strip trailing whitespace from the
+# middle column of the input disassembly, then process pairs of nibbles.
+#
+cut -c 11-28 -- "$STEM".disasm \
+| sed -e 's, \+$,,' -e 's/\(..\)/ 0x\1,/g' >"$STEM".bytes
+
+#
+# Write the output file, recombining the columns. The output should have CRLF
+# line endings.
+#
+{
+ printf '//\n'
+ printf '// THIS FILE WAS GENERATED BY "%s". DO NOT EDIT.\n' \
+ "$(basename -- "$0")"
+ printf '//\n'
+ printf '#ifndef _VBE_SHIM_H_\n'
+ printf '#define _VBE_SHIM_H_\n'
+ printf 'STATIC CONST UINT8 mVbeShim[] = {\n'
+ paste -d ' ' -- "$STEM".offsets "$STEM".insns "$STEM".bytes
+ printf '};\n'
+ printf '#endif\n'
+} \
+| unix2dos >"$STEM".h
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [edk2-platforms PATCH v2 6/7] SimicsOpenBoardPkg/BoardX58Ich10: Add board module for QSP Build tip
2019-08-28 0:40 [edk2-platforms PATCH v2 0/7] Add Initial QSP MinPlatform Pkg for SIMICS David Wei
` (4 preceding siblings ...)
2019-08-28 0:40 ` [edk2-platforms PATCH v2 5/7] SimicsOpenBoardPkg: Add Overrides modules and Logo image for SIMICS QSP Platform David Wei
@ 2019-08-28 0:40 ` David Wei
2019-08-28 23:13 ` Nate DeSimone
2019-08-28 0:40 ` [edk2-platforms PATCH v2 7/7] Platform/Intel: Add build option for SIMICS QSP Platform David Wei
6 siblings, 1 reply; 16+ messages in thread
From: David Wei @ 2019-08-28 0:40 UTC (permalink / raw)
To: devel
Cc: Hao Wu, Liming Gao, Ankit Sinha, Agyeman Prince,
Kubacki Michael A, Nate DeSimone, Michael D Kinney
Add BoardX58ICH10 module for QSP Build tip
Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../Library/BoardInitLib/PeiBoardInitPostMemLib.c | 44 +++
.../Library/BoardInitLib/PeiBoardInitPreMemLib.c | 110 ++++++++
.../Library/BoardInitLib/PeiX58Ich10Detect.c | 26 ++
.../BoardInitLib/PeiX58Ich10InitPostMemLib.c | 34 +++
.../BoardInitLib/PeiX58Ich10InitPreMemLib.c | 111 ++++++++
.../BoardX58Ich10/DecomprScratchEnd.fdf.inc | 66 +++++
.../BoardInitLib/PeiBoardInitPostMemLib.inf | 36 +++
.../Library/BoardInitLib/PeiBoardInitPreMemLib.inf | 39 +++
.../Library/BoardInitLib/PeiX58Ich10InitLib.h | 16 ++
.../BoardX58Ich10/OpenBoardPkg.dsc | 233 ++++++++++++++++
.../BoardX58Ich10/OpenBoardPkg.fdf | 304 +++++++++++++++++++++
.../BoardX58Ich10/OpenBoardPkg.fdf.inc | 54 ++++
.../BoardX58Ich10/OpenBoardPkgBuildOption.dsc | 78 ++++++
.../BoardX58Ich10/OpenBoardPkgConfig.dsc | 56 ++++
.../BoardX58Ich10/OpenBoardPkgPcd.dsc | 281 +++++++++++++++++++
.../BoardX58Ich10/VarStore.fdf.inc | 53 ++++
.../BoardX58Ich10/build_config.cfg | 31 +++
17 files changed, 1572 insertions(+)
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10Detect.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitPostMemLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitPreMemLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/DecomprScratchEnd.fdf.inc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf.inc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgBuildOption.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgConfig.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgPcd.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/VarStore.fdf.inc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/build_config.cfg
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.c b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.c
new file mode 100644
index 0000000000..5ece8c6e34
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.c
@@ -0,0 +1,44 @@
+/** @file
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardInitLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardInitBeforeSiliconInit (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardInitAfterSiliconInit (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+BoardInitBeforeSiliconInit (
+ VOID
+ )
+{
+ X58Ich10BoardInitBeforeSiliconInit ();
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitAfterSiliconInit (
+ VOID
+ )
+{
+ X58Ich10BoardInitAfterSiliconInit ();
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.c b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.c
new file mode 100644
index 0000000000..d16e649d34
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.c
@@ -0,0 +1,110 @@
+/** @file
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardInitLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardDetect(
+ VOID
+ );
+
+EFI_BOOT_MODE
+EFIAPI
+X58Ich10BoardBootModeDetect (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardDebugInit (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardInitBeforeMemoryInit (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardInitAfterMemoryInit (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+BoardDetect (
+ VOID
+ )
+{
+ X58Ich10BoardDetect ();
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardDebugInit (
+ VOID
+ )
+{
+ X58Ich10BoardDebugInit ();
+ return EFI_SUCCESS;
+}
+
+EFI_BOOT_MODE
+EFIAPI
+BoardBootModeDetect (
+ VOID
+ )
+{
+ return X58Ich10BoardBootModeDetect ();
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitBeforeMemoryInit (
+ VOID
+ )
+{
+ X58Ich10BoardInitBeforeMemoryInit ();
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitAfterMemoryInit (
+ VOID
+ )
+{
+ X58Ich10BoardInitAfterMemoryInit ();
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitBeforeTempRamExit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitAfterTempRamExit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10Detect.c b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10Detect.c
new file mode 100644
index 0000000000..03488ef1f4
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10Detect.c
@@ -0,0 +1,26 @@
+/** @file
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BoardInitLib.h>
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardDetect (
+ VOID
+ )
+{
+ DEBUG ((EFI_D_INFO, "X58Ich10BoardDetect\n"));
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitPostMemLib.c b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitPostMemLib.c
new file mode 100644
index 0000000000..bd6924e269
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitPostMemLib.c
@@ -0,0 +1,34 @@
+/** @file
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+
+#include "PeiX58Ich10InitLib.h"
+EFI_STATUS
+EFIAPI
+X58Ich10BoardInitBeforeSiliconInit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardInitAfterSiliconInit (
+ VOID
+ )
+{
+
+ DEBUG((EFI_D_ERROR, "X58Ich10BoardInitAfterSiliconInit\n"));
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitPreMemLib.c b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitPreMemLib.c
new file mode 100644
index 0000000000..c3a31ed426
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitPreMemLib.c
@@ -0,0 +1,111 @@
+/** @file
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <PiPei.h>
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/BoardInitLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+
+#include "PeiX58Ich10InitLib.h"
+#include <Register/X58Ich10.h>
+/**
+ Reads 8-bits of CMOS data.
+
+ Reads the 8-bits of CMOS data at the location specified by Index.
+ The 8-bit read value is returned.
+
+ @param Index The CMOS location to read.
+
+ @return The value read.
+
+**/
+UINT8
+EFIAPI
+CmosRead8(
+ IN UINTN Index
+ )
+{
+ IoWrite8 (0x70, (UINT8)Index);
+ return IoRead8(0x71);
+}
+
+
+/**
+ Writes 8-bits of CMOS data.
+
+ Writes 8-bits of CMOS data to the location specified by Index
+ with the value specified by Value and returns Value.
+
+ @param Index The CMOS location to write.
+ @param Value The value to write to CMOS.
+
+ @return The value written to CMOS.
+
+**/
+UINT8
+EFIAPI
+CmosWrite8(
+ IN UINTN Index,
+ IN UINT8 Value
+ )
+{
+ IoWrite8 (0x70, (UINT8)Index);
+ IoWrite8 (0x71, Value);
+ return Value;
+}
+
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardInitBeforeMemoryInit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardInitAfterMemoryInit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardDebugInit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_BOOT_MODE
+EFIAPI
+X58Ich10BoardBootModeDetect (
+ VOID
+ )
+{
+ EFI_BOOT_MODE BootMode = BOOT_WITH_FULL_CONFIGURATION;
+
+ DEBUG((EFI_D_INFO, "modeValue = %x\n", IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12)));
+ if (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) == 0x5) {
+ BootMode = BOOT_ON_S3_RESUME;
+ }
+
+ return BootMode;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/DecomprScratchEnd.fdf.inc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/DecomprScratchEnd.fdf.inc
new file mode 100644
index 0000000000..f1eed7819a
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/DecomprScratchEnd.fdf.inc
@@ -0,0 +1,66 @@
+## @file
+# This FDF include file computes the end of the scratch buffer used in
+# DecompressMemFvs() [SimicsX58Pkg/Sec/SecMain.c]. It is based on the decompressed
+# (ie. original) size of the LZMA-compressed section of the one FFS file in
+# the FVMAIN_COMPACT firmware volume.
+#
+# Copyright (C) 2015, Red Hat, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+# The GUID EE4E5898-3914-4259-9D6E-DC7BD79403CF means "LzmaCustomDecompress".
+# The decompressed output will have the following structure (see the file
+# "9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.guided.dummy" in the
+# Build/SimicsX58*/*/FV/Ffs/9E21FD93-9C72-4c15-8C4B-E77F1DB2D792/ directory):
+#
+# Size Contents
+# ------------------- --------------------------------------------------------
+# 4 EFI_COMMON_SECTION_HEADER, stating size 124 (0x7C) and
+# type 0x19 (EFI_SECTION_RAW). The purpose of this section
+# is to pad the start of PEIFV to 128 bytes.
+# 120 Zero bytes (padding).
+#
+# 4 EFI_COMMON_SECTION_HEADER, stating size
+# (PcdSimicsPeiMemFvSize + 4), and type 0x17
+# (EFI_SECTION_FIRMWARE_VOLUME_IMAGE).
+# PcdSimicsPeiMemFvSize PEIFV. Note that the above sizes pad the offset of this
+# object to 128 bytes. See also the "guided.dummy.txt"
+# file in the same directory.
+#
+# 4 EFI_COMMON_SECTION_HEADER, stating size 12 (0xC) and
+# type 0x19 (EFI_SECTION_RAW). The purpose of this section
+# is to pad the start of DXEFV to 16 bytes.
+# 8 Zero bytes (padding).
+#
+# 4 EFI_COMMON_SECTION_HEADER, stating size
+# (PcdSimicsDxeMemFvSize + 4), and type 0x17
+# (EFI_SECTION_FIRMWARE_VOLUME_IMAGE).
+# PcdSimicsDxeMemFvSize DXEFV. Note that the above sizes pad the offset of this
+# object to 16 bytes. See also the "guided.dummy.txt" file
+# in the same directory.
+#
+# The total size after decompression is (128 + PcdSimicsPeiMemFvSize + 16 +
+# PcdSimicsDxeMemFvSize).
+
+DEFINE OUTPUT_SIZE = (128 + gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize + 16 + gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize)
+
+# LzmaCustomDecompressLib uses a constant scratch buffer size of 64KB; see
+# SCRATCH_BUFFER_REQUEST_SIZE in
+# "MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompress.c".
+
+DEFINE DECOMP_SCRATCH_SIZE = 0x00010000
+
+# Note: when we use PcdSimicsDxeMemFvBase in this context, BaseTools have not yet
+# offset it with MEMFD's base address. For that reason we have to do it manually.
+#
+# The calculation below mirrors DecompressMemFvs() [SimicsX58Pkg/Sec/SecMain.c].
+
+DEFINE OUTPUT_BASE = ($(MEMFD_BASE_ADDRESS) + gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase + 0x00100000)
+DEFINE DECOMP_SCRATCH_BASE_UNALIGNED = ($(OUTPUT_BASE) + $(OUTPUT_SIZE))
+DEFINE DECOMP_SCRATCH_BASE_ALIGNMENT = 0x000FFFFF
+DEFINE DECOMP_SCRATCH_BASE_MASK = 0xFFF00000
+DEFINE DECOMP_SCRATCH_BASE = (($(DECOMP_SCRATCH_BASE_UNALIGNED) + $(DECOMP_SCRATCH_BASE_ALIGNMENT)) & $(DECOMP_SCRATCH_BASE_MASK))
+
+SET gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd = $(DECOMP_SCRATCH_BASE) + $(DECOMP_SCRATCH_SIZE)
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.inf b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
new file mode 100644
index 0000000000..a035eb0e50
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
@@ -0,0 +1,36 @@
+## @file
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PeiBoardPostMemInitLib
+ FILE_GUID = 30F407D6-6B92-412A-B2DA-8E73E2B386E6
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = BoardInitLib
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ PcdLib
+
+[Packages]
+ MinPlatformPkg/MinPlatformPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[Sources]
+ PeiX58Ich10InitPostMemLib.c
+ PeiBoardInitPostMemLib.c
+
+[FixedPcd]
+
+[Pcd]
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.inf b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
new file mode 100644
index 0000000000..08a6eb159a
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
@@ -0,0 +1,39 @@
+## @file
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PeiBoardInitPreMemLib
+ FILE_GUID = 73AA24AE-FB20-43F9-A3BA-448953A03A78
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = BoardInitLib
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ PcdLib
+
+[Packages]
+ MinPlatformPkg/MinPlatformPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[Sources]
+ PeiX58Ich10Detect.c
+ PeiX58Ich10InitPreMemLib.c
+ PeiBoardInitPreMemLib.c
+
+[Pcd]
+
+[FixedPcd]
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitLib.h b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitLib.h
new file mode 100644
index 0000000000..93544a838b
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitLib.h
@@ -0,0 +1,16 @@
+/** @file
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_X58Ich10_BOARD_INIT_LIB_H_
+#define _PEI_X58Ich10_BOARD_INIT_LIB_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc
new file mode 100644
index 0000000000..d75d33b494
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc
@@ -0,0 +1,233 @@
+## @file
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ DEFINE PLATFORM_PACKAGE = MinPlatformPkg
+ DEFINE BOARD_NAME = BoardX58Ich10
+ DEFINE BOARD_PKG = SimicsOpenBoardPkg
+ DEFINE SKT_PKG = SimicsX58SktPkg
+ DEFINE PCH_PKG = SimicsIch10Pkg
+ DEFINE DXE_ARCH = X64
+ DEFINE PEI_ARCH = IA32
+
+ PLATFORM_NAME = SimicsX58
+ PLATFORM_GUID = EE8EBB5A-CC95-412f-9987-2AF70F88B69A
+ PLATFORM_VERSION = 0.1
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/SimicsX58Ia32X64
+ SUPPORTED_ARCHITECTURES = IA32|X64
+ BUILD_TARGETS = DEBUG|RELEASE|NOOPT
+ SKUID_IDENTIFIER = DEFAULT
+ FLASH_DEFINITION = $(BOARD_PKG)/$(BOARD_NAME)/OpenBoardPkg.fdf
+
+ DEFINE SMM_REQUIRE = TRUE
+
+ #
+ #PLATFORMX64_ENABLE is set to TRUE when PEI is IA32 and DXE is X64 platform
+ #
+ DEFINE PLATFORMX64_ENABLE = TRUE
+ DEFINE NETWORK_TLS_ENABLE = FALSE
+ DEFINE NETWORK_ISCSI_ENABLE = FALSE
+ DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS = TRUE
+ !include NetworkPkg/NetworkDefines.dsc.inc
+################################################################################
+#
+# SKU Identification section - list of all SKU IDs supported by this Platform.
+#
+################################################################################
+[SkuIds]
+ 0|DEFAULT
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+
+[PcdsFeatureFlag]
+ #
+ # Platform On/Off features are defined here
+ #
+ !include $(BOARD_PKG)/$(BOARD_NAME)/OpenBoardPkgConfig.dsc
+ !include MinPlatformPkg/Include/Dsc/CoreCommonLib.dsc
+ !include $(PCH_PKG)/IchCommonLib.dsc
+
+[LibraryClasses]
+ ReportFvLib|$(BOARD_PKG)/Library/PeiReportFvLib/PeiReportFvLib.inf
+ BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+ SerialPortLib|PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf
+ NvVarsFileLib|$(BOARD_PKG)/Library/NvVarsFileLib/NvVarsFileLib.inf
+ SerializeVariablesLib|$(BOARD_PKG)/Library/SerializeVariablesLib/SerializeVariablesLib.inf
+ DxeLoadLinuxLib|$(BOARD_PKG)/Library/LoadLinuxLib/DxeLoadLinuxLib.inf
+ CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
+
+ TestPointCheckLib|MinPlatformPkg/Test/Library/TestPointCheckLibNull/TestPointCheckLibNull.inf
+ BoardInitLib|MinPlatformPkg/PlatformInit/Library/BoardInitLibNull/BoardInitLibNull.inf
+ SiliconPolicyInitLib|$(BOARD_PKG)/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf
+ SiliconPolicyUpdateLib|$(BOARD_PKG)/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf
+ PciSegmentInfoLib|MinPlatformPkg/Pci/Library/PciSegmentInfoLibSimple/PciSegmentInfoLibSimple.inf
+
+ !include MinPlatformPkg/Include/Dsc/CorePeiLib.dsc
+
+ S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
+ AslUpdateLib|MinPlatformPkg/Acpi/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf
+ LogoLib|$(BOARD_PKG)/Library/DxeLogoLib/DxeLogoLib.inf
+[LibraryClasses.common.SEC]
+ ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf
+
+[LibraryClasses.common.PEI_CORE]
+
+[LibraryClasses.common.PEIM]
+ PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
+ MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+
+[LibraryClasses.IA32]
+!if $(TARGET) == DEBUG
+ TestPointCheckLib|MinPlatformPkg/Test/Library/TestPointCheckLib/PeiTestPointCheckLib.inf
+!endif
+ TestPointLib|MinPlatformPkg/Test/Library/TestPointLib/PeiTestPointLib.inf
+
+ !include MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc
+
+[LibraryClasses.common.DXE_DRIVER]
+ PlatformBootManagerLib|$(BOARD_PKG)/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+
+[LibraryClasses.common.DXE_SMM_DRIVER]
+ SpiFlashCommonLib|$(PCH_PKG)/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
+
+ !include $(BOARD_PKG)/$(BOARD_NAME)/OpenBoardPkgPcd.dsc
+
+[Components.IA32]
+ $(BOARD_PKG)/SecCore/SecMain.inf {
+ <LibraryClasses>
+ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ }
+ !include $(SKT_PKG)/SktPkgPei.dsc
+ !include MinPlatformPkg/Include/Dsc/CorePeiInclude.dsc
+
+ $(BOARD_PKG)/SimicsPei/SimicsPei.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+ }
+# S3 SMM driver
+# UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
+ UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf {
+ <LibraryClasses>
+ LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
+ }
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+ $(SKT_PKG)/Smm/Access/SmmAccessPei.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+ }
+!endif
+ $(PLATFORM_PACKAGE)/PlatformInit/ReportFv/ReportFvPei.inf
+
+ MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPreMem.inf {
+ <LibraryClasses>
+ BoardInitLib|$(BOARD_PKG)/$(BOARD_NAME)/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
+ }
+ MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPostMem.inf {
+ <LibraryClasses>
+ BoardInitLib|$(BOARD_PKG)/$(BOARD_NAME)/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
+ }
+ MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMem.inf
+ MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPostMem.inf
+
+[Components.X64]
+ !include MinPlatformPkg/Include/Dsc/CoreDxeInclude.dsc
+ !include AdvancedFeaturePkg/Include/Dsc/CoreAdvancedDxeInclude.dsc
+
+ MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+
+ MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
+ #
+ # ISA Support
+ #
+ $(BOARD_PKG)/LegacySioDxe/LegacySioDxe.inf
+ MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf
+
+ $(BOARD_PKG)/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+ $(BOARD_PKG)/AcpiTables/AcpiTables.inf
+ #
+ # Video support
+ #
+ $(BOARD_PKG)/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
+
+ MinPlatformPkg/PlatformInit/PlatformInitDxe/PlatformInitDxe.inf
+ MinPlatformPkg/PlatformInit/PlatformInitSmm/PlatformInitSmm.inf
+ $(BOARD_PKG)/SimicsDxe/SimicsDxe.inf
+ MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+ MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
+
+ SimicsIch10SiliconBinPkg/UndiBinary/UndiDxe.inf
+
+ #
+ # Shell
+ #
+ ShellPkg/Application/Shell/Shell.inf {
+ <PcdsFixedAtBuild>
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+ <LibraryClasses>
+ NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
+ ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+ HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+ BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+ ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
+ ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+ }
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+ $(SKT_PKG)/Smm/Access/SmmAccess2Dxe.inf
+ $(PCH_PKG)/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
+ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+ $(PCH_PKG)/Spi/Smm/PchSpiSmm.inf
+ MinPlatformPkg/Flash/SpiFvbService/SpiFvbServiceSmm.inf
+ UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf
+ MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf {
+ <LibraryClasses>
+ LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf
+ }
+!endif
+ MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+ MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+ MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
+ <LibraryClasses>
+ PciHostBridgeLib|$(BOARD_PKG)/Library/PciHostBridgeLib/PciHostBridgeLib.inf
+ }
+ MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
+ UefiCpuPkg/CpuDxe/CpuDxe.inf
+ MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+ MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
+ MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+ MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+ #
+ # ACPI Support
+ #
+ MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
+ $(BOARD_PKG)/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.inf
+
+!if gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosEnable == TRUE
+ AdvancedFeaturePkg/Smbios/SmbiosBasicDxe/SmbiosBasicDxe.inf
+!endif
+
+ !include $(BOARD_PKG)/$(BOARD_NAME)/OpenBoardPkgBuildOption.dsc
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf
new file mode 100644
index 0000000000..bd97f7a3e2
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf
@@ -0,0 +1,304 @@
+## @file
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+!include OpenBoardPkg.fdf.inc
+
+#
+# Build the variable store and the firmware code as one unified flash device
+# image.
+#
+[FD.SIMICSX58IA32X64]
+BaseAddress = $(FW_BASE_ADDRESS)
+Size = $(FW_SIZE)
+ErasePolarity = 1
+BlockSize = $(BLOCK_SIZE)
+NumBlocks = $(FW_BLOCKS)
+
+!include VarStore.fdf.inc
+
+$(VARS_SIZE)|0x00002000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+#NV_FTW_WORKING
+DATA = {
+ # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid =
+ # { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
+ 0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
+ 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95,
+ # Crc:UINT32 #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
+ 0xE2, 0x33, 0xF2, 0x03, 0xFE, 0xFF, 0xFF, 0xFF,
+ # WriteQueueSize: UINT64
+ 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x00040000|0x00040000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+#NV_FTW_SPARE
+
+0x00080000|0x0016C000
+FV = FVMAIN_COMPACT
+
+$(SECFV_OFFSET)|$(SECFV_SIZE)
+FV = FvTempMemorySilicon
+
+#
+# Build the variable store and the firmware code as separate flash device
+# images.
+#
+[FD.SIMICS_VARS]
+BaseAddress = $(FW_BASE_ADDRESS)
+Size = 0x80000
+ErasePolarity = 1
+BlockSize = $(BLOCK_SIZE)
+NumBlocks = 0x80
+
+!include VarStore.fdf.inc
+
+[FD.SIMICS_CODE]
+BaseAddress = $(CODE_BASE_ADDRESS)
+Size = $(CODE_SIZE)
+ErasePolarity = 1
+BlockSize = $(BLOCK_SIZE)
+NumBlocks = $(CODE_BLOCKS)
+
+0x00000000|0x0016C000
+FV = FVMAIN_COMPACT
+
+0x0016C000|$(SECFV_SIZE)
+FV = FvTempMemorySilicon
+
+[FD.MEMFD]
+BaseAddress = $(MEMFD_BASE_ADDRESS)
+Size = 0xB00000
+ErasePolarity = 1
+BlockSize = 0x10000
+NumBlocks = 0xB0
+
+0x000000|0x006000
+gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesBase|gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesSize
+
+0x006000|0x001000
+gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageBase|gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageSize
+
+0x007000|0x001000
+gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gBoardModuleTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+
+0x010000|0x008000
+gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
+
+0x020000|0x0E0000
+gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase|gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize
+FV = FvPreMemory
+
+0x100000|0xA00000
+gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase|gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize
+FV = DXEFV
+
+################################################################################
+
+[FV.FvTempMemorySilicon]
+FvAlignment = 16
+FvForceRebase = TRUE
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+FvNameGuid = 229EEDCE-8E76-4809-B233-EC36BFBF6989
+
+INF RuleOverride=RESET_SECMAIN USE = IA32 $(BOARD_PKG)/SecCore/SecMain.inf
+!include $(SKT_PKG)/SktSecInclude.fdf
+
+[FV.FvPreMemory]
+FvAlignment = 16
+FvForceRebase = TRUE
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+FvNameGuid = 6522280D-28F9-4131-ADC4-F40EBFA45864
+
+##
+# PEI Apriori file example, more PEIM module added later.
+##
+INF MdeModulePkg/Core/Pei/PeiMain.inf
+!include $(SKT_PKG)/SktPreMemoryInclude.fdf
+!include $(PCH_PKG)/IchPreMemoryInclude.fdf
+!include MinPlatformPkg/Include/Fdf/CorePreMemoryInclude.fdf
+INF MinPlatformPkg/PlatformInit/ReportFv/ReportFvPei.inf
+INF MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPreMem.inf
+INF MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMem.inf
+!include MinPlatformPkg/Include/Fdf/CoreSecurityPreMemoryInclude.fdf
+!include AdvancedFeaturePkg/Include/Fdf/CoreAdvancedPreMemoryInclude.fdf
+INF $(BOARD_PKG)/SimicsPei/SimicsPei.inf
+!include $(SKT_PKG)/SktPostMemoryInclude.fdf
+!include $(PCH_PKG)/IchPostMemoryInclude.fdf
+!include MinPlatformPkg/Include/Fdf/CorePostMemoryInclude.fdf
+INF MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPostMem.inf
+INF MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPostMem.inf
+!include MinPlatformPkg/Include/Fdf/CoreSecurityPostMemoryInclude.fdf
+!include AdvancedFeaturePkg/Include/Fdf/CoreAdvancedPostMemoryInclude.fdf
+
+INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
+INF $(SKT_PKG)/Smm/Access/SmmAccessPei.inf
+# S3 SMM PEI driver
+#INF UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
+
+[FV.DXEFV]
+FvNameGuid = EACAB9EA-C3C6-4438-8FD7-2270826DC0BB
+BlockSize = 0x10000
+FvAlignment = 16
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+
+!include MinPlatformPkg/Include/Fdf/CoreUefiBootInclude.fdf
+!include $(SKT_PKG)/SktUefiBootInclude.fdf
+!include $(PCH_PKG)/IchUefiBootInclude.fdf
+
+INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
+INF UefiCpuPkg/CpuDxe/CpuDxe.inf
+
+!include MinPlatformPkg/Include/Fdf/CoreOsBootInclude.fdf
+INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
+INF UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf
+INF MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
+INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+INF MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
+INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+
+INF MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+INF MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+INF MinPlatformPkg/Flash/SpiFvbService/SpiFvbServiceSmm.inf
+INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
+INF $(BOARD_PKG)/LegacySioDxe/LegacySioDxe.inf
+INF MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf
+
+INF $(BOARD_PKG)/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+
+INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
+INF $(BOARD_PKG)/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.inf
+INF RuleOverride=ACPITABLE $(BOARD_PKG)/AcpiTables/AcpiTables.inf
+
+INF $(BOARD_PKG)/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
+INF MinPlatformPkg/PlatformInit/PlatformInitDxe/PlatformInitDxe.inf
+INF MinPlatformPkg/PlatformInit/PlatformInitSmm/PlatformInitSmm.inf
+INF $(BOARD_PKG)/SimicsDxe/SimicsDxe.inf
+
+FILE FREEFORM = 7BB28B99-61BB-11D5-9A5D-0090273FC14D {
+ SECTION RAW = $(BOARD_PKG)/Logo/Logo.bmp
+}
+
+INF ShellPkg/Application/Shell/Shell.inf
+
+#
+# Network modules
+#
+INF SimicsIch10SiliconBinPkg/UndiBinary/UndiDxe.inf
+
+!include AdvancedFeaturePkg/Include/Fdf/CoreAdvancedLateInclude.fdf
+
+!if gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosEnable == TRUE
+ INF AdvancedFeaturePkg/Smbios/SmbiosBasicDxe/SmbiosBasicDxe.inf
+!endif
+
+!include MinPlatformPkg/Include/Fdf/CoreSecurityLateInclude.fdf
+
+[FV.FVMAIN_COMPACT]
+FvNameGuid = 6189987A-DDA6-4060-B313-49168DA9BD46
+FvAlignment = 16
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+
+FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+ SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+ #
+ # These firmware volumes will have files placed in them uncompressed,
+ # and then both firmware volumes will be compressed in a single
+ # compression operation in order to achieve better overall compression.
+ #
+ SECTION FV_IMAGE = FvPreMemory
+ SECTION FV_IMAGE = DXEFV
+ }
+}
+
+!include DecomprScratchEnd.fdf.inc
+
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+
+!include MinPlatformPkg/Include/Fdf/RuleInclude.fdf
+
+[Rule.Common.SEC.RESET_VECTOR]
+ FILE RAW = $(NAMED_GUID) {
+ RAW RAW |.raw
+ }
+
+[Rule.Common.SEC.RESET_SECMAIN]
+ FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ PE32 PE32 Align = 16 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ }
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf.inc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf.inc
new file mode 100644
index 0000000000..9a7368b46c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf.inc
@@ -0,0 +1,54 @@
+## @file
+# FDF include file that defines the main macros and sets the dependent PCDs.
+#
+# Copyright (C) 2014, Red Hat, Inc.
+# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#
+# Default flash size is 2MB.
+#
+# Defining FD_SIZE_2MB on the build command line can override this.
+#
+
+DEFINE BLOCK_SIZE = 0x1000
+DEFINE VARS_SIZE = 0x3e000
+DEFINE VARS_BLOCKS = 0x3e
+
+DEFINE FW_BASE_ADDRESS = 0xFFE00000
+DEFINE FW_SIZE = 0x00200000
+DEFINE FW_BLOCKS = 0x200
+DEFINE CODE_BASE_ADDRESS = 0xFFE80000
+DEFINE CODE_SIZE = 0x00180000
+DEFINE CODE_BLOCKS = 0x180
+DEFINE FVMAIN_SIZE = 0x0016C000
+DEFINE SECFV_OFFSET = 0x001EC000
+DEFINE SECFV_SIZE = 0x14000
+
+
+SET gBoardModuleTokenSpaceGuid.PcdSimicsFdBaseAddress = $(FW_BASE_ADDRESS)
+SET gBoardModuleTokenSpaceGuid.PcdSimicsFirmwareFdSize = $(FW_SIZE)
+SET gBoardModuleTokenSpaceGuid.PcdSimicsFirmwareBlockSize = $(BLOCK_SIZE)
+
+SET gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase = $(FW_BASE_ADDRESS)
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize = 0xE000
+
+SET gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase = gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+SET gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize = $(BLOCK_SIZE)
+
+SET gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase = gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase + gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize = $(BLOCK_SIZE)
+
+SET gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase = gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize = 0x10000
+
+SET gEfiPchTokenSpaceGuid.PcdFlashAreaBaseAddress = 0xFFE00000
+SET gEfiPchTokenSpaceGuid.PcdFlashAreaSize = 0x00200000
+
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress = gEfiPchTokenSpaceGuid.PcdFlashAreaBaseAddress
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize = gEfiPchTokenSpaceGuid.PcdFlashAreaSize
+
+DEFINE MEMFD_BASE_ADDRESS = 0x800000
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgBuildOption.dsc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgBuildOption.dsc
new file mode 100644
index 0000000000..25998b83e7
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgBuildOption.dsc
@@ -0,0 +1,78 @@
+## @file
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[BuildOptions.Common.EDKII]
+# Append build options for EDK and EDKII drivers (= is Append, == is Replace)
+
+ DEFINE EDKII_DSC_FEATURE_BUILD_OPTIONS =
+
+!if $(TARGET) == "DEBUG"
+ DEFINE DEBUG_BUILD_FLAG = -D SERIAL_DBG_MSG=1
+!else
+ DEFINE DEBUG_BUILD_FLAG = -D MDEPKG_NDEBUG -D SILENT_MODE
+!endif
+
+ DEFINE EDKII_DSC_FEATURE_BUILD_OPTIONS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS) $(DEBUG_BUILD_FLAG)
+#
+# PC_BUILD_END
+#
+
+
+ DEFINE EDKII_DSC_FEATURE_BUILD_OPTIONS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+
+
+ *_*_IA32_CC_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_IA32_VFRPP_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_IA32_APP_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_IA32_PP_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_IA32_ASLPP_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_IA32_ASLCC_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+
+ *_*_X64_CC_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_X64_VFRPP_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_X64_APP_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_X64_PP_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_X64_ASLPP_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_X64_ASLCC_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+
+
+
+#
+# Enable source level debugging for RELEASE build
+#
+!if $(TARGET) == "RELEASE"
+ DEFINE EDKII_RELEASE_SRCDBG_ASM_BUILD_OPTIONS = /Zi
+ DEFINE EDKII_RELEASE_SRCDBG_CC_BUILD_OPTIONS = /Zi /Gm
+ DEFINE EDKII_RELEASE_SRCDBG_DLINK_BUILD_OPTIONS = /DEBUG
+
+ MSFT:*_*_*_ASM_FLAGS = $(EDKII_RELEASE_SRCDBG_ASM_BUILD_OPTIONS)
+ MSFT:*_*_*_CC_FLAGS = $(EDKII_RELEASE_SRCDBG_CC_BUILD_OPTIONS)
+ MSFT:*_*_*_DLINK_FLAGS = $(EDKII_RELEASE_SRCDBG_DLINK_BUILD_OPTIONS)
+!endif
+
+
+#
+# Override the existing iasl path in tools_def.template
+#
+# MSFT:*_*_*_ASL_PATH == c:/Iasl/iasl.exe
+
+#
+# Override the VFR compile flags to speed the build time
+#
+
+*_*_*_VFR_FLAGS == -n
+
+# Force PE/COFF sections to be aligned at 4KB boundaries to support page level protection
+#[BuildOptions.common.EDKII.DXE_SMM_DRIVER, BuildOptions.common.EDKII.SMM_CORE]
+# MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+# GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+# Force PE/COFF sections to be aligned at 4KB boundaries to support MemoryAttribute table
+#[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+# MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+# GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgConfig.dsc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgConfig.dsc
new file mode 100644
index 0000000000..75de60e5bc
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgConfig.dsc
@@ -0,0 +1,56 @@
+## @file
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#
+# TRUE is ENABLE. FALSE is DISABLE.
+#
+
+[PcdsFixedAtBuild]
+ gMinPlatformPkgTokenSpaceGuid.PcdBootStage|4
+
+[PcdsFeatureFlag]
+ gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|FALSE
+ gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|FALSE
+ gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|FALSE
+ gMinPlatformPkgTokenSpaceGuid.PcdUefiSecureBootEnable|FALSE
+ gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable|FALSE
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 1
+ gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|TRUE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 2
+ gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|FALSE
+ gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|TRUE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 3
+ gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|FALSE
+ gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|TRUE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 4
+ gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|FALSE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 5
+ gMinPlatformPkgTokenSpaceGuid.PcdUefiSecureBootEnable|TRUE
+ gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable|TRUE
+!endif
+
+ !if $(TARGET) == DEBUG
+ gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable|TRUE
+ !else
+ gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable|FALSE
+ !endif
+
+ gMinPlatformPkgTokenSpaceGuid.PcdPerformanceEnable|FALSE
+
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdNetworkEnable|TRUE
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosEnable|TRUE
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgPcd.dsc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgPcd.dsc
new file mode 100644
index 0000000000..3bf10ee524
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgPcd.dsc
@@ -0,0 +1,281 @@
+## @file
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+[PcdsFeatureFlag.common]
+!if $(TARGET) == RELEASE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
+!else
+ gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE
+!endif
+ # Server doesn't support capsle update on Reset.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|FALSE
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmEnableBspElection|FALSE
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugSupport|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport|FALSE
+
+
+#S3 add
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|TRUE
+#S3 add
+
+ ## This PCD specified whether ACPI SDT protocol is installed.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
+
+[PcdsFeatureFlag.X64]
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard|FALSE
+
+[PcdsFeatureFlag]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdBrowerGrayOutReadOnlyMenu|TRUE
+
+[PcdsDynamicExDefault]
+
+[PcdsFixedAtBuild.common]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|TRUE
+!if $(TARGET) == "RELEASE"
+ gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x03
+!else
+ gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+!endif
+ gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+ gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable|0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x0
+#S3 modified
+ gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnS3Boot|TRUE
+#S3 modified
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x0
+ gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x0
+ gEfiMdePkgTokenSpaceGuid.PcdFSBClock|133333333
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeiStackSize|0x100000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizeNonPopulateCapsule|0x1700000
+
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|10000
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|512
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x4000
+
+ ## Specifies delay value in microseconds after sending out an INIT IPI.
+ # @Prompt Configure delay value after send an INIT IPI
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds|10
+
+ ## Specifies max supported number of Logical Processors.
+ # @Prompt Configure max supported number of Logical Processorss
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|512
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize|0x1000
+!if gMinPlatformPkgTokenSpaceGuid.PcdPerformanceEnable == TRUE
+ gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x1
+!endif
+
+ ## Defines the ACPI register set base address.
+ # The invalid 0xFFFF is as its default value. It must be configured to the real value.
+ # @Prompt ACPI Timer IO Port Address
+ gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddress | 0x0400
+
+ ## Defines the PCI Bus Number of the PCI device that contains the BAR and Enable for ACPI hardware registers.
+ # @Prompt ACPI Hardware PCI Bus Number
+ gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBusNumber | 0x00
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision|0x00000002
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId|0x4C544E49
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision|0x20091013
+
+ ## Defines the PCI Device Number of the PCI device that contains the BAR and Enable for ACPI hardware registers.
+ # The invalid 0xFF is as its default value. It must be configured to the real value.
+ # @Prompt ACPI Hardware PCI Device Number
+ gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciDeviceNumber | 0x1F
+
+ ## Defines the PCI Function Number of the PCI device that contains the BAR and Enable for ACPI hardware registers.
+ # The invalid 0xFF is as its default value. It must be configured to the real value.
+ # @Prompt ACPI Hardware PCI Function Number
+ gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciFunctionNumber | 0x00
+
+ ## Defines the PCI Register Offset of the PCI device that contains the Enable for ACPI hardware registers.
+ # The invalid 0xFFFF is as its default value. It must be configured to the real value.
+ # @Prompt ACPI Hardware PCI Register Offset
+ gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciEnableRegisterOffset |0x0044
+
+ ## Defines the bit mask that must be set to enable the APIC hardware register BAR.
+ # @Prompt ACPI Hardware PCI Bar Enable BitMask
+ gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoBarEnableMask | 0x80
+
+ ## Defines the PCI Register Offset of the PCI device that contains the BAR for ACPI hardware registers.
+ # The invalid 0xFFFF is as its default value. It must be configured to the real value.
+ # @Prompt ACPI Hardware PCI Bar Register Offset
+ gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBarRegisterOffset |0x0040
+
+ ## Defines the offset to the 32-bit Timer Value register that resides within the ACPI BAR.
+ # @Prompt Offset to 32-bit Timer register in ACPI BAR
+ gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiPm1TmrOffset |0x0008
+
+ ## Defines the bit mask to retrieve ACPI IO Port Base Address
+ # @Prompt ACPI IO Port Base Address Mask
+ gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddressMask |0xFFFC
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+
+ gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuThreadCount|4
+ gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuCoreCount|128
+ gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuSocketCount|4
+ gMinPlatformPkgTokenSpaceGuid.PcdLocalApicAddress|0xFEE00000
+ gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicAddressBase|0xFEC01000
+ gMinPlatformPkgTokenSpaceGuid.PcdFadtPreferredPmProfile|0x0
+ gMinPlatformPkgTokenSpaceGuid.PcdFadtIaPcBootArch|0x0003
+ gMinPlatformPkgTokenSpaceGuid.PcdFadtFlags|0x000004A5
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1AEventBlockAddress|0x400
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1BEventBlockAddress|0
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1AControlBlockAddress|0x404
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1BControlBlockAddress|0
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm2ControlBlockAddress|0x450
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPmTimerBlockAddress|0x408
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiGpe0BlockAddress|0x420
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiGpe1BlockAddress|0
+
+[PcdsFixedAtBuild.X64]
+ gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeMask|0x0eB8
+ gPcAtChipsetPkgTokenSpaceGuid.PcdMinimalValidYear|2015
+ gPcAtChipsetPkgTokenSpaceGuid.PcdMaximalValidYear|2099
+ # Change PcdBootManagerMenuFile to UiApp
+##
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable |TRUE
+
+ [PcdsPatchableInModule.common]
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable == TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmiHandlerProfilePropertyMask|0x1
+!endif
+
+ gPcAtChipsetPkgTokenSpaceGuid.PcdHpetBaseAddress|0xFED00000
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|1024
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable|TRUE
+
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashFvMicrocodeBase|0x0
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashFvMicrocodeSize|0x0
+
+[PcdsDynamicExDefault.common.DEFAULT]
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|30000
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuS3DataAddress|0
+
+[PcdsDynamicExHii.common.DEFAULT]
+ gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|50 # Variable: L"Timeout"
+ gEfiMdePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel|L"HwErrRecSupport"|gEfiGlobalVariableGuid|0x0|1 # Variable: L"HwErrRecSupport"
+
+
+[PcdsDynamicExDefault]
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMrIovSupport|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSystemPageSize|0x1F
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L""|VOID*|36
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId|{0x49, 0x4E, 0x54, 0x45, 0x4C, 0x20}
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId|0x2046573030363253
+
+[PcdsDynamicExDefault.X64]
+
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1
+ gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|0
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|31
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|100
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|800
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|600
+
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugDataAddress|0
+
+[PcdsFeatureFlag]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
+ #gOptionRomPkgTokenSpaceGuid.PcdSupportGop|TRUE
+ #gOptionRomPkgTokenSpaceGuid.PcdSupportUga|FALSE
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire|TRUE
+!endif
+
+[PcdsFixedAtBuild]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
+ gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x400
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x8000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xc000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0xc000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x2000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x10000
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
+
+ # DEBUG_INIT 0x00000001 // Initialization
+ # DEBUG_WARN 0x00000002 // Warnings
+ # DEBUG_LOAD 0x00000004 // Load events
+ # DEBUG_FS 0x00000008 // EFI File system
+ # DEBUG_POOL 0x00000010 // Alloc & Free (pool)
+ # DEBUG_PAGE 0x00000020 // Alloc & Free (page)
+ # DEBUG_INFO 0x00000040 // Informational debug messages
+ # DEBUG_DISPATCH 0x00000080 // PEI/DXE/SMM Dispatchers
+ # DEBUG_VARIABLE 0x00000100 // Variable
+ # DEBUG_BM 0x00000400 // Boot Manager
+ # DEBUG_BLKIO 0x00001000 // BlkIo Driver
+ # DEBUG_NET 0x00004000 // SNP Driver
+ # DEBUG_UNDI 0x00010000 // UNDI Driver
+ # DEBUG_LOADFILE 0x00020000 // LoadFile
+ # DEBUG_EVENT 0x00080000 // Event messages
+ # DEBUG_GCD 0x00100000 // Global Coherency Database changes
+ # DEBUG_CACHE 0x00200000 // Memory range cachability changes
+ # DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may
+ # // significantly impact boot performance
+ # DEBUG_ERROR 0x80000000 // Error
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
+
+ #
+ # PCI feature overrides.
+ #
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
+
+################################################################################
+#
+# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsDynamicDefault]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0
+
+ gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0
+ gBoardModuleTokenSpaceGuid.PcdPciIoBase|0x0
+ gBoardModuleTokenSpaceGuid.PcdPciIoSize|0x0
+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Base|0x0
+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Size|0x0
+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Base|0x0
+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Size|0x800000000
+
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType0StringBiosVersion|"Ver.1.0.0"
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType1StringProductName|"QSP UEFI BIOS"
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType2StringProductName|"QSP UEFI BIOS"
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType0StringBiosReleaseDate|"2019-08-09"
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable|FALSE
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/VarStore.fdf.inc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/VarStore.fdf.inc
new file mode 100644
index 0000000000..76c28e9efc
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/VarStore.fdf.inc
@@ -0,0 +1,53 @@
+## @file
+# FDF include file with Layout Regions that define an empty variable store.
+#
+# Copyright (C) 2014, Red Hat, Inc.
+# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+0x00000000|0x0003e000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+#NV_VARIABLE_STORE
+DATA = {
+ ## This is the EFI_FIRMWARE_VOLUME_HEADER
+ # ZeroVector []
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ # FileSystemGuid: gEfiSystemNvDataFvGuid =
+ # { 0xFFF12B8D, 0x7696, 0x4C8B,
+ # { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
+ 0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
+ 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
+ # FvLength: 0x80000
+ 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+ #Signature "_FVH" #Attributes
+ 0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
+ #HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision
+ 0x48, 0x00, 0x2A, 0x09, 0x00, 0x00, 0x00, 0x02,
+ #Blockmap[0]: 7 Blocks * 0x10000 Bytes / Block
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ #Blockmap[1]: End
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ ## This is the VARIABLE_STORE_HEADER
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ # Signature: gEfiAuthenticatedVariableGuid =
+ # { 0xaaf32c78, 0x947b, 0x439a,
+ # { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }}
+ 0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
+ 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
+!else
+ #Signature: gEfiVariableGuid =
+ # { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}
+ 0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
+ 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
+!endif
+ #Size: 0x3E000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x03DFB8
+ # This can speed up the Variable Dispatch a bit.
+ 0xB8, 0xDF, 0x03, 0x00,
+ # FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+ 0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/build_config.cfg b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/build_config.cfg
new file mode 100644
index 0000000000..72512837f5
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/build_config.cfg
@@ -0,0 +1,31 @@
+# @ build_config.cfg
+# This is the BoardX58Ich10 board specific build settings
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+
+[CONFIG]
+WORKSPACE_PLATFORM_BIN = edk2-non-osi/Platform/Intel
+EDK_SETUP_OPTION =
+openssl_path =
+PLATFORM_BOARD_PACKAGE = SimicsOpenBoardPkg
+PROJECT = SimicsOpenBoardPkg/BoardX58Ich10
+BOARD = BoardX58Ich10
+FLASH_MAP_FDF = SimicsOpenBoardPkg/BoardX58Ich10/Include/Fdf/FlashMapInclude.fdf
+PROJECT_DSC = SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc
+BOARD_PKG_PCD_DSC = SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgPcd.dsc
+PrepRELEASE = DEBUG
+SILENT_MODE = FALSE
+EXT_CONFIG_CLEAR =
+CapsuleBuild = FALSE
+EXT_BUILD_FLAGS =
+CAPSULE_BUILD = 0
+TARGET = DEBUG
+TARGET_SHORT = D
+PERFORMANCE_BUILD = FALSE
+FSP_WRAPPER_BUILD = FALSE
+FSP_BINARY_BUILD = FALSE
+FSP_TEST_RELEASE = FALSE
+SECURE_BOOT_ENABLE = FALSE
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [edk2-platforms PATCH v2 7/7] Platform/Intel: Add build option for SIMICS QSP Platform
2019-08-28 0:40 [edk2-platforms PATCH v2 0/7] Add Initial QSP MinPlatform Pkg for SIMICS David Wei
` (5 preceding siblings ...)
2019-08-28 0:40 ` [edk2-platforms PATCH v2 6/7] SimicsOpenBoardPkg/BoardX58Ich10: Add board module for QSP Build tip David Wei
@ 2019-08-28 0:40 ` David Wei
2019-08-28 23:15 ` Nate DeSimone
6 siblings, 1 reply; 16+ messages in thread
From: David Wei @ 2019-08-28 0:40 UTC (permalink / raw)
To: devel
Cc: Hao Wu, Liming Gao, Ankit Sinha, Agyeman Prince,
Kubacki Michael A, Nate DeSimone, Michael D Kinney
Add build option in build script for SIMICS QSP Platform
Add Maintainers of Simics QSP related packages
Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: David Wei <david.y.wei@intel.com>
---
Maintainers.txt | 12 ++++++++++++
Platform/Intel/build.cfg | 2 ++
Platform/Intel/build_bios.py | 3 +++
3 files changed, 17 insertions(+)
diff --git a/Maintainers.txt b/Maintainers.txt
index b16432bf87..90eb3c3dd0 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -103,6 +103,10 @@ M: Chasel Chiu <chasel.chiu@intel.com>
M: Michael Kubacki <michael.a.kubacki@intel.com>
M: Nate DeSimone <nathaniel.l.desimone@intel.com>
+Platform/Intel/SimicsOpenBoardPkg
+M: Wei David Y <david.y.wei@intel.com>
+M: Agyeman Prince <prince.agyeman@intel.com>
+
Platform/Intel/Tools
M: Bob Feng <bob.c.feng@intel.com>
M: Liming Gao <liming.gao@intel.com>
@@ -155,6 +159,14 @@ M: Gillispie, Thad <thad.gillispie@intel.com>
M: Bu, Daocheng <daocheng.bu@intel.com>
M: Oram, Isaac W <isaac.w.oram@intel.com>
+Silicon/Intel/SimicsX58SktPkg
+M: Wei David Y <david.y.wei@intel.com>
+M: Agyeman Prince <prince.agyeman@intel.com>
+
+Silicon/Intel/SimicsIch10Pkg
+M: Wei David Y <david.y.wei@intel.com>
+M: Agyeman Prince <prince.agyeman@intel.com>
+
Silicon/Intel/Tools
M: Bob Feng <bob.c.feng@intel.com>
M: Liming Gao <liming.gao@intel.com>
diff --git a/Platform/Intel/build.cfg b/Platform/Intel/build.cfg
index b6d32ada49..75cb446aa5 100644
--- a/Platform/Intel/build.cfg
+++ b/Platform/Intel/build.cfg
@@ -11,6 +11,7 @@ WORKSPACE =
WORKSPACE_FSP_BIN = FSP
EDK_TOOLS_BIN = edk2-BaseTools-win32
EDK_BASETOOLS = BaseTools
+WORKSPACE_DRIVERS = edk2-platforms/Drivers
WORKSPACE_PLATFORM = edk2-platforms/Platform/Intel
WORKSPACE_SILICON = edk2-platforms/Silicon/Intel
WORKSPACE_PLATFORM_BIN =
@@ -52,6 +53,7 @@ NUMBER_OF_PROCESSORS = 0
[PLATFORMS]
# board_name = path_to_board_build_config.cfg
BoardMtOlympus = PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
+BoardX58Ich10 = SimicsOpenBoardPkg/BoardX58Ich10/build_config.cfg
KabylakeRvp3 = KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
N1xxWU = ClevoOpenBoardPkg/N1xxWU/build_config.cfg
WhiskeylakeURvp = WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
diff --git a/Platform/Intel/build_bios.py b/Platform/Intel/build_bios.py
index 9152670dcb..46285df19a 100644
--- a/Platform/Intel/build_bios.py
+++ b/Platform/Intel/build_bios.py
@@ -104,6 +104,8 @@ def pre_build(build_config, build_type="DEBUG", silent=False, toolchain=None):
config["WORKSPACE_PLATFORM"])
config["WORKSPACE_SILICON"] = os.path.join(config["WORKSPACE"],
config["WORKSPACE_SILICON"])
+ config["WORKSPACE_DRIVERS"] = os.path.join(config["WORKSPACE"],
+ config["WORKSPACE_DRIVERS"])
config["WORKSPACE_PLATFORM_BIN"] = \
os.path.join(config["WORKSPACE"], config["WORKSPACE_PLATFORM_BIN"])
config["WORKSPACE_SILICON_BIN"] = \
@@ -115,6 +117,7 @@ def pre_build(build_config, build_type="DEBUG", silent=False, toolchain=None):
config["PACKAGES_PATH"] = config["WORKSPACE_PLATFORM"]
config["PACKAGES_PATH"] += os.pathsep + config["WORKSPACE_SILICON"]
config["PACKAGES_PATH"] += os.pathsep + config["WORKSPACE_SILICON_BIN"]
+ config["PACKAGES_PATH"] += os.pathsep + config["WORKSPACE_DRIVERS"]
config["PACKAGES_PATH"] += os.pathsep + \
os.path.join(config["WORKSPACE"], "FSP")
config["PACKAGES_PATH"] += os.pathsep + \
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [edk2-platforms PATCH v2 5/7] SimicsOpenBoardPkg: Add Overrides modules and Logo image for SIMICS QSP Platform
2019-08-28 0:40 ` [edk2-platforms PATCH v2 5/7] SimicsOpenBoardPkg: Add Overrides modules and Logo image for SIMICS QSP Platform David Wei
@ 2019-08-28 3:01 ` Liming Gao
2019-08-28 23:02 ` Nate DeSimone
1 sibling, 0 replies; 16+ messages in thread
From: Liming Gao @ 2019-08-28 3:01 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Sinha, Ankit, Agyeman, Prince, Kubacki, Michael A,
Desimone, Nathaniel L, Kinney, Michael D
David:
Thanks for your update. I don't think Overrides directory is necessary.
I suggest you directly add AcpiTables and QemuVideoDxe (maybe rename to VideoDxe) in edk2-platforms\Platform\Intel\SimicsOpenBoardPkg.
Thanks
Liming
>-----Original Message-----
>From: Wei, David Y
>Sent: Wednesday, August 28, 2019 8:40 AM
>To: devel@edk2.groups.io
>Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>;
>Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince
><prince.agyeman@intel.com>; Kubacki, Michael A
><michael.a.kubacki@intel.com>; Desimone, Nathaniel L
><nathaniel.l.desimone@intel.com>; Kinney, Michael D
><michael.d.kinney@intel.com>
>Subject: [edk2-platforms PATCH v2 5/7] SimicsOpenBoardPkg: Add Overrides
>modules and Logo image for SIMICS QSP Platform
>
>Add overridden modules specific for SIMICS support.
>Add SIMICS customized Logo image
>
>Cc: Hao Wu <hao.a.wu@intel.com>
>Cc: Liming Gao <liming.gao@intel.com>
>Cc: Ankit Sinha <ankit.sinha@intel.com>
>Cc: Agyeman Prince <prince.agyeman@intel.com>
>Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
>Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
>Cc: Michael D Kinney <michael.d.kinney@intel.com>
>
>Signed-off-by: David Wei <david.y.wei@intel.com>
>---
> .../MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c | 1579
>++++++++++++++++++++
> .../MinPlatformPkg/Acpi/AcpiTables/Facs/Facs.c | 84 ++
> .../MinPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.c | 359 +++++
> .../MinPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.c | 78 +
> .../MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c | 46 +
> .../Overrides/OvmfPkg/QemuVideoDxe/ComponentName.c | 205 +++
> .../Overrides/OvmfPkg/QemuVideoDxe/Driver.c | 1011 +++++++++++++
> .../QemuVideoDxe/DriverSupportedEfiVersion.c | 15 +
> .../Overrides/OvmfPkg/QemuVideoDxe/Gop.c | 416 ++++++
> .../Overrides/OvmfPkg/QemuVideoDxe/Initialize.c | 341 +++++
> .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c | 302 ++++
> Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp | Bin 0 -> 141078
>bytes
> Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec | 152 ++
> .../MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h | 45 +
> .../Acpi/AcpiTables/AcpiPlatform.inf | 105 ++
> .../Overrides/OvmfPkg/QemuVideoDxe/Qemu.h | 507 +++++++
> .../OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | 74 +
> .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm | 279 ++++
> .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h | 701 +++++++++
> .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh | 79 +
> 20 files changed, 6378 insertions(+)
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
>bles/AcpiPlatform.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
>bles/Facs/Facs.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
>bles/Fadt/Fadt.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
>bles/Hpet/Hpet.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
>bles/Wsmt/Wsmt.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Co
>mponentName.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dr
>iver.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dr
>iverSupportedEfiVersion.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/G
>op.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Ini
>tialize.c
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/V
>beShim.c
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
>bles/AcpiPlatform.h
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
>bles/AcpiPlatform.inf
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Q
>emu.h
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Q
>emuVideoDxe.inf
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/V
>beShim.asm
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/V
>beShim.h
> create mode 100644
>Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/V
>beShim.sh
>
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/AcpiPlatform.c
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/AcpiPlatform.c
>new file mode 100644
>index 0000000000..f050d8afc0
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/AcpiPlatform.c
>@@ -0,0 +1,1579 @@
>+/** @file
>+ ACPI Platform Driver
>+
>+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
>+
>+ SPDX-License-Identifier: BSD-2-Clause-Patent
>+**/
>+
>+#include "AcpiPlatform.h"
>+
>+#define MAX_CPU_NUM (FixedPcdGet32(PcdMaxCpuThreadCount) *
>FixedPcdGet32(PcdMaxCpuCoreCount) *
>FixedPcdGet32(PcdMaxCpuSocketCount))
>+
>+#pragma pack(1)
>+
>+typedef struct {
>+ UINT32 AcpiProcessorId;
>+ UINT32 ApicId;
>+ UINT32 Flags;
>+ UINT32 SwProcApicId;
>+ UINT32 SocketNum;
>+} EFI_CPU_ID_ORDER_MAP;
>+
>+//
>+// Private Driver Data
>+//
>+//
>+// Define Union of IO APIC & Local APIC structure;
>+//
>+typedef union {
>+ EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE AcpiLocalApic;
>+ EFI_ACPI_4_0_IO_APIC_STRUCTURE AcpiIoApic;
>+ EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE AcpiLocalx2Apic;
>+ struct {
>+ UINT8 Type;
>+ UINT8 Length;
>+ } AcpiApicCommon;
>+} ACPI_APIC_STRUCTURE_PTR;
>+
>+#pragma pack()
>+
>+extern EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE Facs;
>+extern EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE Fadt;
>+extern EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER Hpet;
>+extern EFI_ACPI_WSMT_TABLE Wsmt;
>+
>+VOID *mLocalTable[] = {
>+ &Facs,
>+ &Fadt,
>+ &Hpet,
>+ &Wsmt,
>+};
>+
>+EFI_ACPI_TABLE_PROTOCOL *mAcpiTable;
>+
>+UINT32 mNumOfBitShift = 6;
>+BOOLEAN mForceX2ApicId;
>+BOOLEAN mX2ApicEnabled;
>+
>+EFI_MP_SERVICES_PROTOCOL *mMpService;
>+BOOLEAN mCpuOrderSorted;
>+EFI_CPU_ID_ORDER_MAP mCpuApicIdOrderTable[MAX_CPU_NUM];
>+UINTN mNumberOfCPUs = 0;
>+UINTN mNumberOfEnabledCPUs = 0;
>+//
>+// following are possible APICID Map for SKX
>+//
>+static const UINT32 ApicIdMapA[] = { //for SKUs have number of core > 16
>+ //it is 14 + 14 + 14 + 14 format
>+ 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005,
>0x00000006, 0x00000007,
>+ 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D,
>0x00000010, 0x00000011,
>+ 0x00000012, 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017,
>0x00000018, 0x00000019,
>+ 0x0000001A, 0x0000001B, 0x0000001C, 0x0000001D, 0x00000020, 0x00000021,
>0x00000022, 0x00000023,
>+ 0x00000024, 0x00000025, 0x00000026, 0x00000027, 0x00000028, 0x00000029,
>0x0000002A, 0x0000002B,
>+ 0x0000002C, 0x0000002D, 0x00000030, 0x00000031, 0x00000032, 0x00000033,
>0x00000034, 0x00000035,
>+ 0x00000036, 0x00000037, 0x00000038, 0x00000039, 0x0000003A, 0x0000003B,
>0x0000003C, 0x0000003D
>+};
>+
>+static const UINT32 ApicIdMapB[] = { //for SKUs have number of cores <= 16
>use 32 ID space
>+ //
>+ //it is 16+16 format
>+ //
>+ 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005,
>0x00000006, 0x00000007,
>+ 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D,
>0x0000000E, 0x0000000F,
>+ 0x00000010, 0x00000011, 0x00000012, 0x00000013, 0x00000014, 0x00000015,
>0x00000016, 0x00000017,
>+ 0x00000018, 0x00000019, 0x0000001A, 0x0000001B, 0x0000001C, 0x0000001D,
>0x0000001E, 0x0000001F,
>+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
>0xFFFFFFFF, 0xFFFFFFFF,
>+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
>0xFFFFFFFF, 0xFFFFFFFF,
>+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
>0xFFFFFFFF, 0xFFFFFFFF
>+};
>+
>+
>+static const UINT32 ApicIdMapC[] = { //for SKUs have number of cores <= 16
>use 64 ID space
>+ //
>+ //it is 16+0+16+0 format
>+ //
>+ 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005,
>0x00000006, 0x00000007,
>+ 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D,
>0x0000000E, 0x0000000F,
>+ 0x00000020, 0x00000021, 0x00000022, 0x00000023, 0x00000024, 0x00000025,
>0x00000026, 0x00000027,
>+ 0x00000028, 0x00000029, 0x0000002A, 0x0000002B, 0x0000002C, 0x0000002D,
>0x0000002E, 0x0000002F,
>+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
>0xFFFFFFFF, 0xFFFFFFFF,
>+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
>0xFFFFFFFF, 0xFFFFFFFF,
>+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
>0xFFFFFFFF, 0xFFFFFFFF
>+};
>+
>+static const UINT32 ApicIdMapD[] = { //for SKUs have number of cores <= 8
>use 16 ID space
>+ //
>+ //it is 16 format
>+ //
>+ 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005,
>0x00000006, 0x00000007,
>+ 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D,
>0x0000000E, 0x0000000F,
>+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
>0xFFFFFFFF, 0xFFFFFFFF,
>+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
>0xFFFFFFFF, 0xFFFFFFFF,
>+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
>0xFFFFFFFF, 0xFFFFFFFF,
>+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
>0xFFFFFFFF, 0xFFFFFFFF,
>+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
>0xFFFFFFFF, 0xFFFFFFFF
>+};
>+
>+const UINT32 *mApicIdMap = NULL;
>+
>+/**
>+ This function detect the APICID map and update ApicID Map pointer
>+
>+ @param None
>+
>+ @retval VOID
>+
>+**/
>+VOID DetectApicIdMap(VOID)
>+{
>+ UINTN CoreCount;
>+
>+ CoreCount = 0;
>+
>+ if(mApicIdMap != NULL) {
>+ return; //aleady initialized
>+ }
>+
>+ mApicIdMap = ApicIdMapA; // default to > 16C SKUs
>+
>+ CoreCount = mNumberOfEnabledCPUs / 2;
>+ DEBUG ((DEBUG_INFO, "CoreCount - %d\n", CoreCount));
>+
>+ if(CoreCount <= 16) {
>+
>+ if(mNumOfBitShift == 4) {
>+ mApicIdMap = ApicIdMapD;
>+ }
>+
>+ if(mNumOfBitShift == 5) {
>+ mApicIdMap = ApicIdMapB;
>+ }
>+
>+ if(mNumOfBitShift == 6) {
>+ mApicIdMap = ApicIdMapC;
>+ }
>+
>+ }
>+
>+ return;
>+}
>+
>+/**
>+ This function return the CoreThreadId of ApicId from ACPI ApicId Map array
>+
>+ @param ApicId
>+
>+ @retval Index of ACPI ApicId Map array
>+
>+**/
>+UINT32
>+GetIndexFromApicId (
>+ UINT32 ApicId
>+ )
>+{
>+ UINT32 CoreThreadId;
>+ UINT32 i;
>+
>+ ASSERT (mApicIdMap != NULL);
>+
>+ CoreThreadId = ApicId & ((1 << mNumOfBitShift) - 1);
>+
>+ for(i = 0; i < (FixedPcdGet32(PcdMaxCpuCoreCount) *
>FixedPcdGet32(PcdMaxCpuThreadCount)); i++) {
>+ if(mApicIdMap[i] == CoreThreadId) {
>+ break;
>+ }
>+ }
>+
>+ ASSERT (i <= (FixedPcdGet32(PcdMaxCpuCoreCount) *
>FixedPcdGet32(PcdMaxCpuThreadCount)));
>+
>+ return i;
>+}
>+
>+UINT32
>+ApicId2SwProcApicId (
>+ UINT32 ApicId
>+ )
>+{
>+ UINT32 Index;
>+
>+ for (Index = 0; Index < MAX_CPU_NUM; Index++) {
>+ if ((mCpuApicIdOrderTable[Index].Flags == 1) &&
>(mCpuApicIdOrderTable[Index].ApicId == ApicId)) {
>+ return Index;
>+ }
>+ }
>+
>+ return (UINT32) -1;
>+
>+}
>+
>+VOID
>+DebugDisplayReOrderTable(
>+ VOID
>+ )
>+{
>+ UINT32 Index;
>+
>+ DEBUG ((EFI_D_ERROR, "Index AcpiProcId ApicId Flags SwApicId Skt\n"));
>+ for (Index=0; Index<MAX_CPU_NUM; Index++) {
>+ DEBUG ((EFI_D_ERROR, " %02d 0x%02X 0x%02X %d
>0x%02X %d\n",
>+ Index, mCpuApicIdOrderTable[Index].AcpiProcessorId,
>+ mCpuApicIdOrderTable[Index].ApicId,
>+ mCpuApicIdOrderTable[Index].Flags,
>+ mCpuApicIdOrderTable[Index].SwProcApicId,
>+ mCpuApicIdOrderTable[Index].SocketNum));
>+ }
>+}
>+
>+EFI_STATUS
>+AppendCpuMapTableEntry (
>+ IN VOID *ApicPtr,
>+ IN UINT32 LocalApicCounter
>+ )
>+{
>+ EFI_STATUS Status;
>+ EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *LocalApicPtr;
>+ EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE *LocalX2ApicPtr;
>+ UINT8 Type;
>+
>+ Status = EFI_SUCCESS;
>+ Type = ((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiApicCommon.Type;
>+ LocalApicPtr = (EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE
>*)(&((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiLocalApic);
>+ LocalX2ApicPtr = (EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE
>*)(&((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiLocalx2Apic);
>+
>+ if(Type == EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC) {
>+ if(!mX2ApicEnabled) {
>+ LocalApicPtr->Flags =
>(UINT8)mCpuApicIdOrderTable[LocalApicCounter].Flags;
>+ LocalApicPtr->ApicId =
>(UINT8)mCpuApicIdOrderTable[LocalApicCounter].ApicId;
>+ LocalApicPtr->AcpiProcessorId =
>(UINT8)mCpuApicIdOrderTable[LocalApicCounter].AcpiProcessorId;
>+ } else {
>+ LocalApicPtr->Flags = 0;
>+ LocalApicPtr->ApicId = 0xFF;
>+ LocalApicPtr->AcpiProcessorId = (UINT8)0xFF;
>+ Status = EFI_UNSUPPORTED;
>+ }
>+ } else if(Type == EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC) {
>+ if(mX2ApicEnabled) {
>+ LocalX2ApicPtr->Flags =
>(UINT8)mCpuApicIdOrderTable[LocalApicCounter].Flags;
>+ LocalX2ApicPtr->X2ApicId =
>mCpuApicIdOrderTable[LocalApicCounter].ApicId;
>+ LocalX2ApicPtr->AcpiProcessorUid =
>mCpuApicIdOrderTable[LocalApicCounter].AcpiProcessorId;
>+ } else {
>+ LocalX2ApicPtr->Flags = 0;
>+ LocalX2ApicPtr->X2ApicId = (UINT32)-1;
>+ LocalX2ApicPtr->AcpiProcessorUid = (UINT32)-1;
>+ Status = EFI_UNSUPPORTED;
>+ }
>+ } else {
>+ Status = EFI_UNSUPPORTED;
>+ }
>+
>+ return Status;
>+
>+}
>+
>+EFI_STATUS
>+SortCpuLocalApicInTable (
>+ VOID
>+ )
>+{
>+ EFI_STATUS Status;
>+ EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;
>+ UINT32 Index;
>+ UINT32 CurrProcessor;
>+ UINT32 BspApicId;
>+ UINT32 TempVal = 0;
>+ EFI_CPU_ID_ORDER_MAP *CpuIdMapPtr;
>+ UINT32 CoreThreadMask;
>+
>+ Index = 0;
>+ Status = EFI_SUCCESS;
>+
>+ CoreThreadMask = (UINT32) ((1 << mNumOfBitShift) - 1);
>+
>+ if(!mCpuOrderSorted) {
>+
>+ Index = 0;
>+
>+ for (CurrProcessor = 0; CurrProcessor < mNumberOfCPUs;
>CurrProcessor++) {
>+ Status = mMpService->GetProcessorInfo (
>+ mMpService,
>+ CurrProcessor,
>+ &ProcessorInfoBuffer
>+ );
>+
>+ if ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) != 0) {
>+ if(ProcessorInfoBuffer.ProcessorId & 1) { //is 2nd thread
>+ CpuIdMapPtr = (EFI_CPU_ID_ORDER_MAP
>*)&mCpuApicIdOrderTable[(Index - 1) + MAX_CPU_NUM / 2];
>+ } else { //is primary thread
>+ CpuIdMapPtr = (EFI_CPU_ID_ORDER_MAP
>*)&mCpuApicIdOrderTable[Index];
>+ Index++;
>+ }
>+ CpuIdMapPtr->ApicId = (UINT32)ProcessorInfoBuffer.ProcessorId;
>+ CpuIdMapPtr->Flags = ((ProcessorInfoBuffer.StatusFlag &
>PROCESSOR_ENABLED_BIT) != 0);
>+ CpuIdMapPtr->SocketNum =
>(UINT32)ProcessorInfoBuffer.Location.Package;
>+ CpuIdMapPtr->AcpiProcessorId = (CpuIdMapPtr->SocketNum *
>FixedPcdGet32(PcdMaxCpuCoreCount) *
>FixedPcdGet32(PcdMaxCpuThreadCount)) +
>GetIndexFromApicId(CpuIdMapPtr->ApicId); //CpuIdMapPtr->ApicId;
>+ CpuIdMapPtr->SwProcApicId =
>((UINT32)(ProcessorInfoBuffer.Location.Package << mNumOfBitShift) +
>(((UINT32)ProcessorInfoBuffer.ProcessorId) & CoreThreadMask));
>+ if(mX2ApicEnabled) { //if X2Apic, re-order the socket # so it starts from
>base 0 and contiguous
>+ //may not necessory!!!!!
>+ }
>+
>+ //update processorbitMask
>+ if (CpuIdMapPtr->Flags == 1) {
>+
>+ if(mForceX2ApicId) {
>+ CpuIdMapPtr->SocketNum &= 0x7;
>+ CpuIdMapPtr->AcpiProcessorId &= 0xFF; //keep lower 8bit due to use
>Proc obj in dsdt
>+ CpuIdMapPtr->SwProcApicId &= 0xFF;
>+ }
>+ }
>+ } else { //not enabled
>+ CpuIdMapPtr = (EFI_CPU_ID_ORDER_MAP
>*)&mCpuApicIdOrderTable[Index];
>+ CpuIdMapPtr->ApicId = (UINT32)-1;
>+ CpuIdMapPtr->Flags = 0;
>+ CpuIdMapPtr->AcpiProcessorId = (UINT32)-1;
>+ CpuIdMapPtr->SwProcApicId = (UINT32)-1;
>+ CpuIdMapPtr->SocketNum = (UINT32)-1;
>+ } //end if PROC ENABLE
>+ } //end for CurrentProcessor
>+ //
>+ //keep for debug purpose
>+ //
>+ DEBUG(( EFI_D_ERROR, "::ACPI:: APIC ID Order Table Init.
>CoreThreadMask = %x, mNumOfBitShift = %x\n", CoreThreadMask,
>mNumOfBitShift));
>+ DebugDisplayReOrderTable();
>+ //
>+ //make sure 1st entry is BSP
>+ //
>+ if(mX2ApicEnabled) {
>+ BspApicId = (UINT32)AsmReadMsr64(0x802);
>+ } else {
>+ BspApicId = (*(volatile UINT32 *)(UINTN)0xFEE00020) >> 24;
>+ }
>+ DEBUG ((EFI_D_INFO, "BspApicId - 0x%x\n", BspApicId));
>+
>+ if(mCpuApicIdOrderTable[0].ApicId != BspApicId) {
>+ //
>+ //check to see if 1st entry is BSP, if not swap it
>+ //
>+ Index = ApicId2SwProcApicId(BspApicId);
>+
>+ if(MAX_CPU_NUM <= Index) {
>+ DEBUG ((EFI_D_ERROR, "Asserting the SortCpuLocalApicInTable Index
>Bufferflow\n"));
>+ ASSERT_EFI_ERROR(EFI_INVALID_PARAMETER);
>+ }
>+
>+ TempVal = mCpuApicIdOrderTable[Index].ApicId;
>+ mCpuApicIdOrderTable[Index].ApicId = mCpuApicIdOrderTable[0].ApicId;
>+ mCpuApicIdOrderTable[0].ApicId = TempVal;
>+ mCpuApicIdOrderTable[Index].Flags = mCpuApicIdOrderTable[0].Flags;
>+ mCpuApicIdOrderTable[0].Flags = 1;
>+ TempVal = mCpuApicIdOrderTable[Index].SwProcApicId;
>+ mCpuApicIdOrderTable[Index].SwProcApicId =
>mCpuApicIdOrderTable[0].SwProcApicId;
>+ mCpuApicIdOrderTable[0].SwProcApicId = TempVal;
>+ //
>+ //swap AcpiProcId
>+ //
>+ TempVal = mCpuApicIdOrderTable[Index].AcpiProcessorId;
>+ mCpuApicIdOrderTable[Index].AcpiProcessorId =
>mCpuApicIdOrderTable[0].AcpiProcessorId;
>+ mCpuApicIdOrderTable[0].AcpiProcessorId = TempVal;
>+
>+ }
>+ //
>+ //Make sure no holes between enabled threads
>+ //
>+ for(CurrProcessor = 0; CurrProcessor < MAX_CPU_NUM; CurrProcessor++)
>{
>+
>+ if(mCpuApicIdOrderTable[CurrProcessor].Flags == 0) {
>+ //
>+ //make sure disabled entry has ProcId set to FFs
>+ //
>+ mCpuApicIdOrderTable[CurrProcessor].ApicId = (UINT32)-1;
>+ mCpuApicIdOrderTable[CurrProcessor].AcpiProcessorId = (UINT32)-1;
>+ mCpuApicIdOrderTable[CurrProcessor].SwProcApicId = (UINT32)-1;
>+
>+ for(Index = CurrProcessor+1; Index < MAX_CPU_NUM; Index++) {
>+ if(mCpuApicIdOrderTable[Index].Flags == 1) {
>+ //
>+ //move enabled entry up
>+ //
>+ mCpuApicIdOrderTable[CurrProcessor].Flags = 1;
>+ mCpuApicIdOrderTable[CurrProcessor].ApicId =
>mCpuApicIdOrderTable[Index].ApicId;
>+ mCpuApicIdOrderTable[CurrProcessor].AcpiProcessorId =
>mCpuApicIdOrderTable[Index].AcpiProcessorId;
>+ mCpuApicIdOrderTable[CurrProcessor].SwProcApicId =
>mCpuApicIdOrderTable[Index].SwProcApicId;
>+ mCpuApicIdOrderTable[CurrProcessor].SocketNum =
>mCpuApicIdOrderTable[Index].SocketNum;
>+ //
>+ //disable moved entry
>+ //
>+ mCpuApicIdOrderTable[Index].Flags = 0;
>+ mCpuApicIdOrderTable[Index].ApicId = (UINT32)-1;
>+ mCpuApicIdOrderTable[Index].AcpiProcessorId = (UINT32)-1;
>+ mCpuApicIdOrderTable[Index].SwProcApicId = (UINT32)-1;
>+ break;
>+ }
>+ }
>+ }
>+ }
>+ //
>+ //keep for debug purpose
>+ //
>+ DEBUG ((EFI_D_ERROR, "APIC ID Order Table ReOrdered\n"));
>+ DebugDisplayReOrderTable();
>+
>+ mCpuOrderSorted = TRUE;
>+ }
>+
>+ return Status;
>+}
>+
>+
>+/** Structure of a sub-structure of the ACPI header.
>+
>+ This structure contains the type and length fields, which are common to
>every
>+ sub-structure of the ACPI tables. A pointer to any structure can be cast as
>this.
>+**/
>+typedef struct {
>+ UINT8 Type;
>+ UINT8 Length;
>+} STRUCTURE_HEADER;
>+
>+STRUCTURE_HEADER mMadtStructureTable[] = {
>+ {EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC, sizeof
>(EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE)},
>+ {EFI_ACPI_4_0_IO_APIC, sizeof
>(EFI_ACPI_4_0_IO_APIC_STRUCTURE)},
>+ {EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE, sizeof
>(EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE)},
>+ {EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE, sizeof
>(EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE)},
>+ {EFI_ACPI_4_0_LOCAL_APIC_NMI, sizeof
>(EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE)},
>+ {EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE, sizeof
>(EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE)},
>+ {EFI_ACPI_4_0_IO_SAPIC, sizeof
>(EFI_ACPI_4_0_IO_SAPIC_STRUCTURE)},
>+ {EFI_ACPI_4_0_LOCAL_SAPIC, sizeof
>(EFI_ACPI_4_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE)},
>+ {EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES, sizeof
>(EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE)},
>+ {EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC, sizeof
>(EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE)},
>+ {EFI_ACPI_4_0_LOCAL_X2APIC_NMI, sizeof
>(EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE)}
>+};
>+
>+/**
>+ Get the size of the ACPI table.
>+
>+ This function calculates the size needed for the ACPI Table based on the
>number and
>+ size of the sub-structures that will compose it.
>+
>+ @param[in] TableSpecificHdrLength Size of the table specific header, not
>the ACPI standard header size.
>+ @param[in] Structures Pointer to an array of sub-structure pointers.
>+ @param[in] StructureCount Number of structure pointers in the array.
>+
>+ @return Total size needed for the ACPI table.
>+**/
>+UINT32
>+GetTableSize (
>+ IN UINTN TableSpecificHdrLength,
>+ IN STRUCTURE_HEADER **Structures,
>+ IN UINTN StructureCount
>+ )
>+{
>+ UINT32 TableLength;
>+ UINT32 Index;
>+
>+ //
>+ // Compute size of the ACPI table; header plus all structures needed.
>+ //
>+ TableLength = (UINT32) TableSpecificHdrLength;
>+
>+ for (Index = 0; Index < StructureCount; Index++) {
>+ ASSERT (Structures[Index] != NULL);
>+ if (Structures[Index] == NULL) {
>+ return 0;
>+ }
>+
>+ TableLength += Structures[Index]->Length;
>+ }
>+
>+ return TableLength;
>+}
>+
>+/**
>+ Allocate the ACPI Table.
>+
>+ This function allocates space for the ACPI table based on the number and
>size of
>+ the sub-structures that will compose it.
>+
>+ @param[in] TableSpecificHdrLength Size of the table specific header, not
>the ACPI standard header size.
>+ @param[in] Structures Pointer to an array of sub-structure pointers.
>+ @param[in] StructureCount Number of structure pointers in the array.
>+ @param[out] Table Newly allocated ACPI Table pointer.
>+
>+ @retval EFI_SUCCESS Successfully allocated the Table.
>+ @retval EFI_OUT_OF_RESOURCES Space for the Table could not be
>allocated.
>+**/
>+EFI_STATUS
>+AllocateTable (
>+ IN UINTN TableSpecificHdrLength,
>+ IN STRUCTURE_HEADER **Structures,
>+ IN UINTN StructureCount,
>+ OUT EFI_ACPI_DESCRIPTION_HEADER **Table
>+ )
>+{
>+ EFI_STATUS Status;
>+ UINT32 Size;
>+ EFI_ACPI_DESCRIPTION_HEADER *InternalTable;
>+
>+ //
>+ // Get the size of the ACPI table and allocate memory.
>+ //
>+ Size = GetTableSize (TableSpecificHdrLength, Structures, StructureCount);
>+ InternalTable = (EFI_ACPI_DESCRIPTION_HEADER *) AllocatePool (Size);
>+
>+ if (InternalTable == NULL) {
>+ Status = EFI_OUT_OF_RESOURCES;
>+ DEBUG ((
>+ DEBUG_ERROR,
>+ "Failed to allocate %d bytes for ACPI Table\n",
>+ Size
>+ ));
>+ } else {
>+ Status = EFI_SUCCESS;
>+ DEBUG ((
>+ DEBUG_INFO,
>+ "Successfully allocated %d bytes for ACPI Table at 0x%p\n",
>+ Size,
>+ InternalTable
>+ ));
>+ *Table = InternalTable;
>+ }
>+
>+ return Status;
>+}
>+
>+/**
>+ Initialize the header.
>+
>+ This function fills in the standard table header with correct values,
>+ except for the length and checksum fields, which are filled in later.
>+
>+ @param[in,out] Header Pointer to the header structure.
>+
>+ @retval EFI_SUCCESS Successfully initialized the header.
>+ @retval EFI_INVALID_PARAMETER Pointer parameter was null.
>+**/
>+EFI_STATUS
>+InitializeHeader (
>+ IN OUT EFI_ACPI_DESCRIPTION_HEADER *Header,
>+ IN UINT32 Signature,
>+ IN UINT8 Revision,
>+ IN UINT32 OemRevision
>+ )
>+{
>+ UINT64 AcpiTableOemId;
>+
>+ if (Header == NULL) {
>+ DEBUG ((DEBUG_ERROR, "Header pointer is NULL\n"));
>+ return EFI_INVALID_PARAMETER;
>+ }
>+
>+ Header->Signature = Signature;
>+ Header->Length = 0; // filled in by Build function
>+ Header->Revision = Revision;
>+ Header->Checksum = 0; // filled in by InstallAcpiTable
>+
>+ CopyMem (
>+ (VOID *) &Header->OemId,
>+ PcdGetPtr (PcdAcpiDefaultOemId),
>+ sizeof (Header->OemId)
>+ );
>+
>+ AcpiTableOemId = PcdGet64 (PcdAcpiDefaultOemTableId);
>+ CopyMem (
>+ (VOID *) &Header->OemTableId,
>+ (VOID *) &AcpiTableOemId,
>+ sizeof (Header->OemTableId)
>+ );
>+
>+ Header->OemRevision = OemRevision;
>+ Header->CreatorId = 0;
>+ Header->CreatorRevision = 0;
>+
>+ return EFI_SUCCESS;
>+}
>+
>+/**
>+ Initialize the MADT header.
>+
>+ This function fills in the MADT's standard table header with correct values,
>+ except for the length and checksum fields, which are filled in later.
>+
>+ @param[in,out] MadtHeader Pointer to the MADT header structure.
>+
>+ @retval EFI_SUCCESS Successfully initialized the MADT header.
>+ @retval EFI_INVALID_PARAMETER Pointer parameter was null.
>+**/
>+EFI_STATUS
>+InitializeMadtHeader (
>+ IN OUT EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER
>*MadtHeader
>+ )
>+{
>+ EFI_STATUS Status;
>+
>+ if (MadtHeader == NULL) {
>+ DEBUG ((DEBUG_ERROR, "MADT header pointer is NULL\n"));
>+ return EFI_INVALID_PARAMETER;
>+ }
>+
>+ Status = InitializeHeader (
>+ &MadtHeader->Header,
>+ EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
>+ EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
>+ 0
>+ );
>+ if (EFI_ERROR (Status)) {
>+ return Status;
>+ }
>+
>+ MadtHeader->LocalApicAddress = PcdGet32(PcdLocalApicAddress);
>+ MadtHeader->Flags = EFI_ACPI_4_0_PCAT_COMPAT;
>+
>+ return EFI_SUCCESS;
>+}
>+
>+/**
>+ Copy an ACPI sub-structure; MADT and SRAT supported
>+
>+ This function validates the structure type and size of a sub-structure
>+ and returns a newly allocated copy of it.
>+
>+ @param[in] Header Pointer to the header of the table.
>+ @param[in] Structure Pointer to the structure to copy.
>+ @param[in] NewStructure Newly allocated copy of the structure.
>+
>+ @retval EFI_SUCCESS Successfully copied the structure.
>+ @retval EFI_INVALID_PARAMETER Pointer parameter was null.
>+ @retval EFI_INVALID_PARAMETER Structure type was unknown.
>+ @retval EFI_INVALID_PARAMETER Structure length was wrong for its type.
>+ @retval EFI_UNSUPPORTED Header passed in is not supported.
>+**/
>+EFI_STATUS
>+CopyStructure (
>+ IN EFI_ACPI_DESCRIPTION_HEADER *Header,
>+ IN STRUCTURE_HEADER *Structure,
>+ OUT STRUCTURE_HEADER **NewStructure
>+ )
>+{
>+ STRUCTURE_HEADER *NewStructureInternal;
>+ STRUCTURE_HEADER *StructureTable;
>+ UINTN TableNumEntries;
>+ BOOLEAN EntryFound;
>+ UINT8 Index;
>+
>+ //
>+ // Initialize the number of table entries and the table based on the table
>header passed in.
>+ //
>+ if (Header->Signature ==
>EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
>+ TableNumEntries = sizeof (mMadtStructureTable) / sizeof
>(STRUCTURE_HEADER);
>+ StructureTable = mMadtStructureTable;
>+ } else {
>+ return EFI_UNSUPPORTED;
>+ }
>+
>+ //
>+ // Check the incoming structure against the table of supported structures.
>+ //
>+ EntryFound = FALSE;
>+ for (Index = 0; Index < TableNumEntries; Index++) {
>+ if (Structure->Type == StructureTable[Index].Type) {
>+ if (Structure->Length == StructureTable[Index].Length) {
>+ EntryFound = TRUE;
>+ } else {
>+ DEBUG ((
>+ DEBUG_ERROR,
>+ "Invalid length for structure type %d: expected %d, actually %d\n",
>+ Structure->Type,
>+ StructureTable[Index].Length,
>+ Structure->Length
>+ ));
>+ return EFI_INVALID_PARAMETER;
>+ }
>+ }
>+ }
>+
>+ //
>+ // If no entry in the table matches the structure type and length passed in
>+ // then return invalid parameter.
>+ //
>+ if (!EntryFound) {
>+ DEBUG ((
>+ DEBUG_ERROR,
>+ "Unknown structure type: %d\n",
>+ Structure->Type
>+ ));
>+ return EFI_INVALID_PARAMETER;
>+ }
>+
>+ NewStructureInternal = (STRUCTURE_HEADER *) AllocatePool (Structure-
>>Length);
>+ if (NewStructureInternal == NULL) {
>+ DEBUG ((
>+ DEBUG_ERROR,
>+ "Failed to allocate %d bytes for type %d structure\n",
>+ Structure->Length,
>+ Structure->Type
>+ ));
>+ return EFI_OUT_OF_RESOURCES;
>+ } else {
>+ DEBUG ((
>+ DEBUG_INFO,
>+ "Successfully allocated %d bytes for type %d structure at 0x%p\n",
>+ Structure->Length,
>+ Structure->Type,
>+ NewStructureInternal
>+ ));
>+ }
>+
>+ CopyMem (
>+ (VOID *) NewStructureInternal,
>+ (VOID *) Structure,
>+ Structure->Length
>+ );
>+
>+ *NewStructure = NewStructureInternal;
>+ return EFI_SUCCESS;
>+}
>+
>+/**
>+ Build ACPI Table. MADT tables supported.
>+
>+ This function builds the ACPI table from the header plus the list of sub-
>structures
>+ passed in. The table returned by this function is ready to be installed using
>+ the ACPI table protocol's InstallAcpiTable function, which copies it into
>+ ACPI memory. After that, the caller should free the memory returned by
>this
>+ function.
>+
>+ @param[in] AcpiHeader Pointer to the header structure.
>+ @param[in] TableSpecificHdrLength Size of the table specific header, not
>the ACPI standard header size.
>+ @param[in] Structures Pointer to an array of sub-structure pointers.
>+ @param[in] StructureCount Number of structure pointers in the array.
>+ @param[out] NewTable Newly allocated and initialized pointer to
>the ACPI Table.
>+
>+ @retval EFI_SUCCESS Successfully built the ACPI table.
>+ @retval EFI_INVALID_PARAMETER Pointer parameter was null.
>+ @retval EFI_INVALID_PARAMETER Header parameter had the wrong
>signature.
>+ @retval EFI_OUT_OF_RESOURCES Space for the ACPI Table could not be
>allocated.
>+**/
>+EFI_STATUS
>+BuildAcpiTable (
>+ IN EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader,
>+ IN UINTN TableSpecificHdrLength,
>+ IN STRUCTURE_HEADER **Structures,
>+ IN UINTN StructureCount,
>+ OUT UINT8 **NewTable
>+ )
>+{
>+ EFI_STATUS Status;
>+ EFI_ACPI_DESCRIPTION_HEADER *InternalTable;
>+ UINTN Index;
>+ UINT8 *CurrPtr;
>+ UINT8 *EndOfTablePtr;
>+
>+ if (AcpiHeader == NULL) {
>+ DEBUG ((DEBUG_ERROR, "AcpiHeader pointer is NULL\n"));
>+ return EFI_INVALID_PARAMETER;
>+ }
>+
>+ if (AcpiHeader->Signature !=
>EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
>+ DEBUG ((
>+ DEBUG_ERROR,
>+ "MADT header signature is expected, actually 0x%08x\n",
>+ AcpiHeader->Signature
>+ ));
>+ return EFI_INVALID_PARAMETER;
>+ }
>+
>+ if (Structures == NULL) {
>+ DEBUG ((DEBUG_ERROR, "Structure array pointer is NULL\n"));
>+ return EFI_INVALID_PARAMETER;
>+ }
>+
>+ for (Index = 0; Index < StructureCount; Index++) {
>+ if (Structures[Index] == NULL) {
>+ DEBUG ((DEBUG_ERROR, "Structure pointer %d is NULL\n", Index));
>+ return EFI_INVALID_PARAMETER;
>+ }
>+ }
>+
>+ //
>+ // Allocate the memory needed for the table.
>+ //
>+ Status = AllocateTable (
>+ TableSpecificHdrLength,
>+ Structures,
>+ StructureCount,
>+ &InternalTable
>+ );
>+ if (EFI_ERROR (Status)) {
>+ return Status;
>+ }
>+
>+ //
>+ // Copy Header and patch in structure length, checksum is programmed
>later
>+ // after all structures are populated.
>+ //
>+ CopyMem (
>+ (VOID *) InternalTable,
>+ (VOID *) AcpiHeader,
>+ TableSpecificHdrLength
>+ );
>+
>+ InternalTable->Length = GetTableSize (TableSpecificHdrLength, Structures,
>StructureCount);
>+
>+ //
>+ // Copy all the sub structures to the table.
>+ //
>+ CurrPtr = ((UINT8 *) InternalTable) + TableSpecificHdrLength;
>+ EndOfTablePtr = ((UINT8 *) InternalTable) + InternalTable->Length;
>+
>+ for (Index = 0; Index < StructureCount; Index++) {
>+ ASSERT (Structures[Index] != NULL);
>+ if (Structures[Index] == NULL) {
>+ break;
>+ }
>+
>+ CopyMem (
>+ (VOID *) CurrPtr,
>+ (VOID *) Structures[Index],
>+ Structures[Index]->Length
>+ );
>+
>+ CurrPtr += Structures[Index]->Length;
>+ ASSERT (CurrPtr <= EndOfTablePtr);
>+ if (CurrPtr > EndOfTablePtr) {
>+ break;
>+ }
>+ }
>+
>+ //
>+ // Update the return pointer.
>+ //
>+ *NewTable = (UINT8 *) InternalTable;
>+ return EFI_SUCCESS;
>+}
>+
>+/**
>+ Build from scratch and install the MADT.
>+
>+ @retval EFI_SUCCESS The MADT was installed successfully.
>+ @retval EFI_OUT_OF_RESOURCES Could not allocate required structures.
>+**/
>+EFI_STATUS
>+InstallMadtFromScratch (
>+ VOID
>+ )
>+{
>+ EFI_STATUS Status;
>+ UINTN Index;
>+ EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER
>*NewMadtTable;
>+ UINTN TableHandle;
>+ EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER
>MadtTableHeader;
>+ EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE
>ProcLocalApicStruct;
>+ EFI_ACPI_4_0_IO_APIC_STRUCTURE IoApicStruct;
>+ EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE
>IntSrcOverrideStruct;
>+ EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE LocalApciNmiStruct;
>+ EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE
>ProcLocalX2ApicStruct;
>+ EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE
>LocalX2ApicNmiStruct;
>+ STRUCTURE_HEADER **MadtStructs;
>+ UINTN MaxMadtStructCount;
>+ UINTN MadtStructsIndex;
>+ UINT32 CurrentIoApicAddress =
>(UINT32)(PcdGet32(PcdPcIoApicAddressBase));
>+ UINT32 PcIoApicEnable;
>+ UINT32 PcIoApicMask;
>+ UINTN PcIoApicIndex;
>+
>+ DetectApicIdMap();
>+
>+ // Call for Local APIC ID Reorder
>+ SortCpuLocalApicInTable ();
>+
>+ NewMadtTable = NULL;
>+
>+ MaxMadtStructCount = (UINT32) (
>+ MAX_CPU_NUM + // processor local APIC structures
>+ MAX_CPU_NUM + // processor local x2APIC structures
>+ 1 + PcdGet8(PcdPcIoApicCount) + // I/O APIC structures
>+ 2 + // interrupt source override structures
>+ 1 + // local APIC NMI structures
>+ 1 // local x2APIC NMI structures
>+ ); // other structures are not used
>+
>+ MadtStructs = (STRUCTURE_HEADER **) AllocateZeroPool
>(MaxMadtStructCount * sizeof (STRUCTURE_HEADER *));
>+ if (MadtStructs == NULL) {
>+ DEBUG ((DEBUG_ERROR, "Could not allocate MADT structure pointer
>array\n"));
>+ return EFI_OUT_OF_RESOURCES;
>+ }
>+
>+ //
>+ // Initialize the next index into the structure pointer array. It is
>+ // incremented every time a structure of any type is copied to the array.
>+ //
>+ MadtStructsIndex = 0;
>+
>+ //
>+ // Initialize MADT Header Structure
>+ //
>+ Status = InitializeMadtHeader (&MadtTableHeader);
>+ if (EFI_ERROR (Status)) {
>+ DEBUG ((EFI_D_ERROR, "InitializeMadtHeader failed: %r\n", Status));
>+ goto Done;
>+ }
>+
>+ DEBUG ((EFI_D_INFO, "Number of CPUs detected = %d \n",
>mNumberOfCPUs));
>+
>+ //
>+ // Build Processor Local APIC Structures and Processor Local X2APIC
>Structures
>+ //
>+ ProcLocalApicStruct.Type = EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC;
>+ ProcLocalApicStruct.Length = sizeof
>(EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE);
>+
>+ ProcLocalX2ApicStruct.Type = EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC;
>+ ProcLocalX2ApicStruct.Length = sizeof
>(EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE);
>+ ProcLocalX2ApicStruct.Reserved[0] = 0;
>+ ProcLocalX2ApicStruct.Reserved[1] = 0;
>+
>+ for (Index = 0; Index < MAX_CPU_NUM; Index++) {
>+ //
>+ // If x2APIC mode is not enabled, and if it is possible to express the
>+ // APIC ID as a UINT8, use a processor local APIC structure. Otherwise,
>+ // use a processor local x2APIC structure.
>+ //
>+ if (!mX2ApicEnabled && mCpuApicIdOrderTable[Index].ApicId <
>MAX_UINT8) {
>+ ProcLocalApicStruct.Flags = (UINT8)
>mCpuApicIdOrderTable[Index].Flags;
>+ ProcLocalApicStruct.ApicId = (UINT8)
>mCpuApicIdOrderTable[Index].ApicId;
>+ ProcLocalApicStruct.AcpiProcessorId = (UINT8)
>mCpuApicIdOrderTable[Index].AcpiProcessorId;
>+
>+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
>+ Status = CopyStructure (
>+ &MadtTableHeader.Header,
>+ (STRUCTURE_HEADER *) &ProcLocalApicStruct,
>+ &MadtStructs[MadtStructsIndex++]
>+ );
>+ } else if (mCpuApicIdOrderTable[Index].ApicId != 0xFFFFFFFF) {
>+ ProcLocalX2ApicStruct.Flags = (UINT8)
>mCpuApicIdOrderTable[Index].Flags;
>+ ProcLocalX2ApicStruct.X2ApicId =
>mCpuApicIdOrderTable[Index].ApicId;
>+ ProcLocalX2ApicStruct.AcpiProcessorUid =
>mCpuApicIdOrderTable[Index].AcpiProcessorId;
>+
>+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
>+ Status = CopyStructure (
>+ &MadtTableHeader.Header,
>+ (STRUCTURE_HEADER *) &ProcLocalX2ApicStruct,
>+ &MadtStructs[MadtStructsIndex++]
>+ );
>+ }
>+ if (EFI_ERROR (Status)) {
>+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (local APIC/x2APIC)
>failed: %r\n", Status));
>+ goto Done;
>+ }
>+ }
>+
>+ //
>+ // Build I/O APIC Structures
>+ //
>+ IoApicStruct.Type = EFI_ACPI_4_0_IO_APIC;
>+ IoApicStruct.Length = sizeof (EFI_ACPI_4_0_IO_APIC_STRUCTURE);
>+ IoApicStruct.Reserved = 0;
>+
>+ PcIoApicEnable = PcdGet32(PcdPcIoApicEnable);
>+
>+ if (FixedPcdGet32(PcdMaxCpuSocketCount) <= 4) {
>+ IoApicStruct.IoApicId = PcdGet8(PcdIoApicId);
>+ IoApicStruct.IoApicAddress = PcdGet32(PcdIoApicAddress);
>+ IoApicStruct.GlobalSystemInterruptBase = 0;
>+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
>+ Status = CopyStructure (
>+ &MadtTableHeader.Header,
>+ (STRUCTURE_HEADER *) &IoApicStruct,
>+ &MadtStructs[MadtStructsIndex++]
>+ );
>+ if (EFI_ERROR (Status)) {
>+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (I/O APIC) failed: %r\n",
>Status));
>+ goto Done;
>+ }
>+ }
>+
>+ for (PcIoApicIndex = 0; PcIoApicIndex < PcdGet8(PcdPcIoApicCount);
>PcIoApicIndex++) {
>+ PcIoApicMask = (1 << PcIoApicIndex);
>+ if ((PcIoApicEnable & PcIoApicMask) == 0) {
>+ continue;
>+ }
>+
>+ IoApicStruct.IoApicId = (UINT8)(PcdGet8(PcdPcIoApicIdBase) +
>PcIoApicIndex);
>+ IoApicStruct.IoApicAddress = CurrentIoApicAddress;
>+ CurrentIoApicAddress = (CurrentIoApicAddress & 0xFFFF8000) +
>0x8000;
>+ IoApicStruct.GlobalSystemInterruptBase = (UINT32)(24 + (PcIoApicIndex
>* 8));
>+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
>+ Status = CopyStructure (
>+ &MadtTableHeader.Header,
>+ (STRUCTURE_HEADER *) &IoApicStruct,
>+ &MadtStructs[MadtStructsIndex++]
>+ );
>+ if (EFI_ERROR (Status)) {
>+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (I/O APIC) failed: %r\n",
>Status));
>+ goto Done;
>+ }
>+ }
>+
>+ //
>+ // Build Interrupt Source Override Structures
>+ //
>+ IntSrcOverrideStruct.Type =
>EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE;
>+ IntSrcOverrideStruct.Length = sizeof
>(EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE);
>+
>+ //
>+ // IRQ0=>IRQ2 Interrupt Source Override Structure
>+ //
>+ IntSrcOverrideStruct.Bus = 0x0; // Bus - ISA
>+ IntSrcOverrideStruct.Source = 0x0; // Source - IRQ0
>+ IntSrcOverrideStruct.GlobalSystemInterrupt = 0x2; // Global System
>Interrupt - IRQ2
>+ IntSrcOverrideStruct.Flags = 0x0; // Flags - Conforms to
>specifications of the bus
>+
>+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
>+ Status = CopyStructure (
>+ &MadtTableHeader.Header,
>+ (STRUCTURE_HEADER *) &IntSrcOverrideStruct,
>+ &MadtStructs[MadtStructsIndex++]
>+ );
>+ if (EFI_ERROR (Status)) {
>+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (IRQ2 source override)
>failed: %r\n", Status));
>+ goto Done;
>+ }
>+
>+ //
>+ // IRQ9 (SCI Active High) Interrupt Source Override Structure
>+ //
>+ IntSrcOverrideStruct.Bus = 0x0; // Bus - ISA
>+ IntSrcOverrideStruct.Source = 0x9; // Source - IRQ9
>+ IntSrcOverrideStruct.GlobalSystemInterrupt = 0x9; // Global System
>Interrupt - IRQ9
>+ IntSrcOverrideStruct.Flags = 0xD; // Flags - Level-tiggered, Active
>High
>+
>+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
>+ Status = CopyStructure (
>+ &MadtTableHeader.Header,
>+ (STRUCTURE_HEADER *) &IntSrcOverrideStruct,
>+ &MadtStructs[MadtStructsIndex++]
>+ );
>+ if (EFI_ERROR (Status)) {
>+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (IRQ9 source override)
>failed: %r\n", Status));
>+ goto Done;
>+ }
>+
>+ //
>+ // Build Local APIC NMI Structures
>+ //
>+ LocalApciNmiStruct.Type = EFI_ACPI_4_0_LOCAL_APIC_NMI;
>+ LocalApciNmiStruct.Length = sizeof
>(EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE);
>+ LocalApciNmiStruct.AcpiProcessorId = 0xFF; // Applies to all processors
>+ LocalApciNmiStruct.Flags = 0x000D; // Flags - Level-tiggered, Active
>High
>+ LocalApciNmiStruct.LocalApicLint = 0x1;
>+
>+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
>+ Status = CopyStructure (
>+ &MadtTableHeader.Header,
>+ (STRUCTURE_HEADER *) &LocalApciNmiStruct,
>+ &MadtStructs[MadtStructsIndex++]
>+ );
>+ if (EFI_ERROR (Status)) {
>+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (APIC NMI) failed: %r\n",
>Status));
>+ goto Done;
>+ }
>+
>+ //
>+ // Build Local x2APIC NMI Structure
>+ //
>+ LocalX2ApicNmiStruct.Type = EFI_ACPI_4_0_LOCAL_X2APIC_NMI;
>+ LocalX2ApicNmiStruct.Length = sizeof
>(EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE);
>+ LocalX2ApicNmiStruct.Flags = 0x000D; // Flags - Level-tiggered,
>Active High
>+ LocalX2ApicNmiStruct.AcpiProcessorUid = 0xFFFFFFFF; // Applies to all
>processors
>+ LocalX2ApicNmiStruct.LocalX2ApicLint = 0x01;
>+ LocalX2ApicNmiStruct.Reserved[0] = 0x00;
>+ LocalX2ApicNmiStruct.Reserved[1] = 0x00;
>+ LocalX2ApicNmiStruct.Reserved[2] = 0x00;
>+
>+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
>+ Status = CopyStructure (
>+ &MadtTableHeader.Header,
>+ (STRUCTURE_HEADER *) &LocalX2ApicNmiStruct,
>+ &MadtStructs[MadtStructsIndex++]
>+ );
>+ if (EFI_ERROR (Status)) {
>+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (x2APIC NMI) failed: %r\n",
>Status));
>+ goto Done;
>+ }
>+
>+ //
>+ // Build Madt Structure from the Madt Header and collection of pointers in
>MadtStructs[]
>+ //
>+ Status = BuildAcpiTable (
>+ (EFI_ACPI_DESCRIPTION_HEADER *) &MadtTableHeader,
>+ sizeof (EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER),
>+ MadtStructs,
>+ MadtStructsIndex,
>+ (UINT8 **)&NewMadtTable
>+ );
>+ if (EFI_ERROR (Status)) {
>+ DEBUG ((EFI_D_ERROR, "BuildAcpiTable failed: %r\n", Status));
>+ goto Done;
>+ }
>+
>+ //
>+ // Publish Madt Structure to ACPI
>+ //
>+ Status = mAcpiTable->InstallAcpiTable (
>+ mAcpiTable,
>+ NewMadtTable,
>+ NewMadtTable->Header.Length,
>+ &TableHandle
>+ );
>+
>+Done:
>+ //
>+ // Free memory
>+ //
>+ for (MadtStructsIndex = 0; MadtStructsIndex < MaxMadtStructCount;
>MadtStructsIndex++) {
>+ if (MadtStructs[MadtStructsIndex] != NULL) {
>+ FreePool (MadtStructs[MadtStructsIndex]);
>+ }
>+ }
>+
>+ FreePool (MadtStructs);
>+
>+ if (NewMadtTable != NULL) {
>+ FreePool (NewMadtTable);
>+ }
>+
>+ return Status;
>+}
>+
>+EFI_STATUS
>+InstallMcfgFromScratch (
>+ VOID
>+ )
>+{
>+ EFI_STATUS Status;
>+
>EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HE
>ADER *McfgTable;
>+
>EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_
>ADDRESS_ALLOCATION_STRUCTURE *Segment;
>+ UINTN Index;
>+ UINTN SegmentCount;
>+ PCI_SEGMENT_INFO *PciSegmentInfo;
>+ UINTN TableHandle;
>+
>+ PciSegmentInfo = GetPciSegmentInfo (&SegmentCount);
>+
>+ McfgTable = AllocateZeroPool (
>+
>sizeof(EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TAB
>LE_HEADER) +
>+
>sizeof(EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_
>BASE_ADDRESS_ALLOCATION_STRUCTURE) * SegmentCount
>+ );
>+ if (McfgTable == NULL) {
>+ DEBUG ((DEBUG_ERROR, "Could not allocate MCFG structure\n"));
>+ return EFI_OUT_OF_RESOURCES;
>+ }
>+
>+ Status = InitializeHeader (
>+ &McfgTable->Header,
>+
>EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_
>BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
>+
>EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REV
>ISION,
>+ 0
>+ );
>+ if (EFI_ERROR (Status)) {
>+ return Status;
>+ }
>+
>+ //
>+ // Set MCFG table "Length" field based on the number of PCIe segments
>enumerated so far
>+ //
>+ McfgTable->Header.Length = (UINT32)(sizeof
>(EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HE
>ADER) +
>+ sizeof
>(EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_
>ADDRESS_ALLOCATION_STRUCTURE) * SegmentCount);
>+
>+ Segment = (VOID *)(McfgTable + 1);
>+
>+ for (Index = 0; Index < SegmentCount; Index++) {
>+ Segment[Index].PciSegmentGroupNumber =
>PciSegmentInfo[Index].SegmentNumber;
>+ Segment[Index].BaseAddress = PciSegmentInfo[Index].BaseAddress;
>+ Segment[Index].StartBusNumber =
>PciSegmentInfo[Index].StartBusNumber;
>+ Segment[Index].EndBusNumber =
>PciSegmentInfo[Index].EndBusNumber;
>+ }
>+
>+ //
>+ // Publish Madt Structure to ACPI
>+ //
>+ Status = mAcpiTable->InstallAcpiTable (
>+ mAcpiTable,
>+ McfgTable,
>+ McfgTable->Header.Length,
>+ &TableHandle
>+ );
>+
>+ return Status;
>+}
>+
>+/**
>+ This function will update any runtime platform specific information.
>+ This currently includes:
>+ Setting OEM table values, ID, table ID, creator ID and creator revision.
>+ Enabling the proper processor entries in the APIC tables
>+ It also indicates with which ACPI table version the table belongs.
>+
>+ @param[in] Table The table to update
>+ @param[in] Version Where to install this table
>+
>+ @retval EFI_SUCCESS Updated tables commplete.
>+**/
>+EFI_STATUS
>+PlatformUpdateTables (
>+ IN OUT EFI_ACPI_COMMON_HEADER *Table,
>+ IN OUT EFI_ACPI_TABLE_VERSION *Version
>+ )
>+{
>+ EFI_ACPI_DESCRIPTION_HEADER *TableHeader;
>+ UINT8 *TempOemId;
>+ UINT64 TempOemTableId;
>+ EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader;
>+ EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *HpetTable;
>+ UINT32 HpetBaseAddress;
>+ EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_BLOCK_ID HpetBlockId;
>+ UINT32 HpetCapabilitiesData;
>+ HPET_GENERAL_CAPABILITIES_ID_REGISTER HpetCapabilities;
>+
>+ TableHeader = NULL;
>+
>+ //
>+ // By default, a table belongs in all ACPI table versions published.
>+ // Some tables will override this because they have different versions of
>the table.
>+ //
>+ TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
>+
>+ //
>+ // Update the OEM and creator information for every table except FACS.
>+ //
>+ if (Table->Signature !=
>EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {
>+ TempOemId = (UINT8 *)PcdGetPtr(PcdAcpiDefaultOemId);
>+ CopyMem (&TableHeader->OemId, TempOemId, 6);
>+
>+ //
>+ // Skip OEM table ID and creator information for DSDT, SSDT and PSDT
>tables, since these are
>+ // created by an ASL compiler and the creator information is useful.
>+ //
>+ if (Table->Signature !=
>EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
>&&
>+ Table->Signature !=
>EFI_ACPI_1_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE &&
>+ Table->Signature !=
>EFI_ACPI_1_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
>+ ) {
>+ TempOemTableId = PcdGet64(PcdAcpiDefaultOemTableId);
>+ CopyMem (&TableHeader->OemTableId, &TempOemTableId, 8);
>+
>+ //
>+ // Update the creator ID
>+ //
>+ TableHeader->CreatorId = PcdGet32(PcdAcpiDefaultCreatorId);
>+
>+ //
>+ // Update the creator revision
>+ //
>+ TableHeader->CreatorRevision =
>PcdGet32(PcdAcpiDefaultCreatorRevision);
>+ }
>+ }
>+
>+
>+ //
>+ // By default, a table belongs in all ACPI table versions published.
>+ // Some tables will override this because they have different versions of
>the table.
>+ //
>+ *Version = EFI_ACPI_TABLE_VERSION_1_0B |
>EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0;
>+
>+ //
>+ // Update the various table types with the necessary updates
>+ //
>+ switch (Table->Signature) {
>+
>+ case EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
>+ ASSERT(FALSE);
>+ break;
>+
>+ case EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
>+ FadtHeader = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *) Table;
>+
>+ FadtHeader->PreferredPmProfile = PcdGet8 (PcdFadtPreferredPmProfile);
>+ FadtHeader->IaPcBootArch = PcdGet16 (PcdFadtIaPcBootArch);
>+ FadtHeader->Flags = PcdGet32 (PcdFadtFlags);
>+
>+ FadtHeader->AcpiEnable = PcdGet8 (PcdAcpiEnableSwSmi);
>+ FadtHeader->AcpiDisable = PcdGet8 (PcdAcpiDisableSwSmi);
>+
>+ FadtHeader->Pm1aEvtBlk = PcdGet16 (PcdAcpiPm1AEventBlockAddress);
>+ FadtHeader->Pm1bEvtBlk = PcdGet16 (PcdAcpiPm1BEventBlockAddress);
>+ FadtHeader->Pm1aCntBlk = PcdGet16 (PcdAcpiPm1AControlBlockAddress);
>+ FadtHeader->Pm1bCntBlk = PcdGet16 (PcdAcpiPm1BControlBlockAddress);
>+ FadtHeader->Pm2CntBlk = PcdGet16 (PcdAcpiPm2ControlBlockAddress);
>+ FadtHeader->PmTmrBlk = PcdGet16 (PcdAcpiPmTimerBlockAddress);
>+ FadtHeader->Gpe0Blk = PcdGet16 (PcdAcpiGpe0BlockAddress);
>+ FadtHeader->Gpe1Blk = PcdGet16 (PcdAcpiGpe1BlockAddress);
>+
>+ FadtHeader->XPm1aEvtBlk.Address = PcdGet16
>(PcdAcpiPm1AEventBlockAddress);
>+ FadtHeader->XPm1bEvtBlk.Address = PcdGet16
>(PcdAcpiPm1BEventBlockAddress);
>+ if (FadtHeader->XPm1bEvtBlk.Address == 0) {
>+ FadtHeader->XPm1bEvtBlk.AccessSize = 0;
>+ }
>+ FadtHeader->XPm1aCntBlk.Address = PcdGet16
>(PcdAcpiPm1AControlBlockAddress);
>+ FadtHeader->XPm1bCntBlk.Address = PcdGet16
>(PcdAcpiPm1BControlBlockAddress);
>+ if (FadtHeader->XPm1bCntBlk.Address == 0) {
>+ FadtHeader->XPm1bCntBlk.AccessSize = 0;
>+ }
>+ FadtHeader->XPm2CntBlk.Address = PcdGet16
>(PcdAcpiPm2ControlBlockAddress);
>+ //if (FadtHeader->XPm2CntBlk.Address == 0) {
>+ FadtHeader->XPm2CntBlk.AccessSize = 0;
>+ //}
>+ FadtHeader->XPmTmrBlk.Address = PcdGet16
>(PcdAcpiPmTimerBlockAddress);
>+ FadtHeader->XGpe0Blk.Address = PcdGet16 (PcdAcpiGpe0BlockAddress);
>+ FadtHeader->XGpe1Blk.Address = PcdGet16 (PcdAcpiGpe1BlockAddress);
>+ if (FadtHeader->XGpe1Blk.Address == 0) {
>+ FadtHeader->XGpe1Blk.AccessSize = 0;
>+ }
>+
>+ DEBUG(( EFI_D_ERROR, "ACPI FADT table @ address 0x%x\n", Table ));
>+ DEBUG(( EFI_D_ERROR, " IaPcBootArch 0x%x\n", FadtHeader-
>>IaPcBootArch ));
>+ DEBUG(( EFI_D_ERROR, " Flags 0x%x\n", FadtHeader->Flags ));
>+ break;
>+
>+ case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE:
>+ HpetTable = (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER
>*)Table;
>+ HpetBaseAddress = PcdGet32 (PcdHpetBaseAddress);
>+ HpetTable->BaseAddressLower32Bit.Address = HpetBaseAddress;
>+ HpetTable->BaseAddressLower32Bit.RegisterBitWidth = 0;
>+ HpetCapabilitiesData = MmioRead32 (HpetBaseAddress +
>HPET_GENERAL_CAPABILITIES_ID_OFFSET);
>+ HpetCapabilities.Uint64 = HpetCapabilitiesData;
>+ HpetCapabilitiesData = MmioRead32 (HpetBaseAddress +
>HPET_GENERAL_CAPABILITIES_ID_OFFSET + 4);
>+ HpetCapabilities.Uint64 |= LShiftU64 (HpetCapabilitiesData, 32);
>+ HpetBlockId.Bits.Revision = HpetCapabilities.Bits.Revision;
>+ HpetBlockId.Bits.NumberOfTimers =
>HpetCapabilities.Bits.NumberOfTimers;
>+ HpetBlockId.Bits.CounterSize = HpetCapabilities.Bits.CounterSize;
>+ HpetBlockId.Bits.Reserved = 0;
>+ HpetBlockId.Bits.LegacyRoute = HpetCapabilities.Bits.LegacyRoute;
>+ HpetBlockId.Bits.VendorId = HpetCapabilities.Bits.VendorId;
>+ HpetTable->EventTimerBlockId = HpetBlockId.Uint32;
>+ HpetTable->MainCounterMinimumClockTickInPeriodicMode =
>(UINT16)HpetCapabilities.Bits.CounterClockPeriod;
>+ DEBUG(( EFI_D_ERROR, "ACPI HPET table @ address 0x%x\n", Table ));
>+ DEBUG(( EFI_D_ERROR, " HPET base 0x%x\n", PcdGet32
>(PcdHpetBaseAddress) ));
>+ break;
>+
>+ case
>EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_
>BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:
>+ ASSERT(FALSE);
>+ break;
>+
>+ default:
>+ break;
>+ }
>+ return EFI_SUCCESS;
>+}
>+
>+/**
>+ This function calculates RCR based on PCI Device ID and Vendor ID from the
>devices
>+ available on the platform.
>+ It also includes other instances of BIOS change to calculate CRC and provides
>as
>+ HWSignature filed in FADT table.
>+**/
>+VOID
>+IsHardwareChange (
>+ VOID
>+ )
>+{
>+ EFI_STATUS Status;
>+ UINTN Index;
>+ UINTN HandleCount;
>+ EFI_HANDLE *HandleBuffer;
>+ EFI_PCI_IO_PROTOCOL *PciIo;
>+ UINT32 CRC;
>+ UINT32 *HWChange;
>+ UINTN HWChangeSize;
>+ UINT32 PciId;
>+ UINTN Handle;
>+ EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *FacsPtr;
>+ EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *pFADT;
>+
>+ HandleCount = 0;
>+ HandleBuffer = NULL;
>+
>+ Status = gBS->LocateHandleBuffer (
>+ ByProtocol,
>+ &gEfiPciIoProtocolGuid,
>+ NULL,
>+ &HandleCount,
>+ &HandleBuffer
>+ );
>+ if (EFI_ERROR (Status)) {
>+ return; // PciIO protocol not installed yet!
>+ }
>+
>+ //
>+ // Allocate memory for HWChange and add additional entrie for
>+ // pFADT->XDsdt
>+ //
>+ HWChangeSize = HandleCount + 1;
>+ HWChange = AllocateZeroPool( sizeof(UINT32) * HWChangeSize );
>+ ASSERT( HWChange != NULL );
>+
>+ if (HWChange == NULL) return;
>+
>+ //
>+ // add HWChange inputs: PCI devices
>+ //
>+ for (Index = 0; HandleCount > 0; HandleCount--) {
>+ PciId = 0;
>+ Status = gBS->HandleProtocol (HandleBuffer[Index],
>&gEfiPciIoProtocolGuid, (VOID **) &PciIo);
>+ if (!EFI_ERROR (Status)) {
>+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0, 1, &PciId);
>+ if (EFI_ERROR (Status)) {
>+ continue;
>+ }
>+ HWChange[Index++] = PciId;
>+ }
>+ }
>+
>+ //
>+ // Locate FACP Table
>+ //
>+ Handle = 0;
>+ Status = LocateAcpiTableBySignature (
>+ EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
>+ (EFI_ACPI_DESCRIPTION_HEADER **) &pFADT,
>+ &Handle
>+ );
>+ if (EFI_ERROR (Status) || (pFADT == NULL)) {
>+ return; //Table not found or out of memory resource for pFADT table
>+ }
>+
>+ //
>+ // add HWChange inputs: others
>+ //
>+ HWChange[Index++] = (UINT32)pFADT->XDsdt;
>+
>+ //
>+ // Calculate CRC value with HWChange data.
>+ //
>+ Status = gBS->CalculateCrc32(HWChange, HWChangeSize, &CRC);
>+ DEBUG((DEBUG_INFO, "CRC = %x and Status = %r\n", CRC, Status));
>+
>+ //
>+ // Set HardwareSignature value based on CRC value.
>+ //
>+ FacsPtr = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
>*)(UINTN)pFADT->FirmwareCtrl;
>+ FacsPtr->HardwareSignature = CRC;
>+ FreePool( HWChange );
>+}
>+
>+VOID
>+UpdateLocalTable (
>+ VOID
>+ )
>+{
>+ EFI_STATUS Status;
>+ EFI_ACPI_COMMON_HEADER *CurrentTable;
>+ EFI_ACPI_TABLE_VERSION Version;
>+ UINTN TableHandle;
>+ UINTN Index;
>+
>+ for (Index = 0; Index < sizeof(mLocalTable)/sizeof(mLocalTable[0]); Index++)
>{
>+ CurrentTable = mLocalTable[Index];
>+
>+ PlatformUpdateTables (CurrentTable, &Version);
>+
>+ TableHandle = 0;
>+
>+ if (Version != EFI_ACPI_TABLE_VERSION_NONE) {
>+ Status = mAcpiTable->InstallAcpiTable (
>+ mAcpiTable,
>+ CurrentTable,
>+ CurrentTable->Length,
>+ &TableHandle
>+ );
>+ ASSERT_EFI_ERROR (Status);
>+ }
>+ }
>+}
>+
>+
>+VOID
>+EFIAPI
>+AcpiEndOfDxeEvent (
>+ EFI_EVENT Event,
>+ VOID *ParentImageHandle
>+ )
>+{
>+
>+ if (Event != NULL) {
>+ gBS->CloseEvent(Event);
>+ }
>+
>+
>+ //
>+ // Calculate Hardware Signature value based on current platform
>configurations
>+ //
>+ IsHardwareChange();
>+}
>+
>+/**
>+ ACPI Platform driver installation function.
>+
>+ @param[in] ImageHandle Handle for this drivers loaded image protocol.
>+ @param[in] SystemTable EFI system table.
>+
>+ @retval EFI_SUCCESS The driver installed without error.
>+ @retval EFI_ABORTED The driver encountered an error and could not
>complete installation of
>+ the ACPI tables.
>+
>+**/
>+EFI_STATUS
>+EFIAPI
>+InstallAcpiPlatform (
>+ IN EFI_HANDLE ImageHandle,
>+ IN EFI_SYSTEM_TABLE *SystemTable
>+ )
>+{
>+ EFI_STATUS Status;
>+ EFI_EVENT EndOfDxeEvent;
>+
>+
>+ Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID
>**)&mMpService);
>+ ASSERT_EFI_ERROR (Status);
>+
>+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID
>**)&mAcpiTable);
>+ ASSERT_EFI_ERROR (Status);
>+
>+ //
>+ // Create an End of DXE event.
>+ //
>+ Status = gBS->CreateEventEx (
>+ EVT_NOTIFY_SIGNAL,
>+ TPL_CALLBACK,
>+ AcpiEndOfDxeEvent,
>+ NULL,
>+ &gEfiEndOfDxeEventGroupGuid,
>+ &EndOfDxeEvent
>+ );
>+ ASSERT_EFI_ERROR (Status);
>+
>+ //
>+ // Determine the number of processors
>+ //
>+ mMpService->GetNumberOfProcessors (
>+ mMpService,
>+ &mNumberOfCPUs,
>+ &mNumberOfEnabledCPUs
>+ );
>+ ASSERT (mNumberOfCPUs <= MAX_CPU_NUM &&
>mNumberOfEnabledCPUs >= 1);
>+ DEBUG ((DEBUG_INFO, "mNumberOfCPUs - %d\n", mNumberOfCPUs));
>+ DEBUG ((DEBUG_INFO, "mNumberOfEnabledCPUs - %d\n",
>mNumberOfEnabledCPUs));
>+
>+ DEBUG ((DEBUG_INFO, "mX2ApicEnabled - 0x%x\n", mX2ApicEnabled));
>+ DEBUG ((DEBUG_INFO, "mForceX2ApicId - 0x%x\n", mForceX2ApicId));
>+
>+ // support up to 64 threads/socket
>+ AsmCpuidEx(CPUID_EXTENDED_TOPOLOGY, 1, &mNumOfBitShift, NULL,
>NULL, NULL);
>+ mNumOfBitShift &= 0x1F;
>+ DEBUG ((DEBUG_INFO, "mNumOfBitShift - 0x%x\n", mNumOfBitShift));
>+
>+ UpdateLocalTable ();
>+
>+ InstallMadtFromScratch ();
>+ InstallMcfgFromScratch ();
>+
>+ return EFI_SUCCESS;
>+}
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/Facs/Facs.c
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/Facs/Facs.c
>new file mode 100644
>index 0000000000..e649b5b89c
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/Facs/Facs.c
>@@ -0,0 +1,84 @@
>+/** @file
>+ This file contains a structure definition for the ACPI 5.0 Firmware ACPI
>+ Control Structure (FACS). The contents of this file should only be modified
>+ for bug fixes, no porting is required.
>+
>+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
>+
>+ SPDX-License-Identifier: BSD-2-Clause-Patent
>+**/
>+
>+//
>+// Statements that include other files
>+//
>+
>+#include <IndustryStandard/Acpi.h>
>+
>+//
>+// FACS Definitions
>+//
>+#define EFI_ACPI_FIRMWARE_WAKING_VECTOR 0x00000000
>+#define EFI_ACPI_GLOBAL_LOCK 0x00000000
>+
>+//
>+// Firmware Control Structure Feature Flags are defined in AcpiX.0.h
>+//
>+#define EFI_ACPI_FIRMWARE_CONTROL_STRUCTURE_FLAGS 0x00000000
>+
>+#define EFI_ACPI_X_FIRMWARE_WAKING_VECTOR
>0x0000000000000000
>+
>+#define EFI_ACPI_OSPM_FLAGS 0x00000000
>+
>+
>+//
>+// Firmware ACPI Control Structure
>+// Please modify all values in Facs.h only.
>+//
>+
>+EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE Facs = {
>+ EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE,
>+ sizeof (EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE),
>+
>+ //
>+ // Hardware Signature will be updated at runtime
>+ //
>+ 0x00000000,
>+
>+ EFI_ACPI_FIRMWARE_WAKING_VECTOR,
>+ EFI_ACPI_GLOBAL_LOCK,
>+ EFI_ACPI_FIRMWARE_CONTROL_STRUCTURE_FLAGS,
>+ EFI_ACPI_X_FIRMWARE_WAKING_VECTOR,
>+ EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION,
>+ {
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE
>+ },
>+ EFI_ACPI_OSPM_FLAGS,
>+ {
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE
>+ }
>+};
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/Fadt/Fadt.c
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/Fadt/Fadt.c
>new file mode 100644
>index 0000000000..d1fe98e24b
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/Fadt/Fadt.c
>@@ -0,0 +1,359 @@
>+/** @file
>+ This file contains a structure definition for the ACPI 5.0 Fixed ACPI
>+ Description Table (FADT). The contents of this file should only be modified
>+ for bug fixes, no porting is required.
>+
>+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
>+
>+ SPDX-License-Identifier: BSD-2-Clause-Patent
>+**/
>+
>+//
>+// Statements that include other files
>+//
>+#include <IndustryStandard/Acpi.h>
>+
>+//
>+// FADT Definitions
>+//
>+#define EFI_ACPI_OEM_FADT_REVISION 0x00000000
>+
>+#define EFI_ACPI_PREFERRED_PM_PROFILE 0x00 // To be fixed
>+
>+#define EFI_ACPI_SCI_INT 0x0009
>+#define EFI_ACPI_SMI_CMD 0x000000B2
>+
>+#define EFI_ACPI_ACPI_ENABLE 0 // To be fixed
>+#define EFI_ACPI_ACPI_DISABLE 0 // To be fixed
>+#define EFI_ACPI_S4_BIOS_REQ 0x00
>+#define EFI_ACPI_CST_CNT 0x00
>+
>+#define EFI_ACPI_PSTATE_CNT 0x00
>+#define EFI_ACPI_GPE1_BASE (EFI_ACPI_GPE1_BLK_BIT_WIDTH / 2)
>+#define EFI_ACPI_P_LVL2_LAT 0x0065 // 101
>+#define EFI_ACPI_P_LVL3_LAT 0x03E9 // 1001
>+#define EFI_ACPI_FLUSH_SIZE 0x0000
>+#define EFI_ACPI_FLUSH_STRIDE 0x0000
>+#define EFI_ACPI_DUTY_OFFSET 0x01
>+#define EFI_ACPI_DUTY_WIDTH 0x00
>+
>+#define EFI_ACPI_DAY_ALRM 0x0D
>+#define EFI_ACPI_MON_ALRM 0x00
>+#define EFI_ACPI_CENTURY 0x32
>+
>+//
>+// IA-PC Boot Architecture Flags
>+//
>+
>+#define EFI_ACPI_IAPC_BOOT_ARCH 0 // To be fixed
>+
>+//
>+// Fixed Feature Flags
>+//
>+#define EFI_ACPI_FIXED_FEATURE_FLAGS 0 // To be fixed
>+
>+//
>+// PM1A Event Register Block Generic Address Information
>+//
>+#define EFI_ACPI_PM1A_EVT_BLK_ADDRESS_SPACE_ID
>EFI_ACPI_2_0_SYSTEM_IO
>+#define EFI_ACPI_PM1A_EVT_BLK_BIT_WIDTH 0x20
>+#define EFI_ACPI_PM1A_EVT_BLK_BIT_OFFSET 0x00
>+#define EFI_ACPI_PM1A_EVT_BLK_ADDRESS 0 // To be fixed
>+
>+//
>+// PM1B Event Register Block Generic Address Information
>+//
>+#define EFI_ACPI_PM1B_EVT_BLK_ADDRESS_SPACE_ID
>EFI_ACPI_2_0_SYSTEM_IO
>+#define EFI_ACPI_PM1B_EVT_BLK_BIT_WIDTH 0x00
>+#define EFI_ACPI_PM1B_EVT_BLK_BIT_OFFSET 0x00
>+#define EFI_ACPI_PM1B_EVT_BLK_ADDRESS 0 // To be fixed
>+
>+//
>+// PM1A Control Register Block Generic Address Information
>+//
>+#define EFI_ACPI_PM1A_CNT_BLK_ADDRESS_SPACE_ID
>EFI_ACPI_2_0_SYSTEM_IO
>+#define EFI_ACPI_PM1A_CNT_BLK_BIT_WIDTH 0x10
>+#define EFI_ACPI_PM1A_CNT_BLK_BIT_OFFSET 0x00
>+#define EFI_ACPI_PM1A_CNT_BLK_ADDRESS 0 // To be fixed
>+
>+//
>+// PM1B Control Register Block Generic Address Information
>+//
>+#define EFI_ACPI_PM1B_CNT_BLK_ADDRESS_SPACE_ID
>EFI_ACPI_2_0_SYSTEM_IO
>+#define EFI_ACPI_PM1B_CNT_BLK_BIT_WIDTH 0x00
>+#define EFI_ACPI_PM1B_CNT_BLK_BIT_OFFSET 0x00
>+#define EFI_ACPI_PM1B_CNT_BLK_ADDRESS 0 // To be fixed
>+
>+//
>+// PM2 Control Register Block Generic Address Information
>+//
>+#define EFI_ACPI_PM2_CNT_BLK_ADDRESS_SPACE_ID
>EFI_ACPI_2_0_SYSTEM_IO
>+#define EFI_ACPI_PM2_CNT_BLK_BIT_WIDTH 0x08
>+#define EFI_ACPI_PM2_CNT_BLK_BIT_OFFSET 0x00
>+#define EFI_ACPI_PM2_CNT_BLK_ADDRESS 0 // To be fixed
>+
>+//
>+// Power Management Timer Control Register Block Generic Address
>+// Information
>+//
>+#define EFI_ACPI_PM_TMR_BLK_ADDRESS_SPACE_ID
>EFI_ACPI_2_0_SYSTEM_IO
>+#define EFI_ACPI_PM_TMR_BLK_BIT_WIDTH 0x20
>+#define EFI_ACPI_PM_TMR_BLK_BIT_OFFSET 0x00
>+#define EFI_ACPI_PM_TMR_BLK_ADDRESS 0 // To be fixed
>+
>+//
>+// General Purpose Event 0 Register Block Generic Address
>+// Information
>+//
>+#define EFI_ACPI_GPE0_BLK_ADDRESS_SPACE_ID
>EFI_ACPI_2_0_SYSTEM_IO
>+#define EFI_ACPI_GPE0_BLK_BIT_WIDTH 0 // size of
>R_PCH_ACPI_GPE0_STS_127_96 + R_PCH_ACPI_GPE0_EN_127_96
>+#define EFI_ACPI_GPE0_BLK_BIT_OFFSET 0x00
>+#define EFI_ACPI_GPE0_BLK_ADDRESS 0 // To be fixed
>+
>+//
>+// General Purpose Event 1 Register Block Generic Address
>+// Information
>+//
>+#define EFI_ACPI_GPE1_BLK_ADDRESS_SPACE_ID
>EFI_ACPI_2_0_SYSTEM_IO
>+#define EFI_ACPI_GPE1_BLK_BIT_WIDTH 0x0
>+#define EFI_ACPI_GPE1_BLK_BIT_OFFSET 0x0
>+#define EFI_ACPI_GPE1_BLK_ADDRESS 0 // To be fixed
>+//
>+// Reset Register Generic Address Information
>+//
>+#define EFI_ACPI_RESET_REG_ADDRESS_SPACE_ID
>EFI_ACPI_2_0_SYSTEM_IO
>+#define EFI_ACPI_RESET_REG_BIT_WIDTH 0x08
>+#define EFI_ACPI_RESET_REG_BIT_OFFSET 0x00
>+#define EFI_ACPI_RESET_REG_ADDRESS 0x00000CF9
>+#define EFI_ACPI_RESET_VALUE 0x06
>+
>+//
>+// Number of bytes decoded by PM1 event blocks (a and b)
>+//
>+#define EFI_ACPI_PM1_EVT_LEN ((EFI_ACPI_PM1A_EVT_BLK_BIT_WIDTH
>+ EFI_ACPI_PM1B_EVT_BLK_BIT_WIDTH) / 8)
>+
>+//
>+// Number of bytes decoded by PM1 control blocks (a and b)
>+//
>+#define EFI_ACPI_PM1_CNT_LEN ((EFI_ACPI_PM1A_CNT_BLK_BIT_WIDTH
>+ EFI_ACPI_PM1B_CNT_BLK_BIT_WIDTH) / 8)
>+
>+//
>+// Number of bytes decoded by PM2 control block
>+//
>+#define EFI_ACPI_PM2_CNT_LEN (EFI_ACPI_PM2_CNT_BLK_BIT_WIDTH / 8)
>+
>+//
>+// Number of bytes decoded by PM timer block
>+//
>+#define EFI_ACPI_PM_TMR_LEN (EFI_ACPI_PM_TMR_BLK_BIT_WIDTH / 8)
>+
>+//
>+// Number of bytes decoded by GPE0 block
>+//
>+#define EFI_ACPI_GPE0_BLK_LEN (EFI_ACPI_GPE0_BLK_BIT_WIDTH / 8)
>+
>+//
>+// Number of bytes decoded by GPE1 block
>+//
>+#define EFI_ACPI_GPE1_BLK_LEN (EFI_ACPI_GPE1_BLK_BIT_WIDTH / 8)
>+
>+//
>+// Fixed ACPI Description Table
>+// Please modify all values in Fadt.h only.
>+//
>+
>+EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE Fadt = {
>+ {
>+ EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
>+ sizeof (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE),
>+ EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,
>+
>+ //
>+ // Checksum will be updated at runtime
>+ //
>+ 0x00,
>+
>+ //
>+ // It is expected that these values will be updated at runtime
>+ //
>+ { ' ', ' ', ' ', ' ', ' ', ' ' },
>+
>+ 0,
>+ EFI_ACPI_OEM_FADT_REVISION,
>+ 0,
>+ 0
>+ },
>+
>+ //
>+ // These addresses will be updated at runtime
>+ //
>+ 0x00000000,
>+ 0x00000000,
>+
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_PREFERRED_PM_PROFILE,
>+ EFI_ACPI_SCI_INT,
>+ EFI_ACPI_SMI_CMD,
>+ EFI_ACPI_ACPI_ENABLE,
>+ EFI_ACPI_ACPI_DISABLE,
>+ EFI_ACPI_S4_BIOS_REQ,
>+ EFI_ACPI_PSTATE_CNT,
>+
>+ EFI_ACPI_PM1A_EVT_BLK_ADDRESS,
>+ EFI_ACPI_PM1B_EVT_BLK_ADDRESS,
>+ EFI_ACPI_PM1A_CNT_BLK_ADDRESS,
>+ EFI_ACPI_PM1B_CNT_BLK_ADDRESS,
>+ EFI_ACPI_PM2_CNT_BLK_ADDRESS,
>+ EFI_ACPI_PM_TMR_BLK_ADDRESS,
>+ EFI_ACPI_GPE0_BLK_ADDRESS,
>+ EFI_ACPI_GPE1_BLK_ADDRESS,
>+ EFI_ACPI_PM1_EVT_LEN,
>+ EFI_ACPI_PM1_CNT_LEN,
>+ EFI_ACPI_PM2_CNT_LEN,
>+ EFI_ACPI_PM_TMR_LEN,
>+ EFI_ACPI_GPE0_BLK_LEN,
>+ EFI_ACPI_GPE1_BLK_LEN,
>+ EFI_ACPI_GPE1_BASE,
>+
>+ //
>+ // Latest OS have C-State capability and CST_CNT SMI doesn't need to be
>defined.
>+ // CST_CNT SMI is not handled in BIOS and it can be removed safely.
>+ //
>+ EFI_ACPI_CST_CNT,
>+ EFI_ACPI_P_LVL2_LAT,
>+ EFI_ACPI_P_LVL3_LAT,
>+ EFI_ACPI_FLUSH_SIZE,
>+ EFI_ACPI_FLUSH_STRIDE,
>+ EFI_ACPI_DUTY_OFFSET,
>+ EFI_ACPI_DUTY_WIDTH,
>+ EFI_ACPI_DAY_ALRM,
>+ EFI_ACPI_MON_ALRM,
>+ EFI_ACPI_CENTURY,
>+ EFI_ACPI_IAPC_BOOT_ARCH,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_FIXED_FEATURE_FLAGS,
>+
>+ //
>+ // Reset Register Block
>+ //
>+ {
>+ EFI_ACPI_RESET_REG_ADDRESS_SPACE_ID,
>+ EFI_ACPI_RESET_REG_BIT_WIDTH,
>+ EFI_ACPI_RESET_REG_BIT_OFFSET,
>+ EFI_ACPI_5_0_BYTE,
>+ EFI_ACPI_RESET_REG_ADDRESS
>+ },
>+ EFI_ACPI_RESET_VALUE,
>+ {
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE,
>+ EFI_ACPI_RESERVED_BYTE
>+ },
>+
>+ //
>+ // These addresses will be updated at runtime
>+ //
>+ 0x0000000000000000, // X_FIRMWARE_CTRL
>+ 0x0000000000000000, // X_DSDT
>+
>+ {
>+ //
>+ // X_PM1a Event Register Block
>+ //
>+ EFI_ACPI_PM1A_EVT_BLK_ADDRESS_SPACE_ID,
>+ EFI_ACPI_PM1A_EVT_BLK_BIT_WIDTH,
>+ EFI_ACPI_PM1A_EVT_BLK_BIT_OFFSET,
>+ EFI_ACPI_5_0_WORD,
>+ EFI_ACPI_PM1A_EVT_BLK_ADDRESS
>+ },
>+ {
>+ //
>+ // X_PM1b Event Register Block
>+ //
>+ EFI_ACPI_PM1B_EVT_BLK_ADDRESS_SPACE_ID,
>+ EFI_ACPI_PM1B_EVT_BLK_BIT_WIDTH,
>+ EFI_ACPI_PM1B_EVT_BLK_BIT_OFFSET,
>+ EFI_ACPI_5_0_WORD,
>+ EFI_ACPI_PM1B_EVT_BLK_ADDRESS
>+ },
>+ {
>+ //
>+ // X_PM1a Control Register Block
>+ //
>+ EFI_ACPI_PM1A_CNT_BLK_ADDRESS_SPACE_ID,
>+ EFI_ACPI_PM1A_CNT_BLK_BIT_WIDTH,
>+ EFI_ACPI_PM1A_CNT_BLK_BIT_OFFSET,
>+ EFI_ACPI_5_0_WORD,
>+ EFI_ACPI_PM1A_CNT_BLK_ADDRESS
>+ },
>+ {
>+ //
>+ // X_PM1b Control Register Block
>+ //
>+ EFI_ACPI_PM1B_CNT_BLK_ADDRESS_SPACE_ID,
>+ EFI_ACPI_PM1B_CNT_BLK_BIT_WIDTH,
>+ EFI_ACPI_PM1B_CNT_BLK_BIT_OFFSET,
>+ EFI_ACPI_5_0_WORD,
>+ EFI_ACPI_PM1B_CNT_BLK_ADDRESS
>+ },
>+ {
>+ //
>+ // X_PM2 Control Register Block
>+ //
>+ EFI_ACPI_PM2_CNT_BLK_ADDRESS_SPACE_ID,
>+ EFI_ACPI_PM2_CNT_BLK_BIT_WIDTH,
>+ EFI_ACPI_PM2_CNT_BLK_BIT_OFFSET,
>+ EFI_ACPI_5_0_BYTE,
>+ EFI_ACPI_PM2_CNT_BLK_ADDRESS
>+ },
>+ {
>+ //
>+ // X_PM Timer Control Register Block
>+ //
>+ EFI_ACPI_PM_TMR_BLK_ADDRESS_SPACE_ID,
>+ EFI_ACPI_PM_TMR_BLK_BIT_WIDTH,
>+ EFI_ACPI_PM_TMR_BLK_BIT_OFFSET,
>+ EFI_ACPI_5_0_DWORD,
>+ EFI_ACPI_PM_TMR_BLK_ADDRESS
>+ },
>+ {
>+ //
>+ // X_General Purpose Event 0 Register Block
>+ //
>+ EFI_ACPI_GPE0_BLK_ADDRESS_SPACE_ID,
>+ EFI_ACPI_GPE0_BLK_BIT_WIDTH,
>+ EFI_ACPI_GPE0_BLK_BIT_OFFSET,
>+ EFI_ACPI_5_0_BYTE,
>+ EFI_ACPI_GPE0_BLK_ADDRESS
>+ },
>+ {
>+ //
>+ // X_General Purpose Event 1 Register Block
>+ //
>+ EFI_ACPI_GPE1_BLK_ADDRESS_SPACE_ID,
>+ EFI_ACPI_GPE1_BLK_BIT_WIDTH,
>+ EFI_ACPI_GPE1_BLK_BIT_OFFSET,
>+ EFI_ACPI_5_0_BYTE,
>+ EFI_ACPI_GPE1_BLK_ADDRESS
>+ },
>+ {
>+ //
>+ // Sleep Control Reg - update in DXE driver
>+ //
>+ 0,
>+ 0,
>+ 0,
>+ 0,
>+ 0
>+ },
>+ {
>+ //
>+ // Sleep Status Reg - update in DXE driver
>+ //
>+ 0,
>+ 0,
>+ 0,
>+ 0,
>+ 0
>+ }
>+};
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/Hpet/Hpet.c
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/Hpet/Hpet.c
>new file mode 100644
>index 0000000000..e9528b0ec3
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/Hpet/Hpet.c
>@@ -0,0 +1,78 @@
>+/** @file
>+ This file contains a structure definition for the ACPI 1.0 High Precision Event
>Timer
>+ Description Table (HPET). The contents of this file should only be modified
>+ for bug fixes, no porting is required.
>+
>+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
>+
>+ SPDX-License-Identifier: BSD-2-Clause-Patent
>+**/
>+
>+//
>+// Statements that include other files
>+//
>+
>+#include <IndustryStandard/Acpi.h>
>+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
>+
>+//
>+// HPET Definitions
>+//
>+#define EFI_ACPI_OEM_HPET_REVISION 0x00000001
>+
>+#define EFI_ACPI_EVENT_TIMER_BLOCK_ID 0x0 // To be filled
>+
>+//
>+// Event Timer Block Base Address Information
>+//
>+#define EFI_ACPI_EVENT_TIMER_BLOCK_ADDRESS_SPACE_ID
>EFI_ACPI_3_0_SYSTEM_MEMORY
>+#define EFI_ACPI_EVENT_TIMER_BLOCK_BIT_WIDTH 0x40
>+#define EFI_ACPI_EVENT_TIMER_BLOCK_BIT_OFFSET 0x00
>+#define EFI_ACPI_EVENT_TIMER_ACCESS_SIZE 0x00
>+#define EFI_ACPI_EVENT_TIMER_BLOCK_ADDRESS 0x0 // To be filled
>+
>+#define EFI_ACPI_HPET_NUMBER 0x00
>+
>+#define EFI_ACPI_MIN_CLOCK_TICK 0x0080
>+
>+#define EFI_ACPI_HPET_ATTRIBUTES 0x00
>+
>+//
>+// High Precision Event Timer Table
>+// Please modify all values in Hpet.h only.
>+//
>+
>+EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER Hpet = {
>+ {
>+ EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE,
>+ sizeof (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER),
>+ EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_REVISION,
>+
>+ //
>+ // Checksum will be updated at runtime
>+ //
>+ 0x00,
>+
>+ //
>+ // It is expected that these values will be updated at runtime
>+ //
>+ { ' ', ' ', ' ', ' ', ' ', ' ' },
>+
>+ 0,
>+ EFI_ACPI_OEM_HPET_REVISION,
>+ 0,
>+ 0
>+ },
>+
>+ EFI_ACPI_EVENT_TIMER_BLOCK_ID,
>+ {
>+ EFI_ACPI_EVENT_TIMER_BLOCK_ADDRESS_SPACE_ID,
>+ EFI_ACPI_EVENT_TIMER_BLOCK_BIT_WIDTH,
>+ EFI_ACPI_EVENT_TIMER_BLOCK_BIT_OFFSET,
>+ EFI_ACPI_EVENT_TIMER_ACCESS_SIZE,
>+ EFI_ACPI_EVENT_TIMER_BLOCK_ADDRESS
>+ },
>+ EFI_ACPI_HPET_NUMBER,
>+ EFI_ACPI_MIN_CLOCK_TICK,
>+ EFI_ACPI_HPET_ATTRIBUTES
>+};
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/Wsmt/Wsmt.c
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/Wsmt/Wsmt.c
>new file mode 100644
>index 0000000000..625b7560bb
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/Wsmt/Wsmt.c
>@@ -0,0 +1,46 @@
>+/** @file
>+ ACPI WSMT table
>+
>+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
>+
>+ SPDX-License-Identifier: BSD-2-Clause-Patent
>+**/
>+
>+//
>+// Statements that include other files
>+//
>+
>+#include <IndustryStandard/Acpi.h>
>+#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
>+#include <Library/PcdLib.h>
>+
>+//
>+// WSMT Definitions
>+//
>+
>+#define EFI_ACPI_OEM_WSMT_REVISION 0x00000001
>+
>+EFI_ACPI_WSMT_TABLE Wsmt = {
>+ {
>+ EFI_ACPI_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE,
>+ sizeof (EFI_ACPI_WSMT_TABLE),
>+ EFI_WSMT_TABLE_REVISION,
>+
>+ //
>+ // Checksum will be updated at runtime
>+ //
>+ 0x00,
>+
>+ //
>+ // It is expected that these values will be updated at runtime
>+ //
>+ { ' ', ' ', ' ', ' ', ' ', ' ' },
>+
>+ 0,
>+ EFI_ACPI_OEM_WSMT_REVISION,
>+ 0,
>+ 0
>+ },
>+
>+ FixedPcdGet32(PcdWsmtProtectionFlags)
>+};
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>ComponentName.c
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>ComponentName.c
>new file mode 100644
>index 0000000000..d6d1d451df
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>ComponentName.c
>@@ -0,0 +1,205 @@
>+/** @file
>+ Component name for the QEMU video controller.
>+
>+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
>+
>+ SPDX-License-Identifier: BSD-2-Clause-Patent
>+**/
>+
>+#include "Qemu.h"
>+
>+//
>+// EFI Component Name Protocol
>+//
>+GLOBAL_REMOVE_IF_UNREFERENCED
>EFI_COMPONENT_NAME_PROTOCOL gQemuVideoComponentName = {
>+ QemuVideoComponentNameGetDriverName,
>+ QemuVideoComponentNameGetControllerName,
>+ "eng"
>+};
>+
>+//
>+// EFI Component Name 2 Protocol
>+//
>+GLOBAL_REMOVE_IF_UNREFERENCED
>EFI_COMPONENT_NAME2_PROTOCOL gQemuVideoComponentName2 = {
>+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)
>QemuVideoComponentNameGetDriverName,
>+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)
>QemuVideoComponentNameGetControllerName,
>+ "en"
>+};
>+
>+
>+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
>mQemuVideoDriverNameTable[] = {
>+ { "eng;en", L"QEMU Video Driver" },
>+ { NULL , NULL }
>+};
>+
>+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
>mQemuVideoControllerNameTable[] = {
>+ { "eng;en", L"QEMU Video PCI Adapter" },
>+ { NULL , NULL }
>+};
>+
>+/**
>+ Retrieves a Unicode string that is the user readable name of the driver.
>+
>+ This function retrieves the user readable name of a driver in the form of a
>+ Unicode string. If the driver specified by This has a user readable name in
>+ the language specified by Language, then a pointer to the driver name is
>+ returned in DriverName, and EFI_SUCCESS is returned. If the driver
>specified
>+ by This does not support the language specified by Language,
>+ then EFI_UNSUPPORTED is returned.
>+
>+ @param This[in] A pointer to the
>EFI_COMPONENT_NAME2_PROTOCOL or
>+ EFI_COMPONENT_NAME_PROTOCOL instance.
>+
>+ @param Language[in] A pointer to a Null-terminated ASCII string
>+ array indicating the language. This is the
>+ language of the driver name that the caller is
>+ requesting, and it must match one of the
>+ languages specified in SupportedLanguages. The
>+ number of languages supported by a driver is up
>+ to the driver writer. Language is specified
>+ in RFC 4646 or ISO 639-2 language code format.
>+
>+ @param DriverName[out] A pointer to the Unicode string to return.
>+ This Unicode string is the name of the
>+ driver specified by This in the language
>+ specified by Language.
>+
>+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
>+ This and the language specified by Language was
>+ returned in DriverName.
>+
>+ @retval EFI_INVALID_PARAMETER Language is NULL.
>+
>+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
>+
>+ @retval EFI_UNSUPPORTED The driver specified by This does not
>support
>+ the language specified by Language.
>+
>+**/
>+EFI_STATUS
>+EFIAPI
>+QemuVideoComponentNameGetDriverName (
>+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
>+ IN CHAR8 *Language,
>+ OUT CHAR16 **DriverName
>+ )
>+{
>+ return LookupUnicodeString2 (
>+ Language,
>+ This->SupportedLanguages,
>+ mQemuVideoDriverNameTable,
>+ DriverName,
>+ (BOOLEAN)(This == &gQemuVideoComponentName)
>+ );
>+}
>+
>+/**
>+ Retrieves a Unicode string that is the user readable name of the controller
>+ that is being managed by a driver.
>+
>+ This function retrieves the user readable name of the controller specified
>by
>+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
>+ driver specified by This has a user readable name in the language specified
>by
>+ Language, then a pointer to the controller name is returned in
>ControllerName,
>+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
>+ managing the controller specified by ControllerHandle and ChildHandle,
>+ then EFI_UNSUPPORTED is returned. If the driver specified by This does
>not
>+ support the language specified by Language, then EFI_UNSUPPORTED is
>returned.
>+
>+ @param This[in] A pointer to the
>EFI_COMPONENT_NAME2_PROTOCOL or
>+ EFI_COMPONENT_NAME_PROTOCOL instance.
>+
>+ @param ControllerHandle[in] The handle of a controller that the driver
>+ specified by This is managing. This handle
>+ specifies the controller whose name is to be
>+ returned.
>+
>+ @param ChildHandle[in] The handle of the child controller to retrieve
>+ the name of. This is an optional parameter that
>+ may be NULL. It will be NULL for device
>+ drivers. It will also be NULL for a bus drivers
>+ that wish to retrieve the name of the bus
>+ controller. It will not be NULL for a bus
>+ driver that wishes to retrieve the name of a
>+ child controller.
>+
>+ @param Language[in] A pointer to a Null-terminated ASCII string
>+ array indicating the language. This is the
>+ language of the driver name that the caller is
>+ requesting, and it must match one of the
>+ languages specified in SupportedLanguages. The
>+ number of languages supported by a driver is up
>+ to the driver writer. Language is specified in
>+ RFC 4646 or ISO 639-2 language code format.
>+
>+ @param ControllerName[out] A pointer to the Unicode string to return.
>+ This Unicode string is the name of the
>+ controller specified by ControllerHandle and
>+ ChildHandle in the language specified by
>+ Language from the point of view of the driver
>+ specified by This.
>+
>+ @retval EFI_SUCCESS The Unicode string for the user readable name in
>+ the language specified by Language for the
>+ driver specified by This was returned in
>+ DriverName.
>+
>+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid
>EFI_HANDLE.
>+
>+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a
>valid
>+ EFI_HANDLE.
>+
>+ @retval EFI_INVALID_PARAMETER Language is NULL.
>+
>+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
>+
>+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
>+ managing the controller specified by
>+ ControllerHandle and ChildHandle.
>+
>+ @retval EFI_UNSUPPORTED The driver specified by This does not
>support
>+ the language specified by Language.
>+
>+**/
>+EFI_STATUS
>+EFIAPI
>+QemuVideoComponentNameGetControllerName (
>+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
>+ IN EFI_HANDLE ControllerHandle,
>+ IN EFI_HANDLE ChildHandle OPTIONAL,
>+ IN CHAR8 *Language,
>+ OUT CHAR16 **ControllerName
>+ )
>+{
>+ EFI_STATUS Status;
>+
>+ //
>+ // This is a device driver, so ChildHandle must be NULL.
>+ //
>+ if (ChildHandle != NULL) {
>+ return EFI_UNSUPPORTED;
>+ }
>+
>+ //
>+ // Make sure this driver is currently managing ControllHandle
>+ //
>+ Status = EfiTestManagedDevice (
>+ ControllerHandle,
>+ gQemuVideoDriverBinding.DriverBindingHandle,
>+ &gEfiPciIoProtocolGuid
>+ );
>+ if (EFI_ERROR (Status)) {
>+ return Status;
>+ }
>+
>+ //
>+ // Get the QEMU Video's Device structure
>+ //
>+ return LookupUnicodeString2 (
>+ Language,
>+ This->SupportedLanguages,
>+ mQemuVideoControllerNameTable,
>+ ControllerName,
>+ (BOOLEAN)(This == &gQemuVideoComponentName)
>+ );
>+}
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>Driver.c
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>Driver.c
>new file mode 100644
>index 0000000000..e49e7a465c
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>Driver.c
>@@ -0,0 +1,1011 @@
>+/** @file
>+ This driver is a sample implementation of the Graphics Output Protocol for
>+ the QEMU (Cirrus Logic 5446) video controller.
>+
>+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
>+
>+ SPDX-License-Identifier: BSD-2-Clause-Patent
>+**/
>+
>+#include "Qemu.h"
>+#include <IndustryStandard/Acpi.h>
>+
>+EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding = {
>+ QemuVideoControllerDriverSupported,
>+ QemuVideoControllerDriverStart,
>+ QemuVideoControllerDriverStop,
>+ 0x10,
>+ NULL,
>+ NULL
>+};
>+
>+QEMU_VIDEO_CARD gQemuVideoCardList[] = {
>+ {
>+ PCI_CLASS_DISPLAY_VGA,
>+ CIRRUS_LOGIC_VENDOR_ID,
>+ CIRRUS_LOGIC_5430_DEVICE_ID,
>+ QEMU_VIDEO_CIRRUS_5430,
>+ L"Cirrus 5430"
>+ },{
>+ PCI_CLASS_DISPLAY_VGA,
>+ CIRRUS_LOGIC_VENDOR_ID,
>+ CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID,
>+ QEMU_VIDEO_CIRRUS_5430,
>+ L"Cirrus 5430"
>+ },{
>+ PCI_CLASS_DISPLAY_VGA,
>+ CIRRUS_LOGIC_VENDOR_ID,
>+ CIRRUS_LOGIC_5446_DEVICE_ID,
>+ QEMU_VIDEO_CIRRUS_5446,
>+ L"Cirrus 5446"
>+ },{
>+ PCI_CLASS_DISPLAY_VGA,
>+ 0x4321,
>+ 0x1111,
>+ QEMU_VIDEO_BOCHS_MMIO,
>+ L"QEMU Standard VGA"
>+ },{
>+ PCI_CLASS_DISPLAY_OTHER,
>+ 0x1234,
>+ 0x1111,
>+ QEMU_VIDEO_BOCHS_MMIO,
>+ L"QEMU Standard VGA (secondary)"
>+ },{
>+ PCI_CLASS_DISPLAY_VGA,
>+ 0x1b36,
>+ 0x0100,
>+ QEMU_VIDEO_BOCHS,
>+ L"QEMU QXL VGA"
>+ },{
>+ PCI_CLASS_DISPLAY_VGA,
>+ 0x1af4,
>+ 0x1050,
>+ QEMU_VIDEO_BOCHS_MMIO,
>+ L"QEMU VirtIO VGA"
>+ },{
>+ 0 /* end of list */
>+ }
>+};
>+
>+static QEMU_VIDEO_CARD*
>+QemuVideoDetect(
>+ IN UINT8 SubClass,
>+ IN UINT16 VendorId,
>+ IN UINT16 DeviceId
>+ )
>+{
>+ UINTN Index = 0;
>+
>+ while (gQemuVideoCardList[Index].VendorId != 0) {
>+ if (gQemuVideoCardList[Index].SubClass == SubClass &&
>+ gQemuVideoCardList[Index].VendorId == VendorId &&
>+ gQemuVideoCardList[Index].DeviceId == DeviceId) {
>+ return gQemuVideoCardList + Index;
>+ }
>+ Index++;
>+ }
>+ return NULL;
>+}
>+
>+/**
>+ Check if this device is supported.
>+
>+ @param This The driver binding protocol.
>+ @param Controller The controller handle to check.
>+ @param RemainingDevicePath The remaining device path.
>+
>+ @retval EFI_SUCCESS The bus supports this controller.
>+ @retval EFI_UNSUPPORTED This device isn't supported.
>+
>+**/
>+EFI_STATUS
>+EFIAPI
>+QemuVideoControllerDriverSupported (
>+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
>+ IN EFI_HANDLE Controller,
>+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
>+ )
>+{
>+ EFI_STATUS Status;
>+ EFI_PCI_IO_PROTOCOL *PciIo;
>+ PCI_TYPE00 Pci;
>+ QEMU_VIDEO_CARD *Card;
>+
>+ //
>+ // Open the PCI I/O Protocol
>+ //
>+ Status = gBS->OpenProtocol (
>+ Controller,
>+ &gEfiPciIoProtocolGuid,
>+ (VOID **) &PciIo,
>+ This->DriverBindingHandle,
>+ Controller,
>+ EFI_OPEN_PROTOCOL_BY_DRIVER
>+ );
>+ if (EFI_ERROR (Status)) {
>+ return Status;
>+ }
>+
>+ //
>+ // Read the PCI Configuration Header from the PCI Device
>+ //
>+ Status = PciIo->Pci.Read (
>+ PciIo,
>+ EfiPciIoWidthUint32,
>+ 0,
>+ sizeof (Pci) / sizeof (UINT32),
>+ &Pci
>+ );
>+ if (EFI_ERROR (Status)) {
>+ goto Done;
>+ }
>+
>+ Status = EFI_UNSUPPORTED;
>+ if (!IS_PCI_DISPLAY (&Pci)) {
>+ goto Done;
>+ }
>+ Card = QemuVideoDetect(Pci.Hdr.ClassCode[1], Pci.Hdr.VendorId,
>Pci.Hdr.DeviceId);
>+ if (Card != NULL) {
>+ DEBUG ((EFI_D_INFO, "QemuVideo: %s detected\n", Card->Name));
>+ Status = EFI_SUCCESS;
>+ }
>+
>+Done:
>+ //
>+ // Close the PCI I/O Protocol
>+ //
>+ gBS->CloseProtocol (
>+ Controller,
>+ &gEfiPciIoProtocolGuid,
>+ This->DriverBindingHandle,
>+ Controller
>+ );
>+
>+ return Status;
>+}
>+
>+/**
>+ Start to process the controller.
>+
>+ @param This The USB bus driver binding instance.
>+ @param Controller The controller to check.
>+ @param RemainingDevicePath The remaining device patch.
>+
>+ @retval EFI_SUCCESS The controller is controlled by the usb bus.
>+ @retval EFI_ALREADY_STARTED The controller is already controlled by the
>usb
>+ bus.
>+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
>+
>+**/
>+EFI_STATUS
>+EFIAPI
>+QemuVideoControllerDriverStart (
>+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
>+ IN EFI_HANDLE Controller,
>+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
>+ )
>+{
>+ EFI_TPL OldTpl;
>+ EFI_STATUS Status;
>+ QEMU_VIDEO_PRIVATE_DATA *Private;
>+ BOOLEAN IsQxl;
>+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
>+ ACPI_ADR_DEVICE_PATH AcpiDeviceNode;
>+ PCI_TYPE00 Pci;
>+ QEMU_VIDEO_CARD *Card;
>+ EFI_PCI_IO_PROTOCOL *ChildPciIo;
>+
>+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
>+
>+ //
>+ // Allocate Private context data for GOP inteface.
>+ //
>+ Private = AllocateZeroPool (sizeof (QEMU_VIDEO_PRIVATE_DATA));
>+ if (Private == NULL) {
>+ Status = EFI_OUT_OF_RESOURCES;
>+ goto RestoreTpl;
>+ }
>+
>+ //
>+ // Set up context record
>+ //
>+ Private->Signature = QEMU_VIDEO_PRIVATE_DATA_SIGNATURE;
>+
>+ //
>+ // Open PCI I/O Protocol
>+ //
>+ Status = gBS->OpenProtocol (
>+ Controller,
>+ &gEfiPciIoProtocolGuid,
>+ (VOID **) &Private->PciIo,
>+ This->DriverBindingHandle,
>+ Controller,
>+ EFI_OPEN_PROTOCOL_BY_DRIVER
>+ );
>+ if (EFI_ERROR (Status)) {
>+ goto FreePrivate;
>+ }
>+
>+ //
>+ // Read the PCI Configuration Header from the PCI Device
>+ //
>+ Status = Private->PciIo->Pci.Read (
>+ Private->PciIo,
>+ EfiPciIoWidthUint32,
>+ 0,
>+ sizeof (Pci) / sizeof (UINT32),
>+ &Pci
>+ );
>+ if (EFI_ERROR (Status)) {
>+ goto ClosePciIo;
>+ }
>+
>+ //
>+ // Determine card variant.
>+ //
>+ Card = QemuVideoDetect(Pci.Hdr.ClassCode[1], Pci.Hdr.VendorId,
>Pci.Hdr.DeviceId);
>+ if (Card == NULL) {
>+ Status = EFI_DEVICE_ERROR;
>+ goto ClosePciIo;
>+ }
>+ Private->Variant = Card->Variant;
>+
>+ //
>+ // IsQxl is based on the detected Card->Variant, which at a later point might
>+ // not match Private->Variant.
>+ //
>+ IsQxl = (BOOLEAN)(Card->Variant == QEMU_VIDEO_BOCHS);
>+
>+ //
>+ // Save original PCI attributes
>+ //
>+ Status = Private->PciIo->Attributes (
>+ Private->PciIo,
>+ EfiPciIoAttributeOperationGet,
>+ 0,
>+ &Private->OriginalPciAttributes
>+ );
>+
>+ if (EFI_ERROR (Status)) {
>+ goto ClosePciIo;
>+ }
>+
>+ //
>+ // Set new PCI attributes
>+ //
>+ Status = Private->PciIo->Attributes (
>+ Private->PciIo,
>+ EfiPciIoAttributeOperationEnable,
>+ EFI_PCI_DEVICE_ENABLE |
>EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,
>+ NULL
>+ );
>+ if (EFI_ERROR (Status)) {
>+ goto ClosePciIo;
>+ }
>+
>+ //
>+ // Check whenever the qemu stdvga mmio bar is present (qemu 1.3+).
>+ //
>+ if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
>+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *MmioDesc;
>+
>+ Status = Private->PciIo->GetBarAttributes (
>+ Private->PciIo,
>+ PCI_BAR_IDX2,
>+ NULL,
>+ (VOID**) &MmioDesc
>+ );
>+ if (EFI_ERROR (Status) ||
>+ MmioDesc->ResType != ACPI_ADDRESS_SPACE_TYPE_MEM) {
>+ DEBUG ((EFI_D_INFO, "QemuVideo: No mmio bar, fallback to port io\n"));
>+ Private->Variant = QEMU_VIDEO_BOCHS;
>+ } else {
>+ DEBUG ((EFI_D_INFO, "QemuVideo: Using mmio bar @ 0x%lx\n",
>+ MmioDesc->AddrRangeMin));
>+ }
>+
>+ if (!EFI_ERROR (Status)) {
>+ FreePool (MmioDesc);
>+ }
>+ }
>+
>+ //
>+ // Check if accessing the bochs interface works.
>+ //
>+ if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO ||
>+ Private->Variant == QEMU_VIDEO_BOCHS) {
>+ UINT16 BochsId;
>+ BochsId = BochsRead(Private, VBE_DISPI_INDEX_ID);
>+ if ((BochsId & 0xFFF0) != VBE_DISPI_ID0) {
>+ DEBUG ((EFI_D_INFO, "QemuVideo: BochsID mismatch (got 0x%x)\n",
>BochsId));
>+ Status = EFI_DEVICE_ERROR;
>+ goto RestoreAttributes;
>+ }
>+ }
>+
>+ //
>+ // Get ParentDevicePath
>+ //
>+ Status = gBS->HandleProtocol (
>+ Controller,
>+ &gEfiDevicePathProtocolGuid,
>+ (VOID **) &ParentDevicePath
>+ );
>+ if (EFI_ERROR (Status)) {
>+ goto RestoreAttributes;
>+ }
>+
>+ //
>+ // Set Gop Device Path
>+ //
>+ ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));
>+ AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;
>+ AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;
>+ AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0,
>ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);
>+ SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof
>(ACPI_ADR_DEVICE_PATH));
>+
>+ Private->GopDevicePath = AppendDevicePathNode (
>+ ParentDevicePath,
>+ (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode
>+ );
>+ if (Private->GopDevicePath == NULL) {
>+ Status = EFI_OUT_OF_RESOURCES;
>+ goto RestoreAttributes;
>+ }
>+
>+ //
>+ // Create new child handle and install the device path protocol on it.
>+ //
>+ Status = gBS->InstallMultipleProtocolInterfaces (
>+ &Private->Handle,
>+ &gEfiDevicePathProtocolGuid,
>+ Private->GopDevicePath,
>+ NULL
>+ );
>+ if (EFI_ERROR (Status)) {
>+ goto FreeGopDevicePath;
>+ }
>+
>+ //
>+ // Construct video mode buffer
>+ //
>+ switch (Private->Variant) {
>+ case QEMU_VIDEO_CIRRUS_5430:
>+ case QEMU_VIDEO_CIRRUS_5446:
>+ Status = QemuVideoCirrusModeSetup (Private);
>+ break;
>+ case QEMU_VIDEO_BOCHS_MMIO:
>+ case QEMU_VIDEO_BOCHS:
>+ Status = QemuVideoBochsModeSetup (Private, IsQxl);
>+ break;
>+ default:
>+ ASSERT (FALSE);
>+ Status = EFI_DEVICE_ERROR;
>+ break;
>+ }
>+ if (EFI_ERROR (Status)) {
>+ goto UninstallGopDevicePath;
>+ }
>+
>+ //
>+ // Start the GOP software stack.
>+ //
>+ Status = QemuVideoGraphicsOutputConstructor (Private);
>+ if (EFI_ERROR (Status)) {
>+ goto FreeModeData;
>+ }
>+
>+ Status = gBS->InstallMultipleProtocolInterfaces (
>+ &Private->Handle,
>+ &gEfiGraphicsOutputProtocolGuid,
>+ &Private->GraphicsOutput,
>+ NULL
>+ );
>+ if (EFI_ERROR (Status)) {
>+ goto DestructQemuVideoGraphics;
>+ }
>+
>+ //
>+ // Reference parent handle from child handle.
>+ //
>+ Status = gBS->OpenProtocol (
>+ Controller,
>+ &gEfiPciIoProtocolGuid,
>+ (VOID **) &ChildPciIo,
>+ This->DriverBindingHandle,
>+ Private->Handle,
>+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
>+ );
>+ if (EFI_ERROR (Status)) {
>+ goto UninstallGop;
>+ }
>+
>+#if defined MDE_CPU_IA32 || defined MDE_CPU_X64
>+ if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO ||
>+ Private->Variant == QEMU_VIDEO_BOCHS) {
>+ InstallVbeShim (Card->Name, Private->GraphicsOutput.Mode-
>>FrameBufferBase);
>+ }
>+#endif
>+
>+ gBS->RestoreTPL (OldTpl);
>+ return EFI_SUCCESS;
>+
>+UninstallGop:
>+ gBS->UninstallProtocolInterface (Private->Handle,
>+ &gEfiGraphicsOutputProtocolGuid, &Private->GraphicsOutput);
>+
>+DestructQemuVideoGraphics:
>+ QemuVideoGraphicsOutputDestructor (Private);
>+
>+FreeModeData:
>+ FreePool (Private->ModeData);
>+
>+UninstallGopDevicePath:
>+ gBS->UninstallProtocolInterface (Private->Handle,
>+ &gEfiDevicePathProtocolGuid, Private->GopDevicePath);
>+
>+FreeGopDevicePath:
>+ FreePool (Private->GopDevicePath);
>+
>+RestoreAttributes:
>+ Private->PciIo->Attributes (Private->PciIo, EfiPciIoAttributeOperationSet,
>+ Private->OriginalPciAttributes, NULL);
>+
>+ClosePciIo:
>+ gBS->CloseProtocol (Controller, &gEfiPciIoProtocolGuid,
>+ This->DriverBindingHandle, Controller);
>+
>+FreePrivate:
>+ FreePool (Private);
>+
>+RestoreTpl:
>+ gBS->RestoreTPL (OldTpl);
>+
>+ return Status;
>+}
>+
>+/**
>+ Stop this device
>+
>+ @param This The USB bus driver binding protocol.
>+ @param Controller The controller to release.
>+ @param NumberOfChildren The number of children of this device that
>+ opened the controller BY_CHILD.
>+ @param ChildHandleBuffer The array of child handle.
>+
>+ @retval EFI_SUCCESS The controller or children are stopped.
>+ @retval EFI_DEVICE_ERROR Failed to stop the driver.
>+
>+**/
>+EFI_STATUS
>+EFIAPI
>+QemuVideoControllerDriverStop (
>+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
>+ IN EFI_HANDLE Controller,
>+ IN UINTN NumberOfChildren,
>+ IN EFI_HANDLE *ChildHandleBuffer
>+ )
>+{
>+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
>+
>+ EFI_STATUS Status;
>+ QEMU_VIDEO_PRIVATE_DATA *Private;
>+
>+ if (NumberOfChildren == 0) {
>+ //
>+ // Close the PCI I/O Protocol
>+ //
>+ gBS->CloseProtocol (
>+ Controller,
>+ &gEfiPciIoProtocolGuid,
>+ This->DriverBindingHandle,
>+ Controller
>+ );
>+ return EFI_SUCCESS;
>+ }
>+
>+ //
>+ // free all resources for whose access we need the child handle, because
>the
>+ // child handle is going away
>+ //
>+ ASSERT (NumberOfChildren == 1);
>+ Status = gBS->OpenProtocol (
>+ ChildHandleBuffer[0],
>+ &gEfiGraphicsOutputProtocolGuid,
>+ (VOID **) &GraphicsOutput,
>+ This->DriverBindingHandle,
>+ Controller,
>+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
>+ );
>+ if (EFI_ERROR (Status)) {
>+ return Status;
>+ }
>+
>+ //
>+ // Get our private context information
>+ //
>+ Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS
>(GraphicsOutput);
>+ ASSERT (Private->Handle == ChildHandleBuffer[0]);
>+
>+ QemuVideoGraphicsOutputDestructor (Private);
>+ //
>+ // Remove the GOP protocol interface from the system
>+ //
>+ Status = gBS->UninstallMultipleProtocolInterfaces (
>+ Private->Handle,
>+ &gEfiGraphicsOutputProtocolGuid,
>+ &Private->GraphicsOutput,
>+ NULL
>+ );
>+
>+ if (EFI_ERROR (Status)) {
>+ return Status;
>+ }
>+
>+ //
>+ // Restore original PCI attributes
>+ //
>+ Private->PciIo->Attributes (
>+ Private->PciIo,
>+ EfiPciIoAttributeOperationSet,
>+ Private->OriginalPciAttributes,
>+ NULL
>+ );
>+
>+ gBS->CloseProtocol (
>+ Controller,
>+ &gEfiPciIoProtocolGuid,
>+ This->DriverBindingHandle,
>+ Private->Handle
>+ );
>+
>+ FreePool (Private->ModeData);
>+ gBS->UninstallProtocolInterface (Private->Handle,
>+ &gEfiDevicePathProtocolGuid, Private->GopDevicePath);
>+ FreePool (Private->GopDevicePath);
>+
>+ //
>+ // Free our instance data
>+ //
>+ gBS->FreePool (Private);
>+
>+ return EFI_SUCCESS;
>+}
>+
>+/**
>+ TODO: Add function description
>+
>+ @param Private TODO: add argument description
>+ @param Address TODO: add argument description
>+ @param Data TODO: add argument description
>+
>+ TODO: add return values
>+
>+**/
>+VOID
>+outb (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ UINTN Address,
>+ UINT8 Data
>+ )
>+{
>+ EFI_STATUS Status;
>+ VOID *Interface;
>+ Private->PciIo->Io.Write (
>+ Private->PciIo,
>+ EfiPciIoWidthUint8,
>+ EFI_PCI_IO_PASS_THROUGH_BAR,
>+ Address,
>+ 1,
>+ &Data
>+ );
>+ Status = gBS->LocateProtocol(&gEfiDxeSmmReadyToLockProtocolGuid,
>NULL, &Interface);
>+ if (!EFI_ERROR(Status)) {
>+ return;
>+ }
>+
>+ Status = S3BootScriptSaveIoWrite(
>+ S3BootScriptWidthUint8,
>+ Address,
>+ (UINTN)1,
>+ &Data
>+ );
>+}
>+
>+/**
>+ TODO: Add function description
>+
>+ @param Private TODO: add argument description
>+ @param Address TODO: add argument description
>+ @param Data TODO: add argument description
>+
>+ TODO: add return values
>+
>+**/
>+VOID
>+outw (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ UINTN Address,
>+ UINT16 Data
>+ )
>+{
>+ EFI_STATUS Status;
>+ VOID *Interface;
>+
>+ Private->PciIo->Io.Write (
>+ Private->PciIo,
>+ EfiPciIoWidthUint16,
>+ EFI_PCI_IO_PASS_THROUGH_BAR,
>+ Address,
>+ 1,
>+ &Data
>+ );
>+
>+ Status = gBS->LocateProtocol(&gEfiDxeSmmReadyToLockProtocolGuid,
>NULL, &Interface);
>+ if (!EFI_ERROR(Status)) {
>+ return;
>+ }
>+ Status = S3BootScriptSaveIoWrite(
>+ S3BootScriptWidthUint16,
>+ Address,
>+ 1,
>+ &Data
>+ );
>+}
>+
>+/**
>+ TODO: Add function description
>+
>+ @param Private TODO: add argument description
>+ @param Address TODO: add argument description
>+
>+ TODO: add return values
>+
>+**/
>+UINT8
>+inb (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ UINTN Address
>+ )
>+{
>+ UINT8 Data;
>+
>+ Private->PciIo->Io.Read (
>+ Private->PciIo,
>+ EfiPciIoWidthUint8,
>+ EFI_PCI_IO_PASS_THROUGH_BAR,
>+ Address,
>+ 1,
>+ &Data
>+ );
>+ return Data;
>+}
>+
>+/**
>+ TODO: Add function description
>+
>+ @param Private TODO: add argument description
>+ @param Address TODO: add argument description
>+
>+ TODO: add return values
>+
>+**/
>+UINT16
>+inw (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ UINTN Address
>+ )
>+{
>+ UINT16 Data;
>+
>+ Private->PciIo->Io.Read (
>+ Private->PciIo,
>+ EfiPciIoWidthUint16,
>+ EFI_PCI_IO_PASS_THROUGH_BAR,
>+ Address,
>+ 1,
>+ &Data
>+ );
>+ return Data;
>+}
>+
>+/**
>+ TODO: Add function description
>+
>+ @param Private TODO: add argument description
>+ @param Index TODO: add argument description
>+ @param Red TODO: add argument description
>+ @param Green TODO: add argument description
>+ @param Blue TODO: add argument description
>+
>+ TODO: add return values
>+
>+**/
>+VOID
>+SetPaletteColor (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ UINTN Index,
>+ UINT8 Red,
>+ UINT8 Green,
>+ UINT8 Blue
>+ )
>+{
>+ VgaOutb (Private, PALETTE_INDEX_REGISTER, (UINT8) Index);
>+ VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8) (Red >> 2));
>+ VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8) (Green >> 2));
>+ VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8) (Blue >> 2));
>+}
>+
>+/**
>+ TODO: Add function description
>+
>+ @param Private TODO: add argument description
>+
>+ TODO: add return values
>+
>+**/
>+VOID
>+SetDefaultPalette (
>+ QEMU_VIDEO_PRIVATE_DATA *Private
>+ )
>+{
>+ UINTN Index;
>+ UINTN RedIndex;
>+ UINTN GreenIndex;
>+ UINTN BlueIndex;
>+
>+ Index = 0;
>+ for (RedIndex = 0; RedIndex < 8; RedIndex++) {
>+ for (GreenIndex = 0; GreenIndex < 8; GreenIndex++) {
>+ for (BlueIndex = 0; BlueIndex < 4; BlueIndex++) {
>+ SetPaletteColor (Private, Index, (UINT8) (RedIndex << 5), (UINT8)
>(GreenIndex << 5), (UINT8) (BlueIndex << 6));
>+ Index++;
>+ }
>+ }
>+ }
>+}
>+
>+/**
>+ TODO: Add function description
>+
>+ @param Private TODO: add argument description
>+
>+ TODO: add return values
>+
>+**/
>+VOID
>+ClearScreen (
>+ QEMU_VIDEO_PRIVATE_DATA *Private
>+ )
>+{
>+ UINT32 Color;
>+
>+ Color = 0;
>+ Private->PciIo->Mem.Write (
>+ Private->PciIo,
>+ EfiPciIoWidthFillUint32,
>+ 0,
>+ 0,
>+ 0x400000 >> 2,
>+ &Color
>+ );
>+}
>+
>+/**
>+ TODO: Add function description
>+
>+ @param Private TODO: add argument description
>+
>+ TODO: add return values
>+
>+**/
>+VOID
>+DrawLogo (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ UINTN ScreenWidth,
>+ UINTN ScreenHeight
>+ )
>+{
>+}
>+
>+/**
>+ TODO: Add function description
>+
>+ @param Private TODO: add argument description
>+ @param ModeData TODO: add argument description
>+
>+ TODO: add return values
>+
>+**/
>+VOID
>+InitializeCirrusGraphicsMode (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ QEMU_VIDEO_CIRRUS_MODES *ModeData
>+ )
>+{
>+ UINT8 Byte;
>+ UINTN Index;
>+
>+ outw (Private, SEQ_ADDRESS_REGISTER, 0x1206);
>+ outw (Private, SEQ_ADDRESS_REGISTER, 0x0012);
>+
>+ for (Index = 0; Index < 15; Index++) {
>+ outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]);
>+ }
>+
>+ if (Private->Variant == QEMU_VIDEO_CIRRUS_5430) {
>+ outb (Private, SEQ_ADDRESS_REGISTER, 0x0f);
>+ Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30);
>+ outb (Private, SEQ_DATA_REGISTER, Byte);
>+ }
>+
>+ outb (Private, MISC_OUTPUT_REGISTER, ModeData->MiscSetting);
>+ outw (Private, GRAPH_ADDRESS_REGISTER, 0x0506);
>+ outw (Private, SEQ_ADDRESS_REGISTER, 0x0300);
>+ outw (Private, CRTC_ADDRESS_REGISTER, 0x2011);
>+
>+ for (Index = 0; Index < 28; Index++) {
>+ outw (Private, CRTC_ADDRESS_REGISTER, (UINT16) ((ModeData-
>>CrtcSettings[Index] << 8) | Index));
>+ }
>+
>+ for (Index = 0; Index < 9; Index++) {
>+ outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16)
>((GraphicsController[Index] << 8) | Index));
>+ }
>+
>+ inb (Private, INPUT_STATUS_1_REGISTER);
>+
>+ for (Index = 0; Index < 21; Index++) {
>+ outb (Private, ATT_ADDRESS_REGISTER, (UINT8) Index);
>+ outb (Private, ATT_ADDRESS_REGISTER, AttributeController[Index]);
>+ }
>+
>+ outb (Private, ATT_ADDRESS_REGISTER, 0x20);
>+
>+ outw (Private, GRAPH_ADDRESS_REGISTER, 0x0009);
>+ outw (Private, GRAPH_ADDRESS_REGISTER, 0x000a);
>+ outw (Private, GRAPH_ADDRESS_REGISTER, 0x000b);
>+ outb (Private, DAC_PIXEL_MASK_REGISTER, 0xff);
>+
>+ SetDefaultPalette (Private);
>+ ClearScreen (Private);
>+}
>+
>+VOID
>+BochsWrite (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ UINT16 Reg,
>+ UINT16 Data
>+ )
>+{
>+ EFI_STATUS Status;
>+
>+ if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
>+ Status = Private->PciIo->Mem.Write (
>+ Private->PciIo,
>+ EfiPciIoWidthUint16,
>+ PCI_BAR_IDX2,
>+ 0x500 + (Reg << 1),
>+ 1,
>+ &Data
>+ );
>+ ASSERT_EFI_ERROR (Status);
>+ } else {
>+ outw (Private, VBE_DISPI_IOPORT_INDEX, Reg);
>+ outw (Private, VBE_DISPI_IOPORT_DATA, Data);
>+ }
>+}
>+
>+UINT16
>+BochsRead (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ UINT16 Reg
>+ )
>+{
>+ EFI_STATUS Status;
>+ UINT16 Data;
>+
>+ if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
>+ Status = Private->PciIo->Mem.Read (
>+ Private->PciIo,
>+ EfiPciIoWidthUint16,
>+ PCI_BAR_IDX2,
>+ 0x500 + (Reg << 1),
>+ 1,
>+ &Data
>+ );
>+ ASSERT_EFI_ERROR (Status);
>+ } else {
>+ outw (Private, VBE_DISPI_IOPORT_INDEX, Reg);
>+ Data = inw (Private, VBE_DISPI_IOPORT_DATA);
>+ }
>+ return Data;
>+}
>+
>+VOID
>+VgaOutb (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ UINTN Reg,
>+ UINT8 Data
>+ )
>+{
>+ EFI_STATUS Status;
>+
>+ if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
>+ Status = Private->PciIo->Mem.Write (
>+ Private->PciIo,
>+ EfiPciIoWidthUint8,
>+ PCI_BAR_IDX2,
>+ 0x400 - 0x3c0 + Reg,
>+ 1,
>+ &Data
>+ );
>+ ASSERT_EFI_ERROR (Status);
>+ } else {
>+ outb (Private, Reg, Data);
>+ }
>+}
>+
>+VOID
>+InitializeBochsGraphicsMode (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ QEMU_VIDEO_BOCHS_MODES *ModeData
>+ )
>+{
>+ DEBUG ((EFI_D_INFO, "InitializeBochsGraphicsMode: %dx%d @ %d\n",
>+ ModeData->Width, ModeData->Height, ModeData->ColorDepth));
>+
>+ /* unblank */
>+ VgaOutb (Private, ATT_ADDRESS_REGISTER, 0x20);
>+
>+ BochsWrite (Private, VBE_DISPI_INDEX_ENABLE, 0);
>+ BochsWrite (Private, VBE_DISPI_INDEX_BANK, 0);
>+ BochsWrite (Private, VBE_DISPI_INDEX_X_OFFSET, 0);
>+ BochsWrite (Private, VBE_DISPI_INDEX_Y_OFFSET, 0);
>+
>+ BochsWrite (Private, VBE_DISPI_INDEX_BPP, (UINT16) ModeData-
>>ColorDepth);
>+ BochsWrite (Private, VBE_DISPI_INDEX_XRES, (UINT16) ModeData-
>>Width);
>+ BochsWrite (Private, VBE_DISPI_INDEX_VIRT_WIDTH, (UINT16) ModeData-
>>Width);
>+ BochsWrite (Private, VBE_DISPI_INDEX_YRES, (UINT16) ModeData-
>>Height);
>+ BochsWrite (Private, VBE_DISPI_INDEX_VIRT_HEIGHT, (UINT16)
>ModeData->Height);
>+
>+ BochsWrite (Private, VBE_DISPI_INDEX_ENABLE,
>+ VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
>+
>+ SetDefaultPalette (Private);
>+ ClearScreen (Private);
>+}
>+
>+EFI_STATUS
>+EFIAPI
>+InitializeQemuVideo (
>+ IN EFI_HANDLE ImageHandle,
>+ IN EFI_SYSTEM_TABLE *SystemTable
>+ )
>+{
>+ EFI_STATUS Status;
>+
>+ Status = EfiLibInstallDriverBindingComponentName2 (
>+ ImageHandle,
>+ SystemTable,
>+ &gQemuVideoDriverBinding,
>+ ImageHandle,
>+ &gQemuVideoComponentName,
>+ &gQemuVideoComponentName2
>+ );
>+ ASSERT_EFI_ERROR (Status);
>+
>+ //
>+ // Install EFI Driver Supported EFI Version Protocol required for
>+ // EFI drivers that are on PCI and other plug in cards.
>+ //
>+ gQemuVideoDriverSupportedEfiVersion.FirmwareVersion = PcdGet32
>(PcdDriverSupportedEfiVersion);
>+ Status = gBS->InstallMultipleProtocolInterfaces (
>+ &ImageHandle,
>+ &gEfiDriverSupportedEfiVersionProtocolGuid,
>+ &gQemuVideoDriverSupportedEfiVersion,
>+ NULL
>+ );
>+ ASSERT_EFI_ERROR (Status);
>+
>+ return Status;
>+}
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>DriverSupportedEfiVersion.c
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>DriverSupportedEfiVersion.c
>new file mode 100644
>index 0000000000..af658f9f60
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>DriverSupportedEfiVersion.c
>@@ -0,0 +1,15 @@
>+/** @file
>+ Driver supported version protocol for the QEMU video driver.
>+
>+ Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved. <BR>
>+
>+ SPDX-License-Identifier: BSD-2-Clause-Patent
>+**/
>+
>+#include "Qemu.h"
>+
>+EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL
>gQemuVideoDriverSupportedEfiVersion = {
>+ sizeof (EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL), // Size of
>Protocol structure.
>+ 0 // Version number to be filled at start up.
>+};
>+
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>Gop.c
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>Gop.c
>new file mode 100644
>index 0000000000..5158e4851e
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>Gop.c
>@@ -0,0 +1,416 @@
>+/** @file
>+ Graphics Output Protocol functions for the QEMU video controller.
>+
>+ Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved. <BR>
>+
>+ SPDX-License-Identifier: BSD-2-Clause-Patent
>+**/
>+
>+#include "Qemu.h"
>+
>+STATIC
>+VOID
>+QemuVideoCompleteModeInfo (
>+ IN QEMU_VIDEO_MODE_DATA *ModeData,
>+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info
>+ )
>+{
>+ Info->Version = 0;
>+ if (ModeData->ColorDepth == 8) {
>+ Info->PixelFormat = PixelBitMask;
>+ Info->PixelInformation.RedMask = PIXEL_RED_MASK;
>+ Info->PixelInformation.GreenMask = PIXEL_GREEN_MASK;
>+ Info->PixelInformation.BlueMask = PIXEL_BLUE_MASK;
>+ Info->PixelInformation.ReservedMask = 0;
>+ } else if (ModeData->ColorDepth == 24) {
>+ Info->PixelFormat = PixelBitMask;
>+ Info->PixelInformation.RedMask = PIXEL24_RED_MASK;
>+ Info->PixelInformation.GreenMask = PIXEL24_GREEN_MASK;
>+ Info->PixelInformation.BlueMask = PIXEL24_BLUE_MASK;
>+ Info->PixelInformation.ReservedMask = 0;
>+ } else if (ModeData->ColorDepth == 32) {
>+ DEBUG ((EFI_D_INFO, "PixelBlueGreenRedReserved8BitPerColor\n"));
>+ Info->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
>+ }
>+ Info->PixelsPerScanLine = Info->HorizontalResolution;
>+}
>+
>+
>+STATIC
>+EFI_STATUS
>+QemuVideoCompleteModeData (
>+ IN QEMU_VIDEO_PRIVATE_DATA *Private,
>+ OUT EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode
>+ )
>+{
>+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
>+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *FrameBufDesc;
>+ QEMU_VIDEO_MODE_DATA *ModeData;
>+
>+ ModeData = &Private->ModeData[Mode->Mode];
>+ Info = Mode->Info;
>+ QemuVideoCompleteModeInfo (ModeData, Info);
>+
>+ Private->PciIo->GetBarAttributes (
>+ Private->PciIo,
>+ 0,
>+ NULL,
>+ (VOID**) &FrameBufDesc
>+ );
>+
>+ Mode->FrameBufferBase = FrameBufDesc->AddrRangeMin;
>+ Mode->FrameBufferSize = Info->HorizontalResolution * Info-
>>VerticalResolution;
>+ Mode->FrameBufferSize = Mode->FrameBufferSize * ((ModeData-
>>ColorDepth + 7) / 8);
>+ Mode->FrameBufferSize = EFI_PAGES_TO_SIZE (
>+ EFI_SIZE_TO_PAGES (Mode->FrameBufferSize)
>+ );
>+ DEBUG ((EFI_D_INFO, "FrameBufferBase: 0x%Lx, FrameBufferSize:
>0x%Lx\n",
>+ Mode->FrameBufferBase, (UINT64)Mode->FrameBufferSize));
>+
>+ FreePool (FrameBufDesc);
>+ return EFI_SUCCESS;
>+}
>+
>+//
>+// Graphics Output Protocol Member Functions
>+//
>+EFI_STATUS
>+EFIAPI
>+QemuVideoGraphicsOutputQueryMode (
>+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
>+ IN UINT32 ModeNumber,
>+ OUT UINTN *SizeOfInfo,
>+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Graphics Output protocol interface to query video mode
>+
>+ Arguments:
>+ This - Protocol instance pointer.
>+ ModeNumber - The mode number to return information on.
>+ Info - Caller allocated buffer that returns information about
>ModeNumber.
>+ SizeOfInfo - A pointer to the size, in bytes, of the Info buffer.
>+
>+ Returns:
>+ EFI_SUCCESS - Mode information returned.
>+ EFI_BUFFER_TOO_SMALL - The Info buffer was too small.
>+ EFI_DEVICE_ERROR - A hardware error occurred trying to retrieve the
>video mode.
>+ EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()
>+ EFI_INVALID_PARAMETER - One of the input args was NULL.
>+
>+--*/
>+{
>+ QEMU_VIDEO_PRIVATE_DATA *Private;
>+ QEMU_VIDEO_MODE_DATA *ModeData;
>+
>+ Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS
>(This);
>+
>+ if (Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode-
>>MaxMode) {
>+ return EFI_INVALID_PARAMETER;
>+ }
>+
>+ *Info = AllocatePool (sizeof
>(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
>+ if (*Info == NULL) {
>+ return EFI_OUT_OF_RESOURCES;
>+ }
>+
>+ *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
>+
>+ ModeData = &Private->ModeData[ModeNumber];
>+ (*Info)->HorizontalResolution = ModeData->HorizontalResolution;
>+ (*Info)->VerticalResolution = ModeData->VerticalResolution;
>+ QemuVideoCompleteModeInfo (ModeData, *Info);
>+
>+ return EFI_SUCCESS;
>+}
>+
>+EFI_STATUS
>+EFIAPI
>+QemuVideoGraphicsOutputSetMode (
>+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
>+ IN UINT32 ModeNumber
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Graphics Output protocol interface to set video mode
>+
>+ Arguments:
>+ This - Protocol instance pointer.
>+ ModeNumber - The mode number to be set.
>+
>+ Returns:
>+ EFI_SUCCESS - Graphics mode was changed.
>+ EFI_DEVICE_ERROR - The device had an error and could not complete the
>request.
>+ EFI_UNSUPPORTED - ModeNumber is not supported by this device.
>+
>+--*/
>+{
>+ QEMU_VIDEO_PRIVATE_DATA *Private;
>+ QEMU_VIDEO_MODE_DATA *ModeData;
>+ RETURN_STATUS Status;
>+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black;
>+
>+ Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS
>(This);
>+
>+ if (ModeNumber >= This->Mode->MaxMode) {
>+ return EFI_UNSUPPORTED;
>+ }
>+
>+ ModeData = &Private->ModeData[ModeNumber];
>+
>+ switch (Private->Variant) {
>+ case QEMU_VIDEO_CIRRUS_5430:
>+ case QEMU_VIDEO_CIRRUS_5446:
>+ InitializeCirrusGraphicsMode (Private,
>&QemuVideoCirrusModes[ModeData->InternalModeIndex]);
>+ break;
>+ case QEMU_VIDEO_BOCHS_MMIO:
>+ case QEMU_VIDEO_BOCHS:
>+ InitializeBochsGraphicsMode (Private,
>&QemuVideoBochsModes[ModeData->InternalModeIndex]);
>+ break;
>+ default:
>+ ASSERT (FALSE);
>+ return EFI_DEVICE_ERROR;
>+ }
>+
>+ This->Mode->Mode = ModeNumber;
>+ This->Mode->Info->HorizontalResolution = ModeData-
>>HorizontalResolution;
>+ This->Mode->Info->VerticalResolution = ModeData->VerticalResolution;
>+ This->Mode->SizeOfInfo =
>sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
>+
>+ QemuVideoCompleteModeData (Private, This->Mode);
>+
>+ //
>+ // Re-initialize the frame buffer configure when mode changes.
>+ //
>+ Status = FrameBufferBltConfigure (
>+ (VOID*) (UINTN) This->Mode->FrameBufferBase,
>+ This->Mode->Info,
>+ Private->FrameBufferBltConfigure,
>+ &Private->FrameBufferBltConfigureSize
>+ );
>+ if (Status == RETURN_BUFFER_TOO_SMALL) {
>+ //
>+ // Frame buffer configure may be larger in new mode.
>+ //
>+ if (Private->FrameBufferBltConfigure != NULL) {
>+ FreePool (Private->FrameBufferBltConfigure);
>+ }
>+ Private->FrameBufferBltConfigure =
>+ AllocatePool (Private->FrameBufferBltConfigureSize);
>+ ASSERT (Private->FrameBufferBltConfigure != NULL);
>+
>+ //
>+ // Create the configuration for FrameBufferBltLib
>+ //
>+ Status = FrameBufferBltConfigure (
>+ (VOID*) (UINTN) This->Mode->FrameBufferBase,
>+ This->Mode->Info,
>+ Private->FrameBufferBltConfigure,
>+ &Private->FrameBufferBltConfigureSize
>+ );
>+ }
>+ ASSERT (Status == RETURN_SUCCESS);
>+
>+ //
>+ // Per UEFI Spec, need to clear the visible portions of the output display to
>black.
>+ //
>+ ZeroMem (&Black, sizeof (Black));
>+ Status = FrameBufferBlt (
>+ Private->FrameBufferBltConfigure,
>+ &Black,
>+ EfiBltVideoFill,
>+ 0, 0,
>+ 0, 0,
>+ This->Mode->Info->HorizontalResolution, This->Mode->Info-
>>VerticalResolution,
>+ 0
>+ );
>+ ASSERT_RETURN_ERROR (Status);
>+
>+ return EFI_SUCCESS;
>+}
>+
>+EFI_STATUS
>+EFIAPI
>+QemuVideoGraphicsOutputBlt (
>+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
>+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
>+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
>+ IN UINTN SourceX,
>+ IN UINTN SourceY,
>+ IN UINTN DestinationX,
>+ IN UINTN DestinationY,
>+ IN UINTN Width,
>+ IN UINTN Height,
>+ IN UINTN Delta
>+ )
>+/*++
>+
>+Routine Description:
>+
>+ Graphics Output protocol instance to block transfer for CirrusLogic device
>+
>+Arguments:
>+
>+ This - Pointer to Graphics Output protocol instance
>+ BltBuffer - The data to transfer to screen
>+ BltOperation - The operation to perform
>+ SourceX - The X coordinate of the source for BltOperation
>+ SourceY - The Y coordinate of the source for BltOperation
>+ DestinationX - The X coordinate of the destination for BltOperation
>+ DestinationY - The Y coordinate of the destination for BltOperation
>+ Width - The width of a rectangle in the blt rectangle in pixels
>+ Height - The height of a rectangle in the blt rectangle in pixels
>+ Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
>+ If a Delta of 0 is used, the entire BltBuffer will be operated on.
>+ If a subrectangle of the BltBuffer is used, then Delta represents
>+ the number of bytes in a row of the BltBuffer.
>+
>+Returns:
>+
>+ EFI_INVALID_PARAMETER - Invalid parameter passed in
>+ EFI_SUCCESS - Blt operation success
>+
>+--*/
>+{
>+ EFI_STATUS Status;
>+ EFI_TPL OriginalTPL;
>+ QEMU_VIDEO_PRIVATE_DATA *Private;
>+
>+ Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS
>(This);
>+ //
>+ // We have to raise to TPL Notify, so we make an atomic write the frame
>buffer.
>+ // We would not want a timer based event (Cursor, ...) to come in while we
>are
>+ // doing this operation.
>+ //
>+ OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);
>+
>+ switch (BltOperation) {
>+ case EfiBltVideoToBltBuffer:
>+ case EfiBltBufferToVideo:
>+ case EfiBltVideoFill:
>+ case EfiBltVideoToVideo:
>+ Status = FrameBufferBlt (
>+ Private->FrameBufferBltConfigure,
>+ BltBuffer,
>+ BltOperation,
>+ SourceX,
>+ SourceY,
>+ DestinationX,
>+ DestinationY,
>+ Width,
>+ Height,
>+ Delta
>+ );
>+ break;
>+
>+ default:
>+ Status = EFI_INVALID_PARAMETER;
>+ break;
>+ }
>+
>+ gBS->RestoreTPL (OriginalTPL);
>+
>+ return Status;
>+}
>+
>+EFI_STATUS
>+QemuVideoGraphicsOutputConstructor (
>+ QEMU_VIDEO_PRIVATE_DATA *Private
>+ )
>+{
>+ EFI_STATUS Status;
>+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
>+
>+
>+ GraphicsOutput = &Private->GraphicsOutput;
>+ GraphicsOutput->QueryMode = QemuVideoGraphicsOutputQueryMode;
>+ GraphicsOutput->SetMode = QemuVideoGraphicsOutputSetMode;
>+ GraphicsOutput->Blt = QemuVideoGraphicsOutputBlt;
>+
>+ //
>+ // Initialize the private data
>+ //
>+ Status = gBS->AllocatePool (
>+ EfiBootServicesData,
>+ sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE),
>+ (VOID **) &Private->GraphicsOutput.Mode
>+ );
>+ if (EFI_ERROR (Status)) {
>+ return Status;
>+ }
>+
>+ Status = gBS->AllocatePool (
>+ EfiBootServicesData,
>+ sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
>+ (VOID **) &Private->GraphicsOutput.Mode->Info
>+ );
>+ if (EFI_ERROR (Status)) {
>+ goto FreeMode;
>+ }
>+ Private->GraphicsOutput.Mode->MaxMode = (UINT32) Private-
>>MaxMode;
>+ Private->GraphicsOutput.Mode->Mode =
>GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;
>+ Private->FrameBufferBltConfigure = NULL;
>+ Private->FrameBufferBltConfigureSize = 0;
>+
>+ //
>+ // Initialize the hardware
>+ //
>+ Status = GraphicsOutput->SetMode (GraphicsOutput, 0);
>+ if (EFI_ERROR (Status)) {
>+ goto FreeInfo;
>+ }
>+
>+ DrawLogo (
>+ Private,
>+ Private->ModeData[Private->GraphicsOutput.Mode-
>>Mode].HorizontalResolution,
>+ Private->ModeData[Private->GraphicsOutput.Mode-
>>Mode].VerticalResolution
>+ );
>+
>+ return EFI_SUCCESS;
>+
>+FreeInfo:
>+ FreePool (Private->GraphicsOutput.Mode->Info);
>+
>+FreeMode:
>+ FreePool (Private->GraphicsOutput.Mode);
>+ Private->GraphicsOutput.Mode = NULL;
>+
>+ return Status;
>+}
>+
>+EFI_STATUS
>+QemuVideoGraphicsOutputDestructor (
>+ QEMU_VIDEO_PRIVATE_DATA *Private
>+ )
>+/*++
>+
>+Routine Description:
>+
>+Arguments:
>+
>+Returns:
>+
>+ None
>+
>+--*/
>+{
>+ if (Private->FrameBufferBltConfigure != NULL) {
>+ FreePool (Private->FrameBufferBltConfigure);
>+ }
>+
>+ if (Private->GraphicsOutput.Mode != NULL) {
>+ if (Private->GraphicsOutput.Mode->Info != NULL) {
>+ gBS->FreePool (Private->GraphicsOutput.Mode->Info);
>+ }
>+ gBS->FreePool (Private->GraphicsOutput.Mode);
>+ }
>+
>+ return EFI_SUCCESS;
>+}
>+
>+
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>Initialize.c
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>Initialize.c
>new file mode 100644
>index 0000000000..543d360861
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>Initialize.c
>@@ -0,0 +1,341 @@
>+/** @file
>+ Graphics Output Protocol functions for the QEMU video controller.
>+
>+ Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved. <BR>
>+
>+ SPDX-License-Identifier: BSD-2-Clause-Patent
>+**/
>+
>+#include "Qemu.h"
>+
>+
>+///
>+/// Generic Attribute Controller Register Settings
>+///
>+UINT8 AttributeController[21] = {
>+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
>+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
>+ 0x41, 0x00, 0x0F, 0x00, 0x00
>+};
>+
>+///
>+/// Generic Graphics Controller Register Settings
>+///
>+UINT8 GraphicsController[9] = {
>+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF
>+};
>+
>+//
>+// 640 x 480 x 256 color @ 60 Hertz
>+//
>+UINT8 Crtc_640_480_256_60[28] = {
>+ 0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,
>+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>+ 0xe1, 0x83, 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3,
>+ 0xff, 0x00, 0x00, 0x22
>+};
>+
>+UINT8 Crtc_640_480_32bpp_60[28] = {
>+ 0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,
>+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>+ 0xe1, 0x83, 0xdf, 0x40, 0x00, 0xe7, 0x04, 0xe3,
>+ 0xff, 0x00, 0x00, 0x32
>+};
>+
>+UINT16 Seq_640_480_256_60[15] = {
>+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
>+ 0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e
>+};
>+
>+UINT16 Seq_640_480_32bpp_60[15] = {
>+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,
>+ 0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e
>+};
>+
>+//
>+// 800 x 600 x 256 color @ 60 Hertz
>+//
>+UINT8 Crtc_800_600_256_60[28] = {
>+ 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0,
>+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>+ 0x58, 0x8C, 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3,
>+ 0xFF, 0x00, 0x00, 0x22
>+};
>+
>+UINT8 Crtc_800_600_32bpp_60[28] = {
>+ 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0,
>+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>+ 0x58, 0x8C, 0x57, 0x90, 0x00, 0x5F, 0x91, 0xE3,
>+ 0xFF, 0x00, 0x00, 0x32
>+};
>+
>+UINT16 Seq_800_600_256_60[15] = {
>+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
>+ 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e
>+};
>+
>+UINT16 Seq_800_600_32bpp_60[15] = {
>+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,
>+ 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e
>+};
>+
>+UINT8 Crtc_960_720_32bpp_60[28] = {
>+ 0xA3, 0x77, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
>+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>+ 0x02, 0x88, 0xCF, 0xe0, 0x00, 0x00, 0x64, 0xE3,
>+ 0xFF, 0x4A, 0x00, 0x32
>+};
>+
>+UINT16 Seq_960_720_32bpp_60[15] = {
>+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,
>+ 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
>+};
>+
>+//
>+// 1024 x 768 x 256 color @ 60 Hertz
>+//
>+UINT8 Crtc_1024_768_256_60[28] = {
>+ 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
>+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>+ 0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,
>+ 0xFF, 0x4A, 0x00, 0x22
>+};
>+
>+UINT16 Seq_1024_768_256_60[15] = {
>+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
>+ 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
>+};
>+
>+//
>+// 1024 x 768 x 24-bit color @ 60 Hertz
>+//
>+UINT8 Crtc_1024_768_24bpp_60[28] = {
>+ 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
>+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>+ 0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,
>+ 0xFF, 0x4A, 0x00, 0x32
>+};
>+
>+UINT16 Seq_1024_768_24bpp_60[15] = {
>+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1507, 0x0008, 0x4a0b,
>+ 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
>+};
>+
>+UINT8 Crtc_1024_768_32bpp_60[28] = {
>+ 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
>+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>+ 0x02, 0x88, 0xFF, 0xe0, 0x00, 0x00, 0x64, 0xE3,
>+ 0xFF, 0x4A, 0x00, 0x32
>+};
>+
>+UINT16 Seq_1024_768_32bpp_60[15] = {
>+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,
>+ 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
>+};
>+
>+///
>+/// Table of supported video modes
>+///
>+QEMU_VIDEO_CIRRUS_MODES QemuVideoCirrusModes[] = {
>+// { 640, 480, 8, Crtc_640_480_256_60, Seq_640_480_256_60, 0xe3 },
>+// { 800, 600, 8, Crtc_800_600_256_60, Seq_800_600_256_60, 0xef },
>+ { 640, 480, 32, Crtc_640_480_32bpp_60, Seq_640_480_32bpp_60, 0xef },
>+ { 800, 600, 32, Crtc_800_600_32bpp_60, Seq_800_600_32bpp_60, 0xef },
>+// { 1024, 768, 8, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef }
>+ { 1024, 768, 24, Crtc_1024_768_24bpp_60, Seq_1024_768_24bpp_60, 0xef }
>+// { 1024, 768, 32, Crtc_1024_768_32bpp_60, Seq_1024_768_32bpp_60, 0xef }
>+// { 960, 720, 32, Crtc_960_720_32bpp_60, Seq_1024_768_32bpp_60, 0xef }
>+};
>+
>+#define QEMU_VIDEO_CIRRUS_MODE_COUNT \
>+ (ARRAY_SIZE (QemuVideoCirrusModes))
>+
>+/**
>+ Construct the valid video modes for QemuVideo.
>+
>+**/
>+EFI_STATUS
>+QemuVideoCirrusModeSetup (
>+ QEMU_VIDEO_PRIVATE_DATA *Private
>+ )
>+{
>+ UINT32 Index;
>+ QEMU_VIDEO_MODE_DATA *ModeData;
>+ QEMU_VIDEO_CIRRUS_MODES *VideoMode;
>+
>+ //
>+ // Setup Video Modes
>+ //
>+ Private->ModeData = AllocatePool (
>+ sizeof (Private->ModeData[0]) *
>QEMU_VIDEO_CIRRUS_MODE_COUNT
>+ );
>+ if (Private->ModeData == NULL) {
>+ return EFI_OUT_OF_RESOURCES;
>+ }
>+ ModeData = Private->ModeData;
>+ VideoMode = &QemuVideoCirrusModes[0];
>+ for (Index = 0; Index < QEMU_VIDEO_CIRRUS_MODE_COUNT; Index ++) {
>+ ModeData->InternalModeIndex = Index;
>+ ModeData->HorizontalResolution = VideoMode->Width;
>+ ModeData->VerticalResolution = VideoMode->Height;
>+ ModeData->ColorDepth = VideoMode->ColorDepth;
>+ DEBUG ((EFI_D_INFO,
>+ "Adding Mode %d as Cirrus Internal Mode %d: %dx%d, %d-bit\n",
>+ (INT32) (ModeData - Private->ModeData),
>+ ModeData->InternalModeIndex,
>+ ModeData->HorizontalResolution,
>+ ModeData->VerticalResolution,
>+ ModeData->ColorDepth
>+ ));
>+
>+ ModeData ++ ;
>+ VideoMode ++;
>+ }
>+ Private->MaxMode = ModeData - Private->ModeData;
>+
>+ return EFI_SUCCESS;
>+}
>+
>+///
>+/// Table of supported video modes
>+///
>+QEMU_VIDEO_BOCHS_MODES QemuVideoBochsModes[] = {
>+ { 640, 480, 32 },
>+ { 800, 480, 32 },
>+ { 800, 600, 32 },
>+ { 832, 624, 32 },
>+ { 960, 640, 32 },
>+ { 1024, 600, 32 },
>+ { 1024, 768, 32 },
>+ { 1152, 864, 32 },
>+ { 1152, 870, 32 },
>+ { 1280, 720, 32 },
>+ { 1280, 760, 32 },
>+ { 1280, 768, 32 },
>+ { 1280, 800, 32 },
>+ { 1280, 960, 32 },
>+ { 1280, 1024, 32 },
>+ { 1360, 768, 32 },
>+ { 1366, 768, 32 },
>+ { 1400, 1050, 32 },
>+ { 1440, 900, 32 },
>+ { 1600, 900, 32 },
>+ { 1600, 1200, 32 },
>+ { 1680, 1050, 32 },
>+ { 1920, 1080, 32 },
>+ { 1920, 1200, 32 },
>+ { 1920, 1440, 32 },
>+ { 2000, 2000, 32 },
>+ { 2048, 1536, 32 },
>+ { 2048, 2048, 32 },
>+ { 2560, 1440, 32 },
>+ { 2560, 1600, 32 },
>+ { 2560, 2048, 32 },
>+ { 2800, 2100, 32 },
>+ { 3200, 2400, 32 },
>+ { 3840, 2160, 32 },
>+ { 4096, 2160, 32 },
>+ { 7680, 4320, 32 },
>+ { 8192, 4320, 32 }
>+};
>+
>+#define QEMU_VIDEO_BOCHS_MODE_COUNT \
>+ (ARRAY_SIZE (QemuVideoBochsModes))
>+
>+EFI_STATUS
>+QemuVideoBochsModeSetup (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ BOOLEAN IsQxl
>+ )
>+{
>+ UINT32 AvailableFbSize;
>+ UINT32 Index;
>+ QEMU_VIDEO_MODE_DATA *ModeData;
>+ QEMU_VIDEO_BOCHS_MODES *VideoMode;
>+
>+ //
>+ // Fetch the available framebuffer size.
>+ //
>+ // VBE_DISPI_INDEX_VIDEO_MEMORY_64K is expected to return the size
>of the
>+ // drawable framebuffer. Up to and including qemu-2.1 however it used to
>+ // return the size of PCI BAR 0 (ie. the full video RAM size).
>+ //
>+ // On stdvga the two concepts coincide with each other; the full memory
>size
>+ // is usable for drawing.
>+ //
>+ // On QXL however, only a leading segment, "surface 0", can be used for
>+ // drawing; the rest of the video memory is used for the QXL guest-host
>+ // protocol. VBE_DISPI_INDEX_VIDEO_MEMORY_64K should report the size
>of
>+ // "surface 0", but since it doesn't (up to and including qemu-2.1), we
>+ // retrieve the size of the drawable portion from a field in the QXL ROM BAR,
>+ // where it is also available.
>+ //
>+ if (IsQxl) {
>+ UINT32 Signature;
>+ UINT32 DrawStart;
>+
>+ Signature = 0;
>+ DrawStart = 0xFFFFFFFF;
>+ AvailableFbSize = 0;
>+ if (EFI_ERROR (
>+ Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32,
>+ PCI_BAR_IDX2, 0, 1, &Signature)) ||
>+ Signature != SIGNATURE_32 ('Q', 'X', 'R', 'O') ||
>+ EFI_ERROR (
>+ Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32,
>+ PCI_BAR_IDX2, 36, 1, &DrawStart)) ||
>+ DrawStart != 0 ||
>+ EFI_ERROR (
>+ Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32,
>+ PCI_BAR_IDX2, 40, 1, &AvailableFbSize))) {
>+ DEBUG ((EFI_D_ERROR, "%a: can't read size of drawable buffer from QXL
>"
>+ "ROM\n", __FUNCTION__));
>+ return EFI_NOT_FOUND;
>+ }
>+ } else {
>+ AvailableFbSize = BochsRead (Private,
>VBE_DISPI_INDEX_VIDEO_MEMORY_64K);
>+ AvailableFbSize *= SIZE_64KB;
>+ }
>+ DEBUG ((EFI_D_INFO, "%a: AvailableFbSize=0x%x\n", __FUNCTION__,
>+ AvailableFbSize));
>+
>+ //
>+ // Setup Video Modes
>+ //
>+ Private->ModeData = AllocatePool (
>+ sizeof (Private->ModeData[0]) *
>QEMU_VIDEO_BOCHS_MODE_COUNT
>+ );
>+ if (Private->ModeData == NULL) {
>+ return EFI_OUT_OF_RESOURCES;
>+ }
>+ ModeData = Private->ModeData;
>+ VideoMode = &QemuVideoBochsModes[0];
>+ for (Index = 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index ++) {
>+ UINTN RequiredFbSize;
>+
>+ ASSERT (VideoMode->ColorDepth % 8 == 0);
>+ RequiredFbSize = (UINTN) VideoMode->Width * VideoMode->Height *
>+ (VideoMode->ColorDepth / 8);
>+ if (RequiredFbSize <= AvailableFbSize) {
>+ ModeData->InternalModeIndex = Index;
>+ ModeData->HorizontalResolution = VideoMode->Width;
>+ ModeData->VerticalResolution = VideoMode->Height;
>+ ModeData->ColorDepth = VideoMode->ColorDepth;
>+ DEBUG ((EFI_D_INFO,
>+ "Adding Mode %d as Bochs Internal Mode %d: %dx%d, %d-bit\n",
>+ (INT32) (ModeData - Private->ModeData),
>+ ModeData->InternalModeIndex,
>+ ModeData->HorizontalResolution,
>+ ModeData->VerticalResolution,
>+ ModeData->ColorDepth
>+ ));
>+
>+ ModeData ++ ;
>+ }
>+ VideoMode ++;
>+ }
>+ Private->MaxMode = ModeData - Private->ModeData;
>+
>+ return EFI_SUCCESS;
>+}
>+
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>VbeShim.c
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>VbeShim.c
>new file mode 100644
>index 0000000000..aa4648f813
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>VbeShim.c
>@@ -0,0 +1,302 @@
>+/** @file
>+ Install a fake VGABIOS service handler (real mode Int10h) for the buggy
>+ Windows 2008 R2 SP1 UEFI guest.
>+
>+ The handler is never meant to be directly executed by a VCPU; it's there for
>+ the internal real mode emulator of Windows 2008 R2 SP1.
>+
>+ The code is based on Ralf Brown's Interrupt List:
>+ <http://www.cs.cmu.edu/~ralf/files.html>
>+ <http://www.ctyme.com/rbrown.htm>
>+
>+ Copyright (C) 2014, Red Hat, Inc.
>+ Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
>+
>+ SPDX-License-Identifier: BSD-2-Clause-Patent
>+**/
>+
>+#include <IndustryStandard/LegacyVgaBios.h>
>+#include <Library/DebugLib.h>
>+#include <Library/PciLib.h>
>+#include <Library/PrintLib.h>
>+#include <SimicsPlatforms.h>
>+
>+#include "Qemu.h"
>+#include "VbeShim.h"
>+
>+#pragma pack (1)
>+typedef struct {
>+ UINT16 Offset;
>+ UINT16 Segment;
>+} IVT_ENTRY;
>+#pragma pack ()
>+
>+//
>+// This string is displayed by Windows 2008 R2 SP1 in the Screen Resolution,
>+// Advanced Settings dialog. It should be short.
>+//
>+STATIC CONST CHAR8 mProductRevision[] = "OVMF Int10h (fake)";
>+
>+/**
>+ Install the VBE Info and VBE Mode Info structures, and the VBE service
>+ handler routine in the C segment. Point the real-mode Int10h interrupt
>vector
>+ to the handler. The only advertised mode is 1024x768x32.
>+
>+ @param[in] CardName Name of the video card to be exposed in the
>+ Product Name field of the VBE Info structure. The
>+ parameter must originate from a
>+ QEMU_VIDEO_CARD.Name field.
>+ @param[in] FrameBufferBase Guest-physical base address of the video
>card's
>+ frame buffer.
>+**/
>+VOID
>+InstallVbeShim (
>+ IN CONST CHAR16 *CardName,
>+ IN EFI_PHYSICAL_ADDRESS FrameBufferBase
>+ )
>+{
>+ EFI_PHYSICAL_ADDRESS Segment0, SegmentC, SegmentF;
>+ UINTN Segment0Pages;
>+ IVT_ENTRY *Int0x10;
>+ EFI_STATUS Segment0AllocationStatus;
>+ UINT16 HostBridgeDevId;
>+ UINTN SegmentCPages;
>+ VBE_INFO *VbeInfoFull;
>+ VBE_INFO_BASE *VbeInfo;
>+ UINT8 *Ptr;
>+ UINTN Printed;
>+ VBE_MODE_INFO *VbeModeInfo;
>+
>+ if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT0|BIT7)) == BIT0)
>{
>+ DEBUG ((
>+ DEBUG_WARN,
>+ "%a: page 0 protected, not installing VBE shim\n",
>+ __FUNCTION__
>+ ));
>+ DEBUG ((
>+ DEBUG_WARN,
>+ "%a: page 0 protection prevents Windows 7 from booting anyway\n",
>+ __FUNCTION__
>+ ));
>+ return;
>+ }
>+
>+ Segment0 = 0x00000;
>+ SegmentC = 0xC0000;
>+ SegmentF = 0xF0000;
>+
>+ //
>+ // Attempt to cover the real mode IVT with an allocation. This is a UEFI
>+ // driver, hence the arch protocols have been installed previously. Among
>+ // those, the CPU arch protocol has configured the IDT, so we can overwrite
>+ // the IVT used in real mode.
>+ //
>+ // The allocation request may fail, eg. if LegacyBiosDxe has already run.
>+ //
>+ Segment0Pages = 1;
>+ Int0x10 = (IVT_ENTRY *)(UINTN)Segment0 + 0x10;
>+ Segment0AllocationStatus = gBS->AllocatePages (
>+ AllocateAddress,
>+ EfiBootServicesCode,
>+ Segment0Pages,
>+ &Segment0
>+ );
>+
>+ if (EFI_ERROR (Segment0AllocationStatus)) {
>+ EFI_PHYSICAL_ADDRESS Handler;
>+
>+ //
>+ // Check if a video BIOS handler has been installed previously -- we
>+ // shouldn't override a real video BIOS with our shim, nor our own shim if
>+ // it's already present.
>+ //
>+ Handler = (Int0x10->Segment << 4) + Int0x10->Offset;
>+ if (Handler >= SegmentC && Handler < SegmentF) {
>+ DEBUG ((EFI_D_INFO, "%a: Video BIOS handler found at %04x:%04x\n",
>+ __FUNCTION__, Int0x10->Segment, Int0x10->Offset));
>+ return;
>+ }
>+
>+ //
>+ // Otherwise we'll overwrite the Int10h vector, even though we may not
>own
>+ // the page at zero.
>+ //
>+ DEBUG ((
>+ DEBUG_INFO,
>+ "%a: failed to allocate page at zero: %r\n",
>+ __FUNCTION__,
>+ Segment0AllocationStatus
>+ ));
>+ } else {
>+ //
>+ // We managed to allocate the page at zero. SVN r14218 guarantees that it
>+ // is NUL-filled.
>+ //
>+ ASSERT (Int0x10->Segment == 0x0000);
>+ ASSERT (Int0x10->Offset == 0x0000);
>+ }
>+
>+ HostBridgeDevId = PcdGet16(PcdSimicsX58HostBridgePciDevId);
>+ switch (HostBridgeDevId) {
>+ case INTEL_ICH10_DEVICE_ID:
>+ break;
>+ default:
>+ DEBUG((
>+ DEBUG_ERROR,
>+ "%a: unknown host bridge device ID: 0x%04x\n",
>+ __FUNCTION__,
>+ HostBridgeDevId
>+ ));
>+ ASSERT (FALSE);
>+
>+ if (!EFI_ERROR(Segment0AllocationStatus)) {
>+ gBS->FreePages(Segment0, Segment0Pages);
>+ }
>+ return;
>+ }
>+ //
>+ // low nibble covers 0xC0000 to 0xC3FFF
>+ // high nibble covers 0xC4000 to 0xC7FFF
>+ // bit1 in each nibble is Write Enable
>+ // bit0 in each nibble is Read Enable
>+ //
>+
>+ //
>+ // We never added memory space during PEI or DXE for the C segment, so
>we
>+ // don't need to (and can't) allocate from there. Also, guest operating
>+ // systems will see a hole in the UEFI memory map there.
>+ //
>+ SegmentCPages = 4;
>+
>+ ASSERT (sizeof mVbeShim <= EFI_PAGES_TO_SIZE (SegmentCPages));
>+ CopyMem ((VOID *)(UINTN)SegmentC, mVbeShim, sizeof mVbeShim);
>+
>+ //
>+ // Fill in the VBE INFO structure.
>+ //
>+ VbeInfoFull = (VBE_INFO *)(UINTN)SegmentC;
>+ VbeInfo = &VbeInfoFull->Base;
>+ Ptr = VbeInfoFull->Buffer;
>+
>+ CopyMem (VbeInfo->Signature, "VESA", 4);
>+ VbeInfo->VesaVersion = 0x0300;
>+
>+ VbeInfo->OemNameAddress = (UINT32)SegmentC << 12 |
>(UINT16)(UINTN)Ptr;
>+ CopyMem (Ptr, "QEMU", 5);
>+ Ptr += 5;
>+
>+ VbeInfo->Capabilities = BIT0; // DAC can be switched into 8-bit mode
>+
>+ VbeInfo->ModeListAddress = (UINT32)SegmentC << 12 |
>(UINT16)(UINTN)Ptr;
>+ *(UINT16*)Ptr = 0x00f1; // mode number
>+ Ptr += 2;
>+ *(UINT16*)Ptr = 0xFFFF; // mode list terminator
>+ Ptr += 2;
>+
>+ VbeInfo->VideoMem64K = (UINT16)((1024 * 768 * 4 + 65535) / 65536);
>+ VbeInfo->OemSoftwareVersion = 0x0000;
>+
>+ VbeInfo->VendorNameAddress = (UINT32)SegmentC << 12 |
>(UINT16)(UINTN)Ptr;
>+ CopyMem (Ptr, "OVMF", 5);
>+ Ptr += 5;
>+
>+ VbeInfo->ProductNameAddress = (UINT32)SegmentC << 12 |
>(UINT16)(UINTN)Ptr;
>+ Printed = AsciiSPrint ((CHAR8 *)Ptr,
>+ sizeof VbeInfoFull->Buffer - (Ptr - VbeInfoFull->Buffer), "%s",
>+ CardName);
>+ Ptr += Printed + 1;
>+
>+ VbeInfo->ProductRevAddress = (UINT32)SegmentC << 12 |
>(UINT16)(UINTN)Ptr;
>+ CopyMem (Ptr, mProductRevision, sizeof mProductRevision);
>+ Ptr += sizeof mProductRevision;
>+
>+ ASSERT (sizeof VbeInfoFull->Buffer >= Ptr - VbeInfoFull->Buffer);
>+ ZeroMem (Ptr, sizeof VbeInfoFull->Buffer - (Ptr - VbeInfoFull->Buffer));
>+
>+ //
>+ // Fil in the VBE MODE INFO structure.
>+ //
>+ VbeModeInfo = (VBE_MODE_INFO *)(VbeInfoFull + 1);
>+
>+ //
>+ // bit0: mode supported by present hardware configuration
>+ // bit1: optional information available (must be =1 for VBE v1.2+)
>+ // bit3: set if color, clear if monochrome
>+ // bit4: set if graphics mode, clear if text mode
>+ // bit5: mode is not VGA-compatible
>+ // bit7: linear framebuffer mode supported
>+ //
>+ VbeModeInfo->ModeAttr = BIT7 | BIT5 | BIT4 | BIT3 | BIT1 | BIT0;
>+
>+ //
>+ // bit0: exists
>+ // bit1: bit1: readable
>+ // bit2: writeable
>+ //
>+ VbeModeInfo->WindowAAttr = BIT2 | BIT1 | BIT0;
>+
>+ VbeModeInfo->WindowBAttr = 0x00;
>+ VbeModeInfo->WindowGranularityKB = 0x0040;
>+ VbeModeInfo->WindowSizeKB = 0x0040;
>+ VbeModeInfo->WindowAStartSegment = 0xA000;
>+ VbeModeInfo->WindowBStartSegment = 0x0000;
>+ VbeModeInfo->WindowPositioningAddress = 0x0000;
>+ VbeModeInfo->BytesPerScanLine = 1024 * 4;
>+
>+ VbeModeInfo->Width = 1024;
>+ VbeModeInfo->Height = 768;
>+ VbeModeInfo->CharCellWidth = 8;
>+ VbeModeInfo->CharCellHeight = 16;
>+ VbeModeInfo->NumPlanes = 1;
>+ VbeModeInfo->BitsPerPixel = 32;
>+ VbeModeInfo->NumBanks = 1;
>+ VbeModeInfo->MemoryModel = 6; // direct color
>+ VbeModeInfo->BankSizeKB = 0;
>+ VbeModeInfo->NumImagePagesLessOne = 0;
>+ VbeModeInfo->Vbe3 = 0x01;
>+
>+ VbeModeInfo->RedMaskSize = 8;
>+ VbeModeInfo->RedMaskPos = 16;
>+ VbeModeInfo->GreenMaskSize = 8;
>+ VbeModeInfo->GreenMaskPos = 8;
>+ VbeModeInfo->BlueMaskSize = 8;
>+ VbeModeInfo->BlueMaskPos = 0;
>+ VbeModeInfo->ReservedMaskSize = 8;
>+ VbeModeInfo->ReservedMaskPos = 24;
>+
>+ //
>+ // bit1: Bytes in reserved field may be used by application
>+ //
>+ VbeModeInfo->DirectColorModeInfo = BIT1;
>+
>+ VbeModeInfo->LfbAddress = (UINT32)FrameBufferBase;
>+ VbeModeInfo->OffScreenAddress = 0;
>+ VbeModeInfo->OffScreenSizeKB = 0;
>+
>+ VbeModeInfo->BytesPerScanLineLinear = 1024 * 4;
>+ VbeModeInfo->NumImagesLessOneBanked = 0;
>+ VbeModeInfo->NumImagesLessOneLinear = 0;
>+ VbeModeInfo->RedMaskSizeLinear = 8;
>+ VbeModeInfo->RedMaskPosLinear = 16;
>+ VbeModeInfo->GreenMaskSizeLinear = 8;
>+ VbeModeInfo->GreenMaskPosLinear = 8;
>+ VbeModeInfo->BlueMaskSizeLinear = 8;
>+ VbeModeInfo->BlueMaskPosLinear = 0;
>+ VbeModeInfo->ReservedMaskSizeLinear = 8;
>+ VbeModeInfo->ReservedMaskPosLinear = 24;
>+ VbeModeInfo->MaxPixelClockHz = 0;
>+
>+ ZeroMem (VbeModeInfo->Reserved, sizeof VbeModeInfo->Reserved);
>+
>+ //
>+ // Clear Write Enable (bit1), keep Read Enable (bit0) set
>+ //
>+
>+ //
>+ // Second, point the Int10h vector at the shim.
>+ //
>+ Int0x10->Segment = (UINT16) ((UINT32)SegmentC >> 4);
>+ Int0x10->Offset = (UINT16) ((UINTN) (VbeModeInfo + 1) - SegmentC);
>+
>+ DEBUG ((EFI_D_INFO, "%a: VBE shim installed\n", __FUNCTION__));
>+}
>diff --git a/Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp
>b/Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp
>new file mode 100644
>index
>0000000000000000000000000000000000000000..86d7030833a096f545393735d9
>31d9f4f2fbf8c0
>GIT binary patch
>literal 141078
>zcmeHwJ9Hz-kzh@gFoN)Qu|weq&F~F*XbyPdaEHTfE*dKcjU5ohf-
>&!%BU8pXGG)q?
>zD^tc9GS`(UQ>MIoGG)r#cb?2OW$Gd_vnu0Pg~E?y>sT{Q)F&%4G9u%Xk&#)e
>|2h0&
>zn&2`0PLf>1@BjWNN&Xl7`zYzU`~UYcP5w_masS+n@=v#$bm8A8pL~*ZKm9c
>M6#l(=
>z^C_Iaf!{aDCtrS<d<p+Pc?<u(e4D(*e{bKy^(^^xHcMvkZ-xI>tK`$wx5>BPew+N{
>zCqGF({r0EHo1gqN`6>SUDV+cGXUUiF?`J>zS@QFr|2+Bf=f6mP@rz$1Z-
>4R2<d?tv
>zW%A`Oeg)^hN`Cb#`2FRtlefS6b@J<9|2p~dSHDSq^PAr!Z-
>4zC$qfGe$A7@@Z+@Hn
>z_P4)H-u~uyaQ?gGcfW(*-~K-
>N{qKLDtbX^0<PU%NLo)l_AL0Cu$shj+zrX)e@~1!j
>zDf#vfe@_1V=RYT_KmKR(E&Th>|AgN^{U!O!U;dK(*MI$2^6j7hn*8;ze@*`Ox
>4)It
>zdHsE*z$*n_Dey{xR|>pR;FSWe6nLe;D+OLD@JfMK3cOO_l>)C6c%=ZLK$`j}9J%
>#+
>z`g{~f-@JKc$n%k3)||b2c=-
>M+LnK+A>$>;;@$vEfKfY?L=VAb__wxr}$K&JI&mkaS
>zw~kS*1G~9@9j0;vimRVfxy_Y(?c(tf7y|!~-77nSYEzvqlcpIQf^ZIl@W;O*3M7fT
>z!9kZ0_+7Z-
>@1+@3FK$(@q_Qx*CNCLHfLrh%DN_M$JaLeE@0@S|JKldEOG8tTLJSzc
>zYJ|Dn!`@e*DIXr+U-e-
>^H5^DwWD+9bE5=`ek8z`XKS_FDqrkua>L0^f)%(?nEBo=A
>z_fYpY?}i^&&`AMu>PnMqa+)M3U!$^re1FlY5cqf;0Cy_D)w70^J`w{D#QyQ|9Rf
>@{
>z8kVb`(W3$AHjlEeUB&Ltb>`mu&NuNEoIQM&cK+Snc~b#~A`kH2n~2dD(13?{J;
>ulG
>z|Id&fV>kskN%9G{)3wsUdQ;W(-n%jm@Z%%a^j$>b;a#Vy<Dc-
>|$FJd0z%bzRz4!P4
>z{sCjp0*YfS>J9)L?rr`_zY37>O@Q{_-78}U2meqcS?f20ZdoD)$&5I7LUsP#5!2mA
>zEIv!W^NqXXbtyvT1i?FFELrj6Q@p|h8in*2V;#tu|Ax1|Dk=1pD}m+Uwxe4Bj5U
>1+
>zJNV<fsLOyKaN}*L9!@<z9mh8h<ni$wkx9P7lK%h4Z%*B<7Jsrp4EO5e<5xcS!oh
>MF
>zJ_0O6y=;Bij258V7V**nn0p+qQDwP~>Dq?`cmO&E`M9W{0!H{GGAQ{1E-
>QX`E<5s}
>zixRkn@-
>arZCEI?0@4(@!dEW!@f%90CZ#9t*CtDBKkZs|re|+@#d>x=TP>&8u37Fif
>zP;WRXRfWgu@yZqbfd>-qeS<tg%t&h+Aa47}cR8#P>jS!=`3l7Lc);J!$~z?;OIihj
>zxJtjk;$;D^S?~^kMG7IeoW6RCcaSk~q(8<IzH0o9OmK=1x&^#M_~DWL3Z%@l
>%Bx4@
>zQb6AQ0u=1$cz8ZPP&8e|HGe+wWG;a{KAZ!dmCOWS0ZA+r)prfR?Qf3}ZHIRt
>%l`lv
>zzO}JApCzUJ@O1P=5WkZCa0l!MTn7vs`QQIzf_!;+1fA~c0XAemf*X$MP!igY&B
>DW#
>zd-rkbYJv*{4EhQVuCL$*Dm%m{luAOUt{}bp7>!hUi69=~R-
>0q&3OmUD4Bta0ky`-E
>zBMCQ&c4z~>MVXJ@dBmalpL?R*f<qBnTQ#X(J_tX?h<1tLTfD%Bj#$v8##j&Vq
>k}Yl
>z@AY!xHNnH@N%pU<a<nu~HUmE#yNG;vNkH|7S}oL&{>V4s^ECYzID`MbpM
>sHs!vn@!
>z&V+3w2Pj#D`tZXJ_M-sGAqlrXPlBcONaEABVz;s4SiqS=@9#jn@OTgGC#?-
>dgT$2G
>z--
>!^SMEK$C2MRMB*}oyW&Rm32W4K0r<wWA0cjG*hKmZaaM^HJ~Vp3Cse}#_
>#BI4uv
>z?}PKYf)sz2zQKnMuroQOk$1S&{|Qw)?8fju9MHeU6|8@9k`j?5-
>ef({?Vfmz{NTul
>z6~lkvK)7~A<pUsHuchXjkS)~s1>zt017ZiRi1VxPE@+rB{(^ty{I0;Y<X_;P2a4d3
>zzTPsx848;6ue=%x{w`7+O9gX_Fu@+d-G_0CQt1Jgj02h4c>L1?!h9HEL8Lugef_t;
>zp{PGRq8g8|BDz@ifQQ!rNT?+7E-FwFyj#SjQa(^$Ab&|ne*?-
>yfnolYlQqW=01AB<
>z`2nRtKFVKgL(mTh)C&}X`>xkSc+-
>}ThiiC5@cGo?>P&AiC2xWXLl_@<ZAS2fn>B~y
>zEP9hpAtG3)%foU#Ho^kTkU&H`)PUUf_74!O_alHGC?AjDQv~}Fsb9)RL?Ea%Q
>e=$y
>zhXSsny77dg7WC*bJj9k_&vlFfOrd>PIjS`$P>+v5YSQ(Be8ll!kPo0&7$ISGu3jg5
>zXsxgbZ_sH7fPv9?AP+Yl!AUOpf$xFw@~#>p8DWL)(2C0&tEB~kMLm!50Ugba{
>s5Us
>z{jxvCJA`Zj-WP~}DDcsbfH{urt^(i(j^2?UIN(APg@+Rg<Px4DH&KuPFrJR#rf;?B
>zU-?Il{bQ^byA-
>_PT`lAX@&y408LS4N0a^3MwID!3+5?Pt9q;bCP7`5;K~m|xn9z2*
>z>AQp%c031C0MSbO0qqHgqY^dWo@^!kv6Qptfgi3X1$_k|p?4zHpiv*AdsRkD
>KJvp4
>zCm;S4$mS{S0Q*XVe}%Ys?dtt2B$q2SM)p<m;qHcx>;OAaaYNG3l=>gnf&eMdp
>2>%o
>z=g?`O9Y^r5u=@fRaNGm>3J*Lli5*cdsZ`zZu8ix(;hvL#HxLPh>lAxe&{qJ{*>j-T
>zxp#cZ&g$A6<iop~AV{7GB|qS0Cm%j|=!XJm&x4gg_WNFq-
>6+ThAcfEZU}xf;_f_Fu
>zcj6*&ffzxTI(}$a&VJDDSqF04`;~k^V}kt%@&V){;uxqD?;wMq2+^Qppxxuh6E6K
>R
>zJo^TR`e2}fJ;%pzH=2)NKVbCl)CxWd_5;oku&)D1;=FPgmV0jy`9Z251JJTdy~Wyq
>zmtH6;zz^;0#~4uv^5JwTigFn02i=EN5hSti9rSSO-H;DQIAW}^{cyxP!JbD3d3}ZN
>zfu3>%iSkkUSMU%B1_L+W2G?fj#&8u}NoPMCO%bpc0?=+K7Y}~e4JT-
>u0UxXixi*Gh
>zIGlXAVJO)1f5UnLVAmAXaT^aO;V4#6*vZF3u;&2GBU!=<_5-pV%C>9--
>mZXie*!<6
>z><6ePY@xE}kwK;20D^trTk6uDd-;H-I6}j3nY4jg4Jiqz_FYR+BAt^PLs>wQ%xgJd
>zuaCaq3@Yg#m6nMlC-
>M;iZzf34d`@{+@&UT97RiyDq}mL)eTmB7g~n9&qa1%k>X+@0
>zcN~L|v{hZf8oJ;_91jwI*R>1&c*9b?=T1I#{CK$doA3Fa^Iix*K76-7`y2AZhl_)F
>zV)bLZ7vzHj#VZ61{a}RWn-
>1Rs@HzmhX9EppR<NKCVs~(WK^wdqVOaV=2iI4w0|Ppt
>zIwy`^BB_8n5%nFE+Vim|sk0j(?EnkM=Z?wf@8XTm(ykMU(x6w32r*QA!#fI&(Y
>}s%
>z8JG`j{I%nUleUr|jvrWW&@vUk@+4?~he~;`_IK<^?429bS8y4eJNHTn%Lg#9*7
>CTH
>zvy!#I+dZi4ITWwt!;Q9}E-
>#LbA)Yjk7k)|_=v=X^s>ew?VhMH}q}|yOjAp>C;O~NF
>z#yA9O<?1bWQch96hj1!!U7!wN;=4}JIqyD>^5IJP;pZ5tf&&e%Iy_*QiUz=&53jF
>0
>zKcc=W-=nYsIgn-8;)nM=tM>BEEq+lx0HzyEMf>5ZgNm>&-
>%{+g{t9lO2Z{q^IHbM`
>z*G@jd_yb-H_8bRQuKSk*!hmQg9d48mnp*l-
>*hR;_(GTAb;}3X^lo~rkeG_=gQvmFd
>zRszWjhAU^!12IrO0P{*dI4txuT(wvTk9HN9wX&Oa@)6pBRUs9z{jO#B2apT|0W
>}|?
>zx!x77g?xYoeuJO@k^{u}k%mMkCs-KkcTFw*D-
><T2)WzyQ13`fw?_VJ%&Lj7|+IvM2
>z8$1hu(W3DOHCG4;tHHjGEr9ci9~@Rts;<04<eNba%q?$69fkVJH8<D~#0F79&0
>O_I
>zk1z(LgTN4fcZ_8NKb(9-`vJYjJq1WXJ|dcFIfWix4m}?oH-Gx>AH4AdLyq#{`yxJq
>z3oJFpli(sous~4&?4EeHm_DjGuOLB#-H@`94++clDgch~-
>QR~%4a_ZXoBkCN&DZ3r
>zLx0rWDes|tkT7hh()H88A0i*fC8w_dRwW<NBk4eD2*QPbo|mDisQBFJ<GTTtz
>+&%C
>zTsa&|c>Ceh<rrRt|D9JvT91IkL4=qT(5IEYf=6Co1^EcD5MYHQ!UiP2hn@=@IBR
>%-
>zqp}|WtFj-y6GJ`zKja7YM?Bmeln-
>~qyQKjQ=Picuh?5VeC7b|K`+<O>zAE9u%|Nwq
>zC-
>4Jme0K&9zj*_#et6@sD97h`1Bft&$8hRQV5CTJh>=)ChU0VV%=M_?sZo7pB8il!
>zkfcqrAh*6}+mGPgx`sl}189H}BH)j}54=Q-!r@vIu8DjAsi=Ioj$OGsp%+4tO2xaH
>zJa;@A@7_U0@B0`S{^0}GNyq2N54<P+-
>O@J=MybTH`PcQRAZcOR1MP=bT~Gx>5=r5@
>zkjrj)I8fd-%17C`VCV#OVn=gIzUr~qh_csK4RSY_d;ndlYaC7aVc!^Gdi&u#13!OW
>z>MQpSV(@jC!L0-jJGHO$Jr0n+c2gVgoL7OqjDO^YKdv80eFcF15dl}I*Pe{sD?k7!
>z5mH}}AO1Exi?Bk6b&}`ncg|!j<kk<Ue0bheN}kTnmhurr9|(d?*7D&5#s@4=uv}
>xH
>z6kzQ<12?5q%15B;<2Rp2goEuu#RszFDuKTj<+Lo4#qq;+9<1JRT*wE$iSJUtWfh-
>5
>zYAM*GfBm$)QT>Abz&1HcgflqsAMgWu5ZvXkLWgzQ+0_rCbC5_DlMk%bIV!X
>|kFBR1
>zizm7UGkyU6V~nr?kub~3X?K_*a#G{4K2QCisvHlxU<y$KSeL7*Qq4#o_y?`^u`9
>gt
>z@pgFNCD>bGZqHp3qyX$2@~O)q!gn7Ovs_On_5%t5KYXrA)Kw*tfR=0h7;!`leF
>gjd
>z4HR)*!k?qKx;|PdpMU`Nmq`9nK4SH*HHaGG<}M)F)eo&fP{!^FfI#fO3U8GJ@
>RyE}
>zUJ`v%LnnY2z<Wud!}_DLA6|mT?yegpIXKuI+&!Qy1?<kDTYNMA2RQxi7(~crlK3
>+C
>zx3V8_j+PB71bzT4#G1kKt@qI)Yy=cIkbFR$0PF&pTggh$&V>5<j-wS*X-
>?W5y?t*+
>z^5G@uhAy<#pTa%35!!~+t5C{iV1mYWhxhGD`EcN%2$~F^=K(K7`{Cr(QSkxhx?
>BhK
>zP<#d{2aFVlA<0*jrTY9EAUEDEk1=8w^c8p{NE+aW8;x2>9z#AVn*ohM`2ZaJpb
>bx>
>zG*rE|M7_Kb{9C;3I=gES_)5-
>k0$}byaR^Uc4Q02CNerd@0I7Y~b9FnOBLvs^$Bub$
>z75GtN2>0>8QLFd09>41N&W(cPMa8}2T1dwt;EN-
>y>hPM+OPY`GqI~=aiQ=5P2+JWE
>z2sFmp52df1Jr61~%15vt1a~D4;RazD_EY~K`mVuIz_vJ7wtNbx|ELV^1)YHTxPg*j
>zsy!2&D!@~uh4<7#HX8a`rGMqPR#6e5xEH<--
>mY6}Hg>%NeE`ho0)ZI2=pyjqGw39h
>zn~hBQ!dK@w>v4lgFvl2l*)@{h-^Kc&-
>G{LsOg@mB&YlAy@H~1`Wv`9m;EDu^#kN!u
>zfb_#~5i}0L0Xv*_!b?0J-bKF#@)@v%Zz?`RQio6-
>_JvRfYVq>Qm5&$L9mc*MFCPxz
>zS1yiN(y#>V6f)of{DAElzd<7gfqW_;6=$IWudgt4>gB_Cni5t((h&&ihvPu@Japq=
>z&mCm1ukbWdpK5hL77pyY(0C$3{(k)XJ($dffm~Qa5%0${udguri&VnWpkW+fU
>^Ltd
>zr!GDWmwr~N8V^EoS89we2CYAKr(bpaoSvg~1sDOKrW`-
>K?*e3}G{0t%czhdxxdkLn
>z;X?2E*tzb=TLVe&?_&Md92>l_^-;+Oyb0$38r3JDi}FE~k-
>J01A>1G$v~}HRWUwuj
>zd^mL;>PEofG}s1^I4{6hK6rpw%2Uy6eV>2zwHuBKz$sSeE!q2C$%h}XeqDA>Y)
>NPz
>z*bgDZ6iG)QtRKjBD1C(#@x~DCxj!%M2lfen0D8!+$f0n9h)`Ly{jblz^77$5BIt#o
>zZUpS=fNDdy%g;t3nX5-
>w%2Uxd!9y9la7_@a3NS)OsT*S>AAjW3rn4dy!oEY|>IkRG
>zuo&<jWi7}@1&b2M^#PcXs=(}X0tf|}K<@(&CLhofJx@Y+!5LhiVFef=_acLKz`~D
>#
>z(T6EBrvRL*$#XuOmcxYdGVr66U`Iv&LZID+2^b-
>Jeth$<Ujy!V4n9KZd*c<hC@kJ_
>zaRg*3z{J}%NJ9Vdfr>KZumc(BD?Z-tJC{q9a<Wpg->t1h7Wl3TjjrxM;}CgF>)ict
>z76H4z?}d)NW!+_^q!MpHoIH_IL2Q6>kf(*DgVtDpOMZL-
>_5&9^;iw3BN%#?h_>S~r
>z2MJvo3szZumimR!dJ1|+q5wj0c;&0)!=nV_xt`b8uA^XaXfa7>-
>mz+U?F)qU`1r$*
>zLq-
>o0CrAMbUMUbI$$|k9<Bzh`=V|ss*BEf`#s=Whet3TuEQsR=b$Ek+@%YupKCa-S
>z&K9gtXGtKab}vI3DHw#^Ig9Zes-
>p+UqPT+#Ze0l!`rVJ9Aga2ML<Dd+#k=mPB!QI*
>zNz{(BjzCb}O(c41Ip7{d@UM^)Fcd)z^VV^tYCz~8;YIktG7U%~*Re4CZ8sxa)l_#<
>z8bf>@&p{lqqVhk)-%a3`Hy~Rt6xoj-*darET&u!J5351Izz;k{r^p@OaY+?UUxi1m
>z`p}O`P&kOO0GHZn3=RTjZ^OF)1*@zMH{>i4!e4}M!3x!55npYEV+Cus6Q{32Kq;
>O>
>zb@YH<;se;#O}C&BuN*;ks~X>ORXUd7AE!G)-
>3U0GMpfWOG;Dm1K>SdFLoom&yayO{
>zj9n|<V~Bsu$L9$w*z(+PML;~9WE!v{fw03oKK{52IUqj!94He2&}ry+4%Ol9@;@
>gZ
>z)fL`7kbF3|3flu9;c(0ibq9VxWkeNteS&?Fl=2!SLh)VIhbk#xcnc^?I}luoevKY@
>zfCN9KZPBm@fe`T+quhrV_^#*u<B*@DVju_F4}ND@-
>k{Cf1(%Qh8R|g}!~Y&usLAoe
>zRf;-19NvI9et3LB_1{DN6QBeNYrqKOpC2D0?I4AxjBJ(_B=I#EqLelv-V{h8jUL{O
>zOZ!$q`H)Y(`vns7@yGkM>XWyQK@^G!7$nTke{{y6lNCFFkl*`fr>tq54T5S1LGnX
>p
>z)3I>>)M+HAlfq^($ExWSZaWHiQL^UG+r9r<>Xibo6nLe;D+OLD@JfMK3cOO_l>
>)C6
>zc%{HA1zsueN`Y4jyi(wm0<RR<mI7I)+w1jD`u*-
>+87A9S`&wR7Ano=C!?V%l_3iEb
>z{r%+rW;FOa;0S&Q;lpc2);k$qT;EL>t9)G@`ShHvqL2)H`PbdS`Diq{I6oVn4o>>r
>zxL^EBMm_EHPe-
>@YWl=GrI>|@X8kd*cf*Rb?!Obi$)<sd|tHpeBcRe~Aym+Q``opV<
>z#S6!j;_Snd^^!a3`J(Dr;iOnhZ!S(>u4T-+gUcz=P!j+3dj7#q>8Hb*hUL?nGZ2%K
>zZ7=6H>z?1&;2aq<{7?m?tE3|~s#xBh^<J1YN&A-#7+1I-
>Zbz=C?TFb$)dc%wc{6xP
>z9O>UIZ9K)@`wvuMbtj@B#^sEBl<H}Fi>$3JH`eP9l^?w}!e1;d53|}v(s#S--u1$8
>zZjBBEw{AYrAxLj!w@2J97FYf4h<EVPozZNg6^~fEJy;Ho!|?&Ok`HWVKEHZa85v
>Gi
>zt%YN~UOX$Vd$6sI{Rq8oH61;hk?dW~x8TNl?e^Q)gDlVX>PG)6s(|%+dH+0aeR
>?+8
>zLRGET#fNG=pd0k(l;RuCi~034n33M)HaNoI{OZ}{cz?M{&)Qk^z^VNH?1_i$>EN
>~v
>zh8TQX%xAON{q^vPG2EXC6hb=MPBkyC4z>3&#iI7Sb2i;%Ir8Ofa(8n%g7`E9sQ
>Vu@
>zH-HZ5@NTxs^Ss#9?jRz?-
>RaXcxqH#9tBNHE#7mBS)^@ap2i@W5>iXv9_I@&*v8kOJ
>zb259X37@oo)ugNP<@EMq@PUr}8u;NK!FB>L^?81IGnp-
>6KBVbbUiP0Newv=#*85e(
>zYJPX|Bxr1;+>r}(PR?&&3bctK#qG)Qbyhm453Uuf+11HY^ob+Wx-Iz5>D81@N-
>O3}
>zj&4NK;Y`&UZWQ_S#l$$<QgrWf+3<GJptt77o)bN*4Rz+TW7oYm@s0za*W?Q?
>jvJIX
>ztDWeWyA9Kh)8dy7H9N2OH&>TO#QwaF9m~tVSBI({H5)jxx;~mktz$=i_XLhaJ
>Hk9y
>zskD1p*H@3mkUC{Gzlb06eJ*-Df4$kDZXB?>IfjI!L%RdycZ1`5+0Rez78rETXZ8s3
>z7!r~WY|jd2jgP_o7R`ToMY6$-
>JwRMt9hyezi9PPvkd~Xdyz29d3zzr$;u9=Q7DGPr
>z>F_+X0g^<UNDIENIXqj9n%*+2ZM>QG@2z@@`}zTB+QTr<-
>DEnSFP6(C#@!*${qp>@
>z_u;5FNPxY#gb3nnzVL0BO?~QaEmN|ydsAmE&kx$_-
>i=jDep?qE>71NhL58~?xk4EJ
>z{_1@20XP6@_w?fWex}ori+nM?y*#UNDIxLN)LDx|PEmC(tq|hs+D=f&`e#>@
>hAg0B
>zIlVqVdD#P&&fwy9Y7*A#iDGeoHMD1SdRM07GlMUv9_Yv}tQwYArU-
>TiqkF43*LSPQ
>z<!P<Z9|-
>N8!KA(6b&EWv#ofh;CFq@z>H6H)DU)sSOox_{T3%ZG?hdYMoIcJExLRDl
>zOpc_zv)j!b$~7mSURtU*y)YSab0AOj#E7sL%aOs>&fwa_MDfDkSlygj{mTISbh
>m&T
>zn-le8dy4s`Wk}4hYjK#MQuiiSU!7U(NNY4_^^!hW-
>B_)8I_j&MI;VG*snnRqJ9BFU
>zc53y@<slL@(@VpwEiY9|((IzahDY?p*^3%arYE*@Bybj&#mw-
>X1{N`9Zi`k$x~*=U
>z8OCFEr9h;8L#qkI?aS%&<nyT(z~^pky>FvU?-
>qC3G?)@{zjvlwZ%Qln=eZ6cXQOS!
>zJc3<azl>D5{x*gqqVLXDS`}FgDQ--k)aV;Ex6&I;XCw2oZ;wg^(sh@`^gtg5uW3ZP
>z+h>-BsY6-aFK$(*vW)t2uW!>Ni6y~zau}GMZI`{L8na%E+R^NIrLt?oOlm~y?-
>Wxx
>z;4|Ic>FGXg=o{K<B0Doo#aPjlden_4%Y6lTpH{-
>Vy*+eQXil+^=^WWek7J6vJpvP{
>zF~u^I=C`+tPoh|o-%F|6lfv7)o(?wVzbb@{8%vop-
>Z6x3p9ytiMo<MRo6_S9oNI3t
>zlV{uFB(;3VT0|QjtZsz=)VtN1V<z=W>z>oqy{5Pl;x=d&bVyj7+~3|p-s|0DzCo=i
>z1>73Z{R%cDBRJY)O#03>;eI-
>AUJ$mrJ>j?**@MO1u0Gb4_N}BXZ)C@EayvSQ<n~^-
>z+l6hHPR~X+O>y7#^Nd8YrtI*10h!^$)05DK!Rh&BW84>}AQ(fe*xzbLAFHpe(Ol
>@1
>zLA{@gLG^(M;ifn*QoqB=diD&fL^}1!QxH_Y9QH+s4fX}OxTz1tL#_>DNH)@b+i
>WLO
>zncXSfw-U2lClgg9XxGL4s3tO%^)K#f-Q%a1ka}g6&u-52u-
>g&4Gq|jsQ^@bQ4e4Gh
>z8Wnmx&3I^Dq^AmwTtHqo3M>|P=W29BD(Rfv){VU;(upUp9pe;+PPTo9Re<$
>#(SS+s
>zqE629Ti*SRF~f?>P^*S@_0VI^E9%<Hs#r}fnz(_r!!)y2hK?`?o3&}x$aJV%>Cjl*
>z3eBv+bw@Q?E5BtvkCiAjVI?$deJ4Fv{U+xlkB;HX!8=8}HSsWsrsWS`7violJLDb1
>z{lRAE(^k3R{TsUtIiESru5?Q|DO)tDukw3}J2oMhT_Wb{$nQ6HtWbOZPFp$vS3K
>b^
>zKs{T+7i|NaAYR%9#WwKhVn++%wtImYOW>DG2^sQ(yjjU1Y7^^6=72=>t|kC`
>KFf??
>zDGIpzc5^$}HNlC3cglelkc;gGA$>K!m2<CoV0P}sc5-
>;Cgb;aZ%{{iG&X%RDnYMMY
>z-5f<`Cz&sqsZF)U+HUiZY=nei$CNd;XHs&?T|M@Od0{Jz`Cc(lvm)!JnE{(`t1i=l
>zNeXVUQ`NoKqisz3iSh!MEb3y;sju&tMzctu?sZL-
>G251}3T}%Vh64$*dAXe)!FueO
>zQ65;*8!#@m@OeARR_C|Wm}euc5Z7xxBh!W|*5c{iLp&{N3`J5aabdZoTKBN}c
>TAJ`
>zi=4$8Qtdfxk!_-rr{}E4+EbC+2w<dJ$6`o+9Sa=k%&JxeuUppLvludG0&t=<R(k=-
>zE@k)U3G>#tytvt3S^3s>tz^`F=QTGH(wItE@5&CG&XN=ZKkbIv^z>SJ#;pb9ME
>T3i
>zP+Qr&`A*8pQ>|yjk=F}muQrl*+X9v?U&;BsEr41KSuy3;Q+b<hCqi_t2v4^%LOy
>wu
>zlbCgTCvep78*FCJPita%TM((fXwOJa$}e}7aIEJ<&lRmX!IgJiwDcYHT8{~pyq=Ex
>z7E`7x2_3p8XP4J^um{Uza({Pyc_t(9zNoGdY$A^W5t#d*n(pDw3fJRfjHL=T&hM
>#U
>zc+0dJmCeouXqn>k8s;rb8g&NeFabsMCaj!*FHeXG1$fo;;oEi}v+Bm1S^)t2XZvo
>u
>zqPKVlgG9YjmEF+p69e5_>Af*!WDI|n<|YJgcMk~)V|CX<F--
>*wv2vAGMj9ri^RD0G
>z$V^+lU1Wjc5zaGX-3OzbwlVCn0n*)4=3zA=MU9w`Iizh$bzj^JrK(OZh!~YjoHtB{
>zz=ti)&QHzt7X(}DG&MBKIyYBOSg+UL>*^6r&P;?-
>JS(#!^BOX>H0_=m2gNNjLcVE3
>z_r<kbTa>D5fh)C>Apn26DvH(gs%93Fw~1Yy7=wj^4R=}bEiR1d(isi?^wc8E7G9}x
>zc5}Kmw4)tu!+3OthW}FbdjC5+6T`<$nL8+0vm%ac`efynH<GY>%@M(?Vk(engi
>!xb
>zn-HF`t1L*1P_i=DEFV#c+}c>m+pFC>f{=ncAJE30F}YLNAJw7pgDtl-%B;~RA4=EL
>zd()FlkEG_*)lq)r=9%=4k}0YJjhPiT3Uvru3V|@9I-LrS=G2(N<sM3)2lqI*m%oW*
>zx(ma~xh*C<n&B&ggEprDO0^20cA!w!Gn8=_7W`HMx1OtU^gxa7D-
>MX01)sG^jMSJl
>zQ@|d{bjX7f+k7^`vgO8VmXaD<|7t&xF<Z?KZ_FN5@oze&$yBJnU@-
>wizkUNb!40@v
>z3MbP@7Y3UyiPE{^khU<!R%o1uu4QFgUS|R~uub=543etI;C-
>{@Qp;~vRR3M5NkN&f
>zn4Bq=apLi-
>CC?k^7&cumtWZi}V<#(#YNlYY;6qt*=U=TIn1Gzhi6v%VbggRkk*0fO
>zDkQcN9egY4K-
>MfcLzHs|MR;r(P}ZG%(Qb3P)QYjU3|eSX*>}=&Igl#uNlE41ZJ1e5
>zLmH}&^e*O9nPIJ`MpTVUguLR*7tBm^No^$`5bRJ&jnJSvwH6mGSV*HPy8DTq
>3t7-H
>zh>8tN<<OW`-BaR3&9x%-
>QfxWUS0yC*)io?Lpa@t?Sfou?eGHWJq^VV*f>R?+b!j`)
>z6s0ZC)1g%A#VrA$I@7XAw$<>03V=>2;d8`EM@g3=zrIo2vZ=?ev4o|Vup;R>_p
>cCU
>zaYL*oX+Ama8^$T8?IUIPIn}}A1wlW%5Xk40Te4mmN~bA_sfshwdH_<YM?;?c
>un1%}
>zt6lve!e4!f1Hcd&nA(6q5gJ91&BANbmQ(9!y|l}{^i&E+ensF6qzanVi*{F)B@-V#
>zS<RZKMJD!!e#H_tSb|R+3}FW*V+0P=UhvGWQzO>GZMqo^mcBC~0iLGTxco
>RPfI4bJ
>zi#Zt+D)DJhSju1%g_Nq4tQBDvwAfC`THc+Pp+nrL#pH-
>kM>=E)BNaA;HiI5BVazx~
>zRMW5{YzXLc2(7PDrPvFCeR|ejVaf3rO?&L9fdya1kf~mQie`GjnAS1Bs>-K>la3zd
>z!1r~S2c^3pRAy|FP|`5f=^fxmZ<Uf(f@<-bsR;5t5fGIbJ+B)QW=dT})t0Ip)D^K(
>zpbw1YBI}jT+CQ;AtRtd0U7d@uUh`p_8n*&Jiu&AP%i<g_aa+?WC%v*G1I%p5P
>1$`S
>zhcd)Ks2*9|(N`0TK;}jmR`Nn2G8^?w8jzcR56nss$;I-m3PGi_0o?kC3#>C0!XwjN
>zs^``Y2~}`~#QS<O_?nAx12&N#xt(BiqNh;S`85$}AfwJ#1<-V8nk1${kl_N)k<4(A
>z*9#F{u9$a#6J;aTGoq8U*Hq)H%hB8-
>0!hy}tzim>;jQ!G*ZEaVH7bS!pmRQRnVw2f
>z#WH;Q*7B~Wqz6U(tk2a6V6pH)&N8)<f;bzQR9HFF{1pNnNdvNn1)p+o1gzeJ6
>B%-a
>z0`*Z>^XqY9NnI+3O#o5Y^u${EuHu`3oa#%69p^u7%R$c7B2J?E(^G5=ISTIZmk1
>1n
>zBeo{euhu>j*@5>@q&8cxx%`xMxL=*F4ajkTNouWz<0@Z!d_ZTR_^>{+voM4
>Xf6<eD
>zn=Xjz3Tm;4V}(m9d74M>Dmy3a#8W=XH(K1d-o&)86K+CM6-
><U|d3eLJ>BjW2l5J47
>zysnA{hdWWh8KOxu8R=MB=%~r2N!0(UNlQ8{l4!!L$Oy=2r0IVWk;Yf7uPTcSGH
>dcx
>zrwC~7^K5+szx{8iusa=ED`U(CSE2H*5V3+pgp|L-I+)f!o95ii-T9@vYQ<mpd`V_a
>zXz+kBG)|$nA+)kTGXO$Y&U;VE5Tqw9196AT+S8#>NkwFu^50h1<!kt>Qx-
>Qaa8eMl
>z@+Ehm%$+p(eqPq{D%i}BBBzI{hDzfv9OO#Iy6N~psUkXl54EfH%L}5eq=&|)So
>CVC
>z7A;oQAw$GCy`v`c!C>?KLDX~tK*@<;=o-iK&_q1>AjCI-
>sF_wW)1uaQuHwj|1l18?
>zRciFrj>v4aqM}LBCgY=H#MKM2)r2)p&siS2nf$pVniiXv(o7<`zew5sL;tF&Ju0>;
>zxI~600TJnh<(CmdsmZyzQd5xa7B^XwiMa?t>FfZx<kH-ub-
>}z1*q$RA{#@s)#C9I^
>zOe!q8KCL6?E_mz#@K7-@qVLq|XV%`1^pj;Ys;-r%M(};f*C?ftkf_i6!9T6nQ3;ix
>z)P&*#hTJ;}<n!xj73=Ui(0w`ATF}%D846L0UDSRHWPH|>{xX}bR(-ggctEQq#z=0S
>z-;iWh>M2hNF$0uJWA;Zk_xE>KL#?O}M1BQE`J}|-
>O=JXH#oT2SxR}HWB*k+!S*@}P
>z`6xPqQD>RN3K=rt9k^%NbY8=WN^v#E>9A~0uLM#!9qxu&;!Ib2$o1$dgw+-
>1oCbkq
>zD3u9-
>3dFBQt=nX*n1Hw!cUP^&yg7@#r)o+X*ebSkX^qkW3(CO}U81VO<s>%cP>`eH
>zRZK%sNsdfkNa0zl@mNC>tyPdKD%bF?m2%6o7qW9{9)TfC5};_n;E0c8Dl|19Dj
>Gzy
>z))6N;{kM!UU==K3Tlz{PU`6!m8$GmgqIm2zRsI`Ldqs21z{<!0FBI80CauTnFi+GX
>zUfR)QxRlWp+$$L{BnCz%WwZ1ZHEqt)RW~<GXUs!fox7`gyb09i@yd>xv4$el;o
>pqN
>z;Y+9xHAP6SJP=twGR8wkgHrBT{-
>){#)M~Y8qiNH{2AoDhB8=r(Otd4X{(&EBdw#M7
>zQU@v`J#o5Hg$_{>SDuZKNS&15M4aSOOJ+V)a*h!ii=d1%Su-
>NXa`fRH#dIvhqau9~
>z4Rv4+ottZ*-
>*iiUcZ&warM+JB*quyAAba+z=|z@&Ao~EVvkBMuOsYeqB=zpFq%j@5
>zUi0h)nbw40SePx=_*7?dR)I#$l|kntblG6i5}B~g*1V-M3bjKxLUtphB<T-GJ##*N
>z#k!Q4t-6h`cX%!-t48-ali?I<?7_Vf;!b94WH6DDO3KxmgKgEu8h4ewt3o!&G``Bf
>z*uNPDGto_C@Sf&Erd&{iE=MO!>!>MzvH)0iU*`SDhdB+>v~6_9bXWPXup?tO
>zz;Fg
>z(UU<TD3b5cKiZ<bxttseP|GXh@oWnv+5M<{C4sVlhICi;^3KgzgS|G0y%rvMSIt
>Nx
>zwc`{&)MF(Q$=G`vbPiTVuBD`LSUJZ{!@nv8gV<B0msvbRMwfO=;7_e}YH~lBfiZ
>OC
>zDY&WZI;hl`I3JAC?Ep!GPJ$kZoF5_ablpM83Q0BKqiF}J4CU>p9#U%uK)HLrlyFCF
>zmZEO${U;V+wIk$#N=aY7AcFywQ%W_xoZ=&E61sxq`G_Ffl}Ycrdi;7BBzA4)K*4
>$+
>zBTU6TsGiKw2PiqUq6GIRI8`ZB%)t^d9x|Vs&<!YDw~OH+DRXQkhK#JPSW@pc
>Ezabu
>z7NQ~clj$1N7W=&q3@fvuRM-
>Zm{maUz2z8?5WCK+#(zp;$QifOAeho6zw?_=m*r^7_
>z;M~cwQn3ZKr3pp0+WT|uPwmYRq>81!kQ_<Vw#p@MBw0xA06{?}a`ui-
>6m7<rmgpM^
>zi84igXq4egWX*52vpz)YJodTt_-
>F)6@`}>#ObiD}?xyrvm^PL&$MZS2Y^{u2x~?q@
>zlC^}K@9@)+gD?amqNiITwtI0I3!=%Ba_C0p{L>3WIv(`X64HpWbQ>8hp*CszR!C
>_>
>zgyej>M8}n3gK+B`bA^#`wmp8^zae8y#7|OdT*%N(4hLy;SBe00cf};{n)+<pW1q
>;;
>z3=&%e#JX}K2Z|JYQx@X`LF<B|y#r=Dz9Jo7I+rcizmgsD<?IKUagwXfX^b+F8UJ+
>s
>z=PoTUZMsN>v9cFv|ABf3BA*}Gx@Oy{?}FSe@5tDAaTTG+y~Oh9)5-
>}SG8~lqljSsV
>zT_z2SNtIZ4+cW8RBO&EFD`_KL8MdOuOb%8V9Bpyhr<_bZpt12xtlJ~g>oOysY`
>81)
>zPS|2l6{Y9y=?*PX(_27omd*mPcbV>j4B-
>PGDeqWfEhZgzKyHUu<Xj#Vc4>TL+JH1W
>zWJXp7)XBsMC<c*Kzkicc8K88O<n!qr>uVPa7Fq0C^XV-%^W1^r&9BJJ7djx6)-
>pOn
>zGF(F3G8yS3UI6R`ClocyTWm(O?y2Rj7AzJG(Kc)A0dCV}v<}%?Ji~mt9KF#&hIGs
>$
>zdUDE%#6;!V4&o)lnq$Eam8Drn^@jU>Bla#o8ZPm5)aEM(Et@U_lnq!M>X95%(
>XBz`
>z06k6~NFgA@NI7a@!*eN(2hj*}428tz3H6ZtZKRX%&pRY)!5DxM0m?%Wy#bDl
>Hqq`Z
>zRdXCn%N#=zzLNZ4={$0y5thc;fMw$&bB{PWkb<{U8Bjo`@sGQii9}*B(}>4G9!k
>p6
>z8A2KPh`m{MH^N1k@Xx{}GL`x;fmAyL#UsaNM&g96YUxV<1z5(vS#uDIHv>_cC
>k`?a
>zN!mEkr}z;A5cMwsBFEuJ(v_ADdp`+rA_=VJRqNOyEYc=97|R{=kfT>(nG<R2<J_
>v8
>zog-F93Ka`qDT{QV)fLkJMt;c8x0%@sm(1&xx)z}<c%IWSd4aH%=Sp06iC#1XiXU-
>Y
>zS8sHnHYp!;N@cH>TI2LWY*%G&PsylVGnk3%RQJNM)ywizcw{7@(l4SED1O9l*
>2oVz
>zQfAa>g>OwE>l@YUl?Xve(Z%l1!@(UH48<a`*)^3P^0t(8nr$w9ujsnU<X$qalOn)
>O
>zwuqPP8%`vINaai?QgY6hbfm^sq+<1n@vSS^>Ld0xQscg-
>S+@`0EbFi=Zy36YKmp}P
>z{m`y~AI&C$Cq0rRx_w)h*xzU2dscO<9ey~q&B4qOV()3^0=|^Bn%@c;mYHQF
>5~a3L
>zh+b_&+(XV0aTCEDvx29C?8%bU$TnOvZvw2P+J_Cp!K{l)qlt1R1~Ypi>Rvx7Cz5k
>I
>z4XzWZ+VNu>`QXA%=1*yI(IJ{B7sMka<@Z@kYL95`sT{L9hVV6`wES-
>8{g{cwx60m4
>zKAQL;LR4HnAcR#$F4}yXYP-
>hDBnwB$xUA6uvurx`@y*?@z!DwEF%J!5tAW^7R9o?*
>z8uB*qL)mjKA4%G~m@HSz*(F!)+flxzw5%H$BEHXJd?5&ij&V2(kj(%k{pLVT?d
>@-i
>z^aHkzb~k%2<}t|Ls*V1xLpkg8dOhh^v~Ns9N#omkFjvlXjqHHPGclhoV@Oy;PC
>7PV
>zvH6kM`h_GvCr#sz2LGy5I*2M9gdb8N2#dNI*?mfM#gr!ECO;%S5c#ZFhEfC<^
>N8-|
>zitL$sL7OEOlhdsfn#Skt`9TC;W^M5h5yk2l=T_HVaR(~3GZHB_nH77NAFrY>Y<Vv
>C
>zEuO^)KvVpxemuzBR_HyHAEIwPEkDfI`<x{&Bz8EM#8GQ(I#B{!(q9%o;hE6|<%
>h_K
>zqUKK~X2igOlpHeuQTb0O<Z#5Gm&EEQ*O?suAP%%qP^&e?3)u^?lj>nILXnDZ
>cl-rE
>z)`TBY!0G&lbk-
>wjRg}K+yb}3RWa94lZ}X=4eU^y117+ECSYAaLVg)F35un@#Eml_U
>zZ842COPv(Q;AE(Py#tQeDmfob@{gMUGNg`m(c=3oFw@~%ME{EARWbyDM
>HhU<^sX&P
>z2ee)gylI5g)Sc_6mKwYO*|EsfdaU)RXQu|S`FE3(RHh9efyC#!?ZHg!$-B2f?l(>S
>zD>>&x^Gl@b8Y6Ei3K>ViGDO7kuXb<47H`&k4TnK6qar+eA(iP)$TKmRVK7@?$i
>>NY
>zF|3@Cp!rvFXcvbPGVPaS1j_ux?e|}3-
>LATVnbo!Bx2vq>RdGTAL0b!S)klr%aA>+O
>zH}9rj;%LfGl%exDm9cC7ZWERVeAcyyExy}ley*FxS_fqe79}GbE4lB~4rphi5}N-d
>z+1)aKcTIQJlUV{WA5QMSPV(F3UgO99Fn~!9zJYFNy+|(V8oOhPDc&=q$N|0w*
>+f0D
>zaWNrmqE=VLe9`PuaQHfsMfS}Dbf^ft?U|T}^w^5oVHp&~LgI7XQbS-
>7F_>wK5h*9N
>zJz3--
>H#5vf<UP5PCFWC$03~ch5&aG+RWXZ>fIjxA+Km<|DL<)VnHl1_1CH4ZA4ww=
>z8m!x`8Op>)Z%8^y#4slf>kZU`39`IPdI3)xFexb{dyJzb|K^%j0FK%$9Be7R;+9P)
>zmNmBjmATu?7^{&3J34)?*5i;=AUX9zjHMj4aHpj`)_ayz+e9F-
><A~Nlx0Y9l&vncA
>z1wz^Pd-P;-5W&Hhsj9Zh(KJ<#awP{@uclUbk#*!vAgg+x;Kckkx=^0hIGu-
>s%>X5x
>z)ZV@&ayUpQALVe6c4oO>GTl%{j>3uBm2G7EGi;Cj?r-
>#s{bWQ4%BD682WQrNI$PAT
>zEryv`oV+IAv5}S0>}MI?rJ*gkDF)GVQsw5+T5XH@p5^6g6Q>*a`t(d%J1j$$1Plw
>M
>z!w4k`qMx@$Qts?c=Fio4C8&=sXO^h)l@U_1fKU!V<X42Z#((D*GRs}%-
>)BiWMvh!T
>zwFJzkiz#hn**-R1c35JL<R)qb{RE(#Nr>Sq>@<i~JjjHn=CR0V*qOdtzu38nX*DIT
>z;`=O+y`WuM{<-edvgtY53295b<fm~-
>c9)FPvaJqfE^AyK1&+BG^0N?(AOi1gTOz+-
>zaeFU!-
>ao92M4r811}Il@1NF9;rt&j^#286mh?s#Sk;_x!@EoT6&&&Q6e#r(V(nsLx
>zxGma;DR*ilEiPl+2P-jcI(I_M0OgD)2e-yo#x~Z(7Rj*!Rj!$s$>n=n$nTTR<B9_*
>z-
>gJ!F8tX$9lr6;W!@s%K?sMH*sloS!V^CrXbmb77s+LQ!O%F5KVk<YYJp<G(l_1IK
>zQWfs5YPV=+O;OXPlj(kZt;O;x8RBqSK@4VUFp#%pE(kH_$`zvSm0Y{O<bediEn<
>{p
>zOiV6Rk_aC6+Wf*DSs#J5%O2#Y9cO#6i0pq@B<J5s!eX0`RDL^}*a*4JIotb1dhd
>KM
>z1-YRCU0^JiVmzZk2l|{yJBXCzd$}jp2c6fP+QXGrS-X5EQhKH|S4x_5_R&(gaTFaY
>z>I@~S1tllxnybwn=-
>?$}a+2%X{0n!fjK{e$d^v>F?O24`+m?7s>$<*+(MdTtWuB1q
>z%j4`I)-
>2~7*Ru##R+(S6#PvwUWdHEQW|f)YU>YET(tIru0)bD4#84oESAQW>AIa88
>zYDp0_=c&xnkh3{Le3#L|l7sj4z5(j`*0p+~0!B#56(5D9<`yT6+A`jaP}aPcZbnD$
>zj6}Cz7HQTTxZJ8rd~YI=A2=ubDrHxKS5KW2C&{98Hd2y*pCvJuS8)$Y23QfwYD?!)
>z1_i-uuCSHQ*eAy1{wi|ou&$6FI@2p<a=-
>X=h41bsG7f>16yImr^>f|CJ!*lU%2z1J
>zOt&;2WS&Yd73c017<3`vG>J(136xhYkUl~Yt80sIqpQuJkY{{8-5ktpWz%K)I*d)L
>z)~ZjVFtsALcBYA02tq04c{J$CpXYl`RTv!QBpaNM&Ie+BSvnL!HAie7f=aFVbWUya
>z1Jcy$ZfcRLf~YIGU*(!<OPPBl(?nzv>UtH&i)#Bj5;EI_@t)5+XLs|(ayh>jskSlz
>ziu{1@v#^MVNp1PLZebb$3jf$-BmV09(=>1?-
>N1r2K`mAl>!e{&D|%c`rq$%`M#QOW
>z#CPw9z3Vb%YQcIJ>Q_xk`Gvclu|8d_N4AoK+uL+$A*gqy(yQqFcp~G4dbdsK{?
>QSk
>zoX&l!?S<*=QXyQ?p0RU&E|?}qPAEi6rWvwxu~ZL>5F^moqvT8!+w-
>O)H4<C@BVE=x
>zch{j>xmE0X9)(|f*-
>@D_V!Yo&z8_4^KJ@{cX&UqCOTMHdHL1;}c+JmsivVR^E7W`?
>zUGuFLIIw8}*_p)0fS^X1rM=FhC!Jmh<?u8LORORgQA4$#7k2GAXIdsFMX?ND
>GSQXu
>zbWoxoX1R_TxW5)cqX&)b$#nXHdK(?Fs(;PnJ+98apgGOdm7|w}<WSTjyyp}7!2
>`Kn
>zjro0+DW6vAT2s87+SXvE%}03kYHYfDgxtD&O=grpwgs)%9BW6oOlne+G^#vaG
>C#5>
>z)oWkZi=C;1g0FRq5R~}l8f*wAn=U=5R1UAO#}^`;WMC=%CoXu(A*XX6Y8WY^J
>+3yn
>zQ~P=qM<B|*Bnb}&s)x8`d@zR_2dJbk)i6*p7k1yW>HKruH5*<>^JzAxC++o`?e
>D8*
>z1*p1G-;T1>jY{IBLNpNGFpdA3=<a({&GP`Mb)P*|L_r6NQL@$Ny2ZRIN(h+-
>x7w0v
>z*`%W~HNGJ6S(w3;_0c?_sy1CJ3W)rw7i`v6y?2b0RIaf{645ReDkb|1VF`B#cQup
>q
>zX;_GnC+Wz^2rMGCBWtF$UmA6w<hrOeQ&&TTPY!7rLsim&oW&@G3a8Nc7
>Q^%~7b+YL
>z*z-
>@G`+C&Z5wVrzW3O1MML3vk&=UwHrb~FcWRee}N22+uw8gA1soZd48E7>!ld
>>Q+
>zsP9>?qB~4s9Ohh!BhrWs<jQ(v925%{BKEGwZBU3$@yh4~f+4$9l(mK5^i(?uRG
>aGM
>zD$Cfl!4DC8UeE=(v?e)-Uy~Fq^{rwWS*Ab^aV}SYA$8V7T4^0B#0o{p3O-
>k~#quhn
>z!>{RZf>vopGwJ@osY*$uo6D<EVKJi6<9W6eY$qcyHC$XXmPa55I5YQuS=DW@
>Wx1<7
>zd8X!b-
>OL=N#(a9gqrqj%%oKUHS)o!UYZ}kUu3Z0$e{}FFR3&}&oCHj@MmNTkCCYpK
>z+WR9h>QVTX16AD662@!-5`%|>4Tou6%y?3Y18VKy0qTz^Bo%t%-
>l+PhDTz#RwB>RI
>zs<3n=2j29qLPf_Rz$BQ)!@tte4iw#D#}%^7j0gu?8(y!Mw_@a+of$!6?rWrS?i)sz
>z#06Kzg)C60Xy8wJ!qBXV!b)U3WrIg3K)1iNGSmzDogW3t_&&=ry6V2TwHts42g
>?N+
>zPNC$}t3ia-J-
>aO@0HV5qGxk+2mC?Ii(&(+4O{yO{q)K6toF$b2e4MW=c4eX%G`C<=
>zor)i7mvk6kL>h+TC(@e-xGOf|x56)2Xm)dP+J`*}PtGpy=5izl1pq&4u66Ds*Pe3S
>z;9AGps}`yVGTly8&Pufj@>G!9o@65_qtITme9nZE%2bZ^T$i)DKMx068#p*}FK3
>hc
>zyZh-
>}1}X3%90mI>km~>ZV`J%1u#`?TNvu_(C0W>+WU7bJrxMg|*Xfx^B*yk`{vNOl
>zLGd2xQ8B~8lejh+rW~x%J|eK;-
>~oJ@C=Jq0tcM<*Hmw)X3X4wOXuHYeeK!v9x8#Ct
>zq{NB}DKB1KiE%nhttkt2WKIXb=HcMXnl9PEjCH~DXLU4yrR}QEr1C&~iEH_*5+>
>;K
>z|E`Jxh#l@rC_Ddlb(9YFzi$%>$Y?+{zok90!lpkFssc#OZMyBtHgjY#sw#jJ{bdFo
>zEl_dN!p1eg>`QgApm9UFcLt<DQqO_nwbMDBFE5EuOycH&O+b5**g2nYif@_
>WU=oCY
>ztPVM?SE5n-
>%je^bwGL!$EMTHmlQyX<V6TdF(x|1}83J_40k^RQ{Vk_4feJI)AtGt@
>zS?_M)x_`d7C2==i&N2{udDXTI5$woRV0X>G`k<!OX`F>4>#o#-
>FuEgVqE{0iWQVnY
>zhqZ6<W?No0B86NnNY%RKQ|Q%WJTWs8dG^9q3@MgOx?mz!&8c(oP?0$qY
>Gdfag<R9a
>z$Cg?^ng-
>4i_J(V1p1|Hx@!aq}JkEMuHSl0>nV;*PkXQ#UcN0;(T2%$Za_a6tMMfBa
>z4yl1(${xf7Q-)}Dq0%i_{-
>hqPiP@hD&ekWXG5IRKn6@=c{eqRfAo{2oFEp8=;*Bcc
>zwC3WGs!#9ozM%0<RJfEaVpoI91MLY3h{)L&q(EK7+rYc+E!94#CLgi4&Ch=t3{iG
>U
>zYpXR+bykxDWc4RQAzr9Op*-xSQY0Z*z{EX5+UhKoiyE-~$H-!lLq|vF6&)4=-
>exwc
>z;K<@!w%hmurO+Nqe)v$*q?qzS$XZ*_t}?_0!{?C+XRDj3N|=Dw%Z$XWAl4Snl
>+HlT
>zi!n}S?L0sklHc^Dr7{8l1r5U+3x5kfOKIY)XE*6iC+e$`fMjcz)U40lRO23O`*yax
>z9=LeY6PvX-GD|(4b}x**AY4)Sli!_6;Yh4}Nw$I$N=Sdc&B`X7I>FvDzSAo<&=JjV
>zb19cwyLPu4m$!i~%P1`l)#;v^^)But{TyD!{ASqI0RST!DV7N7R`Ny863=k0c4R5o
>z;vMxEyUTvVbn^=Z)4B=T8noNrHtlt;v%9k1@akU7cjWWC(ZJw_nVTn;>nibBwV
>Gnp
>z-
>%e&0glC<*9;1>1+tUV1c2v|1pt9u>+risd+O+9QYaH3>4==9oCbRisv6#>9Z?Dcz
>zd(v*W>a55cANeQR+_!Wel}pG2{9R)y4Bw@2BSBb!j`ARY9V;=?VsGqyp}QPZIa
>h0x
>zTs>*0H#i**&xXUnNiWlS$`vx#Vu`r4YG&K9bVrR)dC<#nv%$$SyG;wqnM-
>2w>zanQ
>z0NAF8`MK_?&5#!GOoht^(w1l1!rAq8tLZkL&6=GX6J<-
>Se_J#JLLAnb8E&y!!P&Bq
>znZ2+pLpnyX&|2<>qDF3oke~V%7;`Et<JZ~~a=kKgW9q9YpV;i6du^5_5BzI=u6w
>;3
>zL%J3_a^bDZ1^%07p-
>F>vq?PBy%Kb>4RTrDD5^(jWoeMR`g_?X*kgXnI`zKa#e?7B|
>z`UaRiJuL)nkS?c={Lu{)H&meogim9o*5>u=;%eJ1);i_{=^+OE8ybj@_2dC|g~qgY
>z18UkAJ1Mxn$+D~QEuFHuRWL{{P=hfB3-
>M%fMWM&ycDpfyJw2M!k7O7WIMglkbKS6f
>zM31~1YD}%cB~VMGQ>J?EeygcfHE#kvhj~0YUD0u5dYZCg4J}F16Dz_F0b>zMYJ
>#!X
>zGc!no^YyKpkYw_EfWBX<Z(R@6%)Ll4-qaA4^9WNz3{9OL=TPA(W{tI|;i_*-
>%Ry2j
>z=#~%FK+9vWDcvhVw*?%sR$>u%rq_e4TRT@ClumkF)8!ygNUmb=ZGmi~miY
>%XAtbzu
>zKOzJt8g}4IH9PGQX}e{{&{!@95Q-`5xsa8hL&|c0rHu{K`Rrn5-Y`+FHO2C}HlLuX
>z6%4sOD>^@9f<#qa-
>H8?Z!A2B|7Ne<?Te}U#Oh)tc`U9G&UWXjNueL}AEX5dHd&Q0+
>z>wJFMYy!F$Go?@ct8zk`<8=5dGr<8-Sxq)LTK#L4uIZZq>lg%{nf?T|oNp0tSeJ4`
>z6GW1vSHmmj#@i05)$Cg2>Bkz<{^iuz+|#|c>mWZu-
>}cPfFT<fytR@$=hCMyKu`{dT
>z)fp!eL?E=bTJI8_Q_I)XlDf1;{{mL4`R&Dt4r!(Rv)fr6Hy}}WD_?V4+MDIAe0s-_
>zb+MdYpBXI4PDb~&+<?hBX*~4UL27;zF?Cbt#=%@USB+-
>0!?y;Tb9;Gq(hVWeH0$<<
>zqnoKuS_@_P&vUQ?^LvbFTtF<JPjIn8Cv>bd>kZDX?q;^#z;}w7ib?AERxy@Sgs;
>1y
>zv#nH+Dm%Ab4Bwt&HJ`$q!R6&>ba{1iKbhAz1YT%kL+eo8=YChMvhdi4HZ13py
>Blo7
>z<>mG5{d7?)-B7-
>mO6jn^2F_z0TcB>t6Uj+}?5ts$IkYHWt@6CafXAk99jVx&A<acQ
>z)|!)u7@p;>4Yo@dOBVOic0l-A&-
>wCLU^8y)srA9K30dQbh0~$Ape`cW@@)2`jxK8^
>zY#wPvHCrMci{)~$AyCH{a^@pm`xaM5P`XfQ1}C@m3OFL$e3r9?F<W4Gn4+)
>@Xj9*B
>z#vh+9Z}hn9M6E=J0rMVCi=kTiiV37g?@G($X7p)^l}hzH44vCU8SE|Pi%ah7VBOY
>4
>z(Y$TKzJ<J=gNJ^gBA_sfu}}9Z=354HEKK*k*S!&$B(%S5KF_V06KimjU+smdwE?
>Gg
>zgdpm?(O%cKDWC4sWA<tteL1ZS8q{JQAFM=bj{|J2N93s?wEmXoYT6f&Frpd|c
>-T!u
>ziY5O_c}uj8QS9VyM?+Yct5nP{S?!(6X?_!#tzrwL>F*>WhR1#kQn!PdHjbvEG>Eg
>6
>za&cUBIx7Ui7Nd5UG?cPdOsvfXtY_O>k;TDR=r**Z#iOn{fh_3HFQG@7fUP~|*
>Nyv3
>zm|*nHp<L60_?QgY)~+u%#DO&~N57Ny&1rSc0&-
>Q%YU02qI}S3}mKsA$V2IT#(%waT
>zM}Bc>r(PbN=FJskC)cgr_hNEx<?=!Wa<f{;!UIk2=zK+l&cEGIwlV9Sx3Y>kM6-4H
>zw}kS%zn%W5Rj*p!4(paHTDzry@i<V6jSX~=AvXB5dkPaAu0PcM$!Ax?7t0Oo3y
>|4f
>zJKYo-
>wVK#@?yf6Ydzq`?_#U0kPHI`!4dXif)4Hv2U@CNSb=I$u@;y*I@T+O}<m`G<
>z6OYD42dBN-
>u!rgB?((s)+BT)uun@ero7#M<PVe;m@)jcOc{wa8^5uMb2MPQAj+n8j
>zt@e2zq%dIviwz*cUbdkqR<P9%%<2r9q`PKPNbF?3U)$2583E1jPa9NXr+0EXJcp
>@|
>z>+9>Q%hCDS=}GSc;YCTUw9_A)o?VQt$~Fv7s~NVkjQH)^(R(>jA>P{d(sr`!9R@
>k<
>zG|f7lEUQ~N!3)38t2A?MXp!p&{<7(vEo<E3og190wYuK0Ev{;H*3NZ(xG!d>#tub
>5
>zsDrsyku<3hdq<Y!cf(rC7T^B=<E&c~aLKP4)cUTZN$aLLU|{!QSm<3_-txV)Uqd1J
>zz2lbfHWf>4)d(UoIn#47o1p#OJ@1^^`QebEeFW)1^3_TR?9hGkK^yG-
>J4aSy$f36$
>ziygp_`taxKx_0sD{*8U{5Ympd4AOZ#Ir#$j;oD(5*REpVNDGJX@F=|ih%jC*hrNy
>z
>z<j)bM!!`WO*dMp7KEES-IlllhJrN2u(F;eFV=vrJlA+p?u4D(~=jGGO|KElqo%34R
>zfS7B;zVip_E$Kj~&qt1|^X25yNTfbc<u46PI=GsZ(JexR@^o?NQMuKA2njSMlN7
>7P
>z^ycE^1B+ByE!}Vr6Wtrq!(r*c4y&g()M-Ah37M6>0)F%5Vs>{kIv);TC;D!gA8rEs
>zFmI-P*!ySRoKvH-d5_iBY&apruQ@I9)nYN5&8E}I-AJw(Iu>R}hnse~C&P;?48zyC
>zRGuEIYmw=EOw`hW@gdS0zQAo<Z1jPLR62tTSaEQ5eS0^Vl3AVFHZMj`JLd*#0
>Bdov
>z9*EC09<#F?1NQ07bcxF*ie{lGTV71mx}0NRMPa6=w`QcjL`nXx)KV1+?PZ^DoBz
>JN
>zc|u)Pk*+(6d)Q0r8`o+Xa0Te4pXiSk7|n~fis>_~gLE_;)GsrQ=v8MQtbp{kQO(8T
>zw%v{h$LNLdxv`oYjEW2K<RBX-
>AEOl;U}opB4I9rkE?nPG*}jiE=aUVNU)2P@clN#&
>zKi&K0*ITPru@lHFYu*as39#;5wB!i;?9~$>cBm@UX8;)s$VIWZc@g8R>}=8y#Hk
>SG
>zn`a-2TE~aeYv)H6>f@2eN3E`gba1;_YduA9tq#F`?ziK|>REi;`gV0Lrj237_3GI*
>zYd!LfPr5CFLoYC=BhC7a1CmyoV>c4!nI2}NO6A%o`Q6#ejAmz@{`pPKUP^~p8u
>UyI
>zX;fH{=>C#3k~7#|`{H`C5GxMaeAMxosJ*$`^sFXoRV?l<26bydHp6|Y62Oy_!TIP
>4
>zwqJ2O(J!Xg#`iLw3Y!DelNp=!uI6`Far>eJRB~hxu)$Kd-#<ASz|sHE)8(?^UDz%F
>zXLVrB!PUiwm#lwehCeO%9!x@A!K#T1ST+HZo_~i^o=;29{cD3o2Os#diT!Et3g
>MLk
>TuM~Ktz$*n_Dey{xHWc`O(cS1K
>
>literal 0
>HcmV?d00001
>
>diff --git a/Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec
>b/Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec
>new file mode 100644
>index 0000000000..ea070a10cd
>--- /dev/null
>+++ b/Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec
>@@ -0,0 +1,152 @@
>+## @file
>+# EFI/Framework Simics platform
>+#
>+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
>+#
>+# SPDX-License-Identifier: BSD-2-Clause-Patent
>+#
>+##
>+
>+[Defines]
>+ DEC_SPECIFICATION = 0x00010005
>+ PACKAGE_NAME = SimicsOpenBoardPkg
>+ PACKAGE_GUID = E6A03E0D-5944-4dc6-9292-090D609EDD3A
>+ PACKAGE_VERSION = 0.1
>+
>+[Includes]
>+ Include
>+
>+[Guids]
>+ gBoardModuleTokenSpaceGuid = {0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a,
>0xea, 0x71, 0x5f, 0xd3, 0x59, 0xa5}}
>+ gSimicsBoardConfigGuid = {0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a, 0xea,
>0x71, 0x5f, 0xd3, 0x59, 0xa5}}
>+
>+[PcdsFixedAtBuild]
>+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase|0x0|UINT32|0
>+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize|0x0|UINT32|1
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase|0x0|UINT32|0x15
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize|0x0|UINT32|0x16
>+
>+ #TODO: Remove these two when we integrate new PlatformPei
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsMemFvBase|0x00800000|UINT32|2
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsMemFvSize|0x00500000|UINT32|3
>+
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase|0x0|
>UINT32|0x8
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize|0x0|
>UINT32|0x9
>+ gBoardModuleTokenSpaceGuid.PcdSimicsFirmwareFdSize|0x0|UINT32|0xa
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsFirmwareBlockSize|0|UINT32|0xb
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase|0x0|U
>INT32|0xc
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase|0x0|
>UINT32|0xd
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase|0x
>0|UINT32|0xe
>+ gBoardModuleTokenSpaceGuid.PcdSimicsFdBaseAddress|0x0|UINT32|0xf
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesBase|0x0|UINT32|0
>x11
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesSize|0x0|UINT32|0x
>12
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|0x0|UINT32|
>0x13
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamSize|0x0|UINT32|
>0x14
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageBase|0x0|UINT32|
>0x18
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageSize|0x0|UINT32|0
>x19
>+
>gBoardModuleTokenSpaceGuid.PcdGuidedExtractHandlerTableSize|0x0|UIN
>T32|0x1a
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd|0x0|UI
>NT32|0x1f
>+
>+[PcdsDynamic, PcdsDynamicEx]
>+
>+ # TODO: investigate whether next two Pcds are needed
>+ gBoardModuleTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|0x28
>+
>gBoardModuleTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLE
>AN|0x10
>+
>gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0|UINT16|
>0x1b
>+
>+ ## The IO port aperture shared by all PCI root bridges.
>+ #
>+ gBoardModuleTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x22
>+ gBoardModuleTokenSpaceGuid.PcdPciIoSize|0x0|UINT64|0x23
>+
>+ ## The 32-bit MMIO aperture shared by all PCI root bridges.
>+ #
>+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Base|0x0|UINT64|0x24
>+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Size|0x0|UINT64|0x25
>+
>+ ## The 64-bit MMIO aperture shared by all PCI root bridges.
>+ #
>+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Base|0x0|UINT64|0x26
>+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Size|0x0|UINT64|0x27
>+
>+[PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx, PcdsPatchableInModule]
>+ ## Pcd8259LegacyModeMask defines the default mask value for platform.
>This value is determined<BR><BR>
>+ # 1) If platform only support pure UEFI, value should be set to 0xFFFF or
>0xFFFE;
>+ # Because only clock interrupt is allowed in legacy mode in pure UEFI
>platform.<BR>
>+ # 2) If platform install CSM and use thunk module:<BR>
>+ # a) If thunk call provided by CSM binary requires some legacy interrupt
>support, the corresponding bit
>+ # should be opened as 0.<BR>
>+ # For example, if keyboard interfaces provided CSM binary use legacy
>keyboard interrupt in 8259 bit 1, then
>+ # the value should be set to 0xFFFC.<BR>
>+ # b) If all thunk call provied by CSM binary do not require legacy interrupt
>support, value should be set
>+ # to 0xFFFF or 0xFFFE.<BR>
>+ #
>+ # The default value of legacy mode mask could be changed by
>EFI_LEGACY_8259_PROTOCOL->SetMask(). But it is rarely
>+ # need change it except some special cases such as when initializing the
>CSM binary, it should be set to 0xFFFF to
>+ # mask all legacy interrupt. Please restore the original legacy mask value if
>changing is made for these special case.<BR>
>+ # @Prompt 8259 Legacy Mode mask.
>+
>gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeMask|0xFFFF|UINT16
>|0x00000001
>+
>+ ## Pcd8259LegacyModeEdgeLevel defines the default edge level for legacy
>mode's interrrupt controller.
>+ # For the corresponding bits, 0 = Edge triggered and 1 = Level triggered.
>+ # @Prompt 8259 Legacy Mode edge level.
>+
>gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel|0x0000|UI
>NT16|0x00000002
>+
>+ ## Indicates if we need enable IsaAcpiCom1 device.<BR><BR>
>+ # TRUE - Enables IsaAcpiCom1 device.<BR>
>+ # FALSE - Doesn't enable IsaAcpiCom1 device.<BR>
>+ # @Prompt Enable IsaAcpiCom1 device.
>+
>gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiCom1Enable|TRUE|BOOLEAN|0
>x00000003
>+
>+ ## Indicates if we need enable IsaAcpiCom2 device.<BR><BR>
>+ # TRUE - Enables IsaAcpiCom2 device.<BR>
>+ # FALSE - Doesn't enable IsaAcpiCom2 device.<BR>
>+ # @Prompt Enable IsaAcpiCom12 device.
>+
>gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiCom2Enable|TRUE|BOOLEAN|0
>x00000004
>+
>+ ## Indicates if we need enable IsaAcpiPs2Keyboard device.<BR><BR>
>+ # TRUE - Enables IsaAcpiPs2Keyboard device.<BR>
>+ # FALSE - Doesn't enable IsaAcpiPs2Keyboard device.<BR>
>+ # @Prompt Enable IsaAcpiPs2Keyboard device.
>+
>gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiPs2KeyboardEnable|TRUE|BOOL
>EAN|0x00000005
>+
>+ ## Indicates if we need enable IsaAcpiPs2Mouse device.<BR><BR>
>+ # TRUE - Enables IsaAcpiPs2Mouse device.<BR>
>+ # FALSE - Doesn't enable IsaAcpiPs2Mouse device.<BR>
>+ # @Prompt Enable IsaAcpiPs2Mouse device.
>+
>gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiPs2MouseEnable|TRUE|BOOLEA
>N|0x00000006
>+
>+ ## Indicates if we need enable IsaAcpiFloppyA device.<BR><BR>
>+ # TRUE - Enables IsaAcpiFloppyA device.<BR>
>+ # FALSE - Doesn't enable IsaAcpiFloppyA device.<BR>
>+ # @Prompt Enable IsaAcpiFloppyA device.
>+
>gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiFloppyAEnable|TRUE|BOOLEAN
>|0x00000007
>+
>+ ## Indicates if we need enable IsaAcpiFloppyB device.<BR><BR>
>+ # TRUE - Enables IsaAcpiFloppyB device.<BR>
>+ # FALSE - Doesn't enable IsaAcpiFloppyB device.<BR>
>+ # @Prompt Enable IsaAcpiFloppyB device.
>+
>gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiFloppyBEnable|TRUE|BOOLEAN
>|0x00000008
>+
>+[PcdsFixedAtBuild, PcdsPatchableInModule]
>+ ## FFS filename to find the shell application.
>+ # @Prompt FFS Name of Shell Application
>+ gBoardModuleTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E,
>0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4,
>0xD1 }|VOID*|0x40000004
>+
>+ ## ISA Bus features to support DMA, SlaveDMA and ISA Memory. <BR><BR>
>+ # BIT0 indicates if DMA is supported<BR>
>+ # BIT1 indicates if only slave DMA is supported<BR>
>+ # BIT2 indicates if ISA memory is supported<BR>
>+ # Other BITs are reseved and must be zero.
>+ # If more than one features are supported, the different BIT will be
>enabled at the same time.
>+ # @Prompt ISA Bus Features
>+ # @Expression 0x80000002 |
>(gBoardModuleTokenSpaceGuid.PcdIsaBusSupportedFeatures & 0xF8) == 0
>+
>gBoardModuleTokenSpaceGuid.PcdIsaBusSupportedFeatures|0x05|UINT8|0
>x00010040
>+
>+ gBoardModuleTokenSpaceGuid.PcdLogoFile |{ 0x99, 0x8b, 0xB2, 0x7B, 0xBB,
>0x61, 0xD5, 0x11, 0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1,
>0x4D }|VOID*|0x00010037
>+
>+[Protocols]
>+ ##
>+ ## IntelFrameworkModulePkg
>+ ##
>+ gEfiOEMBadgingProtocolGuid = { 0x170E13C0, 0xBF1B, 0x4218,
>{ 0x87, 0x1D, 0x2A, 0xBD, 0xC6, 0xF8, 0x87, 0xBC }}
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/AcpiPlatform.h
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/AcpiPlatform.h
>new file mode 100644
>index 0000000000..e98aac4676
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/AcpiPlatform.h
>@@ -0,0 +1,45 @@
>+/** @file
>+ This is an implementation of the ACPI platform driver.
>+
>+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
>+
>+ SPDX-License-Identifier: BSD-2-Clause-Patent
>+**/
>+
>+#ifndef _ACPI_PLATFORM_H_
>+#define _ACPI_PLATFORM_H_
>+
>+//
>+// Statements that include other header files
>+//
>+
>+#include <Base.h>
>+#include <Uefi.h>
>+#include <IndustryStandard/Pci30.h>
>+#include <IndustryStandard/Acpi.h>
>+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
>+#include
><IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
>+#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
>+#include <Register/Hpet.h>
>+#include <Guid/EventGroup.h>
>+#include <Guid/GlobalVariable.h>
>+#include <Library/UefiLib.h>
>+#include <Library/UefiBootServicesTableLib.h>
>+#include <Library/UefiRuntimeServicesTableLib.h>
>+#include <Library/DebugLib.h>
>+#include <Library/BaseLib.h>
>+#include <Library/BaseMemoryLib.h>
>+#include <Library/IoLib.h>
>+#include <Library/PcdLib.h>
>+#include <Library/BoardAcpiTableLib.h>
>+#include <Library/MemoryAllocationLib.h>
>+#include <Library/AslUpdateLib.h>
>+#include <Library/PciSegmentInfoLib.h>
>+
>+#include <Protocol/AcpiTable.h>
>+#include <Protocol/MpService.h>
>+#include <Protocol/PciIo.h>
>+
>+#include <Register/Cpuid.h>
>+
>+#endif
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/AcpiPlatform.inf
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/AcpiPlatform.inf
>new file mode 100644
>index 0000000000..7dfd0832a3
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
>Tables/AcpiPlatform.inf
>@@ -0,0 +1,105 @@
>+## @file
>+# Component information file for AcpiPlatform module
>+#
>+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
>+#
>+# SPDX-License-Identifier: BSD-2-Clause-Patent
>+#
>+##
>+
>+[Defines]
>+ INF_VERSION = 0x00010005
>+ BASE_NAME = AcpiPlatform
>+ FILE_GUID = FC90EB7A-3E0A-483C-A26C-484D36593FF4
>+ MODULE_TYPE = DXE_DRIVER
>+ VERSION_STRING = 1.0
>+ ENTRY_POINT = InstallAcpiPlatform
>+
>+[Sources.common]
>+ AcpiPlatform.h
>+ AcpiPlatform.c
>+ Fadt/Fadt.c
>+ Facs/Facs.c
>+ Hpet/Hpet.c
>+ Wsmt/Wsmt.c
>+
>+[Packages]
>+ MdePkg/MdePkg.dec
>+ MdeModulePkg/MdeModulePkg.dec
>+ UefiCpuPkg/UefiCpuPkg.dec
>+ MinPlatformPkg/MinPlatformPkg.dec
>+ PcAtChipsetPkg/PcAtChipsetPkg.dec
>+
>+[LibraryClasses]
>+ UefiDriverEntryPoint
>+ BaseLib
>+ DebugLib
>+ IoLib
>+ PcdLib
>+ UefiBootServicesTableLib
>+ UefiRuntimeServicesTableLib
>+ BaseMemoryLib
>+ HobLib
>+ PciSegmentInfoLib
>+ AslUpdateLib
>+
>+[Pcd]
>+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId
>+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
>+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
>+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
>+
>+ gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicEnable
>+ gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicCount
>+ gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicIdBase
>+ gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicAddressBase
>+ gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicInterruptBase
>+ gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuThreadCount
>+ gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuCoreCount
>+ gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuSocketCount
>+
>+ gMinPlatformPkgTokenSpaceGuid.PcdFadtPreferredPmProfile
>+ gMinPlatformPkgTokenSpaceGuid.PcdFadtIaPcBootArch
>+ gMinPlatformPkgTokenSpaceGuid.PcdFadtFlags
>+
>+ gPcAtChipsetPkgTokenSpaceGuid.PcdHpetBaseAddress
>+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
>+ gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength
>+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiEnableSwSmi
>+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiDisableSwSmi
>+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1AEventBlockAddress
>+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1BEventBlockAddress
>+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1AControlBlockAddress
>+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1BControlBlockAddress
>+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm2ControlBlockAddress
>+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPmTimerBlockAddress
>+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiGpe0BlockAddress
>+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiGpe1BlockAddress
>+
>+ gMinPlatformPkgTokenSpaceGuid.PcdLocalApicAddress
>+ gMinPlatformPkgTokenSpaceGuid.PcdIoApicAddress
>+ gMinPlatformPkgTokenSpaceGuid.PcdIoApicId
>+
>+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
>+ gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuSocketCount
>+
>+ gMinPlatformPkgTokenSpaceGuid.PcdWsmtProtectionFlags
>+
>+[Protocols]
>+ gEfiAcpiTableProtocolGuid ## CONSUMES
>+ gEfiMpServiceProtocolGuid ## CONSUMES
>+ gEfiPciIoProtocolGuid ## CONSUMES
>+
>+[Guids]
>+ gEfiGlobalVariableGuid ## CONSUMES
>+ gEfiHobListGuid ## CONSUMES
>+ gEfiEndOfDxeEventGroupGuid ## CONSUMES
>+
>+[Depex]
>+ gEfiAcpiTableProtocolGuid AND
>+ gEfiMpServiceProtocolGuid AND
>+ gEfiPciRootBridgeIoProtocolGuid AND
>+ gEfiVariableArchProtocolGuid AND
>+ gEfiVariableWriteArchProtocolGuid
>+
>+
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>Qemu.h
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>Qemu.h
>new file mode 100644
>index 0000000000..f6ef44a14f
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>Qemu.h
>@@ -0,0 +1,507 @@
>+/** @file
>+ QEMU Video Controller Driver
>+
>+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
>+
>+ SPDX-License-Identifier: BSD-2-Clause-Patent
>+**/
>+
>+//
>+// QEMU Video Controller Driver
>+//
>+
>+#ifndef _QEMU_H_
>+#define _QEMU_H_
>+
>+
>+#include <Uefi.h>
>+#include <Protocol/GraphicsOutput.h>
>+#include <Protocol/PciIo.h>
>+#include <Protocol/DriverSupportedEfiVersion.h>
>+#include <Protocol/DevicePath.h>
>+
>+#include <Library/DebugLib.h>
>+#include <Library/UefiDriverEntryPoint.h>
>+#include <Library/UefiLib.h>
>+#include <Library/PcdLib.h>
>+#include <Library/MemoryAllocationLib.h>
>+#include <Library/UefiBootServicesTableLib.h>
>+#include <Library/BaseMemoryLib.h>
>+#include <Library/DevicePathLib.h>
>+#include <Library/TimerLib.h>
>+#include <Library/FrameBufferBltLib.h>
>+
>+#include <IndustryStandard/Pci.h>
>+#include <IndustryStandard/Acpi.h>
>+
>+#include <Library/S3BootScriptLib.h>
>+
>+//
>+// QEMU Video PCI Configuration Header values
>+//
>+#define CIRRUS_LOGIC_VENDOR_ID 0x1013
>+#define CIRRUS_LOGIC_5430_DEVICE_ID 0x00a8
>+#define CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID 0x00a0
>+#define CIRRUS_LOGIC_5446_DEVICE_ID 0x00b8
>+
>+//
>+// QEMU Vide Graphical Mode Data
>+//
>+typedef struct {
>+ UINT32 InternalModeIndex; // points into card-specific mode table
>+ UINT32 HorizontalResolution;
>+ UINT32 VerticalResolution;
>+ UINT32 ColorDepth;
>+} QEMU_VIDEO_MODE_DATA;
>+
>+#define PIXEL_RED_SHIFT 0
>+#define PIXEL_GREEN_SHIFT 3
>+#define PIXEL_BLUE_SHIFT 6
>+
>+#define PIXEL_RED_MASK (BIT7 | BIT6 | BIT5)
>+#define PIXEL_GREEN_MASK (BIT4 | BIT3 | BIT2)
>+#define PIXEL_BLUE_MASK (BIT1 | BIT0)
>+
>+#define PIXEL_TO_COLOR_BYTE(pixel, mask, shift) ((UINT8) ((pixel & mask)
><< shift))
>+#define PIXEL_TO_RED_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel,
>PIXEL_RED_MASK, PIXEL_RED_SHIFT)
>+#define PIXEL_TO_GREEN_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel,
>PIXEL_GREEN_MASK, PIXEL_GREEN_SHIFT)
>+#define PIXEL_TO_BLUE_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel,
>PIXEL_BLUE_MASK, PIXEL_BLUE_SHIFT)
>+
>+#define RGB_BYTES_TO_PIXEL(Red, Green, Blue) \
>+ (UINT8) ( (((Red) >> PIXEL_RED_SHIFT) & PIXEL_RED_MASK) | \
>+ (((Green) >> PIXEL_GREEN_SHIFT) & PIXEL_GREEN_MASK) | \
>+ (((Blue) >> PIXEL_BLUE_SHIFT) & PIXEL_BLUE_MASK) )
>+
>+#define PIXEL24_RED_MASK 0x00ff0000
>+#define PIXEL24_GREEN_MASK 0x0000ff00
>+#define PIXEL24_BLUE_MASK 0x000000ff
>+
>+#define GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER 0xffff
>+
>+//
>+// QEMU Video Private Data Structure
>+//
>+#define QEMU_VIDEO_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('Q', 'V',
>'I', 'D')
>+
>+typedef enum {
>+ QEMU_VIDEO_CIRRUS_5430 = 1,
>+ QEMU_VIDEO_CIRRUS_5446,
>+ QEMU_VIDEO_BOCHS,
>+ QEMU_VIDEO_BOCHS_MMIO,
>+} QEMU_VIDEO_VARIANT;
>+
>+typedef struct {
>+ UINT8 SubClass;
>+ UINT16 VendorId;
>+ UINT16 DeviceId;
>+ QEMU_VIDEO_VARIANT Variant;
>+ CHAR16 *Name;
>+} QEMU_VIDEO_CARD;
>+
>+typedef struct {
>+ UINT64 Signature;
>+ EFI_HANDLE Handle;
>+ EFI_PCI_IO_PROTOCOL *PciIo;
>+ UINT64 OriginalPciAttributes;
>+ EFI_GRAPHICS_OUTPUT_PROTOCOL GraphicsOutput;
>+ EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;
>+
>+ //
>+ // The next two fields match the client-visible
>+ // EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.MaxMode field.
>+ //
>+ UINTN MaxMode;
>+ QEMU_VIDEO_MODE_DATA *ModeData;
>+
>+ QEMU_VIDEO_VARIANT Variant;
>+ FRAME_BUFFER_CONFIGURE *FrameBufferBltConfigure;
>+ UINTN FrameBufferBltConfigureSize;
>+} QEMU_VIDEO_PRIVATE_DATA;
>+
>+///
>+/// Card-specific Video Mode structures
>+///
>+typedef struct {
>+ UINT32 Width;
>+ UINT32 Height;
>+ UINT32 ColorDepth;
>+ UINT8 *CrtcSettings;
>+ UINT16 *SeqSettings;
>+ UINT8 MiscSetting;
>+} QEMU_VIDEO_CIRRUS_MODES;
>+
>+typedef struct {
>+ UINT32 Width;
>+ UINT32 Height;
>+ UINT32 ColorDepth;
>+} QEMU_VIDEO_BOCHS_MODES;
>+
>+#define QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS(a)
>\
>+ CR(a, QEMU_VIDEO_PRIVATE_DATA, GraphicsOutput,
>QEMU_VIDEO_PRIVATE_DATA_SIGNATURE)
>+
>+
>+//
>+// Global Variables
>+//
>+extern UINT8 AttributeController[];
>+extern UINT8 GraphicsController[];
>+extern UINT8 Crtc_640_480_256_60[];
>+extern UINT16 Seq_640_480_256_60[];
>+extern UINT8 Crtc_800_600_256_60[];
>+extern UINT16 Seq_800_600_256_60[];
>+extern UINT8 Crtc_1024_768_256_60[];
>+extern UINT16 Seq_1024_768_256_60[];
>+extern QEMU_VIDEO_CIRRUS_MODES QemuVideoCirrusModes[];
>+extern QEMU_VIDEO_BOCHS_MODES QemuVideoBochsModes[];
>+extern EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding;
>+extern EFI_COMPONENT_NAME_PROTOCOL
>gQemuVideoComponentName;
>+extern EFI_COMPONENT_NAME2_PROTOCOL
>gQemuVideoComponentName2;
>+extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL
>gQemuVideoDriverSupportedEfiVersion;
>+
>+//
>+// Io Registers defined by VGA
>+//
>+#define CRTC_ADDRESS_REGISTER 0x3d4
>+#define CRTC_DATA_REGISTER 0x3d5
>+#define SEQ_ADDRESS_REGISTER 0x3c4
>+#define SEQ_DATA_REGISTER 0x3c5
>+#define GRAPH_ADDRESS_REGISTER 0x3ce
>+#define GRAPH_DATA_REGISTER 0x3cf
>+#define ATT_ADDRESS_REGISTER 0x3c0
>+#define MISC_OUTPUT_REGISTER 0x3c2
>+#define INPUT_STATUS_1_REGISTER 0x3da
>+#define DAC_PIXEL_MASK_REGISTER 0x3c6
>+#define PALETTE_INDEX_REGISTER 0x3c8
>+#define PALETTE_DATA_REGISTER 0x3c9
>+
>+#define VBE_DISPI_IOPORT_INDEX 0x01CE
>+#define VBE_DISPI_IOPORT_DATA 0x01D0
>+
>+#define VBE_DISPI_INDEX_ID 0x0
>+#define VBE_DISPI_INDEX_XRES 0x1
>+#define VBE_DISPI_INDEX_YRES 0x2
>+#define VBE_DISPI_INDEX_BPP 0x3
>+#define VBE_DISPI_INDEX_ENABLE 0x4
>+#define VBE_DISPI_INDEX_BANK 0x5
>+#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
>+#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
>+#define VBE_DISPI_INDEX_X_OFFSET 0x8
>+#define VBE_DISPI_INDEX_Y_OFFSET 0x9
>+#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa
>+
>+#define VBE_DISPI_ID0 0xB0C0
>+#define VBE_DISPI_ID1 0xB0C1
>+#define VBE_DISPI_ID2 0xB0C2
>+#define VBE_DISPI_ID3 0xB0C3
>+#define VBE_DISPI_ID4 0xB0C4
>+#define VBE_DISPI_ID5 0xB0C5
>+
>+#define VBE_DISPI_DISABLED 0x00
>+#define VBE_DISPI_ENABLED 0x01
>+#define VBE_DISPI_GETCAPS 0x02
>+#define VBE_DISPI_8BIT_DAC 0x20
>+#define VBE_DISPI_LFB_ENABLED 0x40
>+#define VBE_DISPI_NOCLEARMEM 0x80
>+
>+//
>+// Graphics Output Hardware abstraction internal worker functions
>+//
>+EFI_STATUS
>+QemuVideoGraphicsOutputConstructor (
>+ QEMU_VIDEO_PRIVATE_DATA *Private
>+ );
>+
>+EFI_STATUS
>+QemuVideoGraphicsOutputDestructor (
>+ QEMU_VIDEO_PRIVATE_DATA *Private
>+ );
>+
>+
>+//
>+// EFI_DRIVER_BINDING_PROTOCOL Protocol Interface
>+//
>+/**
>+ TODO: Add function description
>+
>+ @param This TODO: add argument description
>+ @param Controller TODO: add argument description
>+ @param RemainingDevicePath TODO: add argument description
>+
>+ TODO: add return values
>+
>+**/
>+EFI_STATUS
>+EFIAPI
>+QemuVideoControllerDriverSupported (
>+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
>+ IN EFI_HANDLE Controller,
>+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
>+ );
>+
>+/**
>+ TODO: Add function description
>+
>+ @param This TODO: add argument description
>+ @param Controller TODO: add argument description
>+ @param RemainingDevicePath TODO: add argument description
>+
>+ TODO: add return values
>+
>+**/
>+EFI_STATUS
>+EFIAPI
>+QemuVideoControllerDriverStart (
>+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
>+ IN EFI_HANDLE Controller,
>+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
>+ );
>+
>+/**
>+ TODO: Add function description
>+
>+ @param This TODO: add argument description
>+ @param Controller TODO: add argument description
>+ @param NumberOfChildren TODO: add argument description
>+ @param ChildHandleBuffer TODO: add argument description
>+
>+ TODO: add return values
>+
>+**/
>+EFI_STATUS
>+EFIAPI
>+QemuVideoControllerDriverStop (
>+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
>+ IN EFI_HANDLE Controller,
>+ IN UINTN NumberOfChildren,
>+ IN EFI_HANDLE *ChildHandleBuffer
>+ );
>+
>+//
>+// EFI Component Name Functions
>+//
>+/**
>+ Retrieves a Unicode string that is the user readable name of the driver.
>+
>+ This function retrieves the user readable name of a driver in the form of a
>+ Unicode string. If the driver specified by This has a user readable name in
>+ the language specified by Language, then a pointer to the driver name is
>+ returned in DriverName, and EFI_SUCCESS is returned. If the driver
>specified
>+ by This does not support the language specified by Language,
>+ then EFI_UNSUPPORTED is returned.
>+
>+ @param This[in] A pointer to the
>EFI_COMPONENT_NAME2_PROTOCOL or
>+ EFI_COMPONENT_NAME_PROTOCOL instance.
>+
>+ @param Language[in] A pointer to a Null-terminated ASCII string
>+ array indicating the language. This is the
>+ language of the driver name that the caller is
>+ requesting, and it must match one of the
>+ languages specified in SupportedLanguages. The
>+ number of languages supported by a driver is up
>+ to the driver writer. Language is specified
>+ in RFC 4646 or ISO 639-2 language code format.
>+
>+ @param DriverName[out] A pointer to the Unicode string to return.
>+ This Unicode string is the name of the
>+ driver specified by This in the language
>+ specified by Language.
>+
>+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
>+ This and the language specified by Language was
>+ returned in DriverName.
>+
>+ @retval EFI_INVALID_PARAMETER Language is NULL.
>+
>+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
>+
>+ @retval EFI_UNSUPPORTED The driver specified by This does not
>support
>+ the language specified by Language.
>+
>+**/
>+EFI_STATUS
>+EFIAPI
>+QemuVideoComponentNameGetDriverName (
>+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
>+ IN CHAR8 *Language,
>+ OUT CHAR16 **DriverName
>+ );
>+
>+
>+/**
>+ Retrieves a Unicode string that is the user readable name of the controller
>+ that is being managed by a driver.
>+
>+ This function retrieves the user readable name of the controller specified
>by
>+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
>+ driver specified by This has a user readable name in the language specified
>by
>+ Language, then a pointer to the controller name is returned in
>ControllerName,
>+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
>+ managing the controller specified by ControllerHandle and ChildHandle,
>+ then EFI_UNSUPPORTED is returned. If the driver specified by This does
>not
>+ support the language specified by Language, then EFI_UNSUPPORTED is
>returned.
>+
>+ @param This[in] A pointer to the
>EFI_COMPONENT_NAME2_PROTOCOL or
>+ EFI_COMPONENT_NAME_PROTOCOL instance.
>+
>+ @param ControllerHandle[in] The handle of a controller that the driver
>+ specified by This is managing. This handle
>+ specifies the controller whose name is to be
>+ returned.
>+
>+ @param ChildHandle[in] The handle of the child controller to retrieve
>+ the name of. This is an optional parameter that
>+ may be NULL. It will be NULL for device
>+ drivers. It will also be NULL for a bus drivers
>+ that wish to retrieve the name of the bus
>+ controller. It will not be NULL for a bus
>+ driver that wishes to retrieve the name of a
>+ child controller.
>+
>+ @param Language[in] A pointer to a Null-terminated ASCII string
>+ array indicating the language. This is the
>+ language of the driver name that the caller is
>+ requesting, and it must match one of the
>+ languages specified in SupportedLanguages. The
>+ number of languages supported by a driver is up
>+ to the driver writer. Language is specified in
>+ RFC 4646 or ISO 639-2 language code format.
>+
>+ @param ControllerName[out] A pointer to the Unicode string to return.
>+ This Unicode string is the name of the
>+ controller specified by ControllerHandle and
>+ ChildHandle in the language specified by
>+ Language from the point of view of the driver
>+ specified by This.
>+
>+ @retval EFI_SUCCESS The Unicode string for the user readable name in
>+ the language specified by Language for the
>+ driver specified by This was returned in
>+ DriverName.
>+
>+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid
>EFI_HANDLE.
>+
>+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a
>valid
>+ EFI_HANDLE.
>+
>+ @retval EFI_INVALID_PARAMETER Language is NULL.
>+
>+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
>+
>+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
>+ managing the controller specified by
>+ ControllerHandle and ChildHandle.
>+
>+ @retval EFI_UNSUPPORTED The driver specified by This does not
>support
>+ the language specified by Language.
>+
>+**/
>+EFI_STATUS
>+EFIAPI
>+QemuVideoComponentNameGetControllerName (
>+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
>+ IN EFI_HANDLE ControllerHandle,
>+ IN EFI_HANDLE ChildHandle OPTIONAL,
>+ IN CHAR8 *Language,
>+ OUT CHAR16 **ControllerName
>+ );
>+
>+
>+//
>+// Local Function Prototypes
>+//
>+VOID
>+InitializeCirrusGraphicsMode (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ QEMU_VIDEO_CIRRUS_MODES *ModeData
>+ );
>+
>+VOID
>+InitializeBochsGraphicsMode (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ QEMU_VIDEO_BOCHS_MODES *ModeData
>+ );
>+
>+VOID
>+SetPaletteColor (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ UINTN Index,
>+ UINT8 Red,
>+ UINT8 Green,
>+ UINT8 Blue
>+ );
>+
>+VOID
>+SetDefaultPalette (
>+ QEMU_VIDEO_PRIVATE_DATA *Private
>+ );
>+
>+VOID
>+DrawLogo (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ UINTN ScreenWidth,
>+ UINTN ScreenHeight
>+ );
>+
>+VOID
>+outb (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ UINTN Address,
>+ UINT8 Data
>+ );
>+
>+VOID
>+outw (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ UINTN Address,
>+ UINT16 Data
>+ );
>+
>+UINT8
>+inb (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ UINTN Address
>+ );
>+
>+UINT16
>+inw (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ UINTN Address
>+ );
>+
>+VOID
>+BochsWrite (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ UINT16 Reg,
>+ UINT16 Data
>+ );
>+
>+UINT16
>+BochsRead (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ UINT16 Reg
>+ );
>+
>+VOID
>+VgaOutb (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ UINTN Reg,
>+ UINT8 Data
>+ );
>+
>+EFI_STATUS
>+QemuVideoCirrusModeSetup (
>+ QEMU_VIDEO_PRIVATE_DATA *Private
>+ );
>+
>+EFI_STATUS
>+QemuVideoBochsModeSetup (
>+ QEMU_VIDEO_PRIVATE_DATA *Private,
>+ BOOLEAN IsQxl
>+ );
>+
>+VOID
>+InstallVbeShim (
>+ IN CONST CHAR16 *CardName,
>+ IN EFI_PHYSICAL_ADDRESS FrameBufferBase
>+ );
>+#endif
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>QemuVideoDxe.inf
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>QemuVideoDxe.inf
>new file mode 100644
>index 0000000000..4143487366
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>QemuVideoDxe.inf
>@@ -0,0 +1,74 @@
>+## @file
>+# This driver is a sample implementation of the Graphics Output Protocol for
>+# the QEMU (Cirrus Logic 5446) video controller.
>+#
>+# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
>+#
>+# SPDX-License-Identifier: BSD-2-Clause-Patent
>+#
>+##
>+
>+[Defines]
>+ INF_VERSION = 0x00010005
>+ BASE_NAME = QemuVideoDxe
>+ FILE_GUID = e3752948-b9a1-4770-90c4-df41c38986be
>+ MODULE_TYPE = UEFI_DRIVER
>+ VERSION_STRING = 1.0
>+
>+ ENTRY_POINT = InitializeQemuVideo
>+
>+#
>+# The following information is for reference only and not required by the
>build tools.
>+#
>+# VALID_ARCHITECTURES = IA32 X64 EBC
>+#
>+# DRIVER_BINDING = gQemuVideoDriverBinding
>+# COMPONENT_NAME = gQemuVideoComponentName
>+#
>+
>+[Sources.common]
>+ ComponentName.c
>+ Driver.c
>+ DriverSupportedEfiVersion.c
>+ Gop.c
>+ Initialize.c
>+ Qemu.h
>+
>+[Sources.Ia32, Sources.X64]
>+ VbeShim.c
>+ VbeShim.h
>+
>+[Packages]
>+ MdePkg/MdePkg.dec
>+ MdeModulePkg/MdeModulePkg.dec
>+ OptionRomPkg/OptionRomPkg.dec
>+ OvmfPkg/OvmfPkg.dec
>+ SimicsOpenBoardPkg/OpenBoardPkg.dec
>+ SimicsIch10Pkg/Ich10Pkg.dec
>+
>+[LibraryClasses]
>+ BaseMemoryLib
>+ FrameBufferBltLib
>+ DebugLib
>+ DevicePathLib
>+ MemoryAllocationLib
>+ PcdLib
>+ PciLib
>+ PrintLib
>+ TimerLib
>+ UefiBootServicesTableLib
>+ UefiDriverEntryPoint
>+ UefiLib
>+ S3BootScriptLib
>+
>+[Protocols]
>+ gEfiDriverSupportedEfiVersionProtocolGuid # PROTOCOL
>ALWAYS_PRODUCED
>+ gEfiGraphicsOutputProtocolGuid # PROTOCOL BY_START
>+ gEfiDevicePathProtocolGuid # PROTOCOL BY_START
>+ gEfiPciIoProtocolGuid # PROTOCOL TO_START
>+ gEfiDxeSmmReadyToLockProtocolGuid
>+
>+[Pcd]
>+ gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion
>+ gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
>+
>gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>VbeShim.asm
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>VbeShim.asm
>new file mode 100644
>index 0000000000..a82077e2d9
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>VbeShim.asm
>@@ -0,0 +1,279 @@
>+; @file
>+; A minimal Int10h stub that allows the Windows 2008 R2 SP1 UEFI guest's
>buggy,
>+; default VGA driver to switch to 1024x768x32, on the stdvga and QXL video
>+; cards of QEMU.
>+;
>+; Copyright (C) 2014, Red Hat, Inc.
>+; Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
>+;
>+; SPDX-License-Identifier: BSD-2-Clause-Patent
>+;
>+
>+; enable this macro for debug messages
>+;%define DEBUG
>+
>+%macro DebugLog 1
>+%ifdef DEBUG
>+ push si
>+ mov si, %1
>+ call PrintStringSi
>+ pop si
>+%endif
>+%endmacro
>+
>+
>+BITS 16
>+ORG 0
>+
>+VbeInfo:
>+TIMES 256 nop
>+
>+VbeModeInfo:
>+TIMES 256 nop
>+
>+
>+Handler:
>+ cmp ax, 0x4f00
>+ je GetInfo
>+ cmp ax, 0x4f01
>+ je GetModeInfo
>+ cmp ax, 0x4f02
>+ je SetMode
>+ cmp ax, 0x4f03
>+ je GetMode
>+ cmp ax, 0x4f10
>+ je GetPmCapabilities
>+ cmp ax, 0x4f15
>+ je ReadEdid
>+ cmp ah, 0x00
>+ je SetModeLegacy
>+ DebugLog StrUnkownFunction
>+Hang:
>+ jmp Hang
>+
>+
>+GetInfo:
>+ push es
>+ push di
>+ push ds
>+ push si
>+ push cx
>+
>+ DebugLog StrEnterGetInfo
>+
>+ ; target (es:di) set on input
>+ push cs
>+ pop ds
>+ mov si, VbeInfo
>+ ; source (ds:si) set now
>+
>+ mov cx, 256
>+ cld
>+ rep movsb
>+
>+ pop cx
>+ pop si
>+ pop ds
>+ pop di
>+ pop es
>+ jmp Success
>+
>+
>+GetModeInfo:
>+ push es
>+ push di
>+ push ds
>+ push si
>+ push cx
>+
>+ DebugLog StrEnterGetModeInfo
>+
>+ and cx, ~0x4000 ; clear potentially set LFB bit in mode number
>+ cmp cx, 0x00f1
>+ je KnownMode1
>+ DebugLog StrUnkownMode
>+ jmp Hang
>+KnownMode1:
>+ ; target (es:di) set on input
>+ push cs
>+ pop ds
>+ mov si, VbeModeInfo
>+ ; source (ds:si) set now
>+
>+ mov cx, 256
>+ cld
>+ rep movsb
>+
>+ pop cx
>+ pop si
>+ pop ds
>+ pop di
>+ pop es
>+ jmp Success
>+
>+
>+%define ATT_ADDRESS_REGISTER 0x03c0
>+%define VBE_DISPI_IOPORT_INDEX 0x01ce
>+%define VBE_DISPI_IOPORT_DATA 0x01d0
>+
>+%define VBE_DISPI_INDEX_XRES 0x1
>+%define VBE_DISPI_INDEX_YRES 0x2
>+%define VBE_DISPI_INDEX_BPP 0x3
>+%define VBE_DISPI_INDEX_ENABLE 0x4
>+%define VBE_DISPI_INDEX_BANK 0x5
>+%define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
>+%define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
>+%define VBE_DISPI_INDEX_X_OFFSET 0x8
>+%define VBE_DISPI_INDEX_Y_OFFSET 0x9
>+
>+%define VBE_DISPI_ENABLED 0x01
>+%define VBE_DISPI_LFB_ENABLED 0x40
>+
>+%macro BochsWrite 2
>+ push dx
>+ push ax
>+
>+ mov dx, VBE_DISPI_IOPORT_INDEX
>+ mov ax, %1
>+ out dx, ax
>+
>+ mov dx, VBE_DISPI_IOPORT_DATA
>+ mov ax, %2
>+ out dx, ax
>+
>+ pop ax
>+ pop dx
>+%endmacro
>+
>+SetMode:
>+ push dx
>+ push ax
>+
>+ DebugLog StrEnterSetMode
>+
>+ cmp bx, 0x40f1
>+ je KnownMode2
>+ DebugLog StrUnkownMode
>+ jmp Hang
>+KnownMode2:
>+
>+ ; unblank
>+ mov dx, ATT_ADDRESS_REGISTER
>+ mov al, 0x20
>+ out dx, al
>+
>+ BochsWrite VBE_DISPI_INDEX_ENABLE, 0
>+ BochsWrite VBE_DISPI_INDEX_BANK, 0
>+ BochsWrite VBE_DISPI_INDEX_X_OFFSET, 0
>+ BochsWrite VBE_DISPI_INDEX_Y_OFFSET, 0
>+ BochsWrite VBE_DISPI_INDEX_BPP, 32
>+ BochsWrite VBE_DISPI_INDEX_XRES, 1024
>+ BochsWrite VBE_DISPI_INDEX_VIRT_WIDTH, 1024
>+ BochsWrite VBE_DISPI_INDEX_YRES, 768
>+ BochsWrite VBE_DISPI_INDEX_VIRT_HEIGHT, 768
>+ BochsWrite VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED |
>VBE_DISPI_LFB_ENABLED
>+
>+ pop ax
>+ pop dx
>+ jmp Success
>+
>+
>+GetMode:
>+ DebugLog StrEnterGetMode
>+ mov bx, 0x40f1
>+ jmp Success
>+
>+
>+GetPmCapabilities:
>+ DebugLog StrGetPmCapabilities
>+ jmp Unsupported
>+
>+
>+ReadEdid:
>+ DebugLog StrReadEdid
>+ jmp Unsupported
>+
>+
>+SetModeLegacy:
>+ DebugLog StrEnterSetModeLegacy
>+
>+ cmp al, 0x03
>+ je KnownMode3
>+ cmp al, 0x12
>+ je KnownMode4
>+ DebugLog StrUnkownMode
>+ jmp Hang
>+KnownMode3:
>+ mov al, 0x30
>+ jmp SetModeLegacyDone
>+KnownMode4:
>+ mov al, 0x20
>+SetModeLegacyDone:
>+ DebugLog StrExitSuccess
>+ iret
>+
>+
>+Success:
>+ DebugLog StrExitSuccess
>+ mov ax, 0x004f
>+ iret
>+
>+
>+Unsupported:
>+ DebugLog StrExitUnsupported
>+ mov ax, 0x014f
>+ iret
>+
>+
>+%ifdef DEBUG
>+PrintStringSi:
>+ pusha
>+ push ds ; save original
>+ push cs
>+ pop ds
>+ mov dx, 0x0402
>+PrintStringSiLoop:
>+ lodsb
>+ cmp al, 0
>+ je PrintStringSiDone
>+ out dx, al
>+ jmp PrintStringSiLoop
>+PrintStringSiDone:
>+ pop ds ; restore original
>+ popa
>+ ret
>+
>+
>+StrExitSuccess:
>+ db 'Exit', 0x0a, 0
>+
>+StrExitUnsupported:
>+ db 'Unsupported', 0x0a, 0
>+
>+StrUnkownFunction:
>+ db 'Unknown Function', 0x0a, 0
>+
>+StrEnterGetInfo:
>+ db 'GetInfo', 0x0a, 0
>+
>+StrEnterGetModeInfo:
>+ db 'GetModeInfo', 0x0a, 0
>+
>+StrEnterGetMode:
>+ db 'GetMode', 0x0a, 0
>+
>+StrEnterSetMode:
>+ db 'SetMode', 0x0a, 0
>+
>+StrEnterSetModeLegacy:
>+ db 'SetModeLegacy', 0x0a, 0
>+
>+StrUnkownMode:
>+ db 'Unkown Mode', 0x0a, 0
>+
>+StrGetPmCapabilities:
>+ db 'GetPmCapabilities', 0x0a, 0
>+
>+StrReadEdid:
>+ db 'ReadEdid', 0x0a, 0
>+%endif
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>VbeShim.h
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>VbeShim.h
>new file mode 100644
>index 0000000000..cc9b6e14cd
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>VbeShim.h
>@@ -0,0 +1,701 @@
>+//
>+// THIS FILE WAS GENERATED BY "VbeShim.sh". DO NOT EDIT.
>+//
>+#ifndef _VBE_SHIM_H_
>+#define _VBE_SHIM_H_
>+STATIC CONST UINT8 mVbeShim[] = {
>+ /* 00000000 nop */ 0x90,
>+ /* 00000001 nop */ 0x90,
>+ /* 00000002 nop */ 0x90,
>+ /* 00000003 nop */ 0x90,
>+ /* 00000004 nop */ 0x90,
>+ /* 00000005 nop */ 0x90,
>+ /* 00000006 nop */ 0x90,
>+ /* 00000007 nop */ 0x90,
>+ /* 00000008 nop */ 0x90,
>+ /* 00000009 nop */ 0x90,
>+ /* 0000000A nop */ 0x90,
>+ /* 0000000B nop */ 0x90,
>+ /* 0000000C nop */ 0x90,
>+ /* 0000000D nop */ 0x90,
>+ /* 0000000E nop */ 0x90,
>+ /* 0000000F nop */ 0x90,
>+ /* 00000010 nop */ 0x90,
>+ /* 00000011 nop */ 0x90,
>+ /* 00000012 nop */ 0x90,
>+ /* 00000013 nop */ 0x90,
>+ /* 00000014 nop */ 0x90,
>+ /* 00000015 nop */ 0x90,
>+ /* 00000016 nop */ 0x90,
>+ /* 00000017 nop */ 0x90,
>+ /* 00000018 nop */ 0x90,
>+ /* 00000019 nop */ 0x90,
>+ /* 0000001A nop */ 0x90,
>+ /* 0000001B nop */ 0x90,
>+ /* 0000001C nop */ 0x90,
>+ /* 0000001D nop */ 0x90,
>+ /* 0000001E nop */ 0x90,
>+ /* 0000001F nop */ 0x90,
>+ /* 00000020 nop */ 0x90,
>+ /* 00000021 nop */ 0x90,
>+ /* 00000022 nop */ 0x90,
>+ /* 00000023 nop */ 0x90,
>+ /* 00000024 nop */ 0x90,
>+ /* 00000025 nop */ 0x90,
>+ /* 00000026 nop */ 0x90,
>+ /* 00000027 nop */ 0x90,
>+ /* 00000028 nop */ 0x90,
>+ /* 00000029 nop */ 0x90,
>+ /* 0000002A nop */ 0x90,
>+ /* 0000002B nop */ 0x90,
>+ /* 0000002C nop */ 0x90,
>+ /* 0000002D nop */ 0x90,
>+ /* 0000002E nop */ 0x90,
>+ /* 0000002F nop */ 0x90,
>+ /* 00000030 nop */ 0x90,
>+ /* 00000031 nop */ 0x90,
>+ /* 00000032 nop */ 0x90,
>+ /* 00000033 nop */ 0x90,
>+ /* 00000034 nop */ 0x90,
>+ /* 00000035 nop */ 0x90,
>+ /* 00000036 nop */ 0x90,
>+ /* 00000037 nop */ 0x90,
>+ /* 00000038 nop */ 0x90,
>+ /* 00000039 nop */ 0x90,
>+ /* 0000003A nop */ 0x90,
>+ /* 0000003B nop */ 0x90,
>+ /* 0000003C nop */ 0x90,
>+ /* 0000003D nop */ 0x90,
>+ /* 0000003E nop */ 0x90,
>+ /* 0000003F nop */ 0x90,
>+ /* 00000040 nop */ 0x90,
>+ /* 00000041 nop */ 0x90,
>+ /* 00000042 nop */ 0x90,
>+ /* 00000043 nop */ 0x90,
>+ /* 00000044 nop */ 0x90,
>+ /* 00000045 nop */ 0x90,
>+ /* 00000046 nop */ 0x90,
>+ /* 00000047 nop */ 0x90,
>+ /* 00000048 nop */ 0x90,
>+ /* 00000049 nop */ 0x90,
>+ /* 0000004A nop */ 0x90,
>+ /* 0000004B nop */ 0x90,
>+ /* 0000004C nop */ 0x90,
>+ /* 0000004D nop */ 0x90,
>+ /* 0000004E nop */ 0x90,
>+ /* 0000004F nop */ 0x90,
>+ /* 00000050 nop */ 0x90,
>+ /* 00000051 nop */ 0x90,
>+ /* 00000052 nop */ 0x90,
>+ /* 00000053 nop */ 0x90,
>+ /* 00000054 nop */ 0x90,
>+ /* 00000055 nop */ 0x90,
>+ /* 00000056 nop */ 0x90,
>+ /* 00000057 nop */ 0x90,
>+ /* 00000058 nop */ 0x90,
>+ /* 00000059 nop */ 0x90,
>+ /* 0000005A nop */ 0x90,
>+ /* 0000005B nop */ 0x90,
>+ /* 0000005C nop */ 0x90,
>+ /* 0000005D nop */ 0x90,
>+ /* 0000005E nop */ 0x90,
>+ /* 0000005F nop */ 0x90,
>+ /* 00000060 nop */ 0x90,
>+ /* 00000061 nop */ 0x90,
>+ /* 00000062 nop */ 0x90,
>+ /* 00000063 nop */ 0x90,
>+ /* 00000064 nop */ 0x90,
>+ /* 00000065 nop */ 0x90,
>+ /* 00000066 nop */ 0x90,
>+ /* 00000067 nop */ 0x90,
>+ /* 00000068 nop */ 0x90,
>+ /* 00000069 nop */ 0x90,
>+ /* 0000006A nop */ 0x90,
>+ /* 0000006B nop */ 0x90,
>+ /* 0000006C nop */ 0x90,
>+ /* 0000006D nop */ 0x90,
>+ /* 0000006E nop */ 0x90,
>+ /* 0000006F nop */ 0x90,
>+ /* 00000070 nop */ 0x90,
>+ /* 00000071 nop */ 0x90,
>+ /* 00000072 nop */ 0x90,
>+ /* 00000073 nop */ 0x90,
>+ /* 00000074 nop */ 0x90,
>+ /* 00000075 nop */ 0x90,
>+ /* 00000076 nop */ 0x90,
>+ /* 00000077 nop */ 0x90,
>+ /* 00000078 nop */ 0x90,
>+ /* 00000079 nop */ 0x90,
>+ /* 0000007A nop */ 0x90,
>+ /* 0000007B nop */ 0x90,
>+ /* 0000007C nop */ 0x90,
>+ /* 0000007D nop */ 0x90,
>+ /* 0000007E nop */ 0x90,
>+ /* 0000007F nop */ 0x90,
>+ /* 00000080 nop */ 0x90,
>+ /* 00000081 nop */ 0x90,
>+ /* 00000082 nop */ 0x90,
>+ /* 00000083 nop */ 0x90,
>+ /* 00000084 nop */ 0x90,
>+ /* 00000085 nop */ 0x90,
>+ /* 00000086 nop */ 0x90,
>+ /* 00000087 nop */ 0x90,
>+ /* 00000088 nop */ 0x90,
>+ /* 00000089 nop */ 0x90,
>+ /* 0000008A nop */ 0x90,
>+ /* 0000008B nop */ 0x90,
>+ /* 0000008C nop */ 0x90,
>+ /* 0000008D nop */ 0x90,
>+ /* 0000008E nop */ 0x90,
>+ /* 0000008F nop */ 0x90,
>+ /* 00000090 nop */ 0x90,
>+ /* 00000091 nop */ 0x90,
>+ /* 00000092 nop */ 0x90,
>+ /* 00000093 nop */ 0x90,
>+ /* 00000094 nop */ 0x90,
>+ /* 00000095 nop */ 0x90,
>+ /* 00000096 nop */ 0x90,
>+ /* 00000097 nop */ 0x90,
>+ /* 00000098 nop */ 0x90,
>+ /* 00000099 nop */ 0x90,
>+ /* 0000009A nop */ 0x90,
>+ /* 0000009B nop */ 0x90,
>+ /* 0000009C nop */ 0x90,
>+ /* 0000009D nop */ 0x90,
>+ /* 0000009E nop */ 0x90,
>+ /* 0000009F nop */ 0x90,
>+ /* 000000A0 nop */ 0x90,
>+ /* 000000A1 nop */ 0x90,
>+ /* 000000A2 nop */ 0x90,
>+ /* 000000A3 nop */ 0x90,
>+ /* 000000A4 nop */ 0x90,
>+ /* 000000A5 nop */ 0x90,
>+ /* 000000A6 nop */ 0x90,
>+ /* 000000A7 nop */ 0x90,
>+ /* 000000A8 nop */ 0x90,
>+ /* 000000A9 nop */ 0x90,
>+ /* 000000AA nop */ 0x90,
>+ /* 000000AB nop */ 0x90,
>+ /* 000000AC nop */ 0x90,
>+ /* 000000AD nop */ 0x90,
>+ /* 000000AE nop */ 0x90,
>+ /* 000000AF nop */ 0x90,
>+ /* 000000B0 nop */ 0x90,
>+ /* 000000B1 nop */ 0x90,
>+ /* 000000B2 nop */ 0x90,
>+ /* 000000B3 nop */ 0x90,
>+ /* 000000B4 nop */ 0x90,
>+ /* 000000B5 nop */ 0x90,
>+ /* 000000B6 nop */ 0x90,
>+ /* 000000B7 nop */ 0x90,
>+ /* 000000B8 nop */ 0x90,
>+ /* 000000B9 nop */ 0x90,
>+ /* 000000BA nop */ 0x90,
>+ /* 000000BB nop */ 0x90,
>+ /* 000000BC nop */ 0x90,
>+ /* 000000BD nop */ 0x90,
>+ /* 000000BE nop */ 0x90,
>+ /* 000000BF nop */ 0x90,
>+ /* 000000C0 nop */ 0x90,
>+ /* 000000C1 nop */ 0x90,
>+ /* 000000C2 nop */ 0x90,
>+ /* 000000C3 nop */ 0x90,
>+ /* 000000C4 nop */ 0x90,
>+ /* 000000C5 nop */ 0x90,
>+ /* 000000C6 nop */ 0x90,
>+ /* 000000C7 nop */ 0x90,
>+ /* 000000C8 nop */ 0x90,
>+ /* 000000C9 nop */ 0x90,
>+ /* 000000CA nop */ 0x90,
>+ /* 000000CB nop */ 0x90,
>+ /* 000000CC nop */ 0x90,
>+ /* 000000CD nop */ 0x90,
>+ /* 000000CE nop */ 0x90,
>+ /* 000000CF nop */ 0x90,
>+ /* 000000D0 nop */ 0x90,
>+ /* 000000D1 nop */ 0x90,
>+ /* 000000D2 nop */ 0x90,
>+ /* 000000D3 nop */ 0x90,
>+ /* 000000D4 nop */ 0x90,
>+ /* 000000D5 nop */ 0x90,
>+ /* 000000D6 nop */ 0x90,
>+ /* 000000D7 nop */ 0x90,
>+ /* 000000D8 nop */ 0x90,
>+ /* 000000D9 nop */ 0x90,
>+ /* 000000DA nop */ 0x90,
>+ /* 000000DB nop */ 0x90,
>+ /* 000000DC nop */ 0x90,
>+ /* 000000DD nop */ 0x90,
>+ /* 000000DE nop */ 0x90,
>+ /* 000000DF nop */ 0x90,
>+ /* 000000E0 nop */ 0x90,
>+ /* 000000E1 nop */ 0x90,
>+ /* 000000E2 nop */ 0x90,
>+ /* 000000E3 nop */ 0x90,
>+ /* 000000E4 nop */ 0x90,
>+ /* 000000E5 nop */ 0x90,
>+ /* 000000E6 nop */ 0x90,
>+ /* 000000E7 nop */ 0x90,
>+ /* 000000E8 nop */ 0x90,
>+ /* 000000E9 nop */ 0x90,
>+ /* 000000EA nop */ 0x90,
>+ /* 000000EB nop */ 0x90,
>+ /* 000000EC nop */ 0x90,
>+ /* 000000ED nop */ 0x90,
>+ /* 000000EE nop */ 0x90,
>+ /* 000000EF nop */ 0x90,
>+ /* 000000F0 nop */ 0x90,
>+ /* 000000F1 nop */ 0x90,
>+ /* 000000F2 nop */ 0x90,
>+ /* 000000F3 nop */ 0x90,
>+ /* 000000F4 nop */ 0x90,
>+ /* 000000F5 nop */ 0x90,
>+ /* 000000F6 nop */ 0x90,
>+ /* 000000F7 nop */ 0x90,
>+ /* 000000F8 nop */ 0x90,
>+ /* 000000F9 nop */ 0x90,
>+ /* 000000FA nop */ 0x90,
>+ /* 000000FB nop */ 0x90,
>+ /* 000000FC nop */ 0x90,
>+ /* 000000FD nop */ 0x90,
>+ /* 000000FE nop */ 0x90,
>+ /* 000000FF nop */ 0x90,
>+ /* 00000100 nop */ 0x90,
>+ /* 00000101 nop */ 0x90,
>+ /* 00000102 nop */ 0x90,
>+ /* 00000103 nop */ 0x90,
>+ /* 00000104 nop */ 0x90,
>+ /* 00000105 nop */ 0x90,
>+ /* 00000106 nop */ 0x90,
>+ /* 00000107 nop */ 0x90,
>+ /* 00000108 nop */ 0x90,
>+ /* 00000109 nop */ 0x90,
>+ /* 0000010A nop */ 0x90,
>+ /* 0000010B nop */ 0x90,
>+ /* 0000010C nop */ 0x90,
>+ /* 0000010D nop */ 0x90,
>+ /* 0000010E nop */ 0x90,
>+ /* 0000010F nop */ 0x90,
>+ /* 00000110 nop */ 0x90,
>+ /* 00000111 nop */ 0x90,
>+ /* 00000112 nop */ 0x90,
>+ /* 00000113 nop */ 0x90,
>+ /* 00000114 nop */ 0x90,
>+ /* 00000115 nop */ 0x90,
>+ /* 00000116 nop */ 0x90,
>+ /* 00000117 nop */ 0x90,
>+ /* 00000118 nop */ 0x90,
>+ /* 00000119 nop */ 0x90,
>+ /* 0000011A nop */ 0x90,
>+ /* 0000011B nop */ 0x90,
>+ /* 0000011C nop */ 0x90,
>+ /* 0000011D nop */ 0x90,
>+ /* 0000011E nop */ 0x90,
>+ /* 0000011F nop */ 0x90,
>+ /* 00000120 nop */ 0x90,
>+ /* 00000121 nop */ 0x90,
>+ /* 00000122 nop */ 0x90,
>+ /* 00000123 nop */ 0x90,
>+ /* 00000124 nop */ 0x90,
>+ /* 00000125 nop */ 0x90,
>+ /* 00000126 nop */ 0x90,
>+ /* 00000127 nop */ 0x90,
>+ /* 00000128 nop */ 0x90,
>+ /* 00000129 nop */ 0x90,
>+ /* 0000012A nop */ 0x90,
>+ /* 0000012B nop */ 0x90,
>+ /* 0000012C nop */ 0x90,
>+ /* 0000012D nop */ 0x90,
>+ /* 0000012E nop */ 0x90,
>+ /* 0000012F nop */ 0x90,
>+ /* 00000130 nop */ 0x90,
>+ /* 00000131 nop */ 0x90,
>+ /* 00000132 nop */ 0x90,
>+ /* 00000133 nop */ 0x90,
>+ /* 00000134 nop */ 0x90,
>+ /* 00000135 nop */ 0x90,
>+ /* 00000136 nop */ 0x90,
>+ /* 00000137 nop */ 0x90,
>+ /* 00000138 nop */ 0x90,
>+ /* 00000139 nop */ 0x90,
>+ /* 0000013A nop */ 0x90,
>+ /* 0000013B nop */ 0x90,
>+ /* 0000013C nop */ 0x90,
>+ /* 0000013D nop */ 0x90,
>+ /* 0000013E nop */ 0x90,
>+ /* 0000013F nop */ 0x90,
>+ /* 00000140 nop */ 0x90,
>+ /* 00000141 nop */ 0x90,
>+ /* 00000142 nop */ 0x90,
>+ /* 00000143 nop */ 0x90,
>+ /* 00000144 nop */ 0x90,
>+ /* 00000145 nop */ 0x90,
>+ /* 00000146 nop */ 0x90,
>+ /* 00000147 nop */ 0x90,
>+ /* 00000148 nop */ 0x90,
>+ /* 00000149 nop */ 0x90,
>+ /* 0000014A nop */ 0x90,
>+ /* 0000014B nop */ 0x90,
>+ /* 0000014C nop */ 0x90,
>+ /* 0000014D nop */ 0x90,
>+ /* 0000014E nop */ 0x90,
>+ /* 0000014F nop */ 0x90,
>+ /* 00000150 nop */ 0x90,
>+ /* 00000151 nop */ 0x90,
>+ /* 00000152 nop */ 0x90,
>+ /* 00000153 nop */ 0x90,
>+ /* 00000154 nop */ 0x90,
>+ /* 00000155 nop */ 0x90,
>+ /* 00000156 nop */ 0x90,
>+ /* 00000157 nop */ 0x90,
>+ /* 00000158 nop */ 0x90,
>+ /* 00000159 nop */ 0x90,
>+ /* 0000015A nop */ 0x90,
>+ /* 0000015B nop */ 0x90,
>+ /* 0000015C nop */ 0x90,
>+ /* 0000015D nop */ 0x90,
>+ /* 0000015E nop */ 0x90,
>+ /* 0000015F nop */ 0x90,
>+ /* 00000160 nop */ 0x90,
>+ /* 00000161 nop */ 0x90,
>+ /* 00000162 nop */ 0x90,
>+ /* 00000163 nop */ 0x90,
>+ /* 00000164 nop */ 0x90,
>+ /* 00000165 nop */ 0x90,
>+ /* 00000166 nop */ 0x90,
>+ /* 00000167 nop */ 0x90,
>+ /* 00000168 nop */ 0x90,
>+ /* 00000169 nop */ 0x90,
>+ /* 0000016A nop */ 0x90,
>+ /* 0000016B nop */ 0x90,
>+ /* 0000016C nop */ 0x90,
>+ /* 0000016D nop */ 0x90,
>+ /* 0000016E nop */ 0x90,
>+ /* 0000016F nop */ 0x90,
>+ /* 00000170 nop */ 0x90,
>+ /* 00000171 nop */ 0x90,
>+ /* 00000172 nop */ 0x90,
>+ /* 00000173 nop */ 0x90,
>+ /* 00000174 nop */ 0x90,
>+ /* 00000175 nop */ 0x90,
>+ /* 00000176 nop */ 0x90,
>+ /* 00000177 nop */ 0x90,
>+ /* 00000178 nop */ 0x90,
>+ /* 00000179 nop */ 0x90,
>+ /* 0000017A nop */ 0x90,
>+ /* 0000017B nop */ 0x90,
>+ /* 0000017C nop */ 0x90,
>+ /* 0000017D nop */ 0x90,
>+ /* 0000017E nop */ 0x90,
>+ /* 0000017F nop */ 0x90,
>+ /* 00000180 nop */ 0x90,
>+ /* 00000181 nop */ 0x90,
>+ /* 00000182 nop */ 0x90,
>+ /* 00000183 nop */ 0x90,
>+ /* 00000184 nop */ 0x90,
>+ /* 00000185 nop */ 0x90,
>+ /* 00000186 nop */ 0x90,
>+ /* 00000187 nop */ 0x90,
>+ /* 00000188 nop */ 0x90,
>+ /* 00000189 nop */ 0x90,
>+ /* 0000018A nop */ 0x90,
>+ /* 0000018B nop */ 0x90,
>+ /* 0000018C nop */ 0x90,
>+ /* 0000018D nop */ 0x90,
>+ /* 0000018E nop */ 0x90,
>+ /* 0000018F nop */ 0x90,
>+ /* 00000190 nop */ 0x90,
>+ /* 00000191 nop */ 0x90,
>+ /* 00000192 nop */ 0x90,
>+ /* 00000193 nop */ 0x90,
>+ /* 00000194 nop */ 0x90,
>+ /* 00000195 nop */ 0x90,
>+ /* 00000196 nop */ 0x90,
>+ /* 00000197 nop */ 0x90,
>+ /* 00000198 nop */ 0x90,
>+ /* 00000199 nop */ 0x90,
>+ /* 0000019A nop */ 0x90,
>+ /* 0000019B nop */ 0x90,
>+ /* 0000019C nop */ 0x90,
>+ /* 0000019D nop */ 0x90,
>+ /* 0000019E nop */ 0x90,
>+ /* 0000019F nop */ 0x90,
>+ /* 000001A0 nop */ 0x90,
>+ /* 000001A1 nop */ 0x90,
>+ /* 000001A2 nop */ 0x90,
>+ /* 000001A3 nop */ 0x90,
>+ /* 000001A4 nop */ 0x90,
>+ /* 000001A5 nop */ 0x90,
>+ /* 000001A6 nop */ 0x90,
>+ /* 000001A7 nop */ 0x90,
>+ /* 000001A8 nop */ 0x90,
>+ /* 000001A9 nop */ 0x90,
>+ /* 000001AA nop */ 0x90,
>+ /* 000001AB nop */ 0x90,
>+ /* 000001AC nop */ 0x90,
>+ /* 000001AD nop */ 0x90,
>+ /* 000001AE nop */ 0x90,
>+ /* 000001AF nop */ 0x90,
>+ /* 000001B0 nop */ 0x90,
>+ /* 000001B1 nop */ 0x90,
>+ /* 000001B2 nop */ 0x90,
>+ /* 000001B3 nop */ 0x90,
>+ /* 000001B4 nop */ 0x90,
>+ /* 000001B5 nop */ 0x90,
>+ /* 000001B6 nop */ 0x90,
>+ /* 000001B7 nop */ 0x90,
>+ /* 000001B8 nop */ 0x90,
>+ /* 000001B9 nop */ 0x90,
>+ /* 000001BA nop */ 0x90,
>+ /* 000001BB nop */ 0x90,
>+ /* 000001BC nop */ 0x90,
>+ /* 000001BD nop */ 0x90,
>+ /* 000001BE nop */ 0x90,
>+ /* 000001BF nop */ 0x90,
>+ /* 000001C0 nop */ 0x90,
>+ /* 000001C1 nop */ 0x90,
>+ /* 000001C2 nop */ 0x90,
>+ /* 000001C3 nop */ 0x90,
>+ /* 000001C4 nop */ 0x90,
>+ /* 000001C5 nop */ 0x90,
>+ /* 000001C6 nop */ 0x90,
>+ /* 000001C7 nop */ 0x90,
>+ /* 000001C8 nop */ 0x90,
>+ /* 000001C9 nop */ 0x90,
>+ /* 000001CA nop */ 0x90,
>+ /* 000001CB nop */ 0x90,
>+ /* 000001CC nop */ 0x90,
>+ /* 000001CD nop */ 0x90,
>+ /* 000001CE nop */ 0x90,
>+ /* 000001CF nop */ 0x90,
>+ /* 000001D0 nop */ 0x90,
>+ /* 000001D1 nop */ 0x90,
>+ /* 000001D2 nop */ 0x90,
>+ /* 000001D3 nop */ 0x90,
>+ /* 000001D4 nop */ 0x90,
>+ /* 000001D5 nop */ 0x90,
>+ /* 000001D6 nop */ 0x90,
>+ /* 000001D7 nop */ 0x90,
>+ /* 000001D8 nop */ 0x90,
>+ /* 000001D9 nop */ 0x90,
>+ /* 000001DA nop */ 0x90,
>+ /* 000001DB nop */ 0x90,
>+ /* 000001DC nop */ 0x90,
>+ /* 000001DD nop */ 0x90,
>+ /* 000001DE nop */ 0x90,
>+ /* 000001DF nop */ 0x90,
>+ /* 000001E0 nop */ 0x90,
>+ /* 000001E1 nop */ 0x90,
>+ /* 000001E2 nop */ 0x90,
>+ /* 000001E3 nop */ 0x90,
>+ /* 000001E4 nop */ 0x90,
>+ /* 000001E5 nop */ 0x90,
>+ /* 000001E6 nop */ 0x90,
>+ /* 000001E7 nop */ 0x90,
>+ /* 000001E8 nop */ 0x90,
>+ /* 000001E9 nop */ 0x90,
>+ /* 000001EA nop */ 0x90,
>+ /* 000001EB nop */ 0x90,
>+ /* 000001EC nop */ 0x90,
>+ /* 000001ED nop */ 0x90,
>+ /* 000001EE nop */ 0x90,
>+ /* 000001EF nop */ 0x90,
>+ /* 000001F0 nop */ 0x90,
>+ /* 000001F1 nop */ 0x90,
>+ /* 000001F2 nop */ 0x90,
>+ /* 000001F3 nop */ 0x90,
>+ /* 000001F4 nop */ 0x90,
>+ /* 000001F5 nop */ 0x90,
>+ /* 000001F6 nop */ 0x90,
>+ /* 000001F7 nop */ 0x90,
>+ /* 000001F8 nop */ 0x90,
>+ /* 000001F9 nop */ 0x90,
>+ /* 000001FA nop */ 0x90,
>+ /* 000001FB nop */ 0x90,
>+ /* 000001FC nop */ 0x90,
>+ /* 000001FD nop */ 0x90,
>+ /* 000001FE nop */ 0x90,
>+ /* 000001FF nop */ 0x90,
>+ /* 00000200 cmp ax,0x4f00 */ 0x3D, 0x00, 0x4F,
>+ /* 00000203 jz 0x22d */ 0x74, 0x28,
>+ /* 00000205 cmp ax,0x4f01 */ 0x3D, 0x01, 0x4F,
>+ /* 00000208 jz 0x245 */ 0x74, 0x3B,
>+ /* 0000020A cmp ax,0x4f02 */ 0x3D, 0x02, 0x4F,
>+ /* 0000020D jz 0x269 */ 0x74, 0x5A,
>+ /* 0000020F cmp ax,0x4f03 */ 0x3D, 0x03, 0x4F,
>+ /* 00000212 jz word 0x331 */ 0x0F, 0x84, 0x1B, 0x01,
>+ /* 00000216 cmp ax,0x4f10 */ 0x3D, 0x10, 0x4F,
>+ /* 00000219 jz word 0x336 */ 0x0F, 0x84, 0x19, 0x01,
>+ /* 0000021D cmp ax,0x4f15 */ 0x3D, 0x15, 0x4F,
>+ /* 00000220 jz word 0x338 */ 0x0F, 0x84, 0x14, 0x01,
>+ /* 00000224 cmp ah,0x0 */ 0x80, 0xFC, 0x00,
>+ /* 00000227 jz word 0x33a */ 0x0F, 0x84, 0x0F, 0x01,
>+ /* 0000022B jmp short 0x22b */ 0xEB, 0xFE,
>+ /* 0000022D push es */ 0x06,
>+ /* 0000022E push di */ 0x57,
>+ /* 0000022F push ds */ 0x1E,
>+ /* 00000230 push si */ 0x56,
>+ /* 00000231 push cx */ 0x51,
>+ /* 00000232 push cs */ 0x0E,
>+ /* 00000233 pop ds */ 0x1F,
>+ /* 00000234 mov si,0x0 */ 0xBE, 0x00, 0x00,
>+ /* 00000237 mov cx,0x100 */ 0xB9, 0x00, 0x01,
>+ /* 0000023A cld */ 0xFC,
>+ /* 0000023B rep movsb */ 0xF3, 0xA4,
>+ /* 0000023D pop cx */ 0x59,
>+ /* 0000023E pop si */ 0x5E,
>+ /* 0000023F pop ds */ 0x1F,
>+ /* 00000240 pop di */ 0x5F,
>+ /* 00000241 pop es */ 0x07,
>+ /* 00000242 jmp word 0x34c */ 0xE9, 0x07, 0x01,
>+ /* 00000245 push es */ 0x06,
>+ /* 00000246 push di */ 0x57,
>+ /* 00000247 push ds */ 0x1E,
>+ /* 00000248 push si */ 0x56,
>+ /* 00000249 push cx */ 0x51,
>+ /* 0000024A and cx,0xbfff */ 0x81, 0xE1, 0xFF, 0xBF,
>+ /* 0000024E cmp cx,0xf1 */ 0x81, 0xF9, 0xF1, 0x00,
>+ /* 00000252 jz 0x256 */ 0x74, 0x02,
>+ /* 00000254 jmp short 0x22b */ 0xEB, 0xD5,
>+ /* 00000256 push cs */ 0x0E,
>+ /* 00000257 pop ds */ 0x1F,
>+ /* 00000258 mov si,0x100 */ 0xBE, 0x00, 0x01,
>+ /* 0000025B mov cx,0x100 */ 0xB9, 0x00, 0x01,
>+ /* 0000025E cld */ 0xFC,
>+ /* 0000025F rep movsb */ 0xF3, 0xA4,
>+ /* 00000261 pop cx */ 0x59,
>+ /* 00000262 pop si */ 0x5E,
>+ /* 00000263 pop ds */ 0x1F,
>+ /* 00000264 pop di */ 0x5F,
>+ /* 00000265 pop es */ 0x07,
>+ /* 00000266 jmp word 0x34c */ 0xE9, 0xE3, 0x00,
>+ /* 00000269 push dx */ 0x52,
>+ /* 0000026A push ax */ 0x50,
>+ /* 0000026B cmp bx,0x40f1 */ 0x81, 0xFB, 0xF1, 0x40,
>+ /* 0000026F jz 0x273 */ 0x74, 0x02,
>+ /* 00000271 jmp short 0x22b */ 0xEB, 0xB8,
>+ /* 00000273 mov dx,0x3c0 */ 0xBA, 0xC0, 0x03,
>+ /* 00000276 mov al,0x20 */ 0xB0, 0x20,
>+ /* 00000278 out dx,al */ 0xEE,
>+ /* 00000279 push dx */ 0x52,
>+ /* 0000027A push ax */ 0x50,
>+ /* 0000027B mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
>+ /* 0000027E mov ax,0x4 */ 0xB8, 0x04, 0x00,
>+ /* 00000281 out dx,ax */ 0xEF,
>+ /* 00000282 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
>+ /* 00000285 mov ax,0x0 */ 0xB8, 0x00, 0x00,
>+ /* 00000288 out dx,ax */ 0xEF,
>+ /* 00000289 pop ax */ 0x58,
>+ /* 0000028A pop dx */ 0x5A,
>+ /* 0000028B push dx */ 0x52,
>+ /* 0000028C push ax */ 0x50,
>+ /* 0000028D mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
>+ /* 00000290 mov ax,0x5 */ 0xB8, 0x05, 0x00,
>+ /* 00000293 out dx,ax */ 0xEF,
>+ /* 00000294 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
>+ /* 00000297 mov ax,0x0 */ 0xB8, 0x00, 0x00,
>+ /* 0000029A out dx,ax */ 0xEF,
>+ /* 0000029B pop ax */ 0x58,
>+ /* 0000029C pop dx */ 0x5A,
>+ /* 0000029D push dx */ 0x52,
>+ /* 0000029E push ax */ 0x50,
>+ /* 0000029F mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
>+ /* 000002A2 mov ax,0x8 */ 0xB8, 0x08, 0x00,
>+ /* 000002A5 out dx,ax */ 0xEF,
>+ /* 000002A6 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
>+ /* 000002A9 mov ax,0x0 */ 0xB8, 0x00, 0x00,
>+ /* 000002AC out dx,ax */ 0xEF,
>+ /* 000002AD pop ax */ 0x58,
>+ /* 000002AE pop dx */ 0x5A,
>+ /* 000002AF push dx */ 0x52,
>+ /* 000002B0 push ax */ 0x50,
>+ /* 000002B1 mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
>+ /* 000002B4 mov ax,0x9 */ 0xB8, 0x09, 0x00,
>+ /* 000002B7 out dx,ax */ 0xEF,
>+ /* 000002B8 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
>+ /* 000002BB mov ax,0x0 */ 0xB8, 0x00, 0x00,
>+ /* 000002BE out dx,ax */ 0xEF,
>+ /* 000002BF pop ax */ 0x58,
>+ /* 000002C0 pop dx */ 0x5A,
>+ /* 000002C1 push dx */ 0x52,
>+ /* 000002C2 push ax */ 0x50,
>+ /* 000002C3 mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
>+ /* 000002C6 mov ax,0x3 */ 0xB8, 0x03, 0x00,
>+ /* 000002C9 out dx,ax */ 0xEF,
>+ /* 000002CA mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
>+ /* 000002CD mov ax,0x20 */ 0xB8, 0x20, 0x00,
>+ /* 000002D0 out dx,ax */ 0xEF,
>+ /* 000002D1 pop ax */ 0x58,
>+ /* 000002D2 pop dx */ 0x5A,
>+ /* 000002D3 push dx */ 0x52,
>+ /* 000002D4 push ax */ 0x50,
>+ /* 000002D5 mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
>+ /* 000002D8 mov ax,0x1 */ 0xB8, 0x01, 0x00,
>+ /* 000002DB out dx,ax */ 0xEF,
>+ /* 000002DC mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
>+ /* 000002DF mov ax,0x400 */ 0xB8, 0x00, 0x04,
>+ /* 000002E2 out dx,ax */ 0xEF,
>+ /* 000002E3 pop ax */ 0x58,
>+ /* 000002E4 pop dx */ 0x5A,
>+ /* 000002E5 push dx */ 0x52,
>+ /* 000002E6 push ax */ 0x50,
>+ /* 000002E7 mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
>+ /* 000002EA mov ax,0x6 */ 0xB8, 0x06, 0x00,
>+ /* 000002ED out dx,ax */ 0xEF,
>+ /* 000002EE mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
>+ /* 000002F1 mov ax,0x400 */ 0xB8, 0x00, 0x04,
>+ /* 000002F4 out dx,ax */ 0xEF,
>+ /* 000002F5 pop ax */ 0x58,
>+ /* 000002F6 pop dx */ 0x5A,
>+ /* 000002F7 push dx */ 0x52,
>+ /* 000002F8 push ax */ 0x50,
>+ /* 000002F9 mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
>+ /* 000002FC mov ax,0x2 */ 0xB8, 0x02, 0x00,
>+ /* 000002FF out dx,ax */ 0xEF,
>+ /* 00000300 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
>+ /* 00000303 mov ax,0x300 */ 0xB8, 0x00, 0x03,
>+ /* 00000306 out dx,ax */ 0xEF,
>+ /* 00000307 pop ax */ 0x58,
>+ /* 00000308 pop dx */ 0x5A,
>+ /* 00000309 push dx */ 0x52,
>+ /* 0000030A push ax */ 0x50,
>+ /* 0000030B mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
>+ /* 0000030E mov ax,0x7 */ 0xB8, 0x07, 0x00,
>+ /* 00000311 out dx,ax */ 0xEF,
>+ /* 00000312 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
>+ /* 00000315 mov ax,0x300 */ 0xB8, 0x00, 0x03,
>+ /* 00000318 out dx,ax */ 0xEF,
>+ /* 00000319 pop ax */ 0x58,
>+ /* 0000031A pop dx */ 0x5A,
>+ /* 0000031B push dx */ 0x52,
>+ /* 0000031C push ax */ 0x50,
>+ /* 0000031D mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
>+ /* 00000320 mov ax,0x4 */ 0xB8, 0x04, 0x00,
>+ /* 00000323 out dx,ax */ 0xEF,
>+ /* 00000324 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
>+ /* 00000327 mov ax,0x41 */ 0xB8, 0x41, 0x00,
>+ /* 0000032A out dx,ax */ 0xEF,
>+ /* 0000032B pop ax */ 0x58,
>+ /* 0000032C pop dx */ 0x5A,
>+ /* 0000032D pop ax */ 0x58,
>+ /* 0000032E pop dx */ 0x5A,
>+ /* 0000032F jmp short 0x34c */ 0xEB, 0x1B,
>+ /* 00000331 mov bx,0x40f1 */ 0xBB, 0xF1, 0x40,
>+ /* 00000334 jmp short 0x34c */ 0xEB, 0x16,
>+ /* 00000336 jmp short 0x350 */ 0xEB, 0x18,
>+ /* 00000338 jmp short 0x350 */ 0xEB, 0x16,
>+ /* 0000033A cmp al,0x3 */ 0x3C, 0x03,
>+ /* 0000033C jz 0x345 */ 0x74, 0x07,
>+ /* 0000033E cmp al,0x12 */ 0x3C, 0x12,
>+ /* 00000340 jz 0x349 */ 0x74, 0x07,
>+ /* 00000342 jmp word 0x22b */ 0xE9, 0xE6, 0xFE,
>+ /* 00000345 mov al,0x30 */ 0xB0, 0x30,
>+ /* 00000347 jmp short 0x34b */ 0xEB, 0x02,
>+ /* 00000349 mov al,0x20 */ 0xB0, 0x20,
>+ /* 0000034B iretw */ 0xCF,
>+ /* 0000034C mov ax,0x4f */ 0xB8, 0x4F, 0x00,
>+ /* 0000034F iretw */ 0xCF,
>+ /* 00000350 mov ax,0x14f */ 0xB8, 0x4F, 0x01,
>+ /* 00000353 iretw */ 0xCF,
>+};
>+#endif
>diff --git
>a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>VbeShim.sh
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>VbeShim.sh
>new file mode 100644
>index 0000000000..7669f8a219
>--- /dev/null
>+++
>b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
>VbeShim.sh
>@@ -0,0 +1,79 @@
>+#!/bin/sh
>+###
>+# @file
>+# Shell script to assemble and dump the fake Int10h handler from NASM
>source to
>+# a C array.
>+#
>+# Copyright (C) 2014, Red Hat, Inc.
>+# Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
>+#
>+# SPDX-License-Identifier: BSD-2-Clause-Patent
>+#
>+###
>+
>+set -e -u
>+
>+STEM=$(dirname -- "$0")/$(basename -- "$0" .sh)
>+
>+#
>+# Install exit handler -- remove temporary files.
>+#
>+exit_handler()
>+{
>+ rm -f -- "$STEM".bin "$STEM".disasm "$STEM".offsets "$STEM".insns \
>+ "$STEM".bytes
>+}
>+trap exit_handler EXIT
>+
>+#
>+# Assemble the source file.
>+#
>+nasm -o "$STEM".bin -- "$STEM".asm
>+
>+#
>+# Disassemble it, in order to get a binary dump associated with the source.
>+# (ndisasm doesn't recognize the "--" end-of-options delimiter.)
>+#
>+ndisasm "$STEM".bin >"$STEM".disasm
>+
>+#
>+# Create three files, each with one column of the disassembly.
>+#
>+# The first column contains the offsets, and it starts the comment.
>+#
>+cut -c 1-8 -- "$STEM".disasm \
>+| sed -e 's,^, /* ,' >"$STEM".offsets
>+
>+#
>+# The second column contains the assembly-language instructions, and it
>closes
>+# the comment. We first pad it to 30 characters.
>+#
>+cut -c 29- -- "$STEM".disasm \
>+| sed -e 's,$, ,' \
>+ -e 's,^\(.\{30\}\).*$,\1 */,' >"$STEM".insns
>+
>+#
>+# The third column contains the bytes corresponding to the instruction,
>+# represented as C integer constants. First strip trailing whitespace from the
>+# middle column of the input disassembly, then process pairs of nibbles.
>+#
>+cut -c 11-28 -- "$STEM".disasm \
>+| sed -e 's, \+$,,' -e 's/\(..\)/ 0x\1,/g' >"$STEM".bytes
>+
>+#
>+# Write the output file, recombining the columns. The output should have
>CRLF
>+# line endings.
>+#
>+{
>+ printf '//\n'
>+ printf '// THIS FILE WAS GENERATED BY "%s". DO NOT EDIT.\n' \
>+ "$(basename -- "$0")"
>+ printf '//\n'
>+ printf '#ifndef _VBE_SHIM_H_\n'
>+ printf '#define _VBE_SHIM_H_\n'
>+ printf 'STATIC CONST UINT8 mVbeShim[] = {\n'
>+ paste -d ' ' -- "$STEM".offsets "$STEM".insns "$STEM".bytes
>+ printf '};\n'
>+ printf '#endif\n'
>+} \
>+| unix2dos >"$STEM".h
>--
>2.16.2.windows.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [edk2-platforms PATCH v2 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58
2019-08-28 0:40 ` [edk2-platforms PATCH v2 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58 David Wei
@ 2019-08-28 22:02 ` Nate DeSimone
0 siblings, 0 replies; 16+ messages in thread
From: Nate DeSimone @ 2019-08-28 22:02 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Kubacki, Michael A, Kinney, Michael D
Please update all of the copyright years.
-----Original Message-----
From: Wei, David Y
Sent: Tuesday, August 27, 2019 5:40 PM
To: devel@edk2.groups.io
Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Kubacki, Michael A <michael.a.kubacki@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: [edk2-platforms PATCH v2 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58
Add CPU Pkg for SimicsX58. It is added for simics QSP project support
Cc: Hao Wu <mailto:hao.a.wu@intel.com>
Cc: Liming Gao <mailto:liming.gao@intel.com>
Cc: Ankit Sinha <mailto:ankit.sinha@intel.com>
Cc: Agyeman Prince <mailto:prince.agyeman@intel.com>
Cc: Kubacki Michael A <mailto:michael.a.kubacki@intel.com>
Cc: Nate DeSimone <mailto:nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <mailto:michael.d.kinney@intel.com>
Signed-off-by: David Wei <mailto:david.y.wei@intel.com>
---
.../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c | 148 +++++++++
.../SimicsX58SktPkg/Smm/Access/SmmAccessPei.c | 346 +++++++++++++++++++++
.../SimicsX58SktPkg/Smm/Access/SmramInternal.c | 200 ++++++++++++
.../Include/Register/X58SmramSaveStateMap.h | 178 +++++++++++
Silicon/Intel/SimicsX58SktPkg/SktPkg.dec | 37 +++
Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc | 14 +
.../Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf | 9 +
.../Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf | 10 +
Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf | 16 +
.../Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf | 14 +
.../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf | 54 ++++
.../SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf | 65 ++++
.../SimicsX58SktPkg/Smm/Access/SmramInternal.h | 81 +++++
13 files changed, 1172 insertions(+)
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Include/Register/X58SmramSaveStateMap.h
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPkg.dec
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
new file mode 100644
index 0000000000..771fddb487
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
@@ -0,0 +1,148 @@
+/** @file
+ A DXE_DRIVER providing SMRAM access by producing EFI_SMM_ACCESS2_PROTOCOL.
+
+ X58 TSEG is expected to have been verified and set up by the
+ SmmAccessPei driver.
+
+ Copyright (C) 2013, 2015, Red Hat, Inc.<BR> Copyright (c) 2009 -
+ 2010, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/SmmAccess2.h>
+
+#include "SmramInternal.h"
+
+/**
+ Opens the SMRAM area to be accessible by a boot-service driver.
+
+ This function "opens" SMRAM so that it is visible while not inside of SMM.
+ The function should return EFI_UNSUPPORTED if the hardware does not
+ support hiding of SMRAM. The function should return EFI_DEVICE_ERROR
+ if the SMRAM configuration is locked.
+
+ @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The operation was successful.
+ @retval EFI_UNSUPPORTED The system does not support opening and closing of
+ SMRAM.
+ @retval EFI_DEVICE_ERROR SMRAM cannot be opened, perhaps because it is
+ locked.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeOpen (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ )
+{
+ return SmramAccessOpen (&This->LockState, &This->OpenState); }
+
+/**
+ Inhibits access to the SMRAM.
+
+ This function "closes" SMRAM so that it is not visible while outside of SMM.
+ The function should return EFI_UNSUPPORTED if the hardware does not
+ support hiding of SMRAM.
+
+ @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The operation was successful.
+ @retval EFI_UNSUPPORTED The system does not support opening and closing of
+ SMRAM.
+ @retval EFI_DEVICE_ERROR SMRAM cannot be closed.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeClose (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ )
+{
+ return SmramAccessClose (&This->LockState, &This->OpenState); }
+
+/**
+ Inhibits access to the SMRAM.
+
+ This function prohibits access to the SMRAM region. This function is
+ usually implemented such that it is a write-once operation.
+
+ @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The device was successfully locked.
+ @retval EFI_UNSUPPORTED The system does not support locking of SMRAM.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeLock (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ )
+{
+ return SmramAccessLock (&This->LockState, &This->OpenState); }
+
+/**
+ Queries the memory controller for the possible regions that will
+support
+ SMRAM.
+
+ @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance.
+ @param[in,out] SmramMapSize A pointer to the size, in bytes, of the
+ SmramMemoryMap buffer.
+ @param[in,out] SmramMap A pointer to the buffer in which firmware
+ places the current memory map.
+
+ @retval EFI_SUCCESS The chipset supported the given resource.
+ @retval EFI_BUFFER_TOO_SMALL The SmramMap parameter was too small. The
+ current buffer size needed to hold the memory
+ map is returned in SmramMapSize.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeGetCapabilities (
+ IN CONST EFI_SMM_ACCESS2_PROTOCOL *This,
+ IN OUT UINTN *SmramMapSize,
+ IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
+ )
+{
+ return SmramAccessGetCapabilities (This->LockState, This->OpenState,
+ SmramMapSize, SmramMap);
+}
+
+//
+// LockState and OpenState will be filled in by the entry point.
+//
+STATIC EFI_SMM_ACCESS2_PROTOCOL mAccess2 = {
+ &SmmAccess2DxeOpen,
+ &SmmAccess2DxeClose,
+ &SmmAccess2DxeLock,
+ &SmmAccess2DxeGetCapabilities
+};
+
+//
+// Entry point of this driver.
+//
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ //
+ // This module should only be included if SMRAM support is required.
+ //
+ ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
+
+ GetStates (&mAccess2.LockState, &mAccess2.OpenState);
+ return gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
+ &gEfiSmmAccess2ProtocolGuid, &mAccess2,
+ NULL);
+}
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
new file mode 100644
index 0000000000..c54026b4d1
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
@@ -0,0 +1,346 @@
+/** @file
+ A PEIM with the following responsibilities:
+
+ - verify & configure the X58 TSEG in the entry point,
+ - provide SMRAM access by producing PEI_SMM_ACCESS_PPI,
+ - set aside the SMM_S3_RESUME_STATE object at the bottom of TSEG, and expose
+ it via the gEfiAcpiVariableGuid GUID HOB.
+
+ This PEIM runs from RAM, so we can write to variables with static
+ storage duration.
+
+ Copyright (C) 2013, 2015, Red Hat, Inc.<BR> Copyright (c) 2010 -
+ 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#include <Guid/AcpiS3Context.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/SmmAccess.h>
+
+#include <Register/X58Ich10.h>
+#include "SmramInternal.h"
+
+//
+// PEI_SMM_ACCESS_PPI implementation.
+//
+
+/**
+ Opens the SMRAM area to be accessible by a PEIM driver.
+
+ This function "opens" SMRAM so that it is visible while not inside of SMM.
+ The function should return EFI_UNSUPPORTED if the hardware does not
+ support hiding of SMRAM. The function should return EFI_DEVICE_ERROR
+ if the SMRAM configuration is locked.
+
+ @param PeiServices General purpose services available to every
+ PEIM.
+ @param This The pointer to the SMM Access Interface.
+ @param DescriptorIndex The region of SMRAM to Open.
+
+ @retval EFI_SUCCESS The region was successfully opened.
+ @retval EFI_DEVICE_ERROR The region could not be opened because locked
+ by chipset.
+ @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccessPeiOpen (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_ACCESS_PPI *This,
+ IN UINTN DescriptorIndex
+ )
+{
+ if (DescriptorIndex >= DescIdxCount) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // According to current practice, DescriptorIndex is not considered
+at all,
+ // beyond validating it.
+ //
+ return SmramAccessOpen (&This->LockState, &This->OpenState); }
+
+/**
+ Inhibits access to the SMRAM.
+
+ This function "closes" SMRAM so that it is not visible while outside of SMM.
+ The function should return EFI_UNSUPPORTED if the hardware does not
+ support hiding of SMRAM.
+
+ @param PeiServices General purpose services available to every
+ PEIM.
+ @param This The pointer to the SMM Access Interface.
+ @param DescriptorIndex The region of SMRAM to Close.
+
+ @retval EFI_SUCCESS The region was successfully closed.
+ @retval EFI_DEVICE_ERROR The region could not be closed because
+ locked by chipset.
+ @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccessPeiClose (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_ACCESS_PPI *This,
+ IN UINTN DescriptorIndex
+ )
+{
+ if (DescriptorIndex >= DescIdxCount) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // According to current practice, DescriptorIndex is not considered
+at all,
+ // beyond validating it.
+ //
+ return SmramAccessClose (&This->LockState, &This->OpenState); }
+
+/**
+ Inhibits access to the SMRAM.
+
+ This function prohibits access to the SMRAM region. This function is
+ usually implemented such that it is a write-once operation.
+
+ @param PeiServices General purpose services available to every
+ PEIM.
+ @param This The pointer to the SMM Access Interface.
+ @param DescriptorIndex The region of SMRAM to Close.
+
+ @retval EFI_SUCCESS The region was successfully locked.
+ @retval EFI_DEVICE_ERROR The region could not be locked because at
+ least one range is still open.
+ @retval EFI_INVALID_PARAMETER The descriptor index was out of bounds.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccessPeiLock (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_ACCESS_PPI *This,
+ IN UINTN DescriptorIndex
+ )
+{
+ if (DescriptorIndex >= DescIdxCount) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // According to current practice, DescriptorIndex is not considered
+at all,
+ // beyond validating it.
+ //
+ return SmramAccessLock (&This->LockState, &This->OpenState); }
+
+/**
+ Queries the memory controller for the possible regions that will
+support
+ SMRAM.
+
+ @param PeiServices General purpose services available to every
+ PEIM.
+ @param This The pointer to the SmmAccessPpi Interface.
+ @param SmramMapSize The pointer to the variable containing size of
+ the buffer to contain the description
+ information.
+ @param SmramMap The buffer containing the data describing the
+ Smram region descriptors.
+
+ @retval EFI_BUFFER_TOO_SMALL The user did not provide a sufficient buffer.
+ @retval EFI_SUCCESS The user provided a sufficiently-sized buffer.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccessPeiGetCapabilities (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_ACCESS_PPI *This,
+ IN OUT UINTN *SmramMapSize,
+ IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
+ )
+{
+ return SmramAccessGetCapabilities (This->LockState, This->OpenState,
+SmramMapSize, SmramMap); }
+
+//
+// LockState and OpenState will be filled in by the entry point.
+//
+STATIC PEI_SMM_ACCESS_PPI mAccess = {
+ &SmmAccessPeiOpen,
+ &SmmAccessPeiClose,
+ &SmmAccessPeiLock,
+ &SmmAccessPeiGetCapabilities
+};
+
+
+STATIC EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiSmmAccessPpiGuid, &mAccess
+ }
+};
+
+
+//
+// Utility functions.
+//
+STATIC
+UINT8
+CmosRead8 (
+ IN UINT8 Index
+ )
+{
+ IoWrite8 (0x70, Index);
+ return IoRead8 (0x71);
+}
+
+STATIC
+UINT32
+GetSystemMemorySizeBelow4gb (
+ VOID
+ )
+{
+ UINT32 Cmos0x34;
+ UINT32 Cmos0x35;
+
+ Cmos0x34 = CmosRead8 (0x34);
+ Cmos0x35 = CmosRead8 (0x35);
+
+ return ((Cmos0x35 << 8 | Cmos0x34) << 16) + SIZE_16MB; }
+
+
+//
+// Entry point of this driver.
+//
+EFI_STATUS
+EFIAPI
+SmmAccessPeiEntryPoint (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ UINT16 HostBridgeDevId;
+ UINT32 EsmramcVal;
+ UINT32 TopOfLowRam, TopOfLowRamMb;
+ EFI_STATUS Status;
+ UINTN SmramMapSize;
+ EFI_SMRAM_DESCRIPTOR SmramMap[DescIdxCount];
+ VOID *GuidHob;
+
+ //
+ // This module should only be included if SMRAM support is required.
+ //
+ ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
+
+ //
+ // Verify if we're running on a X58 machine type.
+ //
+ HostBridgeDevId = PciRead16 (SIMICS_HOSTBRIDGE_DID); if
+ (HostBridgeDevId != INTEL_ICH10_DEVICE_ID) {
+ DEBUG ((EFI_D_ERROR, "%a: no SMRAM with host bridge DID=0x%04x; only "
+ "DID=0x%04x (X58) is supported\n", __FUNCTION__, HostBridgeDevId,
+ INTEL_ICH10_DEVICE_ID));
+ goto WrongConfig;
+ }
+
+ //
+ // Confirm if Simics supports SMRAM.
+ //
+ // With no support for it, the ESMRAMC (Extended System Management
+ RAM // Control) register reads as zero. If there is support, the
+ cache-enable // bits are hard-coded as 1 by Simics.
+ //
+
+ TopOfLowRam = GetSystemMemorySizeBelow4gb (); ASSERT ((TopOfLowRam &
+ (SIZE_1MB - 1)) == 0); TopOfLowRamMb = TopOfLowRam >> 20;
+ DEBUG((EFI_D_INFO, "TopOfLowRam =0x%x; TopOfLowRamMb =0x%x \n",
+ TopOfLowRam, TopOfLowRamMb));
+
+
+ //
+ // Set Top of Low Usable DRAM.
+ //
+ PciWrite32 (DRAMC_REGISTER_X58(MCH_TOLUD), TopOfLowRam);
+ DEBUG((EFI_D_INFO, "MCH_TOLUD =0x%x; \n",
+ PciRead32(DRAMC_REGISTER_X58(MCH_TOLUD))));
+
+ //
+ // Set TSEG Memory Base.
+ //
+ EsmramcVal = (TopOfLowRamMb - FixedPcdGet8(PcdX58TsegMbytes)) <<
+ MCH_TSEGMB_MB_SHIFT; // // Set TSEG size, and disable TSEG
+ visibility outside of SMM. Note that the // T_EN bit has inverse
+ meaning; when T_EN is set, then TSEG visibility is // *restricted* to
+ SMM.
+ //
+ EsmramcVal &= ~(UINT32)MCH_ESMRAMC_TSEG_MASK; EsmramcVal |=
+ FixedPcdGet8 (PcdX58TsegMbytes) == 8 ? MCH_ESMRAMC_TSEG_8MB :
+ FixedPcdGet8 (PcdX58TsegMbytes) == 2 ? MCH_ESMRAMC_TSEG_2MB :
+ MCH_ESMRAMC_TSEG_1MB;
+ EsmramcVal |= MCH_ESMRAMC_T_EN;
+ PciWrite32(DRAMC_REGISTER_X58(MCH_TSEGMB), EsmramcVal);
+ DEBUG((EFI_D_INFO, "MCH_TSEGMB =0x%x; \n",
+ PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB))));
+ DEBUG((EFI_D_INFO, "MCH_TSEGMB_1 =0x%x; MCH_TSEGMB_2 =0x%x;\n",
+ ((TopOfLowRamMb - FixedPcdGet8(PcdX58TsegMbytes)) <<
+ MCH_TSEGMB_MB_SHIFT), EsmramcVal));
+
+ //
+ // Create the GUID HOB and point it to the first SMRAM range.
+ //
+ GetStates (&mAccess.LockState, &mAccess.OpenState); SmramMapSize =
+ sizeof SmramMap; Status = SmramAccessGetCapabilities
+ (mAccess.LockState, mAccess.OpenState, &SmramMapSize, SmramMap);
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG_CODE_BEGIN ();
+ {
+ UINTN Count;
+ UINTN Idx;
+
+ Count = SmramMapSize / sizeof SmramMap[0];
+ DEBUG ((EFI_D_VERBOSE, "%a: SMRAM map follows, %d entries\n", __FUNCTION__, (INT32)Count));
+ DEBUG ((EFI_D_VERBOSE, "% 20a % 20a % 20a % 20a\n", "PhysicalStart(0x)",
+ "PhysicalSize(0x)", "CpuStart(0x)", "RegionState(0x)"));
+ for (Idx = 0; Idx < Count; ++Idx) {
+ DEBUG ((EFI_D_VERBOSE, "% 20Lx % 20Lx % 20Lx % 20Lx\n",
+ SmramMap[Idx].PhysicalStart, SmramMap[Idx].PhysicalSize,
+ SmramMap[Idx].CpuStart, SmramMap[Idx].RegionState));
+ }
+ }
+ DEBUG_CODE_END ();
+
+ GuidHob = BuildGuidHob (&gEfiAcpiVariableGuid, sizeof
+ SmramMap[DescIdxSmmS3ResumeState]);
+ if (GuidHob == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CopyMem (GuidHob, &SmramMap[DescIdxSmmS3ResumeState], sizeof
+ SmramMap[DescIdxSmmS3ResumeState]);
+
+ //
+ // We're done. The next step should succeed, but even if it fails, we
+ can't // roll back the above BuildGuidHob() allocation, because PEI
+ doesn't support // releasing memory.
+ //
+ return PeiServicesInstallPpi (mPpiList);
+
+WrongConfig:
+ //
+ // We really don't want to continue in this case.
+ //
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ return EFI_UNSUPPORTED;
+}
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
new file mode 100644
index 0000000000..4b5a92f602
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
@@ -0,0 +1,200 @@
+/** @file
+ Functions and types shared by the SMM accessor PEI and DXE modules.
+
+ Copyright (C) 2015, Red Hat, Inc.
+ Copyright (C) 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#include <Guid/AcpiS3Context.h>
+#include <Register/X58Ich10.h>
+#include <Library/DebugLib.h>
+#include <Library/PciLib.h>
+
+#include "SmramInternal.h"
+
+BOOLEAN gLockState;
+BOOLEAN gOpenState;
+
+/**
+ Read the MCH_SMRAM and ESMRAMC registers, and update the LockState
+and
+ OpenState fields in the PEI_SMM_ACCESS_PPI / EFI_SMM_ACCESS2_PROTOCOL
+object,
+ from the D_LCK and T_EN bits.
+
+ PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member functions can
+ rely on the LockState and OpenState fields being up-to-date on entry,
+ and they need to restore the same invariant on exit, if they touch the bits in question.
+
+ @param[out] LockState Reflects the D_LCK bit on output; TRUE iff SMRAM is
+ locked.
+ @param[out] OpenState Reflects the inverse of the T_EN bit on output; TRUE
+ iff SMRAM is open.
+**/
+VOID
+GetStates (
+ OUT BOOLEAN *LockState,
+ OUT BOOLEAN *OpenState
+)
+{
+ UINT8 EsmramcVal;
+
+ EsmramcVal = PciRead8(DRAMC_REGISTER_X58(MCH_TSEGMB));
+
+ *OpenState = !(EsmramcVal & MCH_ESMRAMC_T_EN); *LockState =
+ !*OpenState;
+
+ *OpenState = gOpenState;
+ *LockState = gLockState;
+}
+
+//
+// The functions below follow the PEI_SMM_ACCESS_PPI and //
+EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices and This
+// pointers are removed (TSEG doesn't depend on them), and so is the //
+DescriptorIndex parameter (TSEG doesn't support range-wise locking).
+//
+// The LockState and OpenState members that are common to both //
+PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken and updated
+in // isolation from the rest of the (non-shared) members.
+//
+
+EFI_STATUS
+SmramAccessOpen (
+ OUT BOOLEAN *LockState,
+ OUT BOOLEAN *OpenState
+ )
+{
+
+ //
+ // Open TSEG by clearing T_EN.
+ //
+ PciAnd8(DRAMC_REGISTER_X58(MCH_TSEGMB),
+ (UINT8)((~(UINT32)MCH_ESMRAMC_T_EN) & 0xff));
+
+ gOpenState = TRUE;
+ gLockState = !gOpenState;
+
+ GetStates (LockState, OpenState);
+ if (!*OpenState) {
+ return EFI_DEVICE_ERROR;
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SmramAccessClose (
+ OUT BOOLEAN *LockState,
+ OUT BOOLEAN *OpenState
+ )
+{
+ //
+ // Close TSEG by setting T_EN.
+ //
+ PciOr8(DRAMC_REGISTER_X58(MCH_TSEGMB), MCH_ESMRAMC_T_EN);
+
+ gOpenState = FALSE;
+ gLockState = !gOpenState;
+
+ GetStates (LockState, OpenState);
+ if (*OpenState) {
+ return EFI_DEVICE_ERROR;
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SmramAccessLock (
+ OUT BOOLEAN *LockState,
+ IN OUT BOOLEAN *OpenState
+ )
+{
+ if (*OpenState) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Close & lock TSEG by setting T_EN and D_LCK.
+ //
+ PciOr8 (DRAMC_REGISTER_X58(MCH_TSEGMB), MCH_ESMRAMC_T_EN);
+
+ gOpenState = FALSE;
+ gLockState = !gOpenState;
+
+ GetStates (LockState, OpenState);
+ if (*OpenState || !*LockState) {
+ return EFI_DEVICE_ERROR;
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SmramAccessGetCapabilities (
+ IN BOOLEAN LockState,
+ IN BOOLEAN OpenState,
+ IN OUT UINTN *SmramMapSize,
+ IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
+ )
+{
+ UINTN OriginalSize;
+ UINT32 TsegMemoryBaseMb, TsegMemoryBase;
+ UINT64 CommonRegionState;
+ UINT8 TsegSizeBits;
+
+ OriginalSize = *SmramMapSize;
+ *SmramMapSize = DescIdxCount * sizeof *SmramMap; if (OriginalSize <
+ *SmramMapSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ //
+ // Read the TSEG Memory Base register.
+ //
+ TsegMemoryBaseMb = PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB));
+
+ TsegMemoryBaseMb = 0xDF800000;
+
+ TsegMemoryBase = (TsegMemoryBaseMb >> MCH_TSEGMB_MB_SHIFT) << 20;
+
+ //
+ // Precompute the region state bits that will be set for all regions.
+ //
+ CommonRegionState = (OpenState ? EFI_SMRAM_OPEN : EFI_SMRAM_CLOSED) |
+ (LockState ? EFI_SMRAM_LOCKED : 0) |
+ EFI_CACHEABLE;
+
+ //
+ // The first region hosts an SMM_S3_RESUME_STATE object. It is
+ located at the // start of TSEG. We round up the size to whole pages,
+ and we report it as // EFI_ALLOCATED, so that the SMM_CORE stays away from it.
+ //
+ SmramMap[DescIdxSmmS3ResumeState].PhysicalStart = TsegMemoryBase;
+ SmramMap[DescIdxSmmS3ResumeState].CpuStart = TsegMemoryBase;
+ SmramMap[DescIdxSmmS3ResumeState].PhysicalSize =
+ EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (sizeof (SMM_S3_RESUME_STATE)));
+ SmramMap[DescIdxSmmS3ResumeState].RegionState =
+ CommonRegionState | EFI_ALLOCATED;
+
+ //
+ // Get the TSEG size bits from the ESMRAMC register.
+ //
+ TsegSizeBits = PciRead8 (DRAMC_REGISTER_X58(MCH_TSEGMB)) &
+ MCH_ESMRAMC_TSEG_MASK;
+
+ TsegSizeBits = MCH_ESMRAMC_TSEG_8MB;
+
+ //
+ // The second region is the main one, following the first.
+ //
+ SmramMap[DescIdxMain].PhysicalStart =
+ SmramMap[DescIdxSmmS3ResumeState].PhysicalStart +
+ SmramMap[DescIdxSmmS3ResumeState].PhysicalSize;
+ SmramMap[DescIdxMain].CpuStart = SmramMap[DescIdxMain].PhysicalStart;
+ SmramMap[DescIdxMain].PhysicalSize =
+ (TsegSizeBits == MCH_ESMRAMC_TSEG_8MB ? SIZE_8MB :
+ TsegSizeBits == MCH_ESMRAMC_TSEG_2MB ? SIZE_2MB :
+ SIZE_1MB) - SmramMap[DescIdxSmmS3ResumeState].PhysicalSize;
+ SmramMap[DescIdxMain].RegionState = CommonRegionState;
+
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/SimicsX58SktPkg/Include/Register/X58SmramSaveStateMap.h b/Silicon/Intel/SimicsX58SktPkg/Include/Register/X58SmramSaveStateMap.h
new file mode 100644
index 0000000000..db8ee2c37a
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Include/Register/X58SmramSaveStateMa
+++ p.h
@@ -0,0 +1,178 @@
+/** @file
+SMRAM Save State Map Definitions.
+
+SMRAM Save State Map definitions based on contents of the
+Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+ Volume 3C, Section 34.4 SMRAM
+ Volume 3C, Section 34.5 SMI Handler Execution Environment
+ Volume 3C, Section 34.7 Managing Synchronous and Asynchronous SMIs
+
+and the AMD64 Architecture Programmer's Manual
+ Volume 2, Section 10.2 SMM Resources
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Red Hat, Inc.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef __X58_SMRAM_SAVE_STATE_MAP_H__
+#define __X58_SMRAM_SAVE_STATE_MAP_H__
+
+#pragma pack (1)
+
+///
+/// 32-bit SMRAM Save State Map
+///
+typedef struct {
+ UINT8 Reserved0[0x200]; // 7c00h
+ UINT8 Reserved1[0xf8]; // 7e00h
+ UINT32 SMBASE; // 7ef8h
+ UINT32 SMMRevId; // 7efch
+ UINT16 IORestart; // 7f00h
+ UINT16 AutoHALTRestart; // 7f02h
+ UINT8 Reserved2[0x9C]; // 7f08h
+ UINT32 IOMemAddr; // 7fa0h
+ UINT32 IOMisc; // 7fa4h
+ UINT32 _ES; // 7fa8h
+ UINT32 _CS; // 7fach
+ UINT32 _SS; // 7fb0h
+ UINT32 _DS; // 7fb4h
+ UINT32 _FS; // 7fb8h
+ UINT32 _GS; // 7fbch
+ UINT32 Reserved3; // 7fc0h
+ UINT32 _TR; // 7fc4h
+ UINT32 _DR7; // 7fc8h
+ UINT32 _DR6; // 7fcch
+ UINT32 _EAX; // 7fd0h
+ UINT32 _ECX; // 7fd4h
+ UINT32 _EDX; // 7fd8h
+ UINT32 _EBX; // 7fdch
+ UINT32 _ESP; // 7fe0h
+ UINT32 _EBP; // 7fe4h
+ UINT32 _ESI; // 7fe8h
+ UINT32 _EDI; // 7fech
+ UINT32 _EIP; // 7ff0h
+ UINT32 _EFLAGS; // 7ff4h
+ UINT32 _CR3; // 7ff8h
+ UINT32 _CR0; // 7ffch
+} X58_SMRAM_SAVE_STATE_MAP32;
+
+///
+/// 64-bit SMRAM Save State Map
+///
+typedef struct {
+ UINT8 Reserved0[0x200]; // 7c00h
+
+ UINT16 _ES; // 7e00h
+ UINT16 _ESAccessRights; // 7e02h
+ UINT32 _ESLimit; // 7e04h
+ UINT64 _ESBase; // 7e08h
+
+ UINT16 _CS; // 7e10h
+ UINT16 _CSAccessRights; // 7e12h
+ UINT32 _CSLimit; // 7e14h
+ UINT64 _CSBase; // 7e18h
+
+ UINT16 _SS; // 7e20h
+ UINT16 _SSAccessRights; // 7e22h
+ UINT32 _SSLimit; // 7e24h
+ UINT64 _SSBase; // 7e28h
+
+ UINT16 _DS; // 7e30h
+ UINT16 _DSAccessRights; // 7e32h
+ UINT32 _DSLimit; // 7e34h
+ UINT64 _DSBase; // 7e38h
+
+ UINT16 _FS; // 7e40h
+ UINT16 _FSAccessRights; // 7e42h
+ UINT32 _FSLimit; // 7e44h
+ UINT64 _FSBase; // 7e48h
+
+ UINT16 _GS; // 7e50h
+ UINT16 _GSAccessRights; // 7e52h
+ UINT32 _GSLimit; // 7e54h
+ UINT64 _GSBase; // 7e58h
+
+ UINT32 _GDTRReserved1; // 7e60h
+ UINT16 _GDTRLimit; // 7e64h
+ UINT16 _GDTRReserved2; // 7e66h
+ UINT64 _GDTRBase; // 7e68h
+
+ UINT16 _LDTR; // 7e70h
+ UINT16 _LDTRAccessRights; // 7e72h
+ UINT32 _LDTRLimit; // 7e74h
+ UINT64 _LDTRBase; // 7e78h
+
+ UINT32 _IDTRReserved1; // 7e80h
+ UINT16 _IDTRLimit; // 7e84h
+ UINT16 _IDTRReserved2; // 7e86h
+ UINT64 _IDTRBase; // 7e88h
+
+ UINT16 _TR; // 7e90h
+ UINT16 _TRAccessRights; // 7e92h
+ UINT32 _TRLimit; // 7e94h
+ UINT64 _TRBase; // 7e98h
+
+ UINT64 IO_RIP; // 7ea0h
+ UINT64 IO_RCX; // 7ea8h
+ UINT64 IO_RSI; // 7eb0h
+ UINT64 IO_RDI; // 7eb8h
+ UINT32 IO_DWord; // 7ec0h
+ UINT8 Reserved1[0x04]; // 7ec4h
+ UINT8 IORestart; // 7ec8h
+ UINT8 AutoHALTRestart; // 7ec9h
+ UINT8 Reserved2[0x06]; // 7ecah
+
+ UINT64 IA32_EFER; // 7ed0h
+ UINT64 SVM_Guest; // 7ed8h
+ UINT64 SVM_GuestVMCB; // 7ee0h
+ UINT64 SVM_GuestVIntr; // 7ee8h
+ UINT8 Reserved3[0x0c]; // 7ef0h
+
+ UINT32 SMMRevId; // 7efch
+ UINT32 SMBASE; // 7f00h
+
+ UINT8 Reserved4[0x1c]; // 7f04h
+ UINT64 SVM_GuestPAT; // 7f20h
+ UINT64 SVM_HostIA32_EFER; // 7f28h
+ UINT64 SVM_HostCR4; // 7f30h
+ UINT64 SVM_HostCR3; // 7f38h
+ UINT64 SVM_HostCR0; // 7f40h
+
+ UINT64 _CR4; // 7f48h
+ UINT64 _CR3; // 7f50h
+ UINT64 _CR0; // 7f58h
+ UINT64 _DR7; // 7f60h
+ UINT64 _DR6; // 7f68h
+ UINT64 _RFLAGS; // 7f70h
+ UINT64 _RIP; // 7f78h
+ UINT64 _R15; // 7f80h
+ UINT64 _R14; // 7f88h
+ UINT64 _R13; // 7f90h
+ UINT64 _R12; // 7f98h
+ UINT64 _R11; // 7fa0h
+ UINT64 _R10; // 7fa8h
+ UINT64 _R9; // 7fb0h
+ UINT64 _R8; // 7fb8h
+ UINT64 _RDI; // 7fc0h
+ UINT64 _RSI; // 7fc8h
+ UINT64 _RBP; // 7fd0h
+ UINT64 _RSP; // 7fd8h
+ UINT64 _RBX; // 7fe0h
+ UINT64 _RDX; // 7fe8h
+ UINT64 _RCX; // 7ff0h
+ UINT64 _RAX; // 7ff8h
+} X58_SMRAM_SAVE_STATE_MAP64;
+
+///
+/// Union of 32-bit and 64-bit SMRAM Save State Maps /// typedef union
+{
+ X58_SMRAM_SAVE_STATE_MAP32 x86;
+ X58_SMRAM_SAVE_STATE_MAP64 x64;
+} X58_SMRAM_SAVE_STATE_MAP;
+
+#pragma pack ()
+
+#endif
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPkg.dec b/Silicon/Intel/SimicsX58SktPkg/SktPkg.dec
new file mode 100644
index 0000000000..9fbc546167
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPkg.dec
@@ -0,0 +1,37 @@
+## @file
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = SimicsX58SktPkg
+ PACKAGE_GUID = 070FEC45-BF03-41C1-8D46-8BBE032A7C0C
+ PACKAGE_VERSION = 0.91
+
+[Includes]
+ Include
+
+[Guids]
+ gSimicsX58PkgTokenSpaceGuid = {0x5b276d20, 0x37d0, 0x4af0, {0x8d, 0x04, 0x47, 0x91, 0x2b, 0x7c, 0x1d, 0x44}}
+
+[PcdsFixedAtBuild]
+ ## The following setting controls how many megabytes we configure as
+TSEG on
+ # X58, for SMRAM purposes. Permitted values are: 1, 2, 8. Other
+values cause
+ # undefined behavior.
+ #
+ # This PCD is only consulted if PcdSmmSmramRequire is TRUE (see below).
+ gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes|8|UINT8|0x20
+
+[PcdsFeatureFlag]
+ ## This feature flag enables SMM/SMRAM support. Note that it also
+requires
+ # such support from the underlying QEMU instance; if that support is
+not
+ # present, the firmware will reject continuing after a certain point.
+ #
+ # The flag also acts as a general "security switch"; when TRUE, many
+ # components will change behavior, with the goal of preventing a
+malicious
+ # runtime OS from tampering with firmware structures (special memory
+ranges
+ # used by OVMF, the varstore pflash chip, LockBox etc).
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire|FALSE|BOOLEAN|0x1e
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc b/Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc
new file mode 100644
index 0000000000..af83c380b8
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc
@@ -0,0 +1,14 @@
+## @file
+# Component description file for the X58 SiPkg PEI drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+ #
+ # SEC Phase modules
+ #
+ UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
+ UefiCpuPkg/CpuMpPei/CpuMpPei.inf
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
new file mode 100644
index 0000000000..12e43e86d0
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
@@ -0,0 +1,9 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
new file mode 100644
index 0000000000..5b9cd9ee25
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
@@ -0,0 +1,10 @@
+## @file
+# Component description file for the X58 SiPkg PEI drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+INF UefiCpuPkg/CpuMpPei/CpuMpPei.inf
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
new file mode 100644
index 0000000000..5019e362e3
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
@@ -0,0 +1,16 @@
+## @file
+# Component description file for the X58 SiPkg PEI drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+#
+# SEC Phase modules
+#
+# The code in this FV handles the initial firmware startup, and #
+decompresses the PEI and DXE FVs which handles the rest of the boot sequence.
+#
+INF RuleOverride=RESET_VECTOR USE = IA32
+UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
new file mode 100644
index 0000000000..b38c3b1108
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
@@ -0,0 +1,14 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+ INF $(SKT_PKG)/Smm/Access/SmmAccess2Dxe.inf
+ INF UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+!endif
+INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
new file mode 100644
index 0000000000..eb8c8f93dd
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
@@ -0,0 +1,54 @@
+## @file
+# A DXE_DRIVER providing SMRAM access by producing EFI_SMM_ACCESS2_PROTOCOL.
+#
+# X58 TSEG is expected to have been verified and set up by the
+SmmAccessPei # driver.
+#
+# Copyright (C) 2013, 2015, Red Hat, Inc.
+# Copyright (C) 2019, Intel Corporation. All rights reserved.<BR> # #
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmmAccess2Dxe
+ FILE_GUID = AC95AD3D-4366-44BF-9A62-E4B29D7A2206
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010400
+ ENTRY_POINT = SmmAccess2DxeEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ SmmAccess2Dxe.c
+ SmramInternal.c
+ SmramInternal.h
+
+[Packages]
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ SimicsX58SktPkg/SktPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[LibraryClasses]
+ DebugLib
+ PcdLib
+ PciLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEfiSmmAccess2ProtocolGuid ## PRODUCES
+
+[FeaturePcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
+
+[Depex]
+ TRUE
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
new file mode 100644
index 0000000000..2b6b14f437
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
@@ -0,0 +1,65 @@
+## @file
+# A PEIM with the following responsibilities:
+#
+# - provide SMRAM access by producing PEI_SMM_ACCESS_PPI, # - verify &
+configure the X58 TSEG in the entry point, # - set aside the
+SMM_S3_RESUME_STATE object at the bottom of TSEG, and expose
+# it via the gEfiAcpiVariableGuid GUIDed HOB.
+#
+# Copyright (C) 2013, 2015, Red Hat, Inc.
+# Copyright (C) 2019, Intel Corporation. All rights reserved.<BR> # #
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmmAccessPei
+ FILE_GUID = 6C0E75B4-B0B9-44D1-8210-3377D7B4E066
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SmmAccessPeiEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ SmmAccessPei.c
+ SmramInternal.c
+ SmramInternal.h
+
+[Packages]
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ SimicsX58SktPkg/SktPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[Guids]
+ gEfiAcpiVariableGuid
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ HobLib
+ IoLib
+ PcdLib
+ PciLib
+ PeiServicesLib
+ PeimEntryPoint
+
+[FeaturePcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
+
+[FixedPcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes
+
+[Ppis]
+ gPeiSmmAccessPpiGuid ## PRODUCES
+
+[Depex]
+ gEfiPeiMemoryDiscoveredPpiGuid
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
new file mode 100644
index 0000000000..43a79b295f
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
@@ -0,0 +1,81 @@
+/** @file
+ Functions and types shared by the SMM accessor PEI and DXE modules.
+
+ Copyright (C) 2015, Red Hat, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#include <Pi/PiMultiPhase.h>
+
+//
+// We'll have two SMRAM ranges.
+//
+// The first is a tiny one that hosts an SMM_S3_RESUME_STATE object, to
+be // filled in by the CPU SMM driver during normal boot, for the PEI
+instance of // the LockBox library (which will rely on the object during S3 resume).
+//
+// The other SMRAM range is the main one, for the SMM core and the SMM drivers.
+//
+typedef enum {
+ DescIdxSmmS3ResumeState = 0,
+ DescIdxMain = 1,
+ DescIdxCount = 2
+} DESCRIPTOR_INDEX;
+
+/**
+ Read the MCH_SMRAM and ESMRAMC registers, and update the LockState
+and
+ OpenState fields in the PEI_SMM_ACCESS_PPI / EFI_SMM_ACCESS2_PROTOCOL
+object,
+ from the D_LCK and T_EN bits.
+
+ PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member functions can
+ rely on the LockState and OpenState fields being up-to-date on entry,
+ and they need to restore the same invariant on exit, if they touch the bits in question.
+
+ @param[out] LockState Reflects the D_LCK bit on output; TRUE iff SMRAM is
+ locked.
+ @param[out] OpenState Reflects the inverse of the T_EN bit on output; TRUE
+ iff SMRAM is open.
+**/
+VOID
+GetStates (
+ OUT BOOLEAN *LockState,
+ OUT BOOLEAN *OpenState
+ );
+
+//
+// The functions below follow the PEI_SMM_ACCESS_PPI and //
+EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices and This
+// pointers are removed (TSEG doesn't depend on them), and so is the //
+DescriptorIndex parameter (TSEG doesn't support range-wise locking).
+//
+// The LockState and OpenState members that are common to both //
+PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken and updated
+in // isolation from the rest of the (non-shared) members.
+//
+
+EFI_STATUS
+SmramAccessOpen (
+ OUT BOOLEAN *LockState,
+ OUT BOOLEAN *OpenState
+ );
+
+EFI_STATUS
+SmramAccessClose (
+ OUT BOOLEAN *LockState,
+ OUT BOOLEAN *OpenState
+ );
+
+EFI_STATUS
+SmramAccessLock (
+ OUT BOOLEAN *LockState,
+ IN OUT BOOLEAN *OpenState
+ );
+
+EFI_STATUS
+SmramAccessGetCapabilities (
+ IN BOOLEAN LockState,
+ IN BOOLEAN OpenState,
+ IN OUT UINTN *SmramMapSize,
+ IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
+ );
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [edk2-platforms PATCH v2 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10
2019-08-28 0:40 ` [edk2-platforms PATCH v2 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10 David Wei
@ 2019-08-28 22:02 ` Nate DeSimone
0 siblings, 0 replies; 16+ messages in thread
From: Nate DeSimone @ 2019-08-28 22:02 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Kubacki, Michael A, Kinney, Michael D
Update copyright year on X58Ich10.h
-----Original Message-----
From: Wei, David Y
Sent: Tuesday, August 27, 2019 5:40 PM
To: devel@edk2.groups.io
Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Kubacki, Michael A <michael.a.kubacki@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: [edk2-platforms PATCH v2 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10
Add PCH Pkg for SimicsICH10. It is added for simics QSP project support
Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../Library/ResetSystemLib/ResetSystemLib.c | 137 +++
.../Library/SmmSpiFlashCommonLib/SpiFlashCommon.c | 194 +++++
.../SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c | 54 ++
.../LibraryPrivate/BasePchSpiCommonLib/SpiCommon.c | 935 +++++++++++++++++++++
.../SmmControl/RuntimeDxe/SmmControl2Dxe.c | 410 +++++++++
Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.c | 175 ++++
Silicon/Intel/SimicsIch10Pkg/Ich10Pkg.dec | 26 +
Silicon/Intel/SimicsIch10Pkg/IchCommonLib.dsc | 12 +
.../Intel/SimicsIch10Pkg/IchPostMemoryInclude.fdf | 9 +
.../Intel/SimicsIch10Pkg/IchPreMemoryInclude.fdf | 9 +
.../Intel/SimicsIch10Pkg/IchUefiBootInclude.fdf | 13 +
.../Include/Library/SpiFlashCommonLib.h | 98 +++
Silicon/Intel/SimicsIch10Pkg/Include/PchAccess.h | 43 +
Silicon/Intel/SimicsIch10Pkg/Include/PchLimits.h | 94 +++
.../SimicsIch10Pkg/Include/PchReservedResources.h | 60 ++
.../Intel/SimicsIch10Pkg/Include/Protocol/Spi.h | 295 +++++++
.../SimicsIch10Pkg/Include/Register/PchRegsPmc.h | 647 ++++++++++++++
.../SimicsIch10Pkg/Include/Register/PchRegsSpi.h | 304 +++++++
.../SimicsIch10Pkg/Include/Register/X58Ich10.h | 113 +++
.../IncludePrivate/Library/PchSpiCommonLib.h | 396 +++++++++
.../Library/ResetSystemLib/ResetSystemLib.inf | 34 +
.../SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf | 50 ++
.../BasePchSpiCommonLib/BasePchSpiCommonLib.inf | 31 +
.../SmmControl/RuntimeDxe/SmmControl2Dxe.inf | 61 ++
Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.h | 23 +
Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpiSmm.inf | 44 +
26 files changed, 4267 insertions(+)
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.c
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c
create mode 100644 Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/SpiCommon.c
create mode 100644 Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.c
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.c
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Ich10Pkg.dec
create mode 100644 Silicon/Intel/SimicsIch10Pkg/IchCommonLib.dsc
create mode 100644 Silicon/Intel/SimicsIch10Pkg/IchPostMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/IchPreMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/IchUefiBootInclude.fdf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Library/SpiFlashCommonLib.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/PchAccess.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/PchLimits.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/PchReservedResources.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Protocol/Spi.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsPmc.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsSpi.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Include/Register/X58Ich10.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/IncludePrivate/Library/PchSpiCommonLib.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.inf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePchSpiCommonLib.inf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.h
create mode 100644 Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpiSmm.inf
diff --git a/Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.c b/Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.c
new file mode 100644
index 0000000000..ad3e4f455e
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.c
@@ -0,0 +1,137 @@
+/** @file
+ Reset System Library functions for Simics ICH10
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Register/X58Ich10.h>
+
+
+VOID
+AcpiPmControl (
+ UINTN SuspendType
+ )
+{
+ ASSERT (SuspendType < 6);
+ DEBUG((EFI_D_ERROR, "SuspendType = 0x%x\n", SuspendType));
+
+ IoBitFieldWrite16 (ICH10_PMBASE_IO + 4, 10, 13, (UINT16) SuspendType);
+ IoOr16 (ICH10_PMBASE_IO + 0x04, BIT13);
+ CpuDeadLoop ();
+}
+
+/**
+ Calling this function causes a system-wide reset. This sets
+ all circuitry within the system to its initial state. This type of reset
+ is asynchronous to system operation and operates without regard to
+ cycle boundaries.
+
+ System reset should not return, if it returns, it means the system does
+ not support cold reset.
+**/
+VOID
+EFIAPI
+ResetCold (
+ VOID
+ )
+{
+ DEBUG((EFI_D_ERROR, "ResetCold_CF9\n"));
+ IoWrite8 (0xCF9, BIT3 | BIT2 | BIT1); // 1st choice: PIIX3 RCR, RCPU|SRST
+ MicroSecondDelay (50);
+
+ DEBUG((EFI_D_ERROR, "ResetCold_Port64\n"));
+ IoWrite8 (0x64, 0xfe); // 2nd choice: keyboard controller
+ CpuDeadLoop ();
+}
+
+/**
+ Calling this function causes a system-wide initialization. The processors
+ are set to their initial state, and pending cycles are not corrupted.
+
+ System reset should not return, if it returns, it means the system does
+ not support warm reset.
+**/
+VOID
+EFIAPI
+ResetWarm (
+ VOID
+ )
+{
+ DEBUG((EFI_D_ERROR, "ResetWarm\n"));
+ //
+ //BUGBUG workaround for warm reset
+ //
+ IoWrite8(0xCF9, BIT2 | BIT1);
+ MicroSecondDelay(50);
+
+ IoWrite8 (0x64, 0xfe);
+ CpuDeadLoop ();
+}
+
+/**
+ Calling this function causes the system to enter a power state equivalent
+ to the ACPI G2/S5 or G3 states.
+
+ System shutdown should not return, if it returns, it means the system does
+ not support shut down reset.
+**/
+VOID
+EFIAPI
+ResetShutdown (
+ VOID
+ )
+{
+ DEBUG((EFI_D_ERROR, "ResetShutdown\n"));
+ AcpiPmControl (0);
+ ASSERT (FALSE);
+}
+
+
+/**
+ Calling this function causes the system to enter a power state for capsule
+ update.
+
+ Reset update should not return, if it returns, it means the system does
+ not support capsule update.
+
+**/
+VOID
+EFIAPI
+EnterS3WithImmediateWake (
+ VOID
+ )
+{
+ DEBUG((EFI_D_ERROR, "EnterS3WithImmediateWake\n"));
+ AcpiPmControl (1);
+ ASSERT (FALSE);
+}
+
+/**
+ This function causes a systemwide reset. The exact type of the reset is
+ defined by the EFI_GUID that follows the Null-terminated Unicode string passed
+ into ResetData. If the platform does not recognize the EFI_GUID in ResetData
+ the platform must pick a supported reset type to perform.The platform may
+ optionally log the parameters from any non-normal reset that occurs.
+
+ @param[in] DataSize The size, in bytes, of ResetData.
+ @param[in] ResetData The data buffer starts with a Null-terminated string,
+ followed by the EFI_GUID.
+**/
+VOID
+EFIAPI
+ResetPlatformSpecific (
+ IN UINTN DataSize,
+ IN VOID *ResetData
+ )
+{
+ DEBUG((EFI_D_ERROR, "ResetPlatformSpecific\n"));
+ ResetCold ();
+}
diff --git a/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c b/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c
new file mode 100644
index 0000000000..9e3461cbd6
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommon.c
@@ -0,0 +1,194 @@
+/** @file
+ Wrap EFI_SPI_PROTOCOL to provide some library level interfaces
+ for module use.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/SpiFlashCommonLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Protocol/Spi.h>
+
+
+EFI_SPI_PROTOCOL *mSpiProtocol;
+
+//
+// FlashAreaBaseAddress and Size for boottime and runtime usage.
+//
+UINTN mFlashAreaBaseAddress = 0;
+UINTN mFlashAreaSize = 0;
+
+/**
+ Enable block protection on the Serial Flash device.
+
+ @retval EFI_SUCCESS Opertion is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashLock (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ Read NumBytes bytes of data from the address specified by
+ PAddress into Buffer.
+
+ @param[in] Address The starting physical address of the read.
+ @param[in,out] NumBytes On input, the number of bytes to read. On output, the number
+ of bytes actually read.
+ @param[out] Buffer The destination data buffer for the read.
+
+ @retval EFI_SUCCESS Opertion is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashRead (
+ IN UINTN Address,
+ IN OUT UINT32 *NumBytes,
+ OUT UINT8 *Buffer
+ )
+{
+ ASSERT ((NumBytes != NULL) && (Buffer != NULL));
+ if ((NumBytes == NULL) || (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // This function is implemented specifically for those platforms
+ // at which the SPI device is memory mapped for read. So this
+ // function just do a memory copy for Spi Flash Read.
+ //
+ CopyMem (Buffer, (VOID *) Address, *NumBytes);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Write NumBytes bytes of data from Buffer to the address specified by
+ PAddresss.
+
+ @param[in] Address The starting physical address of the write.
+ @param[in,out] NumBytes On input, the number of bytes to write. On output,
+ the actual number of bytes written.
+ @param[in] Buffer The source data buffer for the write.
+
+ @retval EFI_SUCCESS Opertion is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashWrite (
+ IN UINTN Address,
+ IN OUT UINT32 *NumBytes,
+ IN UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN Offset;
+ UINT32 Length;
+ UINT32 RemainingBytes;
+
+ ASSERT ((NumBytes != NULL) && (Buffer != NULL));
+ if ((NumBytes == NULL) || (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ASSERT (Address >= mFlashAreaBaseAddress);
+
+ Offset = Address - mFlashAreaBaseAddress;
+
+ ASSERT ((*NumBytes + Offset) <= mFlashAreaSize);
+
+ Status = EFI_SUCCESS;
+ RemainingBytes = *NumBytes;
+
+
+ while (RemainingBytes > 0) {
+ if (RemainingBytes > SECTOR_SIZE_4KB) {
+ Length = SECTOR_SIZE_4KB;
+ } else {
+ Length = RemainingBytes;
+ }
+ Status = mSpiProtocol->FlashWrite (
+ mSpiProtocol,
+ FlashRegionBios,
+ (UINT32) Offset,
+ Length,
+ Buffer
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ RemainingBytes -= Length;
+ Offset += Length;
+ Buffer += Length;
+ }
+
+ //
+ // Actual number of bytes written
+ //
+ *NumBytes -= RemainingBytes;
+
+ return Status;
+}
+
+/**
+ Erase the block starting at Address.
+
+ @param[in] Address The starting physical address of the block to be erased.
+ This library assume that caller garantee that the PAddress
+ is at the starting address of this block.
+ @param[in] NumBytes On input, the number of bytes of the logical block to be erased.
+ On output, the actual number of bytes erased.
+
+ @retval EFI_SUCCESS. Opertion is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashBlockErase (
+ IN UINTN Address,
+ IN UINTN *NumBytes
+ )
+{
+ EFI_STATUS Status;
+ UINTN Offset;
+ UINTN RemainingBytes;
+
+ ASSERT (NumBytes != NULL);
+ if (NumBytes == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ASSERT (Address >= mFlashAreaBaseAddress);
+
+ Offset = Address - mFlashAreaBaseAddress;
+
+ ASSERT ((*NumBytes % SECTOR_SIZE_4KB) == 0);
+ ASSERT ((*NumBytes + Offset) <= mFlashAreaSize);
+
+ Status = EFI_SUCCESS;
+ RemainingBytes = *NumBytes;
+
+
+ Status = mSpiProtocol->FlashErase (
+ mSpiProtocol,
+ FlashRegionBios,
+ (UINT32) Offset,
+ (UINT32) RemainingBytes
+ );
+ return Status;
+}
+
diff --git a/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c b/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c
new file mode 100644
index 0000000000..984b7733c6
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommonSmmLib.c
@@ -0,0 +1,54 @@
+/** @file
+ SMM Library instance of SPI Flash Common Library Class
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/SpiFlashCommonLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Protocol/Spi.h>
+
+extern EFI_SPI_PROTOCOL *mSpiProtocol;
+
+extern UINTN mFlashAreaBaseAddress;
+extern UINTN mFlashAreaSize;
+
+/**
+ The library constructuor.
+
+ The function does the necessary initialization work for this library
+ instance.
+
+ @param[in] ImageHandle The firmware allocated handle for the UEFI image.
+ @param[in] SystemTable A pointer to the EFI system table.
+
+ @retval EFI_SUCCESS The function always return EFI_SUCCESS for now.
+ It will ASSERT on error for debug version.
+ @retval EFI_ERROR Please reference LocateProtocol for error code details.
+**/
+EFI_STATUS
+EFIAPI
+SmmSpiFlashCommonLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ mFlashAreaBaseAddress = (UINTN)PcdGet32 (PcdFlashAreaBaseAddress);
+ mFlashAreaSize = (UINTN)PcdGet32 (PcdFlashAreaSize);
+
+ //
+ // Locate the SMM SPI protocol.
+ //
+ Status = gSmst->SmmLocateProtocol (
+ &gEfiSmmSpiProtocolGuid,
+ NULL,
+ (VOID **) &mSpiProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/SpiCommon.c b/Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/SpiCommon.c
new file mode 100644
index 0000000000..bd08b2453b
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/SpiCommon.c
@@ -0,0 +1,935 @@
+/** @file
+ PCH SPI Common Driver implements the SPI Host Controller Compatibility Interface.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <PchAccess.h>
+#include <Protocol/Spi.h>
+#include <IncludePrivate/Library/PchSpiCommonLib.h>
+#include <Register/X58Ich10.h>
+
+/**
+ Initialize an SPI protocol instance.
+
+ @param[in] SpiInstance Pointer to SpiInstance to initialize
+
+ @retval EFI_SUCCESS The protocol instance was properly initialized
+ @exception EFI_UNSUPPORTED The PCH is not supported by this module
+**/
+EFI_STATUS
+SpiProtocolConstructor (
+ IN SPI_INSTANCE *SpiInstance
+ )
+{
+ UINTN PchSpiBar0;
+
+ //
+ // Initialize the SPI protocol instance
+ //
+ SpiInstance->Signature = PCH_SPI_PRIVATE_DATA_SIGNATURE;
+ SpiInstance->Handle = NULL;
+ SpiInstance->SpiProtocol.Revision = PCH_SPI_SERVICES_REVISION;
+ SpiInstance->SpiProtocol.FlashRead = SpiProtocolFlashRead;
+ SpiInstance->SpiProtocol.FlashWrite = SpiProtocolFlashWrite;
+ SpiInstance->SpiProtocol.FlashErase = SpiProtocolFlashErase;
+ SpiInstance->SpiProtocol.FlashReadSfdp = SpiProtocolFlashReadSfdp;
+ SpiInstance->SpiProtocol.FlashReadJedecId = SpiProtocolFlashReadJedecId;
+ SpiInstance->SpiProtocol.FlashWriteStatus = SpiProtocolFlashWriteStatus;
+ SpiInstance->SpiProtocol.FlashReadStatus = SpiProtocolFlashReadStatus;
+ SpiInstance->SpiProtocol.GetRegionAddress = SpiProtocolGetRegionAddress;
+ SpiInstance->SpiProtocol.ReadPchSoftStrap = SpiProtocolReadPchSoftStrap;
+ SpiInstance->SpiProtocol.ReadCpuSoftStrap = SpiProtocolReadCpuSoftStrap;
+
+ SpiInstance->PchAcpiBase = ICH10_PMBASE_IO;
+ ASSERT (SpiInstance->PchAcpiBase != 0);
+
+ PchSpiBar0 = RCRB + SPIBAR;
+
+ if (PchSpiBar0 == 0) {
+ DEBUG ((DEBUG_ERROR, "ERROR : PchSpiBar0 is invalid!\n"));
+ ASSERT (FALSE);
+ }
+
+ if ((MmioRead32 (PchSpiBar0 + R_PCH_SPI_HSFSC) & B_PCH_SPI_HSFSC_FDV) == 0) {
+ DEBUG ((DEBUG_ERROR, "ERROR : SPI Flash Signature invalid, cannot use the Hardware Sequencing registers!\n"));
+ ASSERT (FALSE);
+ }
+ SpiInstance->ReadPermission = 0xffff;
+ SpiInstance->WritePermission = 0xffff;
+ DEBUG ((DEBUG_INFO, "Flash Region Permission: Read- 0x%04x; Write= 0x%04x\n",
+ SpiInstance->ReadPermission,
+ SpiInstance->WritePermission));
+
+ //
+ SpiInstance->TotalFlashSize = PcdGet32(PcdFlashAreaSize);
+ DEBUG ((DEBUG_INFO, "Total Flash Size : %0x\n", SpiInstance->TotalFlashSize));
+ return EFI_SUCCESS;
+}
+
+/**
+ Delay for at least the request number of microseconds for Runtime usage.
+
+ @param[in] ABase Acpi base address
+ @param[in] Microseconds Number of microseconds to delay.
+
+**/
+VOID
+EFIAPI
+PchPmTimerStallRuntimeSafe (
+ IN UINT16 ABase,
+ IN UINTN Microseconds
+ )
+{
+ UINTN Ticks;
+ UINTN Counts;
+ UINTN CurrentTick;
+ UINTN OriginalTick;
+ UINTN RemainingTick;
+
+ if (Microseconds == 0) {
+ return;
+ }
+
+ OriginalTick = IoRead32 ((UINTN) (ABase + R_PCH_ACPI_PM1_TMR)) & B_PCH_ACPI_PM1_TMR_VAL;
+ CurrentTick = OriginalTick;
+
+ //
+ // The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks
+ //
+ Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
+
+ //
+ // The loops needed by timer overflow
+ //
+ Counts = Ticks / V_PCH_ACPI_PM1_TMR_MAX_VAL;
+
+ //
+ // Remaining clocks within one loop
+ //
+ RemainingTick = Ticks % V_PCH_ACPI_PM1_TMR_MAX_VAL;
+
+ //
+ // not intend to use TMROF_STS bit of register PM1_STS, because this adds extra
+ // one I/O operation, and maybe generate SMI
+ //
+ while ((Counts != 0) || (RemainingTick > CurrentTick)) {
+ CurrentTick = IoRead32 ((UINTN) (ABase + R_PCH_ACPI_PM1_TMR)) & B_PCH_ACPI_PM1_TMR_VAL;
+ //
+ // Check if timer overflow
+ //
+ if ((CurrentTick < OriginalTick)) {
+ if (Counts != 0) {
+ Counts--;
+ } else {
+ //
+ // If timer overflow and Counts equ to 0, that means we already stalled more than
+ // RemainingTick, break the loop here
+ //
+ break;
+ }
+ }
+
+ OriginalTick = CurrentTick;
+ }
+}
+
+/**
+ Read data from the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+ @param[out] Buffer The Pointer to caller-allocated buffer containing the dada received.
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashRead (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ OUT UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Sends the command to the SPI interface to execute.
+ //
+ Status = SendSpiCmd (
+ This,
+ FlashRegionType,
+ FlashCycleRead,
+ Address,
+ ByteCount,
+ Buffer
+ );
+ return Status;
+}
+
+/**
+ Write data to the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+ @param[in] Buffer Pointer to caller-allocated buffer containing the data sent during the SPI cycle.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashWrite (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ IN UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Sends the command to the SPI interface to execute.
+ //
+ Status = SendSpiCmd (
+ This,
+ FlashRegionType,
+ FlashCycleWrite,
+ Address,
+ ByteCount,
+ Buffer
+ );
+ return Status;
+}
+
+/**
+ Erase some area on the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashErase (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Sends the command to the SPI interface to execute.
+ //
+ Status = SendSpiCmd (
+ This,
+ FlashRegionType,
+ FlashCycleErase,
+ Address,
+ ByteCount,
+ NULL
+ );
+ return Status;
+}
+
+/**
+ Read SFDP data from the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ComponentNumber The Componen Number for chip select
+ @param[in] Address The starting byte address for SFDP data read.
+ @param[in] ByteCount Number of bytes in SFDP data portion of the SPI cycle
+ @param[out] SfdpData The Pointer to caller-allocated buffer containing the SFDP data received
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadSfdp (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT8 ComponentNumber,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ OUT UINT8 *SfdpData
+ )
+{
+ SPI_INSTANCE *SpiInstance;
+ EFI_STATUS Status;
+ UINT32 FlashAddress;
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+ Status = EFI_SUCCESS;
+
+ if (ComponentNumber > SpiInstance->NumberOfComponents) {
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FlashAddress = 0;
+ if (ComponentNumber == FlashComponent1) {
+ FlashAddress = SpiInstance->Component1StartAddr;
+ }
+ FlashAddress += Address;
+ //
+ // Sends the command to the SPI interface to execute.
+ //
+ Status = SendSpiCmd (
+ This,
+ FlashRegionAll,
+ FlashCycleReadSfdp,
+ FlashAddress,
+ ByteCount,
+ SfdpData
+ );
+ return Status;
+}
+
+/**
+ Read Jedec Id from the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ComponentNumber The Componen Number for chip select
+ @param[in] ByteCount Number of bytes in JedecId data portion of the SPI cycle, the data size is 3 typically
+ @param[out] JedecId The Pointer to caller-allocated buffer containing JEDEC ID received
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadJedecId (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT8 ComponentNumber,
+ IN UINT32 ByteCount,
+ OUT UINT8 *JedecId
+ )
+{
+ SPI_INSTANCE *SpiInstance;
+ EFI_STATUS Status;
+ UINT32 Address;
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+ Status = EFI_SUCCESS;
+
+ if (ComponentNumber > SpiInstance->NumberOfComponents) {
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Address = 0;
+ if (ComponentNumber == FlashComponent1) {
+ Address = SpiInstance->Component1StartAddr;
+ }
+
+ //
+ // Sends the command to the SPI interface to execute.
+ //
+ Status = SendSpiCmd (
+ This,
+ FlashRegionAll,
+ FlashCycleReadJedecId,
+ Address,
+ ByteCount,
+ JedecId
+ );
+ return Status;
+}
+
+/**
+ Write the status register in the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ByteCount Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+ @param[in] StatusValue The Pointer to caller-allocated buffer containing the value of Status register writing
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashWriteStatus (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 ByteCount,
+ IN UINT8 *StatusValue
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Sends the command to the SPI interface to execute.
+ //
+ Status = SendSpiCmd (
+ This,
+ FlashRegionAll,
+ FlashCycleWriteStatus,
+ 0,
+ ByteCount,
+ StatusValue
+ );
+ return Status;
+}
+
+/**
+ Read status register in the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ByteCount Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+ @param[out] StatusValue The Pointer to caller-allocated buffer containing the value of Status register received.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadStatus (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 ByteCount,
+ OUT UINT8 *StatusValue
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Sends the command to the SPI interface to execute.
+ //
+ Status = SendSpiCmd (
+ This,
+ FlashRegionAll,
+ FlashCycleReadStatus,
+ 0,
+ ByteCount,
+ StatusValue
+ );
+ return Status;
+}
+
+/**
+ Get the SPI region base and size, based on the enum type
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for for the base address which is listed in the Descriptor.
+ @param[out] BaseAddress The Flash Linear Address for the Region 'n' Base
+ @param[out] RegionSize The size for the Region 'n'
+
+ @retval EFI_SUCCESS Read success
+ @retval EFI_INVALID_PARAMETER Invalid region type given
+ @retval EFI_DEVICE_ERROR The region is not used
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolGetRegionAddress (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ OUT UINT32 *BaseAddress,
+ OUT UINT32 *RegionSize
+ )
+{
+ SPI_INSTANCE *SpiInstance;
+ UINTN PchSpiBar0;
+ UINT32 ReadValue;
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+
+ if (FlashRegionType >= FlashRegionMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (FlashRegionType == FlashRegionAll) {
+ *BaseAddress = 0;
+ *RegionSize = SpiInstance->TotalFlashSize;
+ return EFI_SUCCESS;
+ }
+
+ PchSpiBar0 = AcquireSpiBar0 (SpiInstance);
+ ReadValue = MmioRead32 (PchSpiBar0 + (R_PCH_SPI_FREG0_FLASHD + (S_PCH_SPI_FREGX * ((UINT32) FlashRegionType))));
+ ReleaseSpiBar0 (SpiInstance);
+
+ //
+ // If the region is not used, the Region Base is 7FFFh and Region Limit is 0000h
+ //
+ if (ReadValue == B_PCH_SPI_FREGX_BASE_MASK) {
+ return EFI_DEVICE_ERROR;
+ }
+ *BaseAddress = ((ReadValue & B_PCH_SPI_FREGX_BASE_MASK) >> N_PCH_SPI_FREGX_BASE) <<
+ N_PCH_SPI_FREGX_BASE_REPR;
+ //
+ // Region limit address Bits[11:0] are assumed to be FFFh
+ //
+ *RegionSize = ((((ReadValue & B_PCH_SPI_FREGX_LIMIT_MASK) >> N_PCH_SPI_FREGX_LIMIT) + 1) <<
+ N_PCH_SPI_FREGX_LIMIT_REPR) - *BaseAddress;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Read PCH Soft Strap Values
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] SoftStrapAddr PCH Soft Strap address offset from FPSBA.
+ @param[in] ByteCount Number of bytes in SoftStrap data portion of the SPI cycle
+ @param[out] SoftStrapValue The Pointer to caller-allocated buffer containing PCH Soft Strap Value.
+ If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolReadPchSoftStrap (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 SoftStrapAddr,
+ IN UINT32 ByteCount,
+ OUT VOID *SoftStrapValue
+ )
+{
+ SPI_INSTANCE *SpiInstance;
+ UINT32 StrapFlashAddr;
+ EFI_STATUS Status;
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+
+ if (ByteCount == 0) {
+ *(UINT16 *) SoftStrapValue = SpiInstance->PchStrapSize;
+ return EFI_SUCCESS;
+ }
+
+ if ((SoftStrapAddr + ByteCount) > (UINT32) SpiInstance->PchStrapSize) {
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // PCH Strap Flash Address = FPSBA + RamAddr
+ //
+ StrapFlashAddr = SpiInstance->PchStrapBaseAddr + SoftStrapAddr;
+
+ //
+ // Read PCH Soft straps from using execute command
+ //
+ Status = SendSpiCmd (
+ This,
+ FlashRegionDescriptor,
+ FlashCycleRead,
+ StrapFlashAddr,
+ ByteCount,
+ SoftStrapValue
+ );
+ return Status;
+}
+
+/**
+ Read CPU Soft Strap Values
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] SoftStrapAddr CPU Soft Strap address offset from FCPUSBA.
+ @param[in] ByteCount Number of bytes in SoftStrap data portion of the SPI cycle.
+ @param[out] SoftStrapValue The Pointer to caller-allocated buffer containing CPU Soft Strap Value.
+ If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolReadCpuSoftStrap (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 SoftStrapAddr,
+ IN UINT32 ByteCount,
+ OUT VOID *SoftStrapValue
+ )
+{
+ SPI_INSTANCE *SpiInstance;
+ UINT32 StrapFlashAddr;
+ EFI_STATUS Status;
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+
+ if (ByteCount == 0) {
+ *(UINT16 *) SoftStrapValue = SpiInstance->CpuStrapSize;
+ return EFI_SUCCESS;
+ }
+
+ if ((SoftStrapAddr + ByteCount) > (UINT32) SpiInstance->CpuStrapSize) {
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // CPU Strap Flash Address = FCPUSBA + RamAddr
+ //
+ StrapFlashAddr = SpiInstance->CpuStrapBaseAddr + SoftStrapAddr;
+
+ //
+ // Read Cpu Soft straps from using execute command
+ //
+ Status = SendSpiCmd (
+ This,
+ FlashRegionDescriptor,
+ FlashCycleRead,
+ StrapFlashAddr,
+ ByteCount,
+ SoftStrapValue
+ );
+ return Status;
+}
+
+/**
+ This function sends the programmed SPI command to the slave device.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] SpiRegionType The SPI Region type for flash cycle which is listed in the Descriptor
+ @param[in] FlashCycleType The Flash SPI cycle type list in HSFC (Hardware Sequencing Flash Control Register) register
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+ @param[in,out] Buffer Pointer to caller-allocated buffer containing the dada received or sent during the SPI cycle.
+
+ @retval EFI_SUCCESS SPI command completes successfully.
+ @retval EFI_DEVICE_ERROR Device error, the command aborts abnormally.
+ @retval EFI_ACCESS_DENIED Some unrecognized command encountered in hardware sequencing mode
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+**/
+EFI_STATUS
+SendSpiCmd (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN FLASH_CYCLE_TYPE FlashCycleType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ IN OUT UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Index;
+ SPI_INSTANCE *SpiInstance;
+ UINTN SpiBaseAddress;
+ UINTN PchSpiBar0;
+ UINT32 HardwareSpiAddr;
+ UINT32 FlashRegionSize;
+ UINT32 SpiDataCount;
+ UINT32 FlashCycle;
+ UINT32 SmiEnSave;
+ UINT16 ABase;
+
+ Status = EFI_SUCCESS;
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+ SpiBaseAddress = SpiInstance->PchSpiBase;
+ PchSpiBar0 = AcquireSpiBar0 (SpiInstance);
+ SpiBaseAddress = SpiInstance->PchSpiBase;
+ ABase = SpiInstance->PchAcpiBase;
+
+ //
+ // Disable SMIs to make sure normal mode flash access is not interrupted by an SMI
+ // whose SMI handler accesses flash (e.g. for error logging)
+ //
+ // *** NOTE: if the SMI_LOCK bit is set (i.e., PMC PCI Offset A0h [4]='1'),
+ // clearing B_GBL_SMI_EN will not have effect. In this situation, some other
+ // synchronization methods must be applied here or in the consumer of the
+ // SendSpiCmd. An example method is disabling the specific SMI sources
+ // whose SMI handlers access flash before flash cycle and re-enabling the SMI
+ // sources after the flash cycle .
+ //
+ SmiEnSave = IoRead32 ((UINTN) (ABase + R_PCH_SMI_EN));
+ IoWrite32 ((UINTN) (ABase + R_PCH_SMI_EN), SmiEnSave & (UINT32) (~B_PCH_SMI_EN_GBL_SMI));
+
+ //
+ // If it's write cycle, disable Prefetching, Caching and disable BIOS Write Protect
+ //
+ if ((FlashCycleType == FlashCycleWrite) ||
+ (FlashCycleType == FlashCycleErase)) {
+ Status = DisableBiosWriteProtect ();
+ if (EFI_ERROR (Status)) {
+ goto SendSpiCmdEnd;
+ }
+ }
+ //
+ // Make sure it's safe to program the command.
+ //
+ if (!WaitForSpiCycleComplete (This, PchSpiBar0, FALSE)) {
+ Status = EFI_DEVICE_ERROR;
+ goto SendSpiCmdEnd;
+ }
+
+ Status = SpiProtocolGetRegionAddress (This, FlashRegionType, &HardwareSpiAddr, &FlashRegionSize);
+ if (EFI_ERROR (Status)) {
+ goto SendSpiCmdEnd;
+ }
+ HardwareSpiAddr += Address;
+ if ((Address + ByteCount) > FlashRegionSize) {
+ Status = EFI_INVALID_PARAMETER;
+ goto SendSpiCmdEnd;
+ }
+
+ //
+ // Check for PCH SPI hardware sequencing required commands
+ //
+ FlashCycle = 0;
+ switch (FlashCycleType) {
+ case FlashCycleRead:
+ FlashCycle = (UINT32) (V_PCH_SPI_HSFSC_CYCLE_READ << N_PCH_SPI_HSFSC_CYCLE);
+ break;
+ case FlashCycleWrite:
+ FlashCycle = (UINT32) (V_PCH_SPI_HSFSC_CYCLE_WRITE << N_PCH_SPI_HSFSC_CYCLE);
+ break;
+ case FlashCycleErase:
+ if (((ByteCount % SIZE_4KB) != 0) ||
+ ((HardwareSpiAddr % SIZE_4KB) != 0)) {
+ ASSERT (FALSE);
+ Status = EFI_INVALID_PARAMETER;
+ goto SendSpiCmdEnd;
+ }
+ break;
+ case FlashCycleReadSfdp:
+ FlashCycle = (UINT32) (V_PCH_SPI_HSFSC_CYCLE_READ_SFDP << N_PCH_SPI_HSFSC_CYCLE);
+ break;
+ case FlashCycleReadJedecId:
+ FlashCycle = (UINT32) (V_PCH_SPI_HSFSC_CYCLE_READ_JEDEC_ID << N_PCH_SPI_HSFSC_CYCLE);
+ break;
+ case FlashCycleWriteStatus:
+ FlashCycle = (UINT32) (V_PCH_SPI_HSFSC_CYCLE_WRITE_STATUS << N_PCH_SPI_HSFSC_CYCLE);
+ break;
+ case FlashCycleReadStatus:
+ FlashCycle = (UINT32) (V_PCH_SPI_HSFSC_CYCLE_READ_STATUS << N_PCH_SPI_HSFSC_CYCLE);
+ break;
+ default:
+ //
+ // Unrecognized Operation
+ //
+ ASSERT (FALSE);
+ Status = EFI_INVALID_PARAMETER;
+ goto SendSpiCmdEnd;
+ break;
+ }
+
+ do {
+ SpiDataCount = ByteCount;
+ if ((FlashCycleType == FlashCycleRead) ||
+ (FlashCycleType == FlashCycleWrite) ||
+ (FlashCycleType == FlashCycleReadSfdp)) {
+ //
+ // Trim at 256 byte boundary per operation,
+ // - PCH SPI controller requires trimming at 4KB boundary
+ // - Some SPI chips require trimming at 256 byte boundary for write operation
+ // - Trimming has limited performance impact as we can read / write atmost 64 byte
+ // per operation
+ //
+ if (HardwareSpiAddr + ByteCount > ((HardwareSpiAddr + BIT8) &~(BIT8 - 1))) {
+ SpiDataCount = (((UINT32) (HardwareSpiAddr) + BIT8) &~(BIT8 - 1)) - (UINT32) (HardwareSpiAddr);
+ }
+ //
+ // Calculate the number of bytes to shift in/out during the SPI data cycle.
+ // Valid settings for the number of bytes duing each data portion of the
+ // PCH SPI cycles are: 0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 24, 32, 40, 48, 56, 64
+ //
+ if (SpiDataCount >= 64) {
+ SpiDataCount = 64;
+ } else if ((SpiDataCount &~0x07) != 0) {
+ SpiDataCount = SpiDataCount &~0x07;
+ }
+ }
+ if (FlashCycleType == FlashCycleErase) {
+ if (((ByteCount / SIZE_64KB) != 0) &&
+ ((ByteCount % SIZE_64KB) == 0) &&
+ ((HardwareSpiAddr % SIZE_64KB) == 0)) {
+ if (HardwareSpiAddr < SpiInstance->Component1StartAddr) {
+ //
+ // Check whether Component0 support 64k Erase
+ //
+ if ((SpiInstance->SfdpVscc0Value & B_PCH_SPI_SFDPX_VSCCX_EO_64K) != 0) {
+ SpiDataCount = SIZE_64KB;
+ } else {
+ SpiDataCount = SIZE_4KB;
+ }
+ } else {
+ //
+ // Check whether Component1 support 64k Erase
+ //
+ if ((SpiInstance->SfdpVscc1Value & B_PCH_SPI_SFDPX_VSCCX_EO_64K) != 0) {
+ SpiDataCount = SIZE_64KB;
+ } else {
+ SpiDataCount = SIZE_4KB;
+ }
+ }
+ } else {
+ SpiDataCount = SIZE_4KB;
+ }
+ if (SpiDataCount == SIZE_4KB) {
+ FlashCycle = (UINT32) (V_PCH_SPI_HSFSC_CYCLE_4K_ERASE << N_PCH_SPI_HSFSC_CYCLE);
+ } else {
+ FlashCycle = (UINT32) (V_PCH_SPI_HSFSC_CYCLE_64K_ERASE << N_PCH_SPI_HSFSC_CYCLE);
+ }
+ }
+ //
+ // If it's write cycle, load data into the SPI data buffer.
+ //
+ if ((FlashCycleType == FlashCycleWrite) || (FlashCycleType == FlashCycleWriteStatus)) {
+ if ((SpiDataCount & 0x07) != 0) {
+ //
+ // Use Byte write if Data Count is 0, 1, 2, 3, 4, 5, 6, 7
+ //
+ for (Index = 0; Index < SpiDataCount; Index++) {
+ MmioWrite8 (PchSpiBar0 + R_PCH_SPI_FDATA00 + Index, Buffer[Index]);
+ }
+ } else {
+ //
+ // Use Dword write if Data Count is 8, 16, 24, 32, 40, 48, 56, 64
+ //
+ for (Index = 0; Index < SpiDataCount; Index += sizeof (UINT32)) {
+ MmioWrite32 (PchSpiBar0 + R_PCH_SPI_FDATA00 + Index, *(UINT32 *) (Buffer + Index));
+ }
+ }
+ }
+
+ //
+ // Set the Flash Address
+ //
+ MmioWrite32 (
+ (PchSpiBar0 + R_PCH_SPI_FADDR),
+ (UINT32) (HardwareSpiAddr & B_PCH_SPI_FADDR_MASK)
+ );
+
+ //
+ // Set Data count, Flash cycle, and Set Go bit to start a cycle
+ //
+ MmioAndThenOr32 (
+ PchSpiBar0 + R_PCH_SPI_HSFSC,
+ (UINT32) (~(B_PCH_SPI_HSFSC_FDBC_MASK | B_PCH_SPI_HSFSC_CYCLE_MASK)),
+ (UINT32) ((((SpiDataCount - 1) << N_PCH_SPI_HSFSC_FDBC) & B_PCH_SPI_HSFSC_FDBC_MASK) | FlashCycle | B_PCH_SPI_HSFSC_CYCLE_FGO)
+ );
+ //
+ // end of command execution
+ //
+ // Wait the SPI cycle to complete.
+ //
+ if (!WaitForSpiCycleComplete (This, PchSpiBar0, TRUE)) {
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ goto SendSpiCmdEnd;
+ }
+ //
+ // If it's read cycle, load data into the call's buffer.
+ //
+ if ((FlashCycleType == FlashCycleRead) ||
+ (FlashCycleType == FlashCycleReadSfdp) ||
+ (FlashCycleType == FlashCycleReadJedecId) ||
+ (FlashCycleType == FlashCycleReadStatus)) {
+ if ((SpiDataCount & 0x07) != 0) {
+ //
+ // Use Byte read if Data Count is 0, 1, 2, 3, 4, 5, 6, 7
+ //
+ for (Index = 0; Index < SpiDataCount; Index++) {
+ Buffer[Index] = MmioRead8 (PchSpiBar0 + R_PCH_SPI_FDATA00 + Index);
+ }
+ } else {
+ //
+ // Use Dword read if Data Count is 8, 16, 24, 32, 40, 48, 56, 64
+ //
+ for (Index = 0; Index < SpiDataCount; Index += sizeof (UINT32)) {
+ *(UINT32 *) (Buffer + Index) = MmioRead32 (PchSpiBar0 + R_PCH_SPI_FDATA00 + Index);
+ }
+ }
+ }
+
+ HardwareSpiAddr += SpiDataCount;
+ Buffer += SpiDataCount;
+ ByteCount -= SpiDataCount;
+ } while (ByteCount > 0);
+
+SendSpiCmdEnd:
+ //
+ // Restore the settings for SPI Prefetching and Caching and enable BIOS Write Protect
+ //
+ if ((FlashCycleType == FlashCycleWrite) ||
+ (FlashCycleType == FlashCycleErase)) {
+ EnableBiosWriteProtect ();
+ }
+ //
+ // Restore SMIs.
+ //
+ IoWrite32 ((UINTN) (ABase + R_PCH_SMI_EN), SmiEnSave);
+
+ ReleaseSpiBar0 (SpiInstance);
+ return Status;
+}
+
+/**
+ Wait execution cycle to complete on the SPI interface.
+
+ @param[in] This The SPI protocol instance
+ @param[in] PchSpiBar0 Spi MMIO base address
+ @param[in] ErrorCheck TRUE if the SpiCycle needs to do the error check
+
+ @retval TRUE SPI cycle completed on the interface.
+ @retval FALSE Time out while waiting the SPI cycle to complete.
+ It's not safe to program the next command on the SPI interface.
+**/
+BOOLEAN
+WaitForSpiCycleComplete (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINTN PchSpiBar0,
+ IN BOOLEAN ErrorCheck
+ )
+{
+ UINT64 WaitTicks;
+ UINT64 WaitCount;
+ UINT32 Data32;
+ SPI_INSTANCE *SpiInstance;
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+
+ //
+ // Convert the wait period allowed into to tick count
+ //
+ WaitCount = SPI_WAIT_TIME / SPI_WAIT_PERIOD;
+ //
+ // Wait for the SPI cycle to complete.
+ //
+ for (WaitTicks = 0; WaitTicks < WaitCount; WaitTicks++) {
+ Data32 = MmioRead32 (PchSpiBar0 + R_PCH_SPI_HSFSC);
+ if ((Data32 & B_PCH_SPI_HSFSC_SCIP) == 0) {
+ MmioWrite32 (PchSpiBar0 + R_PCH_SPI_HSFSC, B_PCH_SPI_HSFSC_FCERR | B_PCH_SPI_HSFSC_FDONE);
+ if (((Data32 & B_PCH_SPI_HSFSC_FCERR) != 0) && (ErrorCheck == TRUE)) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+ }
+ PchPmTimerStallRuntimeSafe (SpiInstance->PchAcpiBase, SPI_WAIT_PERIOD);
+ }
+ return FALSE;
+}
diff --git a/Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.c b/Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.c
new file mode 100644
index 0000000000..268b04d25a
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.c
@@ -0,0 +1,410 @@
+/** @file
+ A DXE_RUNTIME_DRIVER providing synchronous SMI activations via the
+ EFI_SMM_CONTROL2_PROTOCOL.
+
+ We expect the PEI phase to have covered the following:
+ - ensure that the underlying QEMU machine type be X58
+ (responsible: OvmfPkg/SmmAccess/SmmAccessPei.inf)
+ - ensure that the ACPI PM IO space be configured
+ (responsible: OvmfPkg/PlatformPei/PlatformPei.inf)
+
+ Our own entry point is responsible for confirming the SMI feature and for
+ configuring it.
+
+ Copyright (C) 2013, 2015, Red Hat, Inc.<BR>
+ Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Register/X58Ich10.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/S3SaveState.h>
+#include <Protocol/SmmControl2.h>
+
+//
+// Forward declaration.
+//
+STATIC
+VOID
+EFIAPI
+OnS3SaveStateInstalled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+//
+// The absolute IO port address of the SMI Control and Enable Register. It is
+// only used to carry information from the entry point function to the
+// S3SaveState protocol installation callback, strictly before the runtime
+// phase.
+//
+STATIC UINTN mSmiEnable;
+
+//
+// Event signaled when an S3SaveState protocol interface is installed.
+//
+STATIC EFI_EVENT mS3SaveStateInstalled;
+
+/**
+ Clear the SMI status
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_DEVICE_ERROR Something error occurred
+
+**/
+EFI_STATUS
+EFIAPI
+SmmClear(
+ VOID
+)
+{
+ EFI_STATUS Status;
+ UINT32 OutputData;
+ UINT32 OutputPort;
+ UINT32 PmBase;
+
+ Status = EFI_SUCCESS;
+ PmBase = ICH10_PMBASE_IO;
+
+ OutputPort = PmBase + ICH10_PMBASE_OFS_SMI_STS;
+ OutputData = ICH10_SMI_STS_APM;
+ IoWrite32(
+ (UINTN)OutputPort,
+ (UINT32)(OutputData)
+ );
+
+ ///
+ /// Set the EOS Bit
+ ///
+ OutputPort = PmBase + ICH10_PMBASE_OFS_SMI_EN;
+ OutputData = IoRead32((UINTN)OutputPort);
+ OutputData |= ICH10_SMI_EN_EOS;
+ IoWrite32(
+ (UINTN)OutputPort,
+ (UINT32)(OutputData)
+ );
+
+ ///
+ /// There is no need to read EOS back and check if it is set.
+ /// This can lead to a reading of zero if an SMI occurs right after the SMI_EN port read
+ /// but before the data is returned to the CPU.
+ /// SMM Dispatcher should make sure that EOS is set after all SMI sources are processed.
+ ///
+ return Status;
+}
+
+/**
+ Invokes SMI activation from either the preboot or runtime environment.
+
+ This function generates an SMI.
+
+ @param[in] This The EFI_SMM_CONTROL2_PROTOCOL instance.
+ @param[in,out] CommandPort The value written to the command port.
+ @param[in,out] DataPort The value written to the data port.
+ @param[in] Periodic Optional mechanism to engender a periodic
+ stream.
+ @param[in] ActivationInterval Optional parameter to repeat at this
+ period one time or, if the Periodic
+ Boolean is set, periodically.
+
+ @retval EFI_SUCCESS The SMI/PMI has been engendered.
+ @retval EFI_DEVICE_ERROR The timing is unsupported.
+ @retval EFI_INVALID_PARAMETER The activation period is unsupported.
+ @retval EFI_INVALID_PARAMETER The last periodic activation has not been
+ cleared.
+ @retval EFI_NOT_STARTED The SMM base service has not been initialized.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmControl2DxeTrigger (
+ IN CONST EFI_SMM_CONTROL2_PROTOCOL *This,
+ IN OUT UINT8 *CommandPort OPTIONAL,
+ IN OUT UINT8 *DataPort OPTIONAL,
+ IN BOOLEAN Periodic OPTIONAL,
+ IN UINTN ActivationInterval OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ //
+ // No support for queued or periodic activation.
+ //
+ if (Periodic || ActivationInterval > 0) {
+ return EFI_DEVICE_ERROR;
+ }
+ ///
+ /// Clear any pending the APM SMI
+ ///
+ Status = SmmClear();
+ //
+ // The so-called "Advanced Power Management Status Port Register" is in fact
+ // a generic data passing register, between the caller and the SMI
+ // dispatcher. The ICH9 spec calls it "scratchpad register" -- calling it
+ // "status" elsewhere seems quite the misnomer. Status registers usually
+ // report about hardware status, while this register is fully governed by
+ // software.
+ //
+ // Write to the status register first, as this won't trigger the SMI just
+ // yet. Then write to the control register.
+ //
+ IoWrite8 (ICH10_APM_STS, DataPort == NULL ? 0 : *DataPort);
+ IoWrite8 (ICH10_APM_CNT, CommandPort == NULL ? 0 : *CommandPort);
+ return EFI_SUCCESS;
+}
+
+/**
+ Clears any system state that was created in response to the Trigger() call.
+
+ This function acknowledges and causes the deassertion of the SMI activation
+ source.
+
+ @param[in] This The EFI_SMM_CONTROL2_PROTOCOL instance.
+ @param[in] Periodic Optional parameter to repeat at this period
+ one time
+
+ @retval EFI_SUCCESS The SMI/PMI has been engendered.
+ @retval EFI_DEVICE_ERROR The source could not be cleared.
+ @retval EFI_INVALID_PARAMETER The service did not support the Periodic input
+ argument.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmControl2DxeClear (
+ IN CONST EFI_SMM_CONTROL2_PROTOCOL *This,
+ IN BOOLEAN Periodic OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+
+ if (Periodic) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // The PI spec v1.4 explains that Clear() is only supposed to clear software
+ // status; it is not in fact responsible for deasserting the SMI. It gives
+ // two reasons for this: (a) many boards clear the SMI automatically when
+ // entering SMM, (b) if Clear() actually deasserted the SMI, then it could
+ // incorrectly suppress an SMI that was asynchronously asserted between the
+ // last return of the SMI handler and the call made to Clear().
+ //
+ // In fact QEMU automatically deasserts CPU_INTERRUPT_SMI in:
+ // - x86_cpu_exec_interrupt() [target-i386/seg_helper.c], and
+ // - kvm_arch_pre_run() [target-i386/kvm.c].
+ //
+ // So, nothing to do here.
+ //
+ Status = SmmClear();
+
+ return EFI_SUCCESS;
+}
+
+STATIC EFI_SMM_CONTROL2_PROTOCOL mControl2 = {
+ &SmmControl2DxeTrigger,
+ &SmmControl2DxeClear,
+ MAX_UINTN // MinimumTriggerPeriod -- we don't support periodic SMIs
+};
+
+//
+// Entry point of this driver.
+//
+EFI_STATUS
+EFIAPI
+SmmControl2DxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ UINT32 PmBase;
+ UINT32 SmiEnableVal;
+ EFI_STATUS Status;
+
+ //
+ // This module should only be included if SMRAM support is required.
+ //
+ ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
+
+ //
+ // Calculate the absolute IO port address of the SMI Control and Enable
+ // Register. (As noted at the top, the PEI phase has left us with a working
+ // ACPI PM IO space.)
+ //
+ PmBase = PciRead32 (POWER_MGMT_REGISTER_ICH10 (ICH10_PMBASE)) &
+ ICH10_PMBASE_MASK;
+ mSmiEnable = PmBase + ICH10_PMBASE_OFS_SMI_EN;
+
+ //
+ // If APMC_EN is pre-set in SMI_EN, that's QEMU's way to tell us that SMI
+ // support is not available. (For example due to KVM lacking it.) Otherwise,
+ // this bit is clear after each reset.
+ //
+ SmiEnableVal = IoRead32 (mSmiEnable);
+ if ((SmiEnableVal & ICH10_SMI_EN_APMC_EN) != 0) {
+ DEBUG ((EFI_D_ERROR, "%a: this X58 implementation lacks SMI\n",
+ __FUNCTION__));
+ }
+
+ //
+ // Otherwise, configure the board to inject an SMI when ICH10_APM_CNT is
+ // written to. (See the Trigger() method above.)
+ //
+ SmiEnableVal |= ICH10_SMI_EN_APMC_EN | ICH10_SMI_EN_GBL_SMI_EN;
+ IoWrite32 (mSmiEnable, SmiEnableVal);
+
+ //
+ // Prevent software from undoing the above (until platform reset).
+ //
+ PciOr16 (POWER_MGMT_REGISTER_ICH10 (ICH10_GEN_PMCON_1),
+ ICH10_GEN_PMCON_1_SMI_LOCK);
+
+ //
+ // If we can clear GBL_SMI_EN now, that means QEMU's SMI support is not
+ // appropriate.
+ //
+ IoWrite32 (mSmiEnable, SmiEnableVal & ~(UINT32)ICH10_SMI_EN_GBL_SMI_EN);
+ if (IoRead32 (mSmiEnable) != SmiEnableVal) {
+ DEBUG ((EFI_D_ERROR, "%a: failed to lock down GBL_SMI_EN\n",
+ __FUNCTION__));
+ goto FatalError;
+ }
+
+ VOID *Registration;
+
+ //
+ // On S3 resume the above register settings have to be repeated. Register a
+ // protocol notify callback that, when boot script saving becomes
+ // available, saves operations equivalent to the above to the boot script.
+ //
+ Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
+ OnS3SaveStateInstalled, NULL /* Context */,
+ &mS3SaveStateInstalled);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: CreateEvent: %r\n", __FUNCTION__, Status));
+ goto FatalError;
+ }
+
+ Status = gBS->RegisterProtocolNotify (&gEfiS3SaveStateProtocolGuid,
+ mS3SaveStateInstalled, &Registration);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: RegisterProtocolNotify: %r\n", __FUNCTION__,
+ Status));
+ goto ReleaseEvent;
+ }
+
+ //
+ // Kick the event right now -- maybe the boot script is already saveable.
+ //
+ Status = gBS->SignalEvent (mS3SaveStateInstalled);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: SignalEvent: %r\n", __FUNCTION__, Status));
+ goto ReleaseEvent;
+ }
+
+ //
+ // We have no pointers to convert to virtual addresses. The handle itself
+ // doesn't matter, as protocol services are not accessible at runtime.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
+ &gEfiSmmControl2ProtocolGuid, &mControl2,
+ NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: InstallMultipleProtocolInterfaces: %r\n",
+ __FUNCTION__, Status));
+ goto ReleaseEvent;
+ }
+
+ return EFI_SUCCESS;
+
+ReleaseEvent:
+ if (mS3SaveStateInstalled != NULL) {
+ gBS->CloseEvent (mS3SaveStateInstalled);
+ }
+
+FatalError:
+ //
+ // We really don't want to continue in this case.
+ //
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Notification callback for S3SaveState installation.
+
+ @param[in] Event Event whose notification function is being invoked.
+
+ @param[in] Context The pointer to the notification function's context, which
+ is implementation-dependent.
+**/
+STATIC
+VOID
+EFIAPI
+OnS3SaveStateInstalled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_S3_SAVE_STATE_PROTOCOL *S3SaveState;
+ UINT32 SmiEnOrMask, SmiEnAndMask;
+ UINT16 GenPmCon1OrMask, GenPmCon1AndMask;
+
+ ASSERT (Event == mS3SaveStateInstalled);
+
+ Status = gBS->LocateProtocol (&gEfiS3SaveStateProtocolGuid,
+ NULL /* Registration */, (VOID **)&S3SaveState);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ //
+ // These operations were originally done, verified and explained in the entry
+ // point function of the driver.
+ //
+ SmiEnOrMask = ICH10_SMI_EN_APMC_EN | ICH10_SMI_EN_GBL_SMI_EN;
+ SmiEnAndMask = MAX_UINT32;
+ Status = S3SaveState->Write (
+ S3SaveState,
+ EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE,
+ EfiBootScriptWidthUint32,
+ (UINT64)mSmiEnable,
+ &SmiEnOrMask,
+ &SmiEnAndMask
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE: %r\n",
+ __FUNCTION__, Status));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+
+ GenPmCon1OrMask = ICH10_GEN_PMCON_1_SMI_LOCK;
+ GenPmCon1AndMask = MAX_UINT16;
+ Status = S3SaveState->Write (
+ S3SaveState,
+ EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE,
+ EfiBootScriptWidthUint16,
+ (UINT64)POWER_MGMT_REGISTER_ICH10 (ICH10_GEN_PMCON_1),
+ &GenPmCon1OrMask,
+ &GenPmCon1AndMask
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR,
+ "%a: EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE: %r\n", __FUNCTION__,
+ Status));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+
+ DEBUG ((EFI_D_VERBOSE, "%a: boot script fragment saved\n", __FUNCTION__));
+ gBS->CloseEvent (Event);
+ mS3SaveStateInstalled = NULL;
+}
diff --git a/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.c b/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.c
new file mode 100644
index 0000000000..0baf730a48
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.c
@@ -0,0 +1,175 @@
+/** @file
+ PCH SPI SMM Driver implements the SPI Host Controller Compatibility Interface.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchSpi.h"
+
+//
+// Global variables
+//
+GLOBAL_REMOVE_IF_UNREFERENCED SPI_INSTANCE *mSpiInstance;
+//
+// mPchSpiResvMmioAddr keeps the reserved MMIO range assiged to SPI.
+// In SMM it always set back the reserved MMIO address to SPI BAR0 to ensure the MMIO range
+// won't overlap with SMRAM range, and trusted.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mSpiResvMmioAddr;
+
+/**
+ <b>SPI Runtime SMM Module Entry Point</b>\n
+ - <b>Introduction</b>\n
+ The SPI SMM module provide a standard way for other modules to use the PCH SPI Interface in SMM.
+
+ - @pre
+ - EFI_SMM_BASE2_PROTOCOL
+ - Documented in System Management Mode Core Interface Specification .
+
+ - @result
+ The SPI SMM driver produces @link _PCH_SPI_PROTOCOL PCH_SPI_PROTOCOL @endlink with GUID
+ gPchSmmSpiProtocolGuid which is different from SPI RUNTIME driver.
+
+ - <b>Integration Check List</b>\n
+ - This driver supports Descriptor Mode only.
+ - This driver supports Hardware Sequence only.
+ - When using SMM SPI Protocol to perform flash access in an SMI handler,
+ and the SMI occurrence is asynchronous to normal mode code execution,
+ proper synchronization mechanism must be applied, e.g. disable SMI before
+ the normal mode SendSpiCmd() starts and re-enable SMI after
+ the normal mode SendSpiCmd() completes.
+ @note The implementation of SendSpiCmd() uses GBL_SMI_EN in
+ SMI_EN register (ABase + 30h) to disable and enable SMIs. But this may
+ not be effective as platform may well set the SMI_LOCK bit (i.e., PMC PCI Offset A0h [4]).
+ So the synchronization at caller level is likely needed.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Global system service table.
+
+ @retval EFI_SUCCESS Initialization complete.
+ @exception EFI_UNSUPPORTED The chipset is unsupported by this driver.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver.
+ @retval EFI_DEVICE_ERROR Device error, driver exits abnormally.
+**/
+EFI_STATUS
+EFIAPI
+InstallPchSpi (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Init PCH spi reserved MMIO address.
+ //
+ mSpiResvMmioAddr = PCH_SPI_BASE_ADDRESS;
+
+ ///
+ /// Allocate pool for SPI protocol instance
+ ///
+ Status = gSmst->SmmAllocatePool (
+ EfiRuntimeServicesData, /// MemoryType don't care
+ sizeof (SPI_INSTANCE),
+ (VOID **) &mSpiInstance
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (mSpiInstance == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMem ((VOID *) mSpiInstance, sizeof (SPI_INSTANCE));
+ ///
+ /// Initialize the SPI protocol instance
+ ///
+ Status = SpiProtocolConstructor (mSpiInstance);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Install the SMM EFI_SPI_PROTOCOL interface
+ //
+ Status = gSmst->SmmInstallProtocolInterface (
+ &(mSpiInstance->Handle),
+ &gEfiSmmSpiProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &(mSpiInstance->SpiProtocol)
+ );
+ if (EFI_ERROR (Status)) {
+ gSmst->SmmFreePool (mSpiInstance);
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Acquire PCH spi mmio address.
+ It is not expected for this BAR0 to change because the SPI device is hidden
+ from the OS for SKL PCH LP/H B stepping and above (refer to section 3.5.1),
+ but if it is ever different from the preallocated address, reassign it back.
+ In SMM, it always override the BAR0 and returns the reserved MMIO range for SPI.
+
+ @param[in] SpiInstance Pointer to SpiInstance to initialize
+
+ @retval PchSpiBar0 return SPI MMIO address
+**/
+UINTN
+AcquireSpiBar0 (
+ IN SPI_INSTANCE *SpiInstance
+ )
+{
+ //
+ // SPIBAR0 will be different before and after PCI enum so need to get it from SPI BAR0 reg.
+ //
+ return mSpiResvMmioAddr;
+}
+
+/**
+ Release pch spi mmio address. Do nothing.
+
+ @param[in] SpiInstance Pointer to SpiInstance to initialize
+
+ @retval None
+**/
+VOID
+ReleaseSpiBar0 (
+ IN SPI_INSTANCE *SpiInstance
+ )
+{
+}
+
+/**
+ This function is a hook for Spi to disable BIOS Write Protect
+
+ @retval EFI_SUCCESS The protocol instance was properly initialized
+ @retval EFI_ACCESS_DENIED The BIOS Region can only be updated in SMM phase
+
+**/
+EFI_STATUS
+EFIAPI
+DisableBiosWriteProtect (
+ VOID
+ )
+{
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is a hook for Spi to enable BIOS Write Protect
+
+
+**/
+VOID
+EFIAPI
+EnableBiosWriteProtect (
+ VOID
+ )
+{
+}
diff --git a/Silicon/Intel/SimicsIch10Pkg/Ich10Pkg.dec b/Silicon/Intel/SimicsIch10Pkg/Ich10Pkg.dec
new file mode 100644
index 0000000000..ad0a599fc5
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Ich10Pkg.dec
@@ -0,0 +1,26 @@
+## @file
+# Copyright (c) 2014 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = Ich10Pkg
+ PACKAGE_GUID = 4E97AC4B-F64C-4008-BBDE-01CC3B0BAA6B
+ PACKAGE_VERSION = 0.91
+
+[Includes]
+ Include
+
+[Ppis]
+
+[Guids]
+ gEfiPchTokenSpaceGuid = { 0x89a1b278, 0xa1a1, 0x4df7, { 0xb1, 0x37, 0xde, 0x5a, 0xd7, 0xc4, 0x79, 0x13 } }
+[Protocols]
+ gEfiSmmSpiProtocolGuid = {0xbd75fe35, 0xfdce, 0x49d7, {0xa9, 0xdd, 0xb2, 0x6f, 0x1f, 0xc6, 0xb4, 0x37}}
+
+[PcdsFixedAtBuild]
+ gEfiPchTokenSpaceGuid.PcdFlashAreaBaseAddress|0xFFE00000|UINT32|0x10000001
+ gEfiPchTokenSpaceGuid.PcdFlashAreaSize|0x00200000|UINT32|0x10000002
\ No newline at end of file
diff --git a/Silicon/Intel/SimicsIch10Pkg/IchCommonLib.dsc b/Silicon/Intel/SimicsIch10Pkg/IchCommonLib.dsc
new file mode 100644
index 0000000000..143abda7c1
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/IchCommonLib.dsc
@@ -0,0 +1,12 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE libraries.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[LibraryClasses.common]
+ ResetSystemLib|$(PCH_PKG)/Library/ResetSystemLib/ResetSystemLib.inf
+ PchSpiCommonLib|$(PCH_PKG)/LibraryPrivate/BasePchSpiCommonLib/BasePchSpiCommonLib.inf
diff --git a/Silicon/Intel/SimicsIch10Pkg/IchPostMemoryInclude.fdf b/Silicon/Intel/SimicsIch10Pkg/IchPostMemoryInclude.fdf
new file mode 100644
index 0000000000..12e43e86d0
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/IchPostMemoryInclude.fdf
@@ -0,0 +1,9 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
diff --git a/Silicon/Intel/SimicsIch10Pkg/IchPreMemoryInclude.fdf b/Silicon/Intel/SimicsIch10Pkg/IchPreMemoryInclude.fdf
new file mode 100644
index 0000000000..079b81574b
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/IchPreMemoryInclude.fdf
@@ -0,0 +1,9 @@
+## @file
+# Component description file for the Ich10 SiPkg PEI drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
diff --git a/Silicon/Intel/SimicsIch10Pkg/IchUefiBootInclude.fdf b/Silicon/Intel/SimicsIch10Pkg/IchUefiBootInclude.fdf
new file mode 100644
index 0000000000..1b683ba97c
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/IchUefiBootInclude.fdf
@@ -0,0 +1,13 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+ INF $(PCH_PKG)/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
+ INF $(PCH_PKG)/Spi/Smm/PchSpiSmm.inf
+!endif
diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/Library/SpiFlashCommonLib.h b/Silicon/Intel/SimicsIch10Pkg/Include/Library/SpiFlashCommonLib.h
new file mode 100644
index 0000000000..53c11bb59a
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Include/Library/SpiFlashCommonLib.h
@@ -0,0 +1,98 @@
+/** @file
+ The header file includes the common header files, defines
+ internal structure and functions used by SpiFlashCommonLib.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __SPI_FLASH_COMMON_LIB_H__
+#define __SPI_FLASH_COMMON_LIB_H__
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#define SECTOR_SIZE_4KB 0x1000 // Common 4kBytes sector size
+/**
+ Enable block protection on the Serial Flash device.
+
+ @retval EFI_SUCCESS Opertion is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashLock (
+ VOID
+ );
+
+/**
+ Read NumBytes bytes of data from the address specified by
+ PAddress into Buffer.
+
+ @param[in] Address The starting physical address of the read.
+ @param[in,out] NumBytes On input, the number of bytes to read. On output, the number
+ of bytes actually read.
+ @param[out] Buffer The destination data buffer for the read.
+
+ @retval EFI_SUCCESS Opertion is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashRead (
+ IN UINTN Address,
+ IN OUT UINT32 *NumBytes,
+ OUT UINT8 *Buffer
+ );
+
+/**
+ Write NumBytes bytes of data from Buffer to the address specified by
+ PAddresss.
+
+ @param[in] Address The starting physical address of the write.
+ @param[in,out] NumBytes On input, the number of bytes to write. On output,
+ the actual number of bytes written.
+ @param[in] Buffer The source data buffer for the write.
+
+ @retval EFI_SUCCESS Opertion is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashWrite (
+ IN UINTN Address,
+ IN OUT UINT32 *NumBytes,
+ IN UINT8 *Buffer
+ );
+
+/**
+ Erase the block starting at Address.
+
+ @param[in] Address The starting physical address of the block to be erased.
+ This library assume that caller garantee that the PAddress
+ is at the starting address of this block.
+ @param[in] NumBytes On input, the number of bytes of the logical block to be erased.
+ On output, the actual number of bytes erased.
+
+ @retval EFI_SUCCESS. Opertion is successful.
+ @retval EFI_DEVICE_ERROR If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashBlockErase (
+ IN UINTN Address,
+ IN UINTN *NumBytes
+ );
+
+#endif
diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/PchAccess.h b/Silicon/Intel/SimicsIch10Pkg/Include/PchAccess.h
new file mode 100644
index 0000000000..8be6ecd83b
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Include/PchAccess.h
@@ -0,0 +1,43 @@
+/** @file
+ Macros that simplify accessing PCH devices's PCI registers.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_ACCESS_H_
+#define _PCH_ACCESS_H_
+
+#include "PchReservedResources.h"
+
+#ifndef STALL_ONE_MICRO_SECOND
+#define STALL_ONE_MICRO_SECOND 1
+#endif
+#ifndef STALL_ONE_SECOND
+#define STALL_ONE_SECOND 1000000
+#endif
+
+
+///
+/// The default PCH PCI bus number
+///
+#define DEFAULT_PCI_BUS_NUMBER_PCH 0
+
+//
+// Default Vendor ID and Subsystem ID
+//
+#define V_PCH_INTEL_VENDOR_ID 0x8086 ///< Default Intel PCH Vendor ID
+#define V_PCH_DEFAULT_SID 0x7270 ///< Default Intel PCH Subsystem ID
+#define V_PCH_DEFAULT_SVID_SID (V_INTEL_VENDOR_ID + (V_PCH_DEFAULT_SID << 16)) ///< Default INTEL PCH Vendor ID and Subsystem ID
+
+//
+// Include device register definitions
+//
+
+#include "Register/PchRegsPmc.h"
+
+#include "Register/PchRegsSpi.h"
+
+#endif
+
diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/PchLimits.h b/Silicon/Intel/SimicsIch10Pkg/Include/PchLimits.h
new file mode 100644
index 0000000000..35bb5741a8
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Include/PchLimits.h
@@ -0,0 +1,94 @@
+/** @file
+ Build time limits of PCH resources.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_LIMITS_H_
+#define _PCH_LIMITS_H_
+
+//
+// PCIe limits
+//
+#define PCH_MAX_PCIE_ROOT_PORTS PCH_H_PCIE_MAX_ROOT_PORTS
+#define PCH_H_PCIE_MAX_ROOT_PORTS 20
+#define PCH_LP_PCIE_MAX_ROOT_PORTS 12
+
+#define PCH_MAX_PCIE_CONTROLLERS PCH_H_PCIE_MAX_CONTROLLERS
+#define PCH_PCIE_CONTROLLER_PORTS 4
+#define PCH_H_PCIE_MAX_CONTROLLERS (PCH_H_PCIE_MAX_ROOT_PORTS / PCH_PCIE_CONTROLLER_PORTS)
+#define PCH_LP_PCIE_MAX_CONTROLLERS (PCH_LP_PCIE_MAX_ROOT_PORTS / PCH_PCIE_CONTROLLER_PORTS)
+
+//
+// PCIe clocks limits
+//
+#define PCH_LP_PCIE_MAX_CLK_REQ 6
+#define PCH_H_PCIE_MAX_CLK_REQ 16
+
+//
+// RST PCIe Storage Cycle Router limits
+//
+#define PCH_MAX_RST_PCIE_STORAGE_CR 3
+
+//
+// SATA limits
+//
+#define PCH_MAX_SATA_PORTS PCH_H_AHCI_MAX_PORTS
+#define PCH_H_AHCI_MAX_PORTS 8 ///< Max number of sata ports in SKL PCH H
+#define PCH_LP_AHCI_MAX_PORTS 3 ///< Max number of sata ports in SKL PCH LP
+#define PCH_SATA_MAX_DEVICES_PER_PORT 1 ///< Max support device numner per port, Port Multiplier is not support.
+
+//
+// USB limits
+//
+#define PCH_MAX_USB2_PORTS PCH_H_XHCI_MAX_USB2_PORTS
+
+#define PCH_H_XHCI_MAX_USB2_PHYSICAL_PORTS 14 ///< Max Physical Connector XHCI, not counting virtual ports like USB-R.
+#define PCH_LP_XHCI_MAX_USB2_PHYSICAL_PORTS 10 ///< Max Physical Connector XHCI, not counting virtual ports like USB-R.
+
+#define PCH_H_XHCI_MAX_USB2_PORTS 16 ///< 14 High Speed lanes + Including two ports reserved for USBr
+#define PCH_LP_XHCI_MAX_USB2_PORTS 12 ///< 10 High Speed lanes + Including two ports reserved for USBr
+
+#define PCH_MAX_USB3_PORTS PCH_H_XHCI_MAX_USB3_PORTS
+
+#define PCH_H_XHCI_MAX_USB3_PORTS 10 ///< 10 Super Speed lanes
+#define PCH_LP_XHCI_MAX_USB3_PORTS 6 ///< 6 Super Speed lanes
+
+#define PCH_XHCI_MAX_SSIC_PORT_COUNT 2 ///< 2 SSIC ports in SKL PCH-LP and SKL PCH-H
+
+//
+// SerialIo limits
+//
+#define PCH_SERIALIO_MAX_CONTROLLERS 11 ///< Number of SerialIo controllers, this includes I2C, SPI and UART
+#define PCH_SERIALIO_MAX_I2C_CONTROLLERS 6 ///< Number of SerialIo I2C controllers
+#define PCH_LP_SERIALIO_MAX_I2C_CONTROLLERS 6 ///< Number of SerialIo I2C controllers for PCH-LP
+#define PCH_H_SERIALIO_MAX_I2C_CONTROLLERS 4 ///< Number of SerialIo I2C controllers for PCH-H
+#define PCH_SERIALIO_MAX_SPI_CONTROLLERS 2 ///< Number of SerialIo SPI controllers
+#define PCH_SERIALIO_MAX_UART_CONTROLLERS 3 ///< Number of SerialIo UART controllers
+
+//
+// ISH limits
+//
+#define PCH_ISH_MAX_GP_PINS 8
+#define PCH_ISH_MAX_UART_CONTROLLERS 2
+#define PCH_ISH_MAX_I2C_CONTROLLERS 3
+#define PCH_ISH_MAX_SPI_CONTROLLERS 1
+
+//
+// SCS limits
+//
+#define PCH_SCS_MAX_CONTROLLERS 3 ///< Number of Storage and Communication Subsystem controllers, this includes eMMC, SDIO, SDCARD
+
+//
+// Flash Protection Range Register
+//
+#define PCH_FLASH_PROTECTED_RANGES 5
+
+//
+// Number of eSPI slaves
+//
+#define PCH_ESPI_MAX_SLAVE_ID 2
+#endif // _PCH_LIMITS_H_
+
diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/PchReservedResources.h b/Silicon/Intel/SimicsIch10Pkg/Include/PchReservedResources.h
new file mode 100644
index 0000000000..5e978237dd
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Include/PchReservedResources.h
@@ -0,0 +1,60 @@
+/** @file
+ PCH preserved MMIO resource definitions.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_PRESERVED_RESOURCES_H_
+#define _PCH_PRESERVED_RESOURCES_H_
+
+/**
+ PCH preserved MMIO range, 24 MB, from 0xFD000000 to 0xFE7FFFFF
+
+ Detailed recommended static allocation
+ +-------------------------------------------------------------------------+
+ | Size | Start | End | Usage |
+ | 16 MB | 0xFD000000 | 0xFDFFFFFF | SBREG |
+ | 64 KB | 0xFE000000 | 0xFE00FFFF | PMC MBAR |
+ | 4 KB | 0xFE010000 | 0xFE010FFF | SPI BAR0 |
+ | 88 KB | 0xFE020000 | 0xFE035FFF | SerialIo BAR in ACPI mode |
+ | 24 KB | 0xFE036000 | 0xFE03BFFF | Unused |
+ | 4 KB | 0xFE03C000 | 0xFE03CFFF | Thermal Device in ACPI mode |
+ | 524 KB | 0xFE03D000 | 0xFE0BFFFF | Unused |
+ | 256 KB | 0xFE0C0000 | 0xFE0FFFFF | TraceHub FW BAR |
+ | 1 MB | 0xFE100000 | 0xFE1FFFFF | TraceHub MTB BAR |
+ | 2 MB | 0xFE200000 | 0xFE3FFFFF | TraceHub SW BAR |
+ | 64 KB | 0xFE400000 | 0xFE40FFFF | CIO2 MMIO BAR in ACPI mode |
+ | 2 MB - 64KB | 0xFE410000 | 0xFE5FFFFF | Unused |
+ | 2 MB | 0xFE600000 | 0xFE7FFFFF | Temp address |
+ +-------------------------------------------------------------------------+
+**/
+#define PCH_PRESERVED_BASE_ADDRESS 0xFD000000 ///< Pch preserved MMIO base address
+#define PCH_PRESERVED_MMIO_SIZE 0x01800000 ///< 24MB
+#define PCH_PCR_BASE_ADDRESS 0xFD000000 ///< SBREG MMIO base address
+#define PCH_PCR_MMIO_SIZE 0x01000000 ///< 16MB
+#define PCH_PWRM_BASE_ADDRESS 0xFE000000 ///< PMC MBAR MMIO base address
+#define PCH_PWRM_MMIO_SIZE 0x00010000 ///< 64KB
+#define PCH_SPI_BASE_ADDRESS 0xFED1C000 + 0x3800 ///< SPI MBAR MMIO base address
+#define PCH_SPI_MMIO_SIZE 0x00001000 ///< 4KB
+#define PCH_SERIAL_IO_BASE_ADDRESS 0xFE020000 ///< SerialIo MMIO base address
+#define PCH_SERIAL_IO_MMIO_SIZE 0x00016000 ///< 88KB
+#define PCH_THERMAL_BASE_ADDRESS 0xFE03C000 ///< Thermal Device in ACPI mode
+#define PCH_THERMAL_MMIO_SIZE 0x00001000 ///< 4KB
+#define PCH_TRACE_HUB_FW_BASE_ADDRESS 0xFE0C0000 ///< TraceHub FW MMIO base address
+#define PCH_TRACE_HUB_FW_MMIO_SIZE 0x00040000 ///< 256KB
+#define PCH_TRACE_HUB_MTB_BASE_ADDRESS 0xFE100000 ///< TraceHub MTB MMIO base address
+#define PCH_TRACE_HUB_MTB_MMIO_SIZE 0x00100000 ///< 1MB
+#define PCH_TRACE_HUB_SW_BASE_ADDRESS 0xFE200000 ///< TraceHub SW MMIO base address
+#define PCH_TRACE_HUB_SW_MMIO_SIZE 0x00200000 ///< 2MB
+#define PCH_CIO2_BASE_ADDRESS 0xFE400000 ///< CIO2 MMIO BAR in ACPI mode
+#define PCH_CIO2_MMIO_SIZE 0x00010000 ///< 64KB
+#define PCH_TEMP_BASE_ADDRESS 0xFE600000 ///< preserved temp address for misc usage
+#define PCH_TEMP_MMIO_SIZE 0x00200000 ///< 2MB
+
+#define RCRB 0xFED1C000
+#define SPIBAR 0x3800
+
+#endif // _PCH_PRESERVED_RESOURCES_H_
+
diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/Protocol/Spi.h b/Silicon/Intel/SimicsIch10Pkg/Include/Protocol/Spi.h
new file mode 100644
index 0000000000..b0c5b3d0e6
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Include/Protocol/Spi.h
@@ -0,0 +1,295 @@
+/** @file
+ This file defines the PCH SPI Protocol which implements the
+ Intel(R) PCH SPI Host Controller Compatibility Interface.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SPI_PROTOCOL_H_
+#define _PCH_SPI_PROTOCOL_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gEfiSpiProtocolGuid;
+extern EFI_GUID gEfiSmmSpiProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _PCH_SPI_PROTOCOL EFI_SPI_PROTOCOL;
+
+//
+// SPI protocol data structures and definitions
+//
+
+/**
+ Flash Region Type
+**/
+typedef enum {
+ FlashRegionDescriptor,
+ FlashRegionBios,
+ FlashRegionMe,
+ FlashRegionGbE,
+ FlashRegionPlatformData,
+ FlashRegionDer,
+ FlashRegionAll,
+ FlashRegionMax
+} FLASH_REGION_TYPE;
+
+
+//
+// Protocol member functions
+//
+
+/**
+ Read data from the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+ @param[out] Buffer The Pointer to caller-allocated buffer containing the dada received.
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_READ) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ OUT UINT8 *Buffer
+ );
+
+/**
+ Write data to the flash part. Remark: Erase may be needed before write to the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+ @param[in] Buffer Pointer to caller-allocated buffer containing the data sent during the SPI cycle.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_WRITE) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ IN UINT8 *Buffer
+ );
+
+/**
+ Erase some area on the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_ERASE) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount
+ );
+
+/**
+ Read SFDP data from the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ComponentNumber The Componen Number for chip select
+ @param[in] Address The starting byte address for SFDP data read.
+ @param[in] ByteCount Number of bytes in SFDP data portion of the SPI cycle
+ @param[out] SfdpData The Pointer to caller-allocated buffer containing the SFDP data received
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_READ_SFDP) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT8 ComponentNumber,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ OUT UINT8 *SfdpData
+ );
+
+/**
+ Read Jedec Id from the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ComponentNumber The Componen Number for chip select
+ @param[in] ByteCount Number of bytes in JedecId data portion of the SPI cycle, the data size is 3 typically
+ @param[out] JedecId The Pointer to caller-allocated buffer containing JEDEC ID received
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_READ_JEDEC_ID) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT8 ComponentNumber,
+ IN UINT32 ByteCount,
+ OUT UINT8 *JedecId
+ );
+
+/**
+ Write the status register in the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ByteCount Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+ @param[in] StatusValue The Pointer to caller-allocated buffer containing the value of Status register writing
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_WRITE_STATUS) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 ByteCount,
+ IN UINT8 *StatusValue
+ );
+
+/**
+ Read status register in the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ByteCount Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+ @param[out] StatusValue The Pointer to caller-allocated buffer containing the value of Status register received.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_READ_STATUS) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 ByteCount,
+ OUT UINT8 *StatusValue
+ );
+
+/**
+ Get the SPI region base and size, based on the enum type
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for for the base address which is listed in the Descriptor.
+ @param[out] BaseAddress The Flash Linear Address for the Region 'n' Base
+ @param[out] RegionSize The size for the Region 'n'
+
+ @retval EFI_SUCCESS Read success
+ @retval EFI_INVALID_PARAMETER Invalid region type given
+ @retval EFI_DEVICE_ERROR The region is not used
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_GET_REGION_ADDRESS) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ OUT UINT32 *BaseAddress,
+ OUT UINT32 *RegionSize
+ );
+
+/**
+ Read PCH Soft Strap Values
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] SoftStrapAddr PCH Soft Strap address offset from FPSBA.
+ @param[in] ByteCount Number of bytes in SoftStrap data portion of the SPI cycle
+ @param[out] SoftStrapValue The Pointer to caller-allocated buffer containing PCH Soft Strap Value.
+ If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_READ_PCH_SOFTSTRAP) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 SoftStrapAddr,
+ IN UINT32 ByteCount,
+ OUT VOID *SoftStrapValue
+ );
+
+/**
+ Read CPU Soft Strap Values
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] SoftStrapAddr CPU Soft Strap address offset from FCPUSBA.
+ @param[in] ByteCount Number of bytes in SoftStrap data portion of the SPI cycle.
+ @param[out] SoftStrapValue The Pointer to caller-allocated buffer containing CPU Soft Strap Value.
+ If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_READ_CPU_SOFTSTRAP) (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 SoftStrapAddr,
+ IN UINT32 ByteCount,
+ OUT VOID *SoftStrapValue
+ );
+
+/**
+ These protocols/PPI allows a platform module to perform SPI operations through the
+ Intel PCH SPI Host Controller Interface.
+**/
+struct _PCH_SPI_PROTOCOL {
+ /**
+ This member specifies the revision of this structure. This field is used to
+ indicate backwards compatible changes to the protocol.
+ **/
+ UINT8 Revision;
+ PCH_SPI_FLASH_READ FlashRead; ///< Read data from the flash part.
+ PCH_SPI_FLASH_WRITE FlashWrite; ///< Write data to the flash part. Remark: Erase may be needed before write to the flash part.
+ PCH_SPI_FLASH_ERASE FlashErase; ///< Erase some area on the flash part.
+ PCH_SPI_FLASH_READ_SFDP FlashReadSfdp; ///< Read SFDP data from the flash part.
+ PCH_SPI_FLASH_READ_JEDEC_ID FlashReadJedecId; ///< Read Jedec Id from the flash part.
+ PCH_SPI_FLASH_WRITE_STATUS FlashWriteStatus; ///< Write the status register in the flash part.
+ PCH_SPI_FLASH_READ_STATUS FlashReadStatus; ///< Read status register in the flash part.
+ PCH_SPI_GET_REGION_ADDRESS GetRegionAddress; ///< Get the SPI region base and size
+ PCH_SPI_READ_PCH_SOFTSTRAP ReadPchSoftStrap; ///< Read PCH Soft Strap Values
+ PCH_SPI_READ_CPU_SOFTSTRAP ReadCpuSoftStrap; ///< Read CPU Soft Strap Values
+};
+
+/**
+ PCH SPI PPI/PROTOCOL revision number
+
+ Revision 1: Initial version
+**/
+#define PCH_SPI_SERVICES_REVISION 1
+
+#endif
diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsPmc.h b/Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsPmc.h
new file mode 100644
index 0000000000..4c495475cb
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsPmc.h
@@ -0,0 +1,647 @@
+/** @file
+ Register names for PCH PMC device
+
+ Conventions:
+
+ - Prefixes:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values within the bits
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+ - In general, PCH registers are denoted by "_PCH_" in register names
+ - Registers / bits that are different between PCH generations are denoted by
+ "_PCH_[generation_name]_" in register/bit names.
+ - Registers / bits that are specific to PCH-H denoted by "_H_" in register/bit names.
+ Registers / bits that are specific to PCH-LP denoted by "_LP_" in register/bit names.
+ e.g., "_PCH_H_", "_PCH_LP_"
+ Registers / bits names without _H_ or _LP_ apply for both H and LP.
+ - Registers / bits that are different between SKUs are denoted by "_[SKU_name]"
+ at the end of the register/bit names
+ - Registers / bits of new devices introduced in a PCH generation will be just named
+ as "_PCH_" without [generation_name] inserted.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_PMC_H_
+#define _PCH_REGS_PMC_H_
+
+//
+// PMC Registers (D31:F2)
+//
+#define PCI_DEVICE_NUMBER_PCH_PMC 31
+#define PCI_FUNCTION_NUMBER_PCH_PMC 2
+
+#define R_PCH_PMC_PM_DATA_BAR 0x10
+#define B_PCH_PMC_PM_DATA_BAR 0xFFFFC000
+#define R_PCH_PMC_ACPI_BASE 0x40
+#define B_PCH_PMC_ACPI_BASE_BAR 0xFFFC
+#define R_PCH_PMC_ACPI_CNT 0x44
+#define B_PCH_PMC_ACPI_CNT_PWRM_EN BIT8 ///< PWRM enable
+#define B_PCH_PMC_ACPI_CNT_ACPI_EN BIT7 ///< ACPI eanble
+#define B_PCH_PMC_ACPI_CNT_SCIS (BIT2 | BIT1 | BIT0) ///< SCI IRQ select
+#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ9 0
+#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ10 1
+#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ11 2
+#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ20 4
+#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ21 5
+#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ22 6
+#define V_PCH_PMC_ACPI_CNT_SCIS_IRQ23 7
+#define R_PCH_PMC_PWRM_BASE 0x48
+#define B_PCH_PMC_PWRM_BASE_BAR 0xFFFF0000 ///< PWRM must be 64KB alignment to align the source decode.
+#define R_PCH_PMC_GEN_PMCON_A 0xA0
+#define B_PCH_PMC_GEN_PMCON_A_DC_PP_DIS BIT30
+#define B_PCH_PMC_GEN_PMCON_A_DSX_PP_DIS BIT29
+#define B_PCH_PMC_GEN_PMCON_A_AG3_PP_EN BIT28
+#define B_PCH_PMC_GEN_PMCON_A_SX_PP_EN BIT27
+#define B_PCH_PMC_GEN_PMCON_A_DISB BIT23
+#define B_PCH_PMC_GEN_PMCON_A_MEM_SR BIT21
+#define B_PCH_PMC_GEN_PMCON_A_MS4V BIT18
+#define B_PCH_PMC_GEN_PMCON_A_GBL_RST_STS BIT16
+#define B_PCH_PMC_GEN_PMCON_A_ALLOW_OPI_PLL_SD_INC0 BIT13
+#define B_PCH_PMC_GEN_PMCON_A_ALLOW_SPXB_CG_INC0 BIT12
+#define B_PCH_PMC_GEN_PMCON_A_BIOS_PCI_EXP_EN BIT10
+#define B_PCH_PMC_GEN_PMCON_A_PWRBTN_LVL BIT9
+#define B_PCH_PMC_GEN_PMCON_A_ALLOW_L1LOW_C0 BIT7
+#define B_PCH_PMC_GEN_PMCON_A_ALLOW_L1LOW_OPI_ON BIT6
+#define B_PCH_PMC_GEN_PMCON_A_ALLOW_L1LOW_BCLKREQ_ON BIT5
+#define B_PCH_PMC_GEN_PMCON_A_SMI_LOCK BIT4
+#define B_PCH_PMC_GEN_PMCON_A_ESPI_SMI_LOCK BIT3 ///< ESPI SMI lock
+#define B_PCH_PMC_GEN_PMCON_A_PER_SMI_SEL 0x0003
+#define V_PCH_PMC_GEN_PMCON_A_PER_SMI_64S 0x0000
+#define V_PCH_PMC_GEN_PMCON_A_PER_SMI_32S 0x0001
+#define V_PCH_PMC_GEN_PMCON_A_PER_SMI_16S 0x0002
+#define V_PCH_PMC_GEN_PMCON_A_PER_SMI_8S 0x0003
+#define R_PCH_PMC_GEN_PMCON_B 0xA4
+#define B_PCH_PMC_GEN_PMCON_B_SLPSX_STR_POL_LOCK BIT18 ///< Lock down SLP_S3/SLP_S4 Minimum Assertion width
+#define B_PCH_PMC_GEN_PMCON_B_ACPI_BASE_LOCK BIT17 ///< Lock ACPI BASE at 0x40, only cleared by reset when set
+#define B_PCH_PMC_GEN_PMCON_B_PM_DATA_BAR_DIS BIT16
+#define B_PCH_PMC_GEN_PMCON_B_PME_B0_S5_DIS BIT15
+#define B_PCH_PMC_GEN_PMCON_B_SUS_PWR_FLR BIT14
+#define B_PCH_PMC_GEN_PMCON_B_WOL_EN_OVRD BIT13
+#define B_PCH_PMC_GEN_PMCON_B_DISABLE_SX_STRETCH BIT12
+#define B_PCH_PMC_GEN_PMCON_B_SLP_S3_MAW 0xC00
+#define V_PCH_PMC_GEN_PMCON_B_SLP_S3_MAW_60US 0x000
+#define V_PCH_PMC_GEN_PMCON_B_SLP_S3_MAW_1MS 0x400
+#define V_PCH_PMC_GEN_PMCON_B_SLP_S3_MAW_50MS 0x800
+#define V_PCH_PMC_GEN_PMCON_B_SLP_S3_MAW_2S 0xC00
+#define B_PCH_PMC_GEN_PMCON_B_HOST_RST_STS BIT9
+#define B_PCH_PMC_GEN_PMCON_B_SWSMI_RTSL 0xC0
+#define V_PCH_PMC_GEN_PMCON_B_SWSMI_RTSL_64MS 0xC0
+#define V_PCH_PMC_GEN_PMCON_B_SWSMI_RTSL_32MS 0x80
+#define V_PCH_PMC_GEN_PMCON_B_SWSMI_RTSL_16MS 0x40
+#define V_PCH_PMC_GEN_PMCON_B_SWSMI_RTSL_1_5MS 0x00
+#define B_PCH_PMC_GEN_PMCON_B_SLP_S4_MAW 0x30
+#define V_PCH_PMC_GEN_PMCON_B_SLP_S4_MAW_1S 0x30
+#define V_PCH_PMC_GEN_PMCON_B_SLP_S4_MAW_2S 0x20
+#define V_PCH_PMC_GEN_PMCON_B_SLP_S4_MAW_3S 0x10
+#define V_PCH_PMC_GEN_PMCON_B_SLP_S4_MAW_4S 0x00
+#define B_PCH_PMC_GEN_PMCON_B_SLP_S4_ASE BIT3
+#define B_PCH_PMC_GEN_PMCON_B_RTC_PWR_STS BIT2
+#define B_PCH_PMC_GEN_PMCON_B_PWR_FLR BIT1
+#define B_PCH_PMC_GEN_PMCON_B_AFTERG3_EN BIT0
+#define R_PCH_PMC_BM_CX_CNF 0xA8
+#define B_PCH_PMC_BM_CX_CNF_STORAGE_BREAK_EN BIT31
+#define B_PCH_PMC_BM_CX_CNF_PCIE_BREAK_EN BIT30
+#define B_PCH_PMC_BM_CX_CNF_AZ_BREAK_EN BIT24
+#define B_PCH_PMC_BM_CX_CNF_DPSN_BREAK_EN BIT19
+#define B_PCH_PMC_BM_CX_CNF_XHCI_BREAK_EN BIT17
+#define B_PCH_PMC_BM_CX_CNF_SATA3_BREAK_EN BIT16
+#define B_PCH_PMC_BM_CX_CNF_SCRATCHPAD BIT15
+#define B_PCH_PMC_BM_CX_CNF_PHOLD_BM_STS_BLOCK BIT14
+#define B_PCH_PMC_BM_CX_CNF_MASK_CF BIT11
+#define B_PCH_PMC_BM_CX_CNF_BM_STS_ZERO_EN BIT10
+#define B_PCH_PMC_BM_CX_CNF_PM_SYNC_MSG_MODE BIT9
+#define R_PCH_PMC_ETR3 0xAC
+#define B_PCH_PMC_ETR3_CF9LOCK BIT31 ///< CF9h Lockdown
+#define B_PCH_PMC_ETR3_USB_CACHE_DIS BIT21
+#define B_PCH_PMC_ETR3_CF9GR BIT20 ///< CF9h Global Reset
+#define B_PCH_PMC_ETR3_SKIP_HOST_RST_HS BIT19
+#define B_PCH_PMC_ETR3_CWORWRE BIT18
+
+//
+// ACPI and legacy I/O register offsets from ACPIBASE
+//
+#define R_PCH_ACPI_PM1_STS 0x00
+#define S_PCH_ACPI_PM1_STS 2
+#define B_PCH_ACPI_PM1_STS_WAK BIT15
+#define B_PCH_ACPI_PM1_STS_PCIEXP_WAKE_STS BIT14
+#define B_PCH_ACPI_PM1_STS_PRBTNOR BIT11
+#define B_PCH_ACPI_PM1_STS_RTC BIT10
+#define B_PCH_ACPI_PM1_STS_PWRBTN BIT8
+#define B_PCH_ACPI_PM1_STS_GBL BIT5
+#define B_PCH_ACPI_PM1_STS_BM BIT4
+#define B_PCH_ACPI_PM1_STS_TMROF BIT0
+#define N_PCH_ACPI_PM1_STS_WAK 15
+#define N_PCH_ACPI_PM1_STS_PCIEXP_WAKE_STS 14
+#define N_PCH_ACPI_PM1_STS_PRBTNOR 11
+#define N_PCH_ACPI_PM1_STS_RTC 10
+#define N_PCH_ACPI_PM1_STS_PWRBTN 8
+#define N_PCH_ACPI_PM1_STS_GBL 5
+#define N_PCH_ACPI_PM1_STS_BM 4
+#define N_PCH_ACPI_PM1_STS_TMROF 0
+
+#define R_PCH_ACPI_PM1_EN 0x02
+#define S_PCH_ACPI_PM1_EN 2
+#define B_PCH_ACPI_PM1_EN_PCIEXP_WAKE_DIS BIT14
+#define B_PCH_ACPI_PM1_EN_RTC BIT10
+#define B_PCH_ACPI_PM1_EN_PWRBTN BIT8
+#define B_PCH_ACPI_PM1_EN_GBL BIT5
+#define B_PCH_ACPI_PM1_EN_TMROF BIT0
+#define N_PCH_ACPI_PM1_EN_PCIEXP_WAKE_DIS 14
+#define N_PCH_ACPI_PM1_EN_RTC 10
+#define N_PCH_ACPI_PM1_EN_PWRBTN 8
+#define N_PCH_ACPI_PM1_EN_GBL 5
+#define N_PCH_ACPI_PM1_EN_TMROF 0
+
+#define R_PCH_ACPI_PM1_CNT 0x04
+#define S_PCH_ACPI_PM1_CNT 4
+#define B_PCH_ACPI_PM1_CNT_SLP_EN BIT13
+#define B_PCH_ACPI_PM1_CNT_SLP_TYP (BIT12 | BIT11 | BIT10)
+#define V_PCH_ACPI_PM1_CNT_S0 0
+#define V_PCH_ACPI_PM1_CNT_S1 BIT10
+#define V_PCH_ACPI_PM1_CNT_S3 (BIT12 | BIT10)
+#define V_PCH_ACPI_PM1_CNT_S4 (BIT12 | BIT11)
+#define V_PCH_ACPI_PM1_CNT_S5 (BIT12 | BIT11 | BIT10)
+#define B_PCH_ACPI_PM1_CNT_GBL_RLS BIT2
+#define B_PCH_ACPI_PM1_CNT_BM_RLD BIT1
+#define B_PCH_ACPI_PM1_CNT_SCI_EN BIT0
+
+#define R_PCH_ACPI_PM1_TMR 0x08
+#define V_PCH_ACPI_TMR_FREQUENCY 3579545
+#define B_PCH_ACPI_PM1_TMR_VAL 0xFFFFFF
+#define V_PCH_ACPI_PM1_TMR_MAX_VAL 0x1000000 ///< The timer is 24 bit overflow
+
+#define R_PCH_SMI_EN 0x30
+#define S_PCH_SMI_EN 4
+#define B_PCH_SMI_EN_LEGACY_USB3 BIT31
+#define B_PCH_SMI_EN_GPIO_UNLOCK_SMI BIT27
+#define B_PCH_SMI_EN_LEGACY_USB2 BIT17
+#define B_PCH_SMI_EN_PERIODIC BIT14
+#define B_PCH_SMI_EN_TCO BIT13
+#define B_PCH_SMI_EN_MCSMI BIT11
+#define B_PCH_SMI_EN_BIOS_RLS BIT7
+#define B_PCH_SMI_EN_SWSMI_TMR BIT6
+#define B_PCH_SMI_EN_APMC BIT5
+#define B_PCH_SMI_EN_ON_SLP_EN BIT4
+#define B_PCH_SMI_EN_LEGACY_USB BIT3
+#define B_PCH_SMI_EN_BIOS BIT2
+#define B_PCH_SMI_EN_EOS BIT1
+#define B_PCH_SMI_EN_GBL_SMI BIT0
+#define N_PCH_SMI_EN_LEGACY_USB3 31
+#define N_PCH_SMI_EN_ESPI 28
+#define N_PCH_SMI_EN_GPIO_UNLOCK 27
+#define N_PCH_SMI_EN_INTEL_USB2 18
+#define N_PCH_SMI_EN_LEGACY_USB2 17
+#define N_PCH_SMI_EN_PERIODIC 14
+#define N_PCH_SMI_EN_TCO 13
+#define N_PCH_SMI_EN_MCSMI 11
+#define N_PCH_SMI_EN_BIOS_RLS 7
+#define N_PCH_SMI_EN_SWSMI_TMR 6
+#define N_PCH_SMI_EN_APMC 5
+#define N_PCH_SMI_EN_ON_SLP_EN 4
+#define N_PCH_SMI_EN_LEGACY_USB 3
+#define N_PCH_SMI_EN_BIOS 2
+#define N_PCH_SMI_EN_EOS 1
+#define N_PCH_SMI_EN_GBL_SMI 0
+
+#define R_PCH_SMI_STS 0x34
+#define S_PCH_SMI_STS 4
+#define B_PCH_SMI_STS_LEGACY_USB3 BIT31
+#define B_PCH_SMI_STS_GPIO_UNLOCK BIT27
+#define B_PCH_SMI_STS_SPI BIT26
+#define B_PCH_SMI_STS_MONITOR BIT21
+#define B_PCH_SMI_STS_PCI_EXP BIT20
+#define B_PCH_SMI_STS_PATCH BIT19
+#define B_PCH_SMI_STS_INTEL_USB2 BIT18
+#define B_PCH_SMI_STS_LEGACY_USB2 BIT17
+#define B_PCH_SMI_STS_SMBUS BIT16
+#define B_PCH_SMI_STS_SERIRQ BIT15
+#define B_PCH_SMI_STS_PERIODIC BIT14
+#define B_PCH_SMI_STS_TCO BIT13
+#define B_PCH_SMI_STS_DEVMON BIT12
+#define B_PCH_SMI_STS_MCSMI BIT11
+#define B_PCH_SMI_STS_GPIO_SMI BIT10
+#define B_PCH_SMI_STS_GPE0 BIT9
+#define B_PCH_SMI_STS_PM1_STS_REG BIT8
+#define B_PCH_SMI_STS_SWSMI_TMR BIT6
+#define B_PCH_SMI_STS_APM BIT5
+#define B_PCH_SMI_STS_ON_SLP_EN BIT4
+#define B_PCH_SMI_STS_LEGACY_USB BIT3
+#define B_PCH_SMI_STS_BIOS BIT2
+#define N_PCH_SMI_STS_LEGACY_USB3 31
+#define N_PCH_SMI_STS_ESPI 28
+#define N_PCH_SMI_STS_GPIO_UNLOCK 27
+#define N_PCH_SMI_STS_SPI 26
+#define N_PCH_SMI_STS_MONITOR 21
+#define N_PCH_SMI_STS_PCI_EXP 20
+#define N_PCH_SMI_STS_PATCH 19
+#define N_PCH_SMI_STS_INTEL_USB2 18
+#define N_PCH_SMI_STS_LEGACY_USB2 17
+#define N_PCH_SMI_STS_SMBUS 16
+#define N_PCH_SMI_STS_SERIRQ 15
+#define N_PCH_SMI_STS_PERIODIC 14
+#define N_PCH_SMI_STS_TCO 13
+#define N_PCH_SMI_STS_DEVMON 12
+#define N_PCH_SMI_STS_MCSMI 11
+#define N_PCH_SMI_STS_GPIO_SMI 10
+#define N_PCH_SMI_STS_GPE0 9
+#define N_PCH_SMI_STS_PM1_STS_REG 8
+#define N_PCH_SMI_STS_SWSMI_TMR 6
+#define N_PCH_SMI_STS_APM 5
+#define N_PCH_SMI_STS_ON_SLP_EN 4
+#define N_PCH_SMI_STS_LEGACY_USB 3
+#define N_PCH_SMI_STS_BIOS 2
+
+#define R_PCH_ACPI_GPE_CNTL 0x40
+#define B_PCH_ACPI_GPE_CNTL_SWGPE_CTRL BIT17
+
+#define R_PCH_DEVACT_STS 0x44
+#define S_PCH_DEVACT_STS 2
+#define B_PCH_DEVACT_STS_MASK 0x13E1
+#define B_PCH_DEVACT_STS_KBC BIT12
+#define B_PCH_DEVACT_STS_PIRQDH BIT9
+#define B_PCH_DEVACT_STS_PIRQCG BIT8
+#define B_PCH_DEVACT_STS_PIRQBF BIT7
+#define B_PCH_DEVACT_STS_PIRQAE BIT6
+#define B_PCH_DEVACT_STS_D0_TRP BIT0
+#define N_PCH_DEVACT_STS_KBC 12
+#define N_PCH_DEVACT_STS_PIRQDH 9
+#define N_PCH_DEVACT_STS_PIRQCG 8
+#define N_PCH_DEVACT_STS_PIRQBF 7
+#define N_PCH_DEVACT_STS_PIRQAE 6
+
+#define R_PCH_ACPI_PM2_CNT 0x50
+#define B_PCH_ACPI_PM2_CNT_ARB_DIS BIT0
+
+#define R_PCH_OC_WDT_CTL 0x54
+#define B_PCH_OC_WDT_CTL_RLD BIT31
+#define B_PCH_OC_WDT_CTL_ICCSURV_STS BIT25
+#define B_PCH_OC_WDT_CTL_NO_ICCSURV_STS BIT24
+#define B_PCH_OC_WDT_CTL_FORCE_ALL BIT15
+#define B_PCH_OC_WDT_CTL_EN BIT14
+#define B_PCH_OC_WDT_CTL_ICCSURV BIT13
+#define B_PCH_OC_WDT_CTL_LCK BIT12
+#define B_PCH_OC_WDT_CTL_TOV_MASK 0x3FF
+#define B_PCH_OC_WDT_CTL_FAILURE_STS BIT23
+#define B_PCH_OC_WDT_CTL_UNXP_RESET_STS BIT22
+#define B_PCH_OC_WDT_CTL_AFTER_POST 0x3F0000
+#define V_PCH_OC_WDT_CTL_STATUS_FAILURE 1
+#define V_PCH_OC_WDT_CTL_STATUS_OK 0
+
+#define R_PCH_ACPI_GPE0_STS_31_0 0x80
+#define R_PCH_ACPI_GPE0_STS_63_32 0x84
+#define R_PCH_ACPI_GPE0_STS_95_64 0x88
+#define R_PCH_ACPI_GPE0_STS_127_96 0x8C
+#define S_PCH_ACPI_GPE0_STS_127_96 4
+#define B_PCH_ACPI_GPE0_STS_127_96_WADT BIT18
+#define B_PCH_ACPI_GPE0_STS_127_96_LAN_WAKE BIT16
+#define B_PCH_ACPI_GPE0_STS_127_96_PME_B0 BIT13
+#define B_PCH_ACPI_GPE0_STS_127_96_ME_SCI BIT12
+#define B_PCH_ACPI_GPE0_STS_127_96_PME BIT11
+#define B_PCH_ACPI_GPE0_STS_127_96_BATLOW BIT10
+#define B_PCH_ACPI_GPE0_STS_127_96_PCI_EXP BIT9
+#define B_PCH_ACPI_GPE0_STS_127_96_RI BIT8
+#define B_PCH_ACPI_GPE0_STS_127_96_SMB_WAK BIT7
+#define B_PCH_ACPI_GPE0_STS_127_96_TC0SCI BIT6
+#define B_PCH_ACPI_GPE0_STS_127_96_SWGPE BIT2
+#define B_PCH_ACPI_GPE0_STS_127_96_HOT_PLUG BIT1
+#define N_PCH_ACPI_GPE0_STS_127_96_PME_B0 13
+#define N_PCH_ACPI_GPE0_STS_127_96_PME 11
+#define N_PCH_ACPI_GPE0_STS_127_96_BATLOW 10
+#define N_PCH_ACPI_GPE0_STS_127_96_PCI_EXP 9
+#define N_PCH_ACPI_GPE0_STS_127_96_RI 8
+#define N_PCH_ACPI_GPE0_STS_127_96_SMB_WAK 7
+#define N_PCH_ACPI_GPE0_STS_127_96_TC0SCI 6
+#define N_PCH_ACPI_GPE0_STS_127_96_SWGPE 2
+#define N_PCH_ACPI_GPE0_STS_127_96_HOT_PLUG 1
+
+#define R_PCH_ACPI_GPE0_EN_31_0 0x90
+#define R_PCH_ACPI_GPE0_EN_63_32 0x94
+#define R_PCH_ACPI_GPE0_EN_95_64 0x98
+#define R_PCH_ACPI_GPE0_EN_127_96 0x9C
+#define S_PCH_ACPI_GPE0_EN_127_96 4
+#define B_PCH_ACPI_GPE0_EN_127_96_WADT BIT18
+#define B_PCH_ACPI_GPE0_EN_127_96_LAN_WAKE BIT16
+#define B_PCH_ACPI_GPE0_EN_127_96_PME_B0 BIT13
+#define B_PCH_ACPI_GPE0_EN_127_96_ME_SCI BIT12
+#define B_PCH_ACPI_GPE0_EN_127_96_PME BIT11
+#define B_PCH_ACPI_GPE0_EN_127_96_BATLOW BIT10
+#define B_PCH_ACPI_GPE0_EN_127_96_PCI_EXP BIT9
+#define B_PCH_ACPI_GPE0_EN_127_96_RI BIT8
+#define B_PCH_ACPI_GPE0_EN_127_96_TC0SCI BIT6
+#define B_PCH_ACPI_GPE0_EN_127_96_SWGPE BIT2
+#define B_PCH_ACPI_GPE0_EN_127_96_HOT_PLUG BIT1
+#define N_PCH_ACPI_GPE0_EN_127_96_PME_B0 13
+#define N_PCH_ACPI_GPE0_EN_127_96_USB3 12
+#define N_PCH_ACPI_GPE0_EN_127_96_PME 11
+#define N_PCH_ACPI_GPE0_EN_127_96_BATLOW 10
+#define N_PCH_ACPI_GPE0_EN_127_96_PCI_EXP 9
+#define N_PCH_ACPI_GPE0_EN_127_96_RI 8
+#define N_PCH_ACPI_GPE0_EN_127_96_TC0SCI 6
+#define N_PCH_ACPI_GPE0_EN_127_96_SWGPE 2
+#define N_PCH_ACPI_GPE0_EN_127_96_HOT_PLUG 1
+
+
+//
+// TCO register I/O map
+//
+#define R_PCH_TCO_RLD 0x0
+#define R_PCH_TCO_DAT_IN 0x2
+#define R_PCH_TCO_DAT_OUT 0x3
+#define R_PCH_TCO1_STS 0x04
+#define S_PCH_TCO1_STS 2
+#define B_PCH_TCO1_STS_DMISERR BIT12
+#define B_PCH_TCO1_STS_DMISMI BIT10
+#define B_PCH_TCO1_STS_DMISCI BIT9
+#define B_PCH_TCO1_STS_BIOSWR BIT8
+#define B_PCH_TCO1_STS_NEWCENTURY BIT7
+#define B_PCH_TCO1_STS_TIMEOUT BIT3
+#define B_PCH_TCO1_STS_TCO_INT BIT2
+#define B_PCH_TCO1_STS_SW_TCO_SMI BIT1
+#define B_PCH_TCO1_STS_NMI2SMI BIT0
+#define N_PCH_TCO1_STS_DMISMI 10
+#define N_PCH_TCO1_STS_BIOSWR 8
+#define N_PCH_TCO1_STS_NEWCENTURY 7
+#define N_PCH_TCO1_STS_TIMEOUT 3
+#define N_PCH_TCO1_STS_SW_TCO_SMI 1
+#define N_PCH_TCO1_STS_NMI2SMI 0
+
+#define R_PCH_TCO2_STS 0x06
+#define S_PCH_TCO2_STS 2
+#define B_PCH_TCO2_STS_SMLINK_SLV_SMI BIT4
+#define B_PCH_TCO2_STS_BAD_BIOS BIT3
+#define B_PCH_TCO2_STS_BOOT BIT2
+#define B_PCH_TCO2_STS_SECOND_TO BIT1
+#define B_PCH_TCO2_STS_INTRD_DET BIT0
+#define N_PCH_TCO2_STS_INTRD_DET 0
+
+#define R_PCH_TCO1_CNT 0x08
+#define S_PCH_TCO1_CNT 2
+#define B_PCH_TCO_CNT_LOCK BIT12
+#define B_PCH_TCO_CNT_TMR_HLT BIT11
+#define B_PCH_TCO_CNT_NMI2SMI_EN BIT9
+#define B_PCH_TCO_CNT_NMI_NOW BIT8
+#define N_PCH_TCO_CNT_NMI2SMI_EN 9
+
+#define R_PCH_TCO2_CNT 0x0A
+#define S_PCH_TCO2_CNT 2
+#define B_PCH_TCO2_CNT_OS_POLICY 0x0030
+#define B_PCH_TCO2_CNT_GPI11_ALERT_DISABLE 0x0008
+#define B_PCH_TCO2_CNT_INTRD_SEL 0x0006
+#define N_PCH_TCO2_CNT_INTRD_SEL 2
+
+#define R_PCH_TCO_MESSAGE1 0x0C
+#define R_PCH_TCO_MESSAGE2 0x0D
+#define R_PCH_TCO_WDCNT 0x0E
+#define R_PCH_TCO_SW_IRQ_GEN 0x10
+#define B_PCH_TCO_IRQ12_CAUSE BIT1
+#define B_PCH_TCO_IRQ1_CAUSE BIT0
+#define R_PCH_TCO_TMR 0x12
+
+//
+// PWRM Registers
+//
+#define R_PCH_WADT_AC 0x0 ///< Wake Alarm Device Timer: AC
+#define R_PCH_WADT_DC 0x4 ///< Wake Alarm Device Timer: DC
+#define R_PCH_WADT_EXP_AC 0x8 ///< Wake Alarm Device Expired Timer: AC
+#define R_PCH_WADT_EXP_DC 0xC ///< Wake Alarm Device Expired Timer: DC
+#define R_PCH_PWRM_PRSTS 0x10 ///< Power and Reset Status
+#define B_PCH_PWRM_PRSTS_VE_WD_TMR_STS BIT7 ///< VE Watchdog Timer Status
+#define B_PCH_PWRM_PRSTS_WOL_OVR_WK_STS BIT5
+#define B_PCH_PWRM_PRSTS_FIELD_1 BIT4
+#define B_PCH_PWRM_PRSTS_ME_WAKE_STS BIT0
+#define R_PCH_PWRM_14 0x14
+#define R_PCH_PWRM_CFG 0x18 ///< Power Management Configuration
+#define B_PCH_PWRM_CFG_ALLOW_24_OSC_SD BIT29 ///< Allow 24MHz Crystal Oscillator Shutdown
+#define B_PCH_PWRM_CFG_ALLOW_USB2_CORE_PG BIT25 ///< Allow USB2 Core Power Gating
+#define B_PCH_PWRM_CFG_RTC_DS_WAKE_DIS BIT21 ///< RTC Wake from Deep S4/S5 Disable
+#define B_PCH_PWRM_CFG_SSMAW_MASK (BIT19 | BIT18) ///< SLP_SUS# Min Assertion Width
+#define V_PCH_PWRM_CFG_SSMAW_4S (BIT19 | BIT18) ///< 4 seconds
+#define V_PCH_PWRM_CFG_SSMAW_1S BIT19 ///< 1 second
+#define V_PCH_PWRM_CFG_SSMAW_0_5S BIT18 ///< 0.5 second (500ms)
+#define V_PCH_PWRM_CFG_SSMAW_0S 0 ///< 0 second
+#define B_PCH_PWRM_CFG_SAMAW_MASK (BIT17 | BIT16) ///< SLP_A# Min Assertion Width
+#define V_PCH_PWRM_CFG_SAMAW_2S (BIT17 | BIT16) ///< 2 seconds
+#define V_PCH_PWRM_CFG_SAMAW_98ms BIT17 ///< 98ms
+#define V_PCH_PWRM_CFG_SAMAW_4S BIT16 ///< 4 seconds
+#define V_PCH_PWRM_CFG_SAMAW_0S 0 ///< 0 second
+#define B_PCH_PWRM_CFG_RPCD_MASK (BIT9 | BIT8) ///< Reset Power Cycle Duration
+#define V_PCH_PWRM_CFG_RPCD_1S (BIT9 | BIT8) ///< 1-2 seconds
+#define V_PCH_PWRM_CFG_RPCD_2S BIT9 ///< 2-3 seconds
+#define V_PCH_PWRM_CFG_RPCD_3S BIT8 ///< 3-4 seconds
+#define V_PCH_PWRM_CFG_RPCD_4S 0 ///< 4-5 seconds (Default)
+#define R_PCH_PWRM_PCH_PM_STS 0x1C ///< Contains misc. fields used to record PCH power management events
+#define B_PCH_PWRM_PCH_PM_STS_PMC_MSG_FULL_STS BIT24 ///< MTPMC transport mechanism full indication
+#define R_PCH_PWRM_MTPMC 0x20 ///< Message to PMC
+#define V_PCH_PWRM_MTPMC_COMMAND_PG_LANE_0_15 0xE ///< Command to override lanes 0-15 power gating
+#define V_PCH_PWRM_MTPMC_COMMAND_PG_LANE_16_31 0xF ///< Command to override lanes 16-31 power gating
+#define B_PCH_PWRM_MTPMC_PG_CMD_DATA 0xFFFF0000 ///< Data part of PowerGate Message to PMC
+#define N_PCH_PWRM_MTPMC_PG_CMD_DATA 16
+#define R_PCH_PWRM_PCH_PM_STS2 0x24 ///< PCH Power Management Status
+#define R_PCH_PWRM_S3_PWRGATE_POL 0x28 ///< S3 Power Gating Policies
+#define B_PCH_PWRM_S3DC_GATE_SUS BIT1 ///< Deep S3 Enable in DC Mode
+#define B_PCH_PWRM_S3AC_GATE_SUS BIT0 ///< Deep S3 Enable in AC Mode
+#define R_PCH_PWRM_S4_PWRGATE_POL 0x2C ///< Deep S4 Power Policies
+#define B_PCH_PWRM_S4DC_GATE_SUS BIT1 ///< Deep S4 Enable in DC Mode
+#define B_PCH_PWRM_S4AC_GATE_SUS BIT0 ///< Deep S4 Enable in AC Mode
+#define R_PCH_PWRM_S5_PWRGATE_POL 0x30 ///< Deep S5 Power Policies
+#define B_PCH_PWRM_S5DC_GATE_SUS BIT15 ///< Deep S5 Enable in DC Mode
+#define B_PCH_PWRM_S5AC_GATE_SUS BIT14 ///< Deep S5 Enable in AC Mode
+#define R_PCH_PWRM_DSX_CFG 0x34 ///< Deep SX Configuration
+#define B_PCH_PWRM_DSX_CFG_WAKE_PIN_DSX_EN BIT2 ///< WAKE# Pin DeepSx Enable
+#define B_PCH_PWRM_DSX_CFG_ACPRES_PD_DSX_DIS BIT1 ///< AC_PRESENT pin pulldown in DeepSx disable
+#define B_PCH_PWRM_DSX_CFG_LAN_WAKE_EN BIT0 ///< LAN_WAKE Pin DeepSx Enable
+#define R_PCH_PWRM_CFG2 0x3C ///< Power Management Configuration Reg 2
+#define B_PCH_PWRM_CFG2_PBOP (BIT31 | BIT30 | BIT29) ///< Power Button Override Period (PBOP)
+#define N_PCH_PWRM_CFG2_PBOP 29 ///< Power Button Override Period (PBOP)
+#define B_PCH_PWRM_CFG2_PB_DIS BIT28 ///< Power Button Native Mode Disable (PB_DIS)
+#define B_PCH_PWRM_CFG2_DRAM_RESET_CTL BIT26 ///< DRAM RESET# control
+#define R_PCH_PWRM_EN_SN_SLOW_RING 0x48 ///< Enable Snoop Request to SLOW_RING
+#define R_PCH_PWRM_EN_SN_SLOW_RING2 0x4C ///< Enable Snoop Request to SLOW_RING 2nd Reg
+#define R_PCH_PWRM_EN_SN_SA 0x50 ///< Enable Snoop Request to SA
+#define R_PCH_PWRM_EN_SN_SA2 0x54 ///< Enable Snoop Request to SA 2nd Reg
+#define R_PCH_PWRM_EN_SN_SLOW_RING_CF 0x58 ///< Enable Snoop Request to SLOW_RING_CF
+#define R_PCH_PWRM_EN_NS_SA 0x68 ///< Enable Non-Snoop Request to SA
+#define R_PCH_PWRM_EN_CW_SLOW_RING 0x80 ///< Enable Clock Wake to SLOW_RING
+#define R_PCH_PWRM_EN_CW_SLOW_RING2 0x84 ///< Enable Clock Wake to SLOW_RING 2nd Reg
+#define R_PCH_PWRM_EN_CW_SA 0x88 ///< Enable Clock Wake to SA
+#define R_PCH_PWRM_EN_CW_SA2 0x8C ///< Enable Clock Wake to SA 2nd Reg
+#define R_PCH_PWRM_EN_CW_SLOW_RING_CF 0x98 ///< Enable Clock Wake to SLOW_RING_CF
+#define R_PCH_PWRM_EN_PA_SLOW_RING 0xA8 ///< Enable Pegged Active to SLOW_RING
+#define R_PCH_PWRM_EN_PA_SLOW_RING2 0xAC ///< Enable Pegged Active to SLOW_RING 2nd Reg
+#define R_PCH_PWRM_EN_PA_SA 0xB0 ///< Enable Pegged Active to SA
+#define R_PCH_PWRM_EN_PA_SA2 0xB4 ///< Enable Pegged Active to SA 2nd Reg
+#define R_PCH_PWRM_EN_MISC_EVENT 0xC0 ///< Enable Misc PM_SYNC Events
+#define R_PCH_PWRM_PMSYNC_TPR_CONFIG 0xC4
+#define B_PCH_PWRM_PMSYNC_TPR_CONFIG_LOCK BIT31
+#define B_PCH_PWRM_PMSYNC_PCH2CPU_TT_EN BIT26
+#define B_PCH_PWRM_PMSYNC_PCH2CPU_TT_STATE (BIT25 | BIT24)
+#define N_PCH_PWRM_PMSYNC_PCH2CPU_TT_STATE 24
+#define V_PCH_PWRM_PMSYNC_PCH2CPU_TT_STATE_1 1
+#define R_PCH_PWRM_PMSYNC_MISC_CFG 0xC8
+#define B_PCH_PWRM_PMSYNC_PM_SYNC_LOCK BIT15 ///< PM_SYNC Configuration Lock
+#define B_PCH_PWRM_PMSYNC_GPIO_D_SEL BIT11
+#define B_PCH_PWRM_PMSYNC_GPIO_C_SEL BIT10
+#define R_PCH_PWRM_PM_SYNC_STATE_HYS 0xD0 ///< PM_SYNC State Hysteresis
+#define R_PCH_PWRM_PM_SYNC_MODE 0xD4 ///< PM_SYNC Pin Mode
+#define R_PCH_PWRM_CFG3 0xE0 ///< Power Management Configuration Reg 3
+#define B_PCH_PWRM_CFG3_DSX_WLAN_PP_EN BIT16 ///< Deep-Sx WLAN Phy Power Enable
+#define B_PCH_PWRM_CFG3_HOST_WLAN_PP_EN BIT17 ///< Host Wireless LAN Phy Power Enable
+#define B_PCH_PWRM_CFG3_PWRG_LOCK BIT2 ///< Lock power gating override messages
+#define R_PCH_PWRM_PM_DOWN_PPB_CFG 0xE4 ///< PM_DOWN PCH_POWER_BUDGET CONFIGURATION
+#define R_PCH_PWRM_CFG4 0xE8 ///< Power Management Configuration Reg 4
+#define B_PCH_PWRM_CFG4_U2_PHY_PG_EN BIT30 ///< USB2 PHY SUS Well Power Gating Enable
+#define B_PCH_PWRM_CFG4_CPU_IOVR_RAMP_DUR (0x000001FF) ///< CPU I/O VR Ramp Duration, [8:0]
+#define N_PCH_PWRM_CFG4_CPU_IOVR_RAMP_DUR 0
+#define V_PCH_PWRM_CFG4_CPU_IOVR_RAMP_DUR_70US 0x007
+#define V_PCH_PWRM_CFG4_CPU_IOVR_RAMP_DUR_240US 0x018
+#define R_PCH_PWRM_CPU_EPOC 0xEC
+#define R_PCH_PWRM_VR_MISC_CTL 0x100
+#define B_PCH_PWRM_VR_MISC_CTL_VIDSOVEN BIT3
+#define R_PCH_PWRM_GPIO_CFG 0x120
+#define B_PCH_PWRM_GPIO_CFG_GPE0_DW2 (BIT11 | BIT10 | BIT9 | BIT8)
+#define N_PCH_PWRM_GPIO_CFG_GPE0_DW2 8
+#define B_PCH_PWRM_GPIO_CFG_GPE0_DW1 (BIT7 | BIT6 | BIT5 | BIT4)
+#define N_PCH_PWRM_GPIO_CFG_GPE0_DW1 4
+#define B_PCH_PWRM_GPIO_CFG_GPE0_DW0 (BIT3 | BIT2 | BIT1 | BIT0)
+#define N_PCH_PWRM_GPIO_CFG_GPE0_DW0 0
+#define R_PCH_PWRM_PM_SYNC_MODE_C0 0xF4 ///< PM_SYNC Pin Mode in C0
+#define R_PCH_PWRM_ACPI_TMR_CTL 0xFC
+#define B_PCH_PWRM_ACPI_TMR_DIS BIT1
+#define R_PCH_PWRM_124 0x124
+#define R_PCH_PWRM_SLP_S0_RESIDENCY_COUNTER 0x13C
+#define R_PCH_PWRM_MODPHY_PM_CFG1 0x200
+#define R_PCH_PWRM_MODPHY_PM_CFG1_MLSXSWPGP 0xFFFF
+#define R_PCH_PWRM_MODPHY_PM_CFG2 0x204 ///< ModPHY Power Management Configuration Reg 2
+#define B_PCH_PWRM_MODPHY_PM_CFG2_MLSPDDGE BIT30 ///< ModPHY Lane SUS Power Domain Dynamic Gating Enable
+#define B_PCH_PWRM_MODPHY_PM_CFG2_EMFC BIT29 ///< Enable ModPHY FET Control
+#define B_PCH_PWRM_MODPHY_PM_CFG2_EFRT (BIT28 | BIT27 | BIT26 | BIT25 | BIT24) ///< External FET Ramp Time
+#define N_PCH_PWRM_MODPHY_PM_CFG2_EFRT 24
+#define V_PCH_PWRM_MODPHY_PM_CFG2_EFRT_200US 0x0A
+#define B_PCH_PWRM_MODPHY_PM_CFG2_ASLOR_UFS BIT16 ///< UFS ModPHY SPD SPD Override
+#define R_PCH_PWRM_MODPHY_PM_CFG3 0x208 ///< ModPHY Power Management Configuration Reg 3
+#define B_PCH_PWRM_MODPHY_PM_CFG3_MSPDRTREQ_UFS BIT16 ///< UFS ModPHY SPD RT Request
+#define B_PCH_PWRM_MODPHY_PM_CFG3_MSPDRTREQ_XDCI BIT15 ///< xDCI ModPHY SPD RT Request
+#define B_PCH_PWRM_MODPHY_PM_CFG3_MSPDRTREQ_XHCI BIT14 ///< xHCI ModPHY SPD RT Request
+#define B_PCH_PWRM_MODPHY_PM_CFG3_MSPDRTREQ_GBE BIT13 ///< GbE ModPHY SPD RT Request
+#define B_PCH_PWRM_MODPHY_PM_CFG3_MSPDRTREQ_SATA BIT12 ///< SATA ModPHY SPD RT Request
+#define R_PCH_PWRM_30C 0x30C
+#define R_PCH_PWRM_OBFF_CFG 0x314 ///< OBFF Configuration
+#define R_PCH_PWRM_31C 0x31C
+#define R_PCH_PWRM_CPPM_MISC_CFG 0x320 ///< CPPM Miscellaneous Configuration
+#define R_PCH_PWRM_CPPM_CG_POL1A 0x324 ///< CPPM Clock Gating Policy Reg 1
+#define R_PCH_PWRM_CPPM_CG_POL2A 0x340 ///< CPPM Clock Gating Policy Reg 3
+#define R_PCH_PWRM_34C 0x34C
+#define R_PCH_PWRM_CPPM_CG_POL3A 0x3A8 ///< CPPM Clock Gating Policy Reg 5
+#define B_PCH_PWRM_CPPM_CG_POLXA_CPPM_GX_QUAL BIT30 ///< CPPM Shutdown Qualifier Enable for Clock Source Group X
+#define B_PCH_PWRM_CPPM_CG_POLXA_LTR_GX_THRESH (0x000001FF) ///< LTR Threshold for Clock Source Group X, [8:0]
+#define R_PCH_PWRM_3D0 0x3D0
+#define R_PCH_PWRM_CPPM_MPG_POL1A 0x3E0 ///< CPPM ModPHY Gating Policy Reg 1A
+#define B_PCH_PWRM_CPPM_MPG_POL1A_CPPM_MODPHY_QUAL BIT30 ///< CPPM Shutdown Qualifier Enable for ModPHY
+#define B_PCH_PWRM_CPPM_MPG_POL1A_LT_MODPHY_SEL BIT29 ///< ASLT/PLT Selection for ModPHY
+#define B_PCH_PWRM_CPPM_MPG_POL1A_LTR_MODPHY_THRESH (0x000001FF) ///< LTR Threshold for ModPHY, [8:0]
+#define R_PCH_PWRM_CS_SD_CTL1 0x3E8 ///< Clock Source Shutdown Control Reg 1
+#define B_PCH_PWRM_CS_SD_CTL1_CS5_CTL_CFG (BIT22 | BIT21 | BIT20) ///< Clock Source 5 Control Configuration
+#define N_PCH_PWRM_CS_SD_CTL1_CS5_CTL_CFG 20
+#define B_PCH_PWRM_CS_SD_CTL1_CS1_CTL_CFG (BIT2 | BIT1 | BIT0) ///< Clock Source 1 Control Configuration
+#define N_PCH_PWRM_CS_SD_CTL1_CS1_CTL_CFG 0
+#define R_PCH_PWRM_CS_SD_CTL2 0x3EC ///< Clock Source Shutdown Control Reg 2
+#define R_PCH_PWRM_HSWPGCR1 0x5D0
+#define B_PCH_PWRM_SW_PG_CTRL_LOCK BIT31
+#define B_PCH_PWRM_DFX_SW_PG_CTRL BIT0
+#define R_PCH_PWRM_600 0x600
+#define R_PCH_PWRM_604 0x604
+#define R_PCH_PWRM_ST_PG_FDIS_PMC_1 0x620 ///< Static PG Related Function Disable Register 1
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_1_ST_FDIS_LK BIT31 ///< Static Function Disable Lock (ST_FDIS_LK)
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_1_CAM_FDIS_PMC BIT6 ///< Camera Function Disable (PMC Version) (CAM_FDIS_PMC)
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_1_ISH_FDIS_PMC BIT5 ///< SH Function Disable (PMC Version) (ISH_FDIS_PMC)
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_1_GBE_FDIS_PMC BIT0 ///< GBE Function Disable (PMC Version) (GBE_FDIS_PMC)
+#define R_PCH_PWRM_ST_PG_FDIS_PMC_2 0x624 ///< Static Function Disable Control Register 2
+#define V_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_FDIS_PMC 0x7FF ///< Static Function Disable Control Register 2
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_GSPI1_FDIS_PMC BIT10 ///< SerialIo Controller GSPI Device 1 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_GSPI0_FDIS_PMC BIT9 ///< SerialIo Controller GSPI Device 0 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_UART2_FDIS_PMC BIT8 ///< SerialIo Controller UART Device 2 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_UART1_FDIS_PMC BIT7 ///< SerialIo Controller UART Device 1 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_UART0_FDIS_PMC BIT6 ///< SerialIo Controller UART Device 0 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C5_FDIS_PMC BIT5 ///< SerialIo Controller I2C Device 5 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C4_FDIS_PMC BIT4 ///< SerialIo Controller I2C Device 4 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C3_FDIS_PMC BIT3 ///< SerialIo Controller I2C Device 3 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C2_FDIS_PMC BIT2 ///< SerialIo Controller I2C Device 2 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C1_FDIS_PMC BIT1 ///< SerialIo Controller I2C Device 1 Function Disable
+#define B_PCH_PWRM_ST_PG_FDIS_PMC_2_SERIALIO_I2C0_FDIS_PMC BIT0 ///< SerialIo Controller I2C Device 0 Function Disable
+#define R_PCH_PWRM_NST_PG_FDIS_1 0x628
+#define B_PCH_PWRM_NST_PG_FDIS_1_SCC_FDIS_PMC BIT25 ///< SCC Function Disable. This is only avaiable in B0 onward.
+#define B_PCH_PWRM_NST_PG_FDIS_1_XDCI_FDIS_PMC BIT24 ///< XDCI Function Disable. This is only avaiable in B0 onward.
+#define B_PCH_PWRM_NST_PG_FDIS_1_ADSP_FDIS_PMC BIT23 ///< ADSP Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_SATA_FDIS_PMC BIT22 ///< SATA Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_C3_FDIS_PMC BIT13 ///< PCIe Controller C Port 3 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_C2_FDIS_PMC BIT12 ///< PCIe Controller C Port 2 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_C1_FDIS_PMC BIT11 ///< PCIe Controller C Port 1 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_C0_FDIS_PMC BIT10 ///< PCIe Controller C Port 0 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_B3_FDIS_PMC BIT9 ///< PCIe Controller B Port 3 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_B2_FDIS_PMC BIT8 ///< PCIe Controller B Port 2 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_B1_FDIS_PMC BIT7 ///< PCIe Controller B Port 1 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_B0_FDIS_PMC BIT6 ///< PCIe Controller B Port 0 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_A3_FDIS_PMC BIT5 ///< PCIe Controller A Port 3 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_A2_FDIS_PMC BIT4 ///< PCIe Controller A Port 2 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_A1_FDIS_PMC BIT3 ///< PCIe Controller A Port 1 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_PCIE_A0_FDIS_PMC BIT2 ///< PCIe Controller A Port 0 Function Disable
+#define B_PCH_PWRM_NST_PG_FDIS_1_XHCI_FDIS_PMC BIT0 ///< XHCI Function Disable
+#define R_PCH_PWRM_FUSE_DIS_RD_1 0x640 ///< Fuse Disable Read 1 Register
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_E3_FUSE_DIS BIT21 ///< PCIe Controller E Port 3 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_E2_FUSE_DIS BIT20 ///< PCIe Controller E Port 2 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_E1_FUSE_DIS BIT19 ///< PCIe Controller E Port 1 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_E0_FUSE_DIS BIT18 ///< PCIe Controller E Port 0 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_D3_FUSE_DIS BIT17 ///< PCIe Controller D Port 3 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_D2_FUSE_DIS BIT16 ///< PCIe Controller D Port 2 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_D1_FUSE_DIS BIT15 ///< PCIe Controller D Port 1 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_D0_FUSE_DIS BIT14 ///< PCIe Controller D Port 0 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_C3_FUSE_DIS BIT13 ///< PCIe Controller C Port 3 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_C2_FUSE_DIS BIT12 ///< PCIe Controller C Port 2 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_C1_FUSE_DIS BIT11 ///< PCIe Controller C Port 1 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_C0_FUSE_DIS BIT10 ///< PCIe Controller C Port 0 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_B3_FUSE_DIS BIT9 ///< PCIe Controller B Port 3 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_B2_FUSE_DIS BIT8 ///< PCIe Controller B Port 2 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_B1_FUSE_DIS BIT7 ///< PCIe Controller B Port 1 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_B0_FUSE_DIS BIT6 ///< PCIe Controller B Port 0 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_A3_FUSE_DIS BIT5 ///< PCIe Controller A Port 3 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_A2_FUSE_DIS BIT4 ///< PCIe Controller A Port 2 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_A1_FUSE_DIS BIT3 ///< PCIe Controller A Port 1 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_PCIE_A0_FUSE_DIS BIT2 ///< PCIe Controller A Port 0 Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_1_XHCI_FUSE_DIS BIT0 ///< XHCI Fuse Disable
+#define R_PCH_PWRM_FUSE_DIS_RD_2 0x644 ///< Fuse Disable Read 2 Register
+#define B_PCH_PWRM_FUSE_DIS_RD_2_SPC_SS_DIS BIT25 ///< SPC Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_SPB_SS_DIS BIT24 ///< SPB Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_SPA_SS_DIS BIT23 ///< SPA Fuse Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_PSTH_FUSE_SS_DIS BIT21 ///< PSTH Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_DMI_FUSE_SS_DIS BIT20 ///< DMI Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_OTG_FUSE_SS_DIS BIT19 ///< OTG Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_XHCI_SS_DIS BIT18 ///< XHCI Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_FIA_FUSE_SS_DIS BIT17 ///< FIA Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_DSP_FUSE_SS_DIS BIT16 ///< DSP Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_SATA_FUSE_SS_DIS BIT15 ///< SATA Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_ICC_FUSE_SS_DIS BIT14 ///< ICC Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_LPC_FUSE_SS_DIS BIT13 ///< LPC Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_RTC_FUSE_SS_DIS BIT12 ///< RTC Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_P2S_FUSE_SS_DIS BIT11 ///< P2S Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_TRSB_FUSE_SS_DIS BIT10 ///< TRSB Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_SMB_FUSE_SS_DIS BIT9 ///< SMB Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_ITSS_FUSE_SS_DIS BIT8 ///< ITSS Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_SERIALIO_FUSE_SS_DIS BIT6 ///< SerialIo Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_SCC_FUSE_SS_DIS BIT4 ///< SCC Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_P2D_FUSE_SS_DIS BIT3 ///< P2D Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_CAM_FUSE_SS_DIS BIT2 ///< Camera Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_ISH_FUSE_SS_DIS BIT1 ///< ISH Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_2_GBE_FUSE_SS_DIS BIT0 ///< GBE Fuse or Soft Strap Disable
+#define R_PCH_PWRM_FUSE_DIS_RD_3 0x648 ///< Static PG Fuse and Soft Strap Disable Read Register 3
+#define B_PCH_PWRM_FUSE_DIS_RD_3_PNCRA3_FUSE_SS_DIS BIT3 ///< PNCRA3 Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_3_PNCRA2_FUSE_SS_DIS BIT2 ///< PNCRA2 Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_3_PNCRA1_FUSE_SS_DIS BIT1 ///< PNCRA1 Fuse or Soft Strap Disable
+#define B_PCH_PWRM_FUSE_DIS_RD_3_PNCRA_FUSE_SS_DIS BIT0 ///< PNCRA Fuse or Soft Strap Disable
+
+
+#endif
diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsSpi.h b/Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsSpi.h
new file mode 100644
index 0000000000..56831b6afe
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Include/Register/PchRegsSpi.h
@@ -0,0 +1,304 @@
+/** @file
+ Register names for PCH SPI device.
+
+ Conventions:
+
+ - Prefixes:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values within the bits
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+ - In general, PCH registers are denoted by "_PCH_" in register names
+ - Registers / bits that are different between PCH generations are denoted by
+ "_PCH_[generation_name]_" in register/bit names.
+ - Registers / bits that are specific to PCH-H denoted by "_H_" in register/bit names.
+ Registers / bits that are specific to PCH-LP denoted by "_LP_" in register/bit names.
+ e.g., "_PCH_H_", "_PCH_LP_"
+ Registers / bits names without _H_ or _LP_ apply for both H and LP.
+ - Registers / bits that are different between SKUs are denoted by "_[SKU_name]"
+ at the end of the register/bit names
+ - Registers / bits of new devices introduced in a PCH generation will be just named
+ as "_PCH_" without [generation_name] inserted.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_REGS_SPI_H_
+#define _PCH_REGS_SPI_H_
+
+//
+// SPI Registers (D31:F5)
+//
+
+#define PCI_DEVICE_NUMBER_PCH_SPI 31
+#define PCI_FUNCTION_NUMBER_PCH_SPI 5
+
+#define R_PCH_SPI_BAR0 0x10
+#define B_PCH_SPI_BAR0_MASK 0x0FFF
+
+#define R_PCH_SPI_BDE 0xD8
+#define B_PCH_SPI_BDE_F8 0x8000
+#define B_PCH_SPI_BDE_F0 0x4000
+#define B_PCH_SPI_BDE_E8 0x2000
+#define B_PCH_SPI_BDE_E0 0x1000
+#define B_PCH_SPI_BDE_D8 0x0800
+#define B_PCH_SPI_BDE_D0 0x0400
+#define B_PCH_SPI_BDE_C8 0x0200
+#define B_PCH_SPI_BDE_C0 0x0100
+#define B_PCH_SPI_BDE_LEG_F 0x0080
+#define B_PCH_SPI_BDE_LEG_E 0x0040
+#define B_PCH_SPI_BDE_70 0x0008
+#define B_PCH_SPI_BDE_60 0x0004
+#define B_PCH_SPI_BDE_50 0x0002
+#define B_PCH_SPI_BDE_40 0x0001
+
+#define R_PCH_SPI_BC 0xDC
+#define S_PCH_SPI_BC 4
+#define N_PCH_SPI_BC_ASE_BWP 11
+#define B_PCH_SPI_BC_ASE_BWP BIT11
+#define N_PCH_SPI_BC_ASYNC_SS 10
+#define B_PCH_SPI_BC_ASYNC_SS BIT10
+#define B_PCH_SPI_BC_OSFH BIT9 ///< OS Function Hide
+#define N_PCH_SPI_BC_SYNC_SS 8
+#define B_PCH_SPI_BC_SYNC_SS BIT8
+#define B_PCH_SPI_BC_BILD BIT7
+#define B_PCH_SPI_BC_BBS BIT6 ///< Boot BIOS strap
+#define N_PCH_SPI_BC_BBS 6
+#define V_PCH_SPI_BC_BBS_SPI 0 ///< Boot BIOS strapped to SPI
+#define V_PCH_SPI_BC_BBS_LPC 1 ///< Boot BIOS strapped to LPC
+#define B_PCH_SPI_BC_EISS BIT5 ///< Enable InSMM.STS
+#define B_PCH_SPI_BC_TSS BIT4
+#define B_PCH_SPI_BC_SRC (BIT3 | BIT2)
+#define N_PCH_SPI_BC_SRC 2
+#define V_PCH_SPI_BC_SRC_PREF_EN_CACHE_EN 0x02 ///< Prefetching and Caching enabled
+#define V_PCH_SPI_BC_SRC_PREF_DIS_CACHE_DIS 0x01 ///< No prefetching and no caching
+#define V_PCH_SPI_BC_SRC_PREF_DIS_CACHE_EN 0x00 ///< No prefetching, but caching enabled
+#define B_PCH_SPI_BC_LE BIT1 ///< Lock Enable
+#define N_PCH_SPI_BC_BLE 1
+#define B_PCH_SPI_BC_WPD BIT0 ///< Write Protect Disable
+
+//
+// BIOS Flash Program Registers (based on SPI_BAR0)
+//
+#define R_PCH_SPI_BFPR 0x00 ///< BIOS Flash Primary Region Register(32bits), which is RO and contains the same value from FREG1
+#define B_PCH_SPI_BFPR_PRL 0x7FFF0000 ///< BIOS Flash Primary Region Limit mask
+#define N_PCH_SPI_BFPR_PRL 16 ///< BIOS Flash Primary Region Limit bit position
+#define B_PCH_SPI_BFPR_PRB 0x00007FFF ///< BIOS Flash Primary Region Base mask
+#define N_PCH_SPI_BFPR_PRB 0 ///< BIOS Flash Primary Region Base bit position
+#define R_PCH_SPI_HSFSC 0x04 ///< Hardware Sequencing Flash Status and Control Register(32bits)
+#define B_PCH_SPI_HSFSC_FSMIE BIT31 ///< Flash SPI SMI# Enable
+#define B_PCH_SPI_HSFSC_FDBC_MASK 0x3F000000 ///< Flash Data Byte Count ( <= 64), Count = (Value in this field) + 1.
+#define N_PCH_SPI_HSFSC_FDBC 24
+#define B_PCH_SPI_HSFSC_CYCLE_MASK 0x001E0000 ///< Flash Cycle.
+#define N_PCH_SPI_HSFSC_CYCLE 17
+#define V_PCH_SPI_HSFSC_CYCLE_READ 0 ///< Flash Cycle Read
+#define V_PCH_SPI_HSFSC_CYCLE_WRITE 2 ///< Flash Cycle Write
+#define V_PCH_SPI_HSFSC_CYCLE_4K_ERASE 3 ///< Flash Cycle 4K Block Erase
+#define V_PCH_SPI_HSFSC_CYCLE_64K_ERASE 4 ///< Flash Cycle 64K Sector Erase
+#define V_PCH_SPI_HSFSC_CYCLE_READ_SFDP 5 ///< Flash Cycle Read SFDP
+#define V_PCH_SPI_HSFSC_CYCLE_READ_JEDEC_ID 6 ///< Flash Cycle Read JEDEC ID
+#define V_PCH_SPI_HSFSC_CYCLE_WRITE_STATUS 7 ///< Flash Cycle Write Status
+#define V_PCH_SPI_HSFSC_CYCLE_READ_STATUS 8 ///< Flash Cycle Read Status
+#define B_PCH_SPI_HSFSC_CYCLE_FGO BIT16 ///< Flash Cycle Go.
+#define B_PCH_SPI_HSFSC_FLOCKDN BIT15 ///< Flash Configuration Lock-Down
+#define B_PCH_SPI_HSFSC_FDV BIT14 ///< Flash Descriptor Valid, once valid software can use hareware sequencing regs
+#define B_PCH_SPI_HSFSC_FDOPSS BIT13 ///< Flash Descriptor Override Pin-Strap Status
+#define B_PCH_SPI_HSFSC_PRR34_LOCKDN BIT12 ///< PRR3 PRR4 Lock-Down
+#define B_PCH_SPI_HSFSC_SAF_CE BIT8 ///< SAF ctype error
+#define B_PCH_SPI_HSFSC_SAF_MODE_ACTIVE BIT7 ///< Indicates flash is attached either directly to the PCH via the SPI bus or EC/BMC
+#define B_PCH_SPI_HSFSC_SAF_LE BIT6 ///< SAF link error
+#define B_PCH_SPI_HSFSC_SCIP BIT5 ///< SPI cycle in progress
+#define B_PCH_SPI_HSFSC_SAF_DLE BIT4 ///< SAF Data length error
+#define B_PCH_SPI_HSFSC_SAF_ERROR BIT3 ///< SAF Error
+#define B_PCH_SPI_HSFSC_AEL BIT2 ///< Access Error Log
+#define B_PCH_SPI_HSFSC_FCERR BIT1 ///< Flash Cycle Error
+#define B_PCH_SPI_HSFSC_FDONE BIT0 ///< Flash Cycle Done
+#define R_PCH_SPI_FADDR 0x08 ///< SPI Flash Address
+#define B_PCH_SPI_FADDR_MASK 0x01FFFFFF ///< SPI Flash Address Mask (0~24bit)
+#define R_PCH_SPI_DLOCK 0x0C ///< Discrete Lock Bits
+#define B_PCH_SPI_DLOCK_PR0LOCKDN BIT8 ///< PR0LOCKDN
+#define R_PCH_SPI_FDATA00 0x10 ///< SPI Data 00 (32 bits)
+#define R_PCH_SPI_FDATA01 0x14 ///< SPI Data 01
+#define R_PCH_SPI_FDATA02 0x18 ///< SPI Data 02
+#define R_PCH_SPI_FDATA03 0x1C ///< SPI Data 03
+#define R_PCH_SPI_FDATA04 0x20 ///< SPI Data 04
+#define R_PCH_SPI_FDATA05 0x24 ///< SPI Data 05
+#define R_PCH_SPI_FDATA06 0x28 ///< SPI Data 06
+#define R_PCH_SPI_FDATA07 0x2C ///< SPI Data 07
+#define R_PCH_SPI_FDATA08 0x30 ///< SPI Data 08
+#define R_PCH_SPI_FDATA09 0x34 ///< SPI Data 09
+#define R_PCH_SPI_FDATA10 0x38 ///< SPI Data 10
+#define R_PCH_SPI_FDATA11 0x3C ///< SPI Data 11
+#define R_PCH_SPI_FDATA12 0x40 ///< SPI Data 12
+#define R_PCH_SPI_FDATA13 0x44 ///< SPI Data 13
+#define R_PCH_SPI_FDATA14 0x48 ///< SPI Data 14
+#define R_PCH_SPI_FDATA15 0x4C ///< SPI Data 15
+#define R_PCH_SPI_FRAP 0x50 ///< Flash Region Access Permisions Register
+#define B_PCH_SPI_FRAP_BRWA_MASK 0x0000FF00 ///< BIOS Region Write Access MASK, Region0~7 - 0: Flash Descriptor; 1: BIOS; 2: ME; 3: GbE; 4: PlatformData
+#define N_PCH_SPI_FRAP_BRWA 8 ///< BIOS Region Write Access bit position
+#define B_PCH_SPI_FRAP_BRRA_MASK 0x000000FF ///< BIOS Region Read Access MASK, Region0~7 - 0: Flash Descriptor; 1: BIOS; 2: ME; 3: GbE; 4: PlatformData
+#define B_PCH_SPI_FRAP_BMRAG_MASK 0x00FF0000 ///< BIOS Master Read Access Grant
+#define B_PCH_SPI_FRAP_BMWAG_MASK 0xFF000000 ///< BIOS Master Write Access Grant
+#define R_PCH_SPI_FREG0_FLASHD 0x54 ///< Flash Region 0(Flash Descriptor)(32bits)
+#define R_PCH_SPI_FREG1_BIOS 0x58 ///< Flash Region 1(BIOS)(32bits)
+#define R_PCH_SPI_FREG2_ME 0x5C ///< Flash Region 2(ME)(32bits)
+#define R_PCH_SPI_FREG3_GBE 0x60 ///< Flash Region 3(GbE)(32bits)
+#define R_PCH_SPI_FREG4_PLATFORM_DATA 0x64 ///< Flash Region 4(Platform Data)(32bits)
+#define R_PCH_SPI_FREG5_DER 0x68 ///< Flash Region 5(Device Expansion Region)(32bits)
+#define S_PCH_SPI_FREGX 4 ///< Size of Flash Region register
+#define B_PCH_SPI_FREGX_LIMIT_MASK 0x7FFF0000 ///< Flash Region Limit [30:16] represents [26:12], [11:0] are assumed to be FFFh
+#define N_PCH_SPI_FREGX_LIMIT 16 ///< Region limit bit position
+#define N_PCH_SPI_FREGX_LIMIT_REPR 12 ///< Region limit bit represents position
+#define B_PCH_SPI_FREGX_BASE_MASK 0x00007FFF ///< Flash Region Base, [14:0] represents [26:12]
+#define N_PCH_SPI_FREGX_BASE 0 ///< Region base bit position
+#define N_PCH_SPI_FREGX_BASE_REPR 12 ///< Region base bit represents position
+#define R_PCH_SPI_PR0 0x84 ///< Protected Region 0 Register
+#define R_PCH_SPI_PR1 0x88 ///< Protected Region 1 Register
+#define R_PCH_SPI_PR2 0x8C ///< Protected Region 2 Register
+#define R_PCH_SPI_PR3 0x90 ///< Protected Region 3 Register
+#define R_PCH_SPI_PR4 0x94 ///< Protected Region 4 Register
+#define S_PCH_SPI_PRX 4 ///< Protected Region X Register size
+#define B_PCH_SPI_PRX_WPE BIT31 ///< Write Protection Enable
+#define B_PCH_SPI_PRX_PRL_MASK 0x7FFF0000 ///< Protected Range Limit Mask, [30:16] here represents upper limit of address [26:12]
+#define N_PCH_SPI_PRX_PRL 16 ///< Protected Range Limit bit position
+#define B_PCH_SPI_PRX_RPE BIT15 ///< Read Protection Enable
+#define B_PCH_SPI_PRX_PRB_MASK 0x00007FFF ///< Protected Range Base Mask, [14:0] here represents base limit of address [26:12]
+#define N_PCH_SPI_PRX_PRB 0 ///< Protected Range Base bit position
+#define R_PCH_SPI_SFRAP 0xB0 ///< Secondary Flash Regions Access Permisions Register
+#define R_PCH_SPI_FDOC 0xB4 ///< Flash Descriptor Observability Control Register(32 bits)
+#define B_PCH_SPI_FDOC_FDSS_MASK (BIT14 | BIT13 | BIT12) ///< Flash Descritor Section Select
+#define V_PCH_SPI_FDOC_FDSS_FSDM 0x0000 ///< Flash Signature and Descriptor Map
+#define V_PCH_SPI_FDOC_FDSS_COMP 0x1000 ///< Component
+#define V_PCH_SPI_FDOC_FDSS_REGN 0x2000 ///< Region
+#define V_PCH_SPI_FDOC_FDSS_MSTR 0x3000 ///< Master
+#define V_PCH_SPI_FDOC_FDSS_PCHS 0x4000 ///< PCH soft straps
+#define V_PCH_SPI_FDOC_FDSS_SFDP 0x5000 ///< SFDP Parameter Table
+#define B_PCH_SPI_FDOC_FDSI_MASK 0x0FFC ///< Flash Descriptor Section Index
+#define R_PCH_SPI_FDOD 0xB8 ///< Flash Descriptor Observability Data Register(32 bits)
+#define R_PCH_SPI_SFDP0_VSCC0 0xC4 ///< Vendor Specific Component Capabilities Register(32 bits)
+#define B_PCH_SPI_SFDPX_VSCCX_CPPTV BIT31 ///< Component Property Parameter Table Valid
+#define B_PCH_SPI_SFDP0_VSCC0_VCL BIT30 ///< Vendor Component Lock
+#define B_PCH_SPI_SFDPX_VSCCX_EO_64K BIT29 ///< 64k Erase valid (EO_64k_valid)
+#define B_PCH_SPI_SFDPX_VSCCX_EO_4K BIT28 ///< 4k Erase valid (EO_4k_valid)
+#define B_PCH_SPI_SFDPX_VSCCX_RPMC BIT27 ///< RPMC Supported
+#define B_PCH_SPI_SFDPX_VSCCX_DPD BIT26 ///< Deep Powerdown Supported
+#define B_PCH_SPI_SFDPX_VSCCX_SUSRES BIT25 ///< Suspend/Resume Supported
+#define B_PCH_SPI_SFDPX_VSCCX_SOFTRES BIT24 ///< Soft Reset Supported
+#define B_PCH_SPI_SFDPX_VSCCX_64k_EO_MASK 0x00FF0000 ///< 64k Erase Opcode (EO_64k)
+#define B_PCH_SPI_SFDPX_VSCCX_4k_EO_MASK 0x0000FF00 ///< 4k Erase Opcode (EO_4k)
+#define B_PCH_SPI_SFDPX_VSCCX_QER (BIT7 | BIT6 | BIT5) ///< Quad Enable Requirements
+#define B_PCH_SPI_SFDPX_VSCCX_WEWS BIT4 ///< Write Enable on Write Status
+#define B_PCH_SPI_SFDPX_VSCCX_WSR BIT3 ///< Write Status Required
+#define B_PCH_SPI_SFDPX_VSCCX_WG_64B BIT2 ///< Write Granularity, 0: 1 Byte; 1: 64 Bytes
+#define R_PCH_SPI_SFDP1_VSCC1 0xC8 ///< Vendor Specific Component Capabilities Register(32 bits)
+#define R_PCH_SPI_PINTX 0xCC ///< Parameter Table Index
+#define N_PCH_SPI_PINTX_SPT 14
+#define V_PCH_SPI_PINTX_SPT_CPT0 0x0 ///< Component 0 Property Parameter Table
+#define V_PCH_SPI_PINTX_SPT_CPT1 0x1 ///< Component 1 Property Parameter Table
+#define N_PCH_SPI_PINTX_HORD 12
+#define V_PCH_SPI_PINTX_HORD_SFDP 0x0 ///< SFDP Header
+#define V_PCH_SPI_PINTX_HORD_PT 0x1 ///< Parameter Table Header
+#define V_PCH_SPI_PINTX_HORD_DATA 0x2 ///< Data
+#define R_PCH_SPI_PTDATA 0xD0 ///< Parameter Table Data
+#define R_PCH_SPI_SBRS 0xD4 ///< SPI Bus Requester Status
+#define R_PCH_SPI_SSML 0xF0 ///< Set Strap Msg Lock
+#define B_PCH_SPI_SSML_SSL BIT0 ///< Set_Strap Lock
+#define R_PCH_SPI_SSMC 0xF4 ///< Set Strap Msg Control
+#define B_PCH_SPI_SSMC_SSMS BIT0 ///< Set_Strap Mux Select
+#define R_PCH_SPI_SSMD 0xF8 ///< Set Strap Msg Data
+//
+// @todo Follow up with EDS owner if it should be 3FFF or FFFF.
+//
+#define B_PCH_SPI_SRD_SSD 0x0000FFFF ///< Set_Strap Data
+//
+// Flash Descriptor Base Address Region (FDBAR) from Flash Region 0
+//
+#define R_PCH_SPI_FDBAR_FLVALSIG 0x00 ///< Flash Valid Signature
+#define V_PCH_SPI_FDBAR_FLVALSIG 0x0FF0A55A
+#define R_PCH_SPI_FDBAR_FLASH_MAP0 0x04
+#define B_PCH_SPI_FDBAR_FCBA 0x000000FF ///< Flash Component Base Address
+#define B_PCH_SPI_FDBAR_NC 0x00000300 ///< Number Of Components
+#define N_PCH_SPI_FDBAR_NC 8 ///< Number Of Components
+#define V_PCH_SPI_FDBAR_NC_1 0x00000000
+#define V_PCH_SPI_FDBAR_NC_2 0x00000100
+#define B_PCH_SPI_FDBAR_FRBA 0x00FF0000 ///< Flash Region Base Address
+#define B_PCH_SPI_FDBAR_NR 0x07000000 ///< Number Of Regions
+#define R_PCH_SPI_FDBAR_FLASH_MAP1 0x08
+#define B_PCH_SPI_FDBAR_FMBA 0x000000FF ///< Flash Master Base Address
+#define B_PCH_SPI_FDBAR_NM 0x00000700 ///< Number Of Masters
+#define B_PCH_SPI_FDBAR_FPSBA 0x00FF0000 ///< PCH Strap Base Address, [23:16] represents [11:4]
+#define N_PCH_SPI_FDBAR_FPSBA 16 ///< PCH Strap base Address bit position
+#define N_PCH_SPI_FDBAR_FPSBA_REPR 4 ///< PCH Strap base Address bit represents position
+#define B_PCH_SPI_FDBAR_PCHSL 0xFF000000 ///< PCH Strap Length, [31:24] represents number of Dwords
+#define N_PCH_SPI_FDBAR_PCHSL 24 ///< PCH Strap Length bit position
+#define R_PCH_SPI_FDBAR_FLASH_MAP2 0x0C
+#define B_PCH_SPI_FDBAR_FCPUSBA 0x000000FF ///< CPU Strap Base Address, [7:0] represents [11:4]
+#define N_PCH_SPI_FDBAR_FCPUSBA 0 ///< CPU Strap Base Address bit position
+#define N_PCH_SPI_FDBAR_FCPUSBA_REPR 4 ///< CPU Strap Base Address bit represents position
+#define B_PCH_SPI_FDBAR_CPUSL 0x0000FF00 ///< CPU Strap Length, [15:8] represents number of Dwords
+#define N_PCH_SPI_FDBAR_CPUSL 8 ///< CPU Strap Length bit position
+//
+// Flash Component Base Address (FCBA) from Flash Region 0
+//
+#define R_PCH_SPI_FCBA_FLCOMP 0x00 ///< Flash Components Register
+#define B_PCH_SPI_FLCOMP_RIDS_FREQ (BIT29 | BIT28 | BIT27) ///< Read ID and Read Status Clock Frequency
+#define B_PCH_SPI_FLCOMP_WE_FREQ (BIT26 | BIT25 | BIT24) ///< Write and Erase Clock Frequency
+#define B_PCH_SPI_FLCOMP_FRCF_FREQ (BIT23 | BIT22 | BIT21) ///< Fast Read Clock Frequency
+#define B_PCH_SPI_FLCOMP_FR_SUP BIT20 ///< Fast Read Support.
+#define B_PCH_SPI_FLCOMP_RC_FREQ (BIT19 | BIT18 | BIT17) ///< Read Clock Frequency.
+#define V_PCH_SPI_FLCOMP_FREQ_48MHZ 0x02
+#define V_PCH_SPI_FLCOMP_FREQ_30MHZ 0x04
+#define V_PCH_SPI_FLCOMP_FREQ_17MHZ 0x06
+#define B_PCH_SPI_FLCOMP_COMP1_MASK 0xF0 ///< Flash Component 1 Size MASK
+#define N_PCH_SPI_FLCOMP_COMP1 4 ///< Flash Component 1 Size bit position
+#define B_PCH_SPI_FLCOMP_COMP0_MASK 0x0F ///< Flash Component 0 Size MASK
+#define V_PCH_SPI_FLCOMP_COMP_512KB 0x80000
+//
+// Descriptor Upper Map Section from Flash Region 0
+//
+#define R_PCH_SPI_FLASH_UMAP1 0xEFC ///< Flash Upper Map 1
+#define B_PCH_SPI_FLASH_UMAP1_VTBA 0x000000FF ///< VSCC Table Base Address
+#define B_PCH_SPI_FLASH_UMAP1_VTL 0x0000FF00 ///< VSCC Table Length
+
+#define R_PCH_SPI_VTBA_JID0 0x00 ///< JEDEC-ID 0 Register
+#define S_PCH_SPI_VTBA_JID0 0x04
+#define B_PCH_SPI_VTBA_JID0_VID 0x000000FF
+#define B_PCH_SPI_VTBA_JID0_DID0 0x0000FF00
+#define B_PCH_SPI_VTBA_JID0_DID1 0x00FF0000
+#define N_PCH_SPI_VTBA_JID0_DID0 0x08
+#define N_PCH_SPI_VTBA_JID0_DID1 0x10
+#define R_PCH_SPI_VTBA_VSCC0 0x04
+#define S_PCH_SPI_VTBA_VSCC0 0x04
+
+
+//
+// SPI Private Configuration Space Registers
+//
+#define R_PCH_PCR_SPI_CLK_CTL 0xC004
+#define R_PCH_PCR_SPI_PWR_CTL 0xC008
+#define R_PCH_PCR_SPI_ESPI_SOFTSTRAPS 0xC210
+#define B_PCH_PCR_SPI_ESPI_SOFTSTRAPS_SLAVE BIT12
+
+//
+// MMP0
+//
+#define R_PCH_SPI_STRP_MMP0 0xC4 ///< MMP0 Soft strap offset
+#define B_PCH_SPI_STRP_MMP0 0x10 ///< MMP0 Soft strap bit
+
+
+#define R_PCH_SPI_STRP_SFDP 0xF0 ///< PCH Soft Strap SFDP
+#define B_PCH_SPI_STRP_SFDP_QIORE BIT3 ///< Quad IO Read Enable
+#define B_PCH_SPI_STRP_SFDP_QORE BIT2 ///< Quad Output Read Enable
+#define B_PCH_SPI_STRP_SFDP_DIORE BIT1 ///< Dual IO Read Enable
+#define B_PCH_SPI_STRP_SFDP_DORE BIT0 ///< Dual Output Read Enable
+
+//
+// Descriptor Record 0
+//
+#define R_PCH_SPI_STRP_DSCR_0 0x00 ///< PCH Soft Strap 0
+#define B_PCH_SPI_STRP_DSCR_0_PTT_SUPP BIT22 ///< PTT Supported
+
+#endif
diff --git a/Silicon/Intel/SimicsIch10Pkg/Include/Register/X58Ich10.h b/Silicon/Intel/SimicsIch10Pkg/Include/Register/X58Ich10.h
new file mode 100644
index 0000000000..12dfb5ce40
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Include/Register/X58Ich10.h
@@ -0,0 +1,113 @@
+/** @file
+ Various register numbers and value bits based on the following publications:
+ - Intel(R) datasheet 319973-003
+ - Intel(R) datasheet 319974-017US
+
+ Copyright (C) 2015, Red Hat, Inc.
+ Copyright (c) 2014, Gabriel L. Somlo <somlo@cmu.edu>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __X58_ICH10_H__
+#define __X58_ICH10_H__
+
+#include <Library/PciLib.h>
+#include <IndustryStandard/Pci22.h>
+
+//
+// Simics Host Bridge DID Address
+//
+#define SIMICS_HOSTBRIDGE_DID \
+ PCI_LIB_ADDRESS (0, 0, 0, PCI_DEVICE_ID_OFFSET)
+
+//
+// Host Bridge Device ID (DID) value for ICH10
+//
+#define INTEL_ICH10_DEVICE_ID 0x3400
+
+//
+// B/D/F/Type: 0/0/0/PCI
+//
+#define DRAMC_REGISTER_Q35(Offset) PCI_LIB_ADDRESS (0, 0, 0, (Offset))
+#define DRAMC_REGISTER_X58(Offset) PCI_LIB_ADDRESS (0, 20, 0, (Offset))
+#define MCH_GGC 0x52
+#define MCH_GGC_IVD BIT1
+
+#define MCH_PCIEXBAR_LOW 0x10C
+#define MCH_PCIEXBAR_LID 0x10E
+#define MCH_PCIEXBAR_SHIFT 16
+#define MCH_PCIEXBAR_LOWMASK 0x0FFFFFFF
+#define MCH_PCIEXBAR_BUS_FF 0
+#define MCH_PCIEXBAR_EN BIT0
+
+#define MCH_PCIEXBAR_HIGH 0x64
+#define MCH_PCIEXBAR_HIGHMASK 0xFFFFFFF0
+
+#define MCH_SMRAM 0x9D
+#define MCH_SMRAM_D_LCK BIT4
+#define MCH_SMRAM_G_SMRAME BIT3
+
+#define MCH_ESMRAMC 0x9E
+#define MCH_ESMRAMC_H_SMRAME BIT7
+#define MCH_ESMRAMC_E_SMERR BIT6
+#define MCH_ESMRAMC_SM_CACHE BIT5
+#define MCH_ESMRAMC_SM_L1 BIT4
+#define MCH_ESMRAMC_SM_L2 BIT3
+#define MCH_ESMRAMC_TSEG_8MB BIT3
+#define MCH_ESMRAMC_TSEG_2MB BIT2
+#define MCH_ESMRAMC_TSEG_1MB BIT1
+#define MCH_ESMRAMC_TSEG_MASK (BIT3 | BIT2 | BIT1)
+#define MCH_ESMRAMC_T_EN BIT0
+
+#define MCH_GBSM 0xA4
+#define MCH_GBSM_MB_SHIFT 20
+
+#define MCH_BGSM 0xA8
+#define MCH_BGSM_MB_SHIFT 20
+
+#define MCH_TSEGMB 0xA8
+#define MCH_TSEGMB_MB_SHIFT 20
+
+#define MCH_TOLUD 0xD0
+
+//
+// B/D/F/Type: 0/0x1f/0/PCI
+//
+#define POWER_MGMT_REGISTER_ICH10(Offset) \
+ PCI_LIB_ADDRESS (0, 0x1f, 0, (Offset))
+
+#define ICH10_PMBASE 0x40
+#define ICH10_PMBASE_MASK (BIT15 | BIT14 | BIT13 | BIT12 | BIT11 | \
+ BIT10 | BIT9 | BIT8 | BIT7)
+
+#define ICH10_ACPI_CNTL 0x44
+#define ICH10_ACPI_CNTL_ACPI_EN BIT7
+
+#define ICH10_GEN_PMCON_1 0xA0
+#define ICH10_GEN_PMCON_1_SMI_LOCK BIT4
+
+#define ICH10_RCBA 0xF0
+#define ICH10_RCBA_EN BIT0
+
+#define ICH10_PMBASE_IO 0x400
+//
+// IO ports
+//
+#define ICH10_APM_CNT 0xB2
+#define ICH10_APM_STS 0xB3
+
+//
+// IO ports relative to PMBASE
+//
+#define ICH10_PMBASE_OFS_SMI_EN 0x30
+#define ICH10_SMI_EN_APMC_EN BIT5
+#define ICH10_SMI_EN_GBL_SMI_EN BIT0
+#define ICH10_SMI_EN_EOS BIT1 // End of SMI
+
+#define ICH10_PMBASE_OFS_SMI_STS 0x34
+#define ICH10_SMI_STS_APM BIT5 // APM Status
+
+#define ICH10_ROOT_COMPLEX_BASE 0xFED1C000
+
+#endif
diff --git a/Silicon/Intel/SimicsIch10Pkg/IncludePrivate/Library/PchSpiCommonLib.h b/Silicon/Intel/SimicsIch10Pkg/IncludePrivate/Library/PchSpiCommonLib.h
new file mode 100644
index 0000000000..cf60f1fd58
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/IncludePrivate/Library/PchSpiCommonLib.h
@@ -0,0 +1,396 @@
+/** @file
+ Header file for the PCH SPI Common Driver.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SPI_COMMON_LIB_H_
+#define _PCH_SPI_COMMON_LIB_H_
+
+//
+// Maximum time allowed while waiting the SPI cycle to complete
+// Wait Time = 6 seconds = 6000000 microseconds
+// Wait Period = 10 microseconds
+//
+#define SPI_WAIT_TIME 6000000 ///< Wait Time = 6 seconds = 6000000 microseconds
+#define SPI_WAIT_PERIOD 10 ///< Wait Period = 10 microseconds
+
+///
+/// Flash cycle Type
+///
+typedef enum {
+ FlashCycleRead,
+ FlashCycleWrite,
+ FlashCycleErase,
+ FlashCycleReadSfdp,
+ FlashCycleReadJedecId,
+ FlashCycleWriteStatus,
+ FlashCycleReadStatus,
+ FlashCycleMax
+} FLASH_CYCLE_TYPE;
+
+///
+/// Flash Component Number
+///
+typedef enum {
+ FlashComponent0,
+ FlashComponent1,
+ FlashComponentMax
+} FLASH_COMPONENT_NUM;
+
+///
+/// Private data structure definitions for the driver
+///
+#define PCH_SPI_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('P', 'S', 'P', 'I')
+
+typedef struct {
+ UINT32 Signature;
+ EFI_HANDLE Handle;
+ EFI_SPI_PROTOCOL SpiProtocol;
+ UINT16 PchAcpiBase;
+ UINTN PchSpiBase;
+ UINT16 ReadPermission;
+ UINT16 WritePermission;
+ UINT32 SfdpVscc0Value;
+ UINT32 SfdpVscc1Value;
+ UINT16 PchStrapBaseAddr;
+ UINT16 PchStrapSize;
+ UINT16 CpuStrapBaseAddr;
+ UINT16 CpuStrapSize;
+ UINT8 NumberOfComponents;
+ UINT32 Component1StartAddr;
+ UINT32 TotalFlashSize;
+} SPI_INSTANCE;
+
+#define SPI_INSTANCE_FROM_SPIPROTOCOL(a) CR (a, SPI_INSTANCE, SpiProtocol, PCH_SPI_PRIVATE_DATA_SIGNATURE)
+
+//
+// Function prototypes used by the SPI protocol.
+//
+
+/**
+ Initialize an SPI protocol instance.
+
+ @param[in] SpiInstance Pointer to SpiInstance to initialize
+
+ @retval EFI_SUCCESS The protocol instance was properly initialized
+ @exception EFI_UNSUPPORTED The PCH is not supported by this module
+**/
+EFI_STATUS
+SpiProtocolConstructor (
+ IN SPI_INSTANCE *SpiInstance
+ );
+
+/**
+ This function is a hook for Spi to disable BIOS Write Protect
+
+ @retval EFI_SUCCESS The protocol instance was properly initialized
+ @retval EFI_ACCESS_DENIED The BIOS Region can only be updated in SMM phase
+
+**/
+EFI_STATUS
+EFIAPI
+DisableBiosWriteProtect (
+ VOID
+ );
+
+/**
+ This function is a hook for Spi to enable BIOS Write Protect
+
+
+**/
+VOID
+EFIAPI
+EnableBiosWriteProtect (
+ VOID
+ );
+
+/**
+ Acquire pch spi mmio address.
+
+ @param[in] SpiInstance Pointer to SpiInstance to initialize
+
+ @retval PchSpiBar0 return SPI MMIO address
+**/
+UINTN
+AcquireSpiBar0 (
+ IN SPI_INSTANCE *SpiInstance
+ );
+
+/**
+ Release pch spi mmio address.
+
+ @param[in] SpiInstance Pointer to SpiInstance to initialize
+
+ @retval None
+**/
+VOID
+ReleaseSpiBar0 (
+ IN SPI_INSTANCE *SpiInstance
+ );
+
+/**
+ Read data from the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+ @param[out] Buffer The Pointer to caller-allocated buffer containing the dada received.
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashRead (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ OUT UINT8 *Buffer
+ );
+
+/**
+ Write data to the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+ @param[in] Buffer Pointer to caller-allocated buffer containing the data sent during the SPI cycle.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashWrite (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ IN UINT8 *Buffer
+ );
+
+/**
+ Erase some area on the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashErase (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount
+ );
+
+/**
+ Read SFDP data from the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ComponentNumber The Componen Number for chip select
+ @param[in] Address The starting byte address for SFDP data read.
+ @param[in] ByteCount Number of bytes in SFDP data portion of the SPI cycle
+ @param[out] SfdpData The Pointer to caller-allocated buffer containing the SFDP data received
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadSfdp (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT8 ComponentNumber,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ OUT UINT8 *SfdpData
+ );
+
+/**
+ Read Jedec Id from the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ComponentNumber The Componen Number for chip select
+ @param[in] ByteCount Number of bytes in JedecId data portion of the SPI cycle, the data size is 3 typically
+ @param[out] JedecId The Pointer to caller-allocated buffer containing JEDEC ID received
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadJedecId (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT8 ComponentNumber,
+ IN UINT32 ByteCount,
+ OUT UINT8 *JedecId
+ );
+
+/**
+ Write the status register in the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ByteCount Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+ @param[in] StatusValue The Pointer to caller-allocated buffer containing the value of Status register writing
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashWriteStatus (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 ByteCount,
+ IN UINT8 *StatusValue
+ );
+
+/**
+ Read status register in the flash part.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] ByteCount Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+ @param[out] StatusValue The Pointer to caller-allocated buffer containing the value of Status register received.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadStatus (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 ByteCount,
+ OUT UINT8 *StatusValue
+ );
+
+/**
+ Get the SPI region base and size, based on the enum type
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] FlashRegionType The Flash Region type for for the base address which is listed in the Descriptor.
+ @param[out] BaseAddress The Flash Linear Address for the Region 'n' Base
+ @param[out] RegionSize The size for the Region 'n'
+
+ @retval EFI_SUCCESS Read success
+ @retval EFI_INVALID_PARAMETER Invalid region type given
+ @retval EFI_DEVICE_ERROR The region is not used
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolGetRegionAddress (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ OUT UINT32 *BaseAddress,
+ OUT UINT32 *RegionSize
+ );
+
+/**
+ Read PCH Soft Strap Values
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] SoftStrapAddr PCH Soft Strap address offset from FPSBA.
+ @param[in] ByteCount Number of bytes in SoftStrap data portion of the SPI cycle
+ @param[out] SoftStrapValue The Pointer to caller-allocated buffer containing PCH Soft Strap Value.
+ If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolReadPchSoftStrap (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 SoftStrapAddr,
+ IN UINT32 ByteCount,
+ OUT VOID *SoftStrapValue
+ );
+
+/**
+ Read CPU Soft Strap Values
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] SoftStrapAddr CPU Soft Strap address offset from FCPUSBA.
+ @param[in] ByteCount Number of bytes in SoftStrap data portion of the SPI cycle.
+ @param[out] SoftStrapValue The Pointer to caller-allocated buffer containing CPU Soft Strap Value.
+ If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolReadCpuSoftStrap (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT32 SoftStrapAddr,
+ IN UINT32 ByteCount,
+ OUT VOID *SoftStrapValue
+ );
+
+/**
+ This function sends the programmed SPI command to the slave device.
+
+ @param[in] This Pointer to the PCH_SPI_PROTOCOL instance.
+ @param[in] SpiRegionType The SPI Region type for flash cycle which is listed in the Descriptor
+ @param[in] FlashCycleType The Flash SPI cycle type list in HSFC (Hardware Sequencing Flash Control Register) register
+ @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
+ @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
+ @param[in,out] Buffer Pointer to caller-allocated buffer containing the dada received or sent during the SPI cycle.
+
+ @retval EFI_SUCCESS SPI command completes successfully.
+ @retval EFI_DEVICE_ERROR Device error, the command aborts abnormally.
+ @retval EFI_ACCESS_DENIED Some unrecognized command encountered in hardware sequencing mode
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+**/
+EFI_STATUS
+SendSpiCmd (
+ IN EFI_SPI_PROTOCOL *This,
+ IN FLASH_REGION_TYPE FlashRegionType,
+ IN FLASH_CYCLE_TYPE FlashCycleType,
+ IN UINT32 Address,
+ IN UINT32 ByteCount,
+ IN OUT UINT8 *Buffer
+ );
+
+/**
+ Wait execution cycle to complete on the SPI interface.
+
+ @param[in] This The SPI protocol instance
+ @param[in] PchSpiBar0 Spi MMIO base address
+ @param[in] ErrorCheck TRUE if the SpiCycle needs to do the error check
+
+ @retval TRUE SPI cycle completed on the interface.
+ @retval FALSE Time out while waiting the SPI cycle to complete.
+ It's not safe to program the next command on the SPI interface.
+**/
+BOOLEAN
+WaitForSpiCycleComplete (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINTN PchSpiBar0,
+ IN BOOLEAN ErrorCheck
+ );
+
+#endif
diff --git a/Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.inf b/Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.inf
new file mode 100644
index 0000000000..7b50ee8867
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Library/ResetSystemLib/ResetSystemLib.inf
@@ -0,0 +1,34 @@
+## @file
+# Library instance for ResetSystem library class for OVMF
+#
+# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ResetSystemLib
+ FILE_GUID = 66564872-21d4-4d2a-a68b-1e844f980820
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ResetSystemLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ ResetSystemLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[LibraryClasses]
+ DebugLib
+ IoLib
+ TimerLib
diff --git a/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf b/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
new file mode 100644
index 0000000000..23b334a080
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
@@ -0,0 +1,50 @@
+## @file
+# SMM Library instance of Spi Flash Common Library Class
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = SmmSpiFlashCommonLib
+ FILE_GUID = 9632D96E-E849-4217-9217-DC500B8AAE47
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_SMM_DRIVER
+ LIBRARY_CLASS = SpiFlashCommonLib|DXE_SMM_DRIVER
+ CONSTRUCTOR = SmmSpiFlashCommonLibConstructor
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[LibraryClasses]
+ PciLib
+ IoLib
+ MemoryAllocationLib
+ BaseLib
+ UefiLib
+ SmmServicesTableLib
+ BaseMemoryLib
+ DebugLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[Pcd]
+ gEfiPchTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
+ gEfiPchTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
+
+[Sources]
+ SpiFlashCommonSmmLib.c
+ SpiFlashCommon.c
+
+[Protocols]
+ gEfiSmmSpiProtocolGuid ## CONSUMES
+
+[Depex.X64.DXE_SMM_DRIVER]
+ gEfiSmmSpiProtocolGuid
diff --git a/Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePchSpiCommonLib.inf b/Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePchSpiCommonLib.inf
new file mode 100644
index 0000000000..df1da274a6
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePchSpiCommonLib.inf
@@ -0,0 +1,31 @@
+## @file
+# Component description file for the PchSpiCommonLib
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BasePchSpiCommonLib
+ FILE_GUID = A37CB67E-7D85-45B3-B07E-BF65BDB603E8
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PchSpiCommonLib
+
+[Sources]
+ SpiCommon.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[LibraryClasses]
+ IoLib
+ DebugLib
+
+[Pcd]
+ gEfiPchTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
+ gEfiPchTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
diff --git a/Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf b/Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
new file mode 100644
index 0000000000..d8bc156dca
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
@@ -0,0 +1,61 @@
+## @file
+# A DXE_RUNTIME_DRIVER providing synchronous SMI activations via the
+# EFI_SMM_CONTROL2_PROTOCOL.
+#
+# We expect the PEI phase to have covered the following:
+# - ensure that the underlying QEMU machine type be X58
+# (responsible: OvmfPkg/SmmAccess/SmmAccessPei.inf)
+# - ensure that the ACPI PM IO space be configured
+# (responsible: OvmfPkg/PlatformPei/PlatformPei.inf)
+#
+# Our own entry point is responsible for confirming the SMI feature and for
+# configuring it.
+#
+# Copyright (C) 2013, 2015, Red Hat, Inc.
+# Copyright (C) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmmControl2Dxe
+ FILE_GUID = 1206F7CA-A475-4624-A83E-E6FC9BB38E49
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010400
+ ENTRY_POINT = SmmControl2DxeEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ SmmControl2Dxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SimicsX58SktPkg/SktPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ IoLib
+ PcdLib
+ PciLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEfiS3SaveStateProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiSmmControl2ProtocolGuid ## PRODUCES
+
+[FeaturePcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
+
+[Depex]
+ TRUE
diff --git a/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.h b/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.h
new file mode 100644
index 0000000000..6ada9b121d
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpi.h
@@ -0,0 +1,23 @@
+/** @file
+ Header file for the PCH SPI SMM Driver.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SPI_H_
+#define _PCH_SPI_H_
+
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <PchAccess.h>
+#include <Protocol/Spi.h>
+#include <IncludePrivate/Library/PchSpiCommonLib.h>
+
+#endif
diff --git a/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpiSmm.inf b/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpiSmm.inf
new file mode 100644
index 0000000000..7b60d36c5b
--- /dev/null
+++ b/Silicon/Intel/SimicsIch10Pkg/Spi/Smm/PchSpiSmm.inf
@@ -0,0 +1,44 @@
+## @file
+# Component description file for the SPI SMM driver.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = PchSpiSmm
+ FILE_GUID = 27F4917B-A707-4aad-9676-26DF168CBF0D
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_SMM_DRIVER
+ PI_SPECIFICATION_VERSION = 1.10
+ ENTRY_POINT = InstallPchSpi
+
+
+ [LibraryClasses]
+ DebugLib
+ IoLib
+ UefiDriverEntryPoint
+ UefiBootServicesTableLib
+ BaseLib
+ SmmServicesTableLib
+ PchSpiCommonLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[Sources]
+ PchSpi.h
+ PchSpi.c
+
+
+[Protocols]
+ gEfiSmmSpiProtocolGuid # PRODUCES #SERVER_BIOS
+
+
+[Depex]
+ gEfiSmmBase2ProtocolGuid #This is for SmmServicesTableLib
+ AND gEfiSmmCpuProtocolGuid # This is for CpuSmmDisableBiosWriteProtect()
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [edk2-platforms PATCH v2 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules
2019-08-28 0:40 ` [edk2-platforms PATCH v2 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules David Wei
@ 2019-08-28 22:02 ` Nate DeSimone
0 siblings, 0 replies; 16+ messages in thread
From: Nate DeSimone @ 2019-08-28 22:02 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Kubacki, Michael A, Kinney, Michael D
1. Update copyright year on SimicsBoardConfig.h, I440FxPiix4.h, SerializeVariablesLib.h, PciHostBridgeLib.c, PciHostBridgeLib.inf, PeiReportFvLib.c, PeiReportFvLib.inf, SecMain.c, Platform.h, Platform.c, Platform.uni, PlatformConfig.h, PlatformConfig.c, PlatformForms.vfr, SimicsDxe.inf, FeatureControl.c, Platform.c, SmbiosPlatformDxe.h, SmbiosPlatformDxe.c, SmbiosPlatformDxe.inf
2. Logo.c, OEMBadging.h - Remove interspersed trailing whitespace
3. Please rename Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/OEMBadging.h to follow Pascal casing: OemBadging.h
4. PciHostBridgeLib.inf, PlatformConfig.h - Update OVMF to Simics
-----Original Message-----
From: Wei, David Y
Sent: Tuesday, August 27, 2019 5:40 PM
To: devel@edk2.groups.io
Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Kubacki, Michael A <michael.a.kubacki@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: [edk2-platforms PATCH v2 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules
Add modules AcpiTables, Include, Library, SimicsDxe, SimicsPei, Policy, SmbiosPlatformDxe
and SecCore for Simics QSP platform support
Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c | 647 ++++++++
.../Library/LoadLinuxLib/Linux.c | 662 +++++++++
.../Library/LoadLinuxLib/LinuxGdt.c | 175 +++
.../Library/NvVarsFileLib/FsAccess.c | 507 +++++++
.../Library/NvVarsFileLib/NvVarsFileLib.c | 77 +
.../Library/PciHostBridgeLib/PciHostBridgeLib.c | 419 ++++++
.../SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c | 100 ++
.../Library/PeiReportFvLib/PeiReportFvLib.c | 118 ++
.../Library/PlatformBootManagerLib/BdsPlatform.c | 1553 ++++++++++++++++++++
.../Library/PlatformBootManagerLib/PlatformData.c | 35 +
.../SerializeVariablesLib/SerializeVariablesLib.c | 869 +++++++++++
.../SiliconPolicyInitLib/SiliconPolicyInitLib.c | 108 ++
.../SiliconPolicyUpdateLib.c | 70 +
.../Intel/SimicsOpenBoardPkg/SecCore/SecMain.c | 956 ++++++++++++
.../Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c | 865 +++++++++++
.../SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c | 123 ++
Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c | 57 +
.../SimicsOpenBoardPkg/SimicsPei/FeatureControl.c | 114 ++
.../Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c | 568 +++++++
.../Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c | 630 ++++++++
.../SmbiosPlatformDxe/SmbiosPlatformDxe.c | 148 ++
.../SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf | 31 +
.../Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl | 821 +++++++++++
.../Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h | 75 +
.../Include/Guid/SimicsBoardConfig.h | 17 +
.../Include/IndustryStandard/I440FxPiix4.h | 49 +
.../Include/IndustryStandard/LinuxBzImage.h | 158 ++
.../Include/Library/LoadLinuxLib.h | 205 +++
.../Include/Library/SerializeVariablesLib.h | 223 +++
.../SimicsOpenBoardPkg/Include/SimicsPlatforms.h | 55 +
.../Library/DxeLogoLib/DxeLogoLib.inf | 55 +
.../Library/DxeLogoLib/OEMBadging.h | 83 ++
.../Library/LoadLinuxLib/DxeLoadLinuxLib.inf | 42 +
.../Library/LoadLinuxLib/Ia32/JumpToKernel.nasm | 41 +
.../Library/LoadLinuxLib/LoadLinuxLib.h | 52 +
.../Library/LoadLinuxLib/X64/JumpToKernel.nasm | 85 ++
.../Library/NvVarsFileLib/NvVarsFileLib.h | 55 +
.../Library/NvVarsFileLib/NvVarsFileLib.inf | 53 +
.../Library/PciHostBridgeLib/PciHostBridge.h | 68 +
.../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 51 +
.../Library/PeiReportFvLib/PeiReportFvLib.inf | 56 +
.../Library/PlatformBootManagerLib/BdsPlatform.h | 172 +++
.../PlatformBootManagerLib.inf | 72 +
.../SerializeVariablesLib/SerializeVariablesLib.h | 33 +
.../SerializeVariablesLib.inf | 36 +
.../SiliconPolicyInitLib/SiliconPolicyInitLib.inf | 38 +
.../SiliconPolicyUpdateLib.inf | 35 +
.../SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm | 45 +
.../Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf | 73 +
.../SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm | 45 +
.../Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h | 37 +
.../SimicsOpenBoardPkg/SimicsDxe/Platform.uni | 31 +
.../SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h | 51 +
.../SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr | 67 +
.../SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf | 65 +
Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h | 50 +
.../Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h | 88 ++
.../SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf | 104 ++
.../SmbiosPlatformDxe/SmbiosPlatformDxe.h | 38 +
.../SmbiosPlatformDxe/SmbiosPlatformDxe.inf | 51 +
60 files changed, 12207 insertions(+)
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/PlatformData.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/FeatureControl.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsBoardConfig.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/I440FxPiix4.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/LinuxBzImage.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Library/LoadLinuxLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Library/SerializeVariablesLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/DxeLogoLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/OEMBadging.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/DxeLoadLinuxLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.nasm
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel.nasm
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridge.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c
new file mode 100644
index 0000000000..4a75f3673f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/Logo.c
@@ -0,0 +1,647 @@
+/** @file
+ BDS Lib functions which contain all the code to connect console device
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiDxe.h>
+#include <Protocol/SimpleTextOut.h>
+#include <OEMBadging.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/UgaDraw.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+
+#include <IndustryStandard/Bmp.h>
+#include <Protocol/BootLogo.h>
+
+/**
+ Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer
+ is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt
+ buffer is passed in it will be used if it is big enough.
+
+ @param BmpImage Pointer to BMP file
+ @param BmpImageSize Number of bytes in BmpImage
+ @param GopBlt Buffer containing GOP version of BmpImage.
+ @param GopBltSize Size of GopBlt in bytes.
+ @param PixelHeight Height of GopBlt/BmpImage in pixels
+ @param PixelWidth Width of GopBlt/BmpImage in pixels
+
+ @retval EFI_SUCCESS GopBlt and GopBltSize are returned.
+ @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image
+ @retval EFI_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big enough.
+ GopBltSize will contain the required size.
+ @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate.
+
+**/
+EFI_STATUS
+ConvertBmpToGopBlt (
+ IN VOID *BmpImage,
+ IN UINTN BmpImageSize,
+ IN OUT VOID **GopBlt,
+ IN OUT UINTN *GopBltSize,
+ OUT UINTN *PixelHeight,
+ OUT UINTN *PixelWidth
+ )
+{
+ UINT8 *Image;
+ UINT8 *ImageHeader;
+ BMP_IMAGE_HEADER *BmpHeader;
+ BMP_COLOR_MAP *BmpColorMap;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
+ UINT64 BltBufferSize;
+ UINTN Index;
+ UINTN Height;
+ UINTN Width;
+ UINTN ImageIndex;
+ UINT32 DataSizePerLine;
+ BOOLEAN IsAllocated;
+ UINT32 ColorMapNum;
+
+ if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;
+
+ if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Doesn't support compress.
+ //
+ if (BmpHeader->CompressionType != 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Only support BITMAPINFOHEADER format.
+ // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER
+ //
+ if (BmpHeader->HeaderSize != sizeof (BMP_IMAGE_HEADER) - OFFSET_OF(BMP_IMAGE_HEADER, HeaderSize)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // The data size in each line must be 4 byte alignment.
+ //
+ DataSizePerLine = ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel + 31) >> 3) & (~0x3);
+ BltBufferSize = MultU64x32 (DataSizePerLine, BmpHeader->PixelHeight);
+ if (BltBufferSize > (UINT32) ~0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((BmpHeader->Size != BmpImageSize) ||
+ (BmpHeader->Size < BmpHeader->ImageOffset) ||
+ (BmpHeader->Size - BmpHeader->ImageOffset != BmpHeader->PixelHeight * DataSizePerLine)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Calculate Color Map offset in the image.
+ //
+ Image = BmpImage;
+ BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));
+ if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) {
+ switch (BmpHeader->BitPerPixel) {
+ case 1:
+ ColorMapNum = 2;
+ break;
+ case 4:
+ ColorMapNum = 16;
+ break;
+ case 8:
+ ColorMapNum = 256;
+ break;
+ default:
+ ColorMapNum = 0;
+ break;
+ }
+ //
+ // BMP file may has padding data between the bmp header section and the bmp data section.
+ //
+ if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) < sizeof (BMP_COLOR_MAP) * ColorMapNum) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
+ // Calculate graphics image data address in the image
+ //
+ Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;
+ ImageHeader = Image;
+
+ //
+ // Calculate the BltBuffer needed size.
+ //
+ BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight);
+ //
+ // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
+ //
+ if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+ return EFI_UNSUPPORTED;
+ }
+ BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+
+ IsAllocated = FALSE;
+ if (*GopBlt == NULL) {
+ //
+ // GopBlt is not allocated by caller.
+ //
+ *GopBltSize = (UINTN) BltBufferSize;
+ *GopBlt = AllocatePool (*GopBltSize);
+ IsAllocated = TRUE;
+ if (*GopBlt == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else {
+ //
+ // GopBlt has been allocated by caller.
+ //
+ if (*GopBltSize < (UINTN) BltBufferSize) {
+ *GopBltSize = (UINTN) BltBufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ }
+
+ *PixelWidth = BmpHeader->PixelWidth;
+ *PixelHeight = BmpHeader->PixelHeight;
+
+ //
+ // Convert image from BMP to Blt buffer format
+ //
+ BltBuffer = *GopBlt;
+ for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {
+ Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];
+ for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {
+ switch (BmpHeader->BitPerPixel) {
+ case 1:
+ //
+ // Convert 1-bit (2 colors) BMP to 24-bit color
+ //
+ for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {
+ Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;
+ Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;
+ Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;
+ Blt++;
+ Width++;
+ }
+
+ Blt--;
+ Width--;
+ break;
+
+ case 4:
+ //
+ // Convert 4-bit (16 colors) BMP Palette to 24-bit color
+ //
+ Index = (*Image) >> 4;
+ Blt->Red = BmpColorMap[Index].Red;
+ Blt->Green = BmpColorMap[Index].Green;
+ Blt->Blue = BmpColorMap[Index].Blue;
+ if (Width < (BmpHeader->PixelWidth - 1)) {
+ Blt++;
+ Width++;
+ Index = (*Image) & 0x0f;
+ Blt->Red = BmpColorMap[Index].Red;
+ Blt->Green = BmpColorMap[Index].Green;
+ Blt->Blue = BmpColorMap[Index].Blue;
+ }
+ break;
+
+ case 8:
+ //
+ // Convert 8-bit (256 colors) BMP Palette to 24-bit color
+ //
+ Blt->Red = BmpColorMap[*Image].Red;
+ Blt->Green = BmpColorMap[*Image].Green;
+ Blt->Blue = BmpColorMap[*Image].Blue;
+ break;
+
+ case 24:
+ //
+ // It is 24-bit BMP.
+ //
+ Blt->Blue = *Image++;
+ Blt->Green = *Image++;
+ Blt->Red = *Image;
+ break;
+
+ default:
+ //
+ // Other bit format BMP is not supported.
+ //
+ if (IsAllocated) {
+ FreePool (*GopBlt);
+ *GopBlt = NULL;
+ }
+ return EFI_UNSUPPORTED;
+ break;
+ };
+
+ }
+
+ ImageIndex = (UINTN) (Image - ImageHeader);
+ if ((ImageIndex % 4) != 0) {
+ //
+ // Bmp Image starts each row on a 32-bit boundary!
+ //
+ Image = Image + (4 - (ImageIndex % 4));
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Use SystemTable Conout to stop video based Simple Text Out consoles from going
+ to the video device. Put up LogoFile on every video device that is a console.
+
+ @param[in] LogoFile File name of logo to display on the center of the screen.
+
+ @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed.
+ @retval EFI_UNSUPPORTED Logo not found
+
+**/
+EFI_STATUS
+EFIAPI
+EnableBootLogo (
+ IN EFI_GUID *LogoFile
+ )
+{
+ EFI_STATUS Status;
+ EFI_OEM_BADGING_PROTOCOL *Badging;
+ UINT32 SizeOfX;
+ UINT32 SizeOfY;
+ INTN DestX;
+ INTN DestY;
+ UINT8 *ImageData;
+ UINTN ImageSize;
+ UINTN BltSize;
+ UINT32 Instance;
+ EFI_BADGING_FORMAT Format;
+ EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;
+ UINTN CoordinateX;
+ UINTN CoordinateY;
+ UINTN Height;
+ UINTN Width;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
+ EFI_UGA_DRAW_PROTOCOL *UgaDraw;
+ UINT32 ColorDepth;
+ UINT32 RefreshRate;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+ EFI_BOOT_LOGO_PROTOCOL *BootLogo;
+ UINTN NumberOfLogos;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LogoBlt;
+ UINTN LogoDestX;
+ UINTN LogoDestY;
+ UINTN LogoHeight;
+ UINTN LogoWidth;
+ UINTN NewDestX;
+ UINTN NewDestY;
+ UINTN NewHeight;
+ UINTN NewWidth;
+ UINT64 BufferSize;
+
+ UgaDraw = NULL;
+ //
+ // Try to open GOP first
+ //
+ Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);
+ if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
+ GraphicsOutput = NULL;
+ //
+ // Open GOP failed, try to open UGA
+ //
+ Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);
+ }
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Try to open Boot Logo Protocol.
+ //
+ BootLogo = NULL;
+ gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);
+
+ //
+ // Erase Cursor from screen
+ //
+ gST->ConOut->EnableCursor (gST->ConOut, FALSE);
+
+ Badging = NULL;
+ Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);
+
+ if (GraphicsOutput != NULL) {
+ SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
+ SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
+
+ } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
+ Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ Blt = NULL;
+ NumberOfLogos = 0;
+ LogoDestX = 0;
+ LogoDestY = 0;
+ LogoHeight = 0;
+ LogoWidth = 0;
+ NewDestX = 0;
+ NewDestY = 0;
+ NewHeight = 0;
+ NewWidth = 0;
+ Instance = 0;
+ while (1) {
+ ImageData = NULL;
+ ImageSize = 0;
+
+ if (Badging != NULL) {
+ //
+ // Get image from OEMBadging protocol.
+ //
+ Status = Badging->GetImage (
+ Badging,
+ &Instance,
+ &Format,
+ &ImageData,
+ &ImageSize,
+ &Attribute,
+ &CoordinateX,
+ &CoordinateY
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ } else {
+ //
+ // Get the specified image from FV.
+ //
+ Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ CoordinateX = 0;
+ CoordinateY = 0;
+ Attribute = EfiBadgingDisplayAttributeCenter;
+ }
+
+ if (Blt != NULL) {
+ FreePool (Blt);
+ }
+
+ //
+ // Try BMP decoder
+ //
+ Blt = NULL;
+ Status = ConvertBmpToGopBlt (
+ ImageData,
+ ImageSize,
+ (VOID **) &Blt,
+ &BltSize,
+ &Height,
+ &Width
+ );
+
+ if (EFI_ERROR (Status)) {
+ FreePool (ImageData);
+
+ if (Badging == NULL) {
+ return Status;
+ } else {
+ continue;
+ }
+ }
+
+ //
+ // Calculate the display position according to Attribute.
+ //
+ switch (Attribute) {
+ case EfiBadgingDisplayAttributeLeftTop:
+ DestX = CoordinateX;
+ DestY = CoordinateY;
+ break;
+
+ case EfiBadgingDisplayAttributeCenterTop:
+ DestX = (SizeOfX - Width) / 2;
+ DestY = CoordinateY;
+ break;
+
+ case EfiBadgingDisplayAttributeRightTop:
+ DestX = (SizeOfX - Width - CoordinateX);
+ DestY = CoordinateY;;
+ break;
+
+ case EfiBadgingDisplayAttributeCenterRight:
+ DestX = (SizeOfX - Width - CoordinateX);
+ DestY = (SizeOfY - Height) / 2;
+ break;
+
+ case EfiBadgingDisplayAttributeRightBottom:
+ DestX = (SizeOfX - Width - CoordinateX);
+ DestY = (SizeOfY - Height - CoordinateY);
+ break;
+
+ case EfiBadgingDisplayAttributeCenterBottom:
+ DestX = (SizeOfX - Width) / 2;
+ DestY = (SizeOfY - Height - CoordinateY);
+ break;
+
+ case EfiBadgingDisplayAttributeLeftBottom:
+ DestX = CoordinateX;
+ DestY = (SizeOfY - Height - CoordinateY);
+ break;
+
+ case EfiBadgingDisplayAttributeCenterLeft:
+ DestX = CoordinateX;
+ DestY = (SizeOfY - Height) / 2;
+ break;
+
+ case EfiBadgingDisplayAttributeCenter:
+ DestX = (SizeOfX - Width) / 2;
+ DestY = (SizeOfY - Height) / 2;
+ break;
+
+ default:
+ DestX = CoordinateX;
+ DestY = CoordinateY;
+ break;
+ }
+
+ if ((DestX >= 0) && (DestY >= 0)) {
+ if (GraphicsOutput != NULL) {
+ Status = GraphicsOutput->Blt (
+ GraphicsOutput,
+ Blt,
+ EfiBltBufferToVideo,
+ 0,
+ 0,
+ (UINTN) DestX,
+ (UINTN) DestY,
+ Width,
+ Height,
+ Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+ );
+ } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
+ Status = UgaDraw->Blt (
+ UgaDraw,
+ (EFI_UGA_PIXEL *) Blt,
+ EfiUgaBltBufferToVideo,
+ 0,
+ 0,
+ (UINTN) DestX,
+ (UINTN) DestY,
+ Width,
+ Height,
+ Width * sizeof (EFI_UGA_PIXEL)
+ );
+ } else {
+ Status = EFI_UNSUPPORTED;
+ }
+
+ //
+ // Report displayed Logo information.
+ //
+ if (!EFI_ERROR (Status)) {
+ NumberOfLogos++;
+
+ if (LogoWidth == 0) {
+ //
+ // The first Logo.
+ //
+ LogoDestX = (UINTN) DestX;
+ LogoDestY = (UINTN) DestY;
+ LogoWidth = Width;
+ LogoHeight = Height;
+ } else {
+ //
+ // Merge new logo with old one.
+ //
+ NewDestX = MIN ((UINTN) DestX, LogoDestX);
+ NewDestY = MIN ((UINTN) DestY, LogoDestY);
+ NewWidth = MAX ((UINTN) DestX + Width, LogoDestX + LogoWidth) - NewDestX;
+ NewHeight = MAX ((UINTN) DestY + Height, LogoDestY + LogoHeight) - NewDestY;
+
+ LogoDestX = NewDestX;
+ LogoDestY = NewDestY;
+ LogoWidth = NewWidth;
+ LogoHeight = NewHeight;
+ }
+ }
+ }
+
+ FreePool (ImageData);
+
+ if (Badging == NULL) {
+ break;
+ }
+ }
+
+Done:
+ if (BootLogo == NULL || NumberOfLogos == 0) {
+ //
+ // No logo displayed.
+ //
+ if (Blt != NULL) {
+ FreePool (Blt);
+ }
+
+ return Status;
+ }
+
+ //
+ // Advertise displayed Logo information.
+ //
+ if (NumberOfLogos == 1) {
+ //
+ // Only one logo displayed, use its Blt buffer directly for BootLogo protocol.
+ //
+ LogoBlt = Blt;
+ Status = EFI_SUCCESS;
+ } else {
+ //
+ // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation.
+ //
+ if (Blt != NULL) {
+ FreePool (Blt);
+ }
+
+ //
+ // Ensure the LogoHeight * LogoWidth doesn't overflow
+ //
+ if (LogoHeight > DivU64x64Remainder ((UINTN) ~0, LogoWidth, NULL)) {
+ return EFI_UNSUPPORTED;
+ }
+ BufferSize = MultU64x64 (LogoWidth, LogoHeight);
+
+ //
+ // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
+ //
+ if (BufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+ return EFI_UNSUPPORTED;
+ }
+
+ LogoBlt = AllocateZeroPool ((UINTN)BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ if (LogoBlt == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (GraphicsOutput != NULL) {
+ Status = GraphicsOutput->Blt (
+ GraphicsOutput,
+ LogoBlt,
+ EfiBltVideoToBltBuffer,
+ LogoDestX,
+ LogoDestY,
+ 0,
+ 0,
+ LogoWidth,
+ LogoHeight,
+ LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+ );
+ } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
+ Status = UgaDraw->Blt (
+ UgaDraw,
+ (EFI_UGA_PIXEL *) LogoBlt,
+ EfiUgaVideoToBltBuffer,
+ LogoDestX,
+ LogoDestY,
+ 0,
+ 0,
+ LogoWidth,
+ LogoHeight,
+ LogoWidth * sizeof (EFI_UGA_PIXEL)
+ );
+ } else {
+ Status = EFI_UNSUPPORTED;
+ }
+ }
+
+ if (!EFI_ERROR (Status)) {
+ BootLogo->SetBootLogo (BootLogo, LogoBlt, LogoDestX, LogoDestY, LogoWidth, LogoHeight);
+ }
+ FreePool (LogoBlt);
+
+ return Status;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
new file mode 100644
index 0000000000..631bb7ee69
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
@@ -0,0 +1,662 @@
+/** @file
+ Copyright (c) 2011 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "LoadLinuxLib.h"
+
+
+/**
+ A simple check of the kernel setup image
+
+ An assumption is made that the size of the data is at least the
+ size of struct boot_params.
+
+ @param[in] KernelSetup - The kernel setup image
+
+ @retval EFI_SUCCESS - The kernel setup looks valid and supported
+ @retval EFI_INVALID_PARAMETER - KernelSetup was NULL
+ @retval EFI_UNSUPPORTED - The kernel setup is not valid or supported
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BasicKernelSetupCheck (
+ IN VOID *KernelSetup
+ )
+{
+ return LoadLinuxCheckKernelSetup(KernelSetup, sizeof (struct boot_params));
+}
+
+
+EFI_STATUS
+EFIAPI
+LoadLinuxCheckKernelSetup (
+ IN VOID *KernelSetup,
+ IN UINTN KernelSetupSize
+ )
+{
+ struct boot_params *Bp;
+
+ if (KernelSetup == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (KernelSetupSize < sizeof (*Bp)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Bp = (struct boot_params*) KernelSetup;
+
+ if ((Bp->hdr.signature != 0xAA55) || // Check boot sector signature
+ (Bp->hdr.header != SETUP_HDR) ||
+ (Bp->hdr.version < 0x205) || // We only support relocatable kernels
+ (!Bp->hdr.relocatable_kernel)
+ ) {
+ return EFI_UNSUPPORTED;
+ } else {
+ return EFI_SUCCESS;
+ }
+}
+
+
+UINTN
+EFIAPI
+LoadLinuxGetKernelSize (
+ IN VOID *KernelSetup,
+ IN UINTN KernelSize
+ )
+{
+ struct boot_params *Bp;
+
+ if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) {
+ return 0;
+ }
+
+ Bp = (struct boot_params*) KernelSetup;
+
+ if (Bp->hdr.version > 0x20a) {
+ return Bp->hdr.init_size;
+ } else {
+ //
+ // Add extra size for kernel decompression
+ //
+ return 3 * KernelSize;
+ }
+}
+
+
+VOID*
+EFIAPI
+LoadLinuxAllocateKernelSetupPages (
+ IN UINTN Pages
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Address;
+
+ Address = BASE_1GB;
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiLoaderData,
+ Pages,
+ &Address
+ );
+ if (!EFI_ERROR (Status)) {
+ return (VOID*)(UINTN) Address;
+ } else {
+ return NULL;
+ }
+}
+
+EFI_STATUS
+EFIAPI
+LoadLinuxInitializeKernelSetup (
+ IN VOID *KernelSetup
+ )
+{
+ EFI_STATUS Status;
+ UINTN SetupEnd;
+ struct boot_params *Bp;
+
+ Status = BasicKernelSetupCheck (KernelSetup);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Bp = (struct boot_params*) KernelSetup;
+
+ SetupEnd = 0x202 + (Bp->hdr.jump & 0xff);
+
+ //
+ // Clear all but the setup_header
+ //
+ ZeroMem (KernelSetup, 0x1f1);
+ ZeroMem (((UINT8 *)KernelSetup) + SetupEnd, 4096 - SetupEnd);
+ DEBUG ((EFI_D_INFO, "Cleared kernel setup 0-0x1f1, 0x%Lx-0x1000\n",
+ (UINT64)SetupEnd));
+
+ return EFI_SUCCESS;
+}
+
+VOID*
+EFIAPI
+LoadLinuxAllocateKernelPages (
+ IN VOID *KernelSetup,
+ IN UINTN Pages
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS KernelAddress;
+ UINT32 Loop;
+ struct boot_params *Bp;
+
+ if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) {
+ return NULL;
+ }
+
+ Bp = (struct boot_params*) KernelSetup;
+
+ for (Loop = 1; Loop < 512; Loop++) {
+ KernelAddress = MultU64x32 (
+ 2 * Bp->hdr.kernel_alignment,
+ Loop
+ );
+ Status = gBS->AllocatePages (
+ AllocateAddress,
+ EfiLoaderData,
+ Pages,
+ &KernelAddress
+ );
+ if (!EFI_ERROR (Status)) {
+ return (VOID*)(UINTN) KernelAddress;
+ }
+ }
+
+ return NULL;
+}
+
+
+VOID*
+EFIAPI
+LoadLinuxAllocateCommandLinePages (
+ IN UINTN Pages
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Address;
+
+ Address = 0xa0000;
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiLoaderData,
+ Pages,
+ &Address
+ );
+ if (!EFI_ERROR (Status)) {
+ return (VOID*)(UINTN) Address;
+ } else {
+ return NULL;
+ }
+}
+
+
+VOID*
+EFIAPI
+LoadLinuxAllocateInitrdPages (
+ IN VOID *KernelSetup,
+ IN UINTN Pages
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Address;
+
+ struct boot_params *Bp;
+
+ if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup))) {
+ return NULL;
+ }
+
+ Bp = (struct boot_params*) KernelSetup;
+
+ Address = (EFI_PHYSICAL_ADDRESS)(UINTN) Bp->hdr.ramdisk_max;
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiLoaderData,
+ Pages,
+ &Address
+ );
+ if (!EFI_ERROR (Status)) {
+ return (VOID*)(UINTN) Address;
+ } else {
+ return NULL;
+ }
+}
+
+
+STATIC
+VOID
+SetupLinuxMemmap (
+ IN OUT struct boot_params *Bp
+ )
+{
+ EFI_STATUS Status;
+ UINT8 TmpMemoryMap[1];
+ UINTN MapKey;
+ UINTN DescriptorSize;
+ UINT32 DescriptorVersion;
+ UINTN MemoryMapSize;
+ EFI_MEMORY_DESCRIPTOR *MemoryMap;
+ EFI_MEMORY_DESCRIPTOR *MemoryMapPtr;
+ UINTN Index;
+ struct efi_info *Efi;
+ struct e820_entry *LastE820;
+ struct e820_entry *E820;
+ UINTN E820EntryCount;
+ EFI_PHYSICAL_ADDRESS LastEndAddr;
+
+ //
+ // Get System MemoryMapSize
+ //
+ MemoryMapSize = sizeof (TmpMemoryMap);
+ Status = gBS->GetMemoryMap (
+ &MemoryMapSize,
+ (EFI_MEMORY_DESCRIPTOR *)TmpMemoryMap,
+ &MapKey,
+ &DescriptorSize,
+ &DescriptorVersion
+ );
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+ //
+ // Enlarge space here, because we will allocate pool now.
+ //
+ MemoryMapSize += EFI_PAGE_SIZE;
+ Status = gBS->AllocatePool (
+ EfiLoaderData,
+ MemoryMapSize,
+ (VOID **) &MemoryMap
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get System MemoryMap
+ //
+ Status = gBS->GetMemoryMap (
+ &MemoryMapSize,
+ MemoryMap,
+ &MapKey,
+ &DescriptorSize,
+ &DescriptorVersion
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ LastE820 = NULL;
+ E820 = &Bp->e820_map[0];
+ E820EntryCount = 0;
+ LastEndAddr = 0;
+ MemoryMapPtr = MemoryMap;
+ for (Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++) {
+ UINTN E820Type = 0;
+
+ if (MemoryMap->NumberOfPages == 0) {
+ continue;
+ }
+
+ switch(MemoryMap->Type) {
+ case EfiReservedMemoryType:
+ case EfiRuntimeServicesCode:
+ case EfiRuntimeServicesData:
+ case EfiMemoryMappedIO:
+ case EfiMemoryMappedIOPortSpace:
+ case EfiPalCode:
+ E820Type = E820_RESERVED;
+ break;
+
+ case EfiUnusableMemory:
+ E820Type = E820_UNUSABLE;
+ break;
+
+ case EfiACPIReclaimMemory:
+ E820Type = E820_ACPI;
+ break;
+
+ case EfiLoaderCode:
+ case EfiLoaderData:
+ case EfiBootServicesCode:
+ case EfiBootServicesData:
+ case EfiConventionalMemory:
+ E820Type = E820_RAM;
+ break;
+
+ case EfiACPIMemoryNVS:
+ E820Type = E820_NVS;
+ break;
+
+ default:
+ DEBUG ((
+ EFI_D_ERROR,
+ "Invalid EFI memory descriptor type (0x%x)!\n",
+ MemoryMap->Type
+ ));
+ continue;
+ }
+
+ if ((LastE820 != NULL) &&
+ (LastE820->type == (UINT32) E820Type) &&
+ (MemoryMap->PhysicalStart == LastEndAddr)) {
+ LastE820->size += EFI_PAGES_TO_SIZE ((UINTN) MemoryMap->NumberOfPages);
+ LastEndAddr += EFI_PAGES_TO_SIZE ((UINTN) MemoryMap->NumberOfPages);
+ } else {
+ if (E820EntryCount >= (sizeof (Bp->e820_map) / sizeof (Bp->e820_map[0]))) {
+ break;
+ }
+ E820->type = (UINT32) E820Type;
+ E820->addr = MemoryMap->PhysicalStart;
+ E820->size = EFI_PAGES_TO_SIZE ((UINTN) MemoryMap->NumberOfPages);
+ LastE820 = E820;
+ LastEndAddr = E820->addr + E820->size;
+ E820++;
+ E820EntryCount++;
+ }
+
+ //
+ // Get next item
+ //
+ MemoryMap = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemoryMap + DescriptorSize);
+ }
+ Bp->e820_entries = (UINT8) E820EntryCount;
+
+ Efi = &Bp->efi_info;
+ Efi->efi_systab = (UINT32)(UINTN) gST;
+ Efi->efi_memdesc_size = (UINT32) DescriptorSize;
+ Efi->efi_memdesc_version = DescriptorVersion;
+ Efi->efi_memmap = (UINT32)(UINTN) MemoryMapPtr;
+ Efi->efi_memmap_size = (UINT32) MemoryMapSize;
+#ifdef MDE_CPU_IA32
+ Efi->efi_loader_signature = SIGNATURE_32 ('E', 'L', '3', '2');
+#else
+ Efi->efi_systab_hi = (UINT32) (((UINT64)(UINTN) gST) >> 32);
+ Efi->efi_memmap_hi = (UINT32) (((UINT64)(UINTN) MemoryMapPtr) >> 32);
+ Efi->efi_loader_signature = SIGNATURE_32 ('E', 'L', '6', '4');
+#endif
+
+ gBS->ExitBootServices (gImageHandle, MapKey);
+}
+
+
+EFI_STATUS
+EFIAPI
+LoadLinuxSetCommandLine (
+ IN OUT VOID *KernelSetup,
+ IN CHAR8 *CommandLine
+ )
+{
+ EFI_STATUS Status;
+ struct boot_params *Bp;
+
+ Status = BasicKernelSetupCheck (KernelSetup);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Bp = (struct boot_params*) KernelSetup;
+
+ Bp->hdr.cmd_line_ptr = (UINT32)(UINTN) CommandLine;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+LoadLinuxSetInitrd (
+ IN OUT VOID *KernelSetup,
+ IN VOID *Initrd,
+ IN UINTN InitrdSize
+ )
+{
+ EFI_STATUS Status;
+ struct boot_params *Bp;
+
+ Status = BasicKernelSetupCheck (KernelSetup);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Bp = (struct boot_params*) KernelSetup;
+
+ Bp->hdr.ramdisk_start = (UINT32)(UINTN) Initrd;
+ Bp->hdr.ramdisk_len = (UINT32) InitrdSize;
+
+ return EFI_SUCCESS;
+}
+
+
+STATIC VOID
+FindBits (
+ unsigned long Mask,
+ UINT8 *Pos,
+ UINT8 *Size
+ )
+{
+ UINT8 First, Len;
+
+ First = 0;
+ Len = 0;
+
+ if (Mask) {
+ while (!(Mask & 0x1)) {
+ Mask = Mask >> 1;
+ First++;
+ }
+
+ while (Mask & 0x1) {
+ Mask = Mask >> 1;
+ Len++;
+ }
+ }
+ *Pos = First;
+ *Size = Len;
+}
+
+
+STATIC
+EFI_STATUS
+SetupGraphicsFromGop (
+ struct screen_info *Si,
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop
+ )
+{
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
+ EFI_STATUS Status;
+ UINTN Size;
+
+ Status = Gop->QueryMode(Gop, Gop->Mode->Mode, &Size, &Info);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ /* We found a GOP */
+
+ /* EFI framebuffer */
+ Si->orig_video_isVGA = 0x70;
+
+ Si->orig_x = 0;
+ Si->orig_y = 0;
+ Si->orig_video_page = 0;
+ Si->orig_video_mode = 0;
+ Si->orig_video_cols = 0;
+ Si->orig_video_lines = 0;
+ Si->orig_video_ega_bx = 0;
+ Si->orig_video_points = 0;
+
+ Si->lfb_base = (UINT32) Gop->Mode->FrameBufferBase;
+ Si->lfb_size = (UINT32) Gop->Mode->FrameBufferSize;
+ Si->lfb_width = (UINT16) Info->HorizontalResolution;
+ Si->lfb_height = (UINT16) Info->VerticalResolution;
+ Si->pages = 1;
+ Si->vesapm_seg = 0;
+ Si->vesapm_off = 0;
+
+ if (Info->PixelFormat == PixelRedGreenBlueReserved8BitPerColor) {
+ Si->lfb_depth = 32;
+ Si->red_size = 8;
+ Si->red_pos = 0;
+ Si->green_size = 8;
+ Si->green_pos = 8;
+ Si->blue_size = 8;
+ Si->blue_pos = 16;
+ Si->rsvd_size = 8;
+ Si->rsvd_pos = 24;
+ Si->lfb_linelength = (UINT16) (Info->PixelsPerScanLine * 4);
+
+ } else if (Info->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
+ Si->lfb_depth = 32;
+ Si->red_size = 8;
+ Si->red_pos = 16;
+ Si->green_size = 8;
+ Si->green_pos = 8;
+ Si->blue_size = 8;
+ Si->blue_pos = 0;
+ Si->rsvd_size = 8;
+ Si->rsvd_pos = 24;
+ Si->lfb_linelength = (UINT16) (Info->PixelsPerScanLine * 4);
+ } else if (Info->PixelFormat == PixelBitMask) {
+ FindBits(Info->PixelInformation.RedMask,
+ &Si->red_pos, &Si->red_size);
+ FindBits(Info->PixelInformation.GreenMask,
+ &Si->green_pos, &Si->green_size);
+ FindBits(Info->PixelInformation.BlueMask,
+ &Si->blue_pos, &Si->blue_size);
+ FindBits(Info->PixelInformation.ReservedMask,
+ &Si->rsvd_pos, &Si->rsvd_size);
+ Si->lfb_depth = Si->red_size + Si->green_size +
+ Si->blue_size + Si->rsvd_size;
+ Si->lfb_linelength = (UINT16) ((Info->PixelsPerScanLine * Si->lfb_depth) / 8);
+ } else {
+ Si->lfb_depth = 4;
+ Si->red_size = 0;
+ Si->red_pos = 0;
+ Si->green_size = 0;
+ Si->green_pos = 0;
+ Si->blue_size = 0;
+ Si->blue_pos = 0;
+ Si->rsvd_size = 0;
+ Si->rsvd_pos = 0;
+ Si->lfb_linelength = Si->lfb_width / 2;
+ }
+
+ return Status;
+}
+
+
+STATIC
+EFI_STATUS
+SetupGraphics (
+ IN OUT struct boot_params *Bp
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount;
+ UINTN Index;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
+
+ ZeroMem ((VOID*)&Bp->screen_info, sizeof(Bp->screen_info));
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiGraphicsOutputProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (!EFI_ERROR (Status)) {
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiGraphicsOutputProtocolGuid,
+ (VOID*) &Gop
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ Status = SetupGraphicsFromGop (&Bp->screen_info, Gop);
+ if (!EFI_ERROR (Status)) {
+ FreePool (HandleBuffer);
+ return EFI_SUCCESS;
+ }
+ }
+
+ FreePool (HandleBuffer);
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+STATIC
+EFI_STATUS
+SetupLinuxBootParams (
+ IN OUT struct boot_params *Bp
+ )
+{
+ SetupGraphics (Bp);
+
+ SetupLinuxMemmap (Bp);
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+LoadLinux (
+ IN VOID *Kernel,
+ IN OUT VOID *KernelSetup
+ )
+{
+ EFI_STATUS Status;
+ struct boot_params *Bp;
+
+ Status = BasicKernelSetupCheck (KernelSetup);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Bp = (struct boot_params *) KernelSetup;
+
+ if (Bp->hdr.version < 0x205 || !Bp->hdr.relocatable_kernel) {
+ //
+ // We only support relocatable kernels
+ //
+ return EFI_UNSUPPORTED;
+ }
+
+ InitLinuxDescriptorTables ();
+
+ Bp->hdr.code32_start = (UINT32)(UINTN) Kernel;
+ if (Bp->hdr.version >= 0x20c && Bp->hdr.handover_offset &&
+ (Bp->hdr.xloadflags & (sizeof (UINTN) == 4 ? BIT2 : BIT3))) {
+ DEBUG ((EFI_D_INFO, "Jumping to kernel EFI handover point at ofs %x\n", Bp->hdr.handover_offset));
+
+ DisableInterrupts ();
+ JumpToUefiKernel ((VOID*) gImageHandle, (VOID*) gST, KernelSetup, Kernel);
+ }
+
+ //
+ // Old kernels without EFI handover protocol
+ //
+ SetupLinuxBootParams (KernelSetup);
+
+ DEBUG ((EFI_D_INFO, "Jumping to kernel\n"));
+ DisableInterrupts ();
+ SetLinuxDescriptorTables ();
+ JumpToKernel (Kernel, (VOID*) KernelSetup);
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
new file mode 100644
index 0000000000..fda185e3d7
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
@@ -0,0 +1,175 @@
+/** @file
+ Initialize GDT for Linux.
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "LoadLinuxLib.h"
+
+
+//
+// Local structure definitions
+//
+
+#pragma pack (1)
+
+//
+// Global Descriptor Entry structures
+//
+
+typedef struct _GDT_ENTRY {
+ UINT16 Limit15_0;
+ UINT16 Base15_0;
+ UINT8 Base23_16;
+ UINT8 Type;
+ UINT8 Limit19_16_and_flags;
+ UINT8 Base31_24;
+} GDT_ENTRY;
+
+typedef
+struct _GDT_ENTRIES {
+ GDT_ENTRY Null;
+ GDT_ENTRY Null2;
+ GDT_ENTRY Linear;
+ GDT_ENTRY LinearCode;
+ GDT_ENTRY TaskSegment;
+ GDT_ENTRY Spare4;
+ GDT_ENTRY Spare5;
+} GDT_ENTRIES;
+
+#pragma pack ()
+
+STATIC GDT_ENTRIES *mGdt = NULL;
+
+//
+// Global descriptor table (GDT) Template
+//
+STATIC GDT_ENTRIES GdtTemplate = {
+ //
+ // Null
+ //
+ {
+ 0x0, // limit 15:0
+ 0x0, // base 15:0
+ 0x0, // base 23:16
+ 0x0, // type
+ 0x0, // limit 19:16, flags
+ 0x0, // base 31:24
+ },
+ //
+ // Null2
+ //
+ {
+ 0x0, // limit 15:0
+ 0x0, // base 15:0
+ 0x0, // base 23:16
+ 0x0, // type
+ 0x0, // limit 19:16, flags
+ 0x0, // base 31:24
+ },
+ //
+ // Linear
+ //
+ {
+ 0x0FFFF, // limit 0xFFFFF
+ 0x0, // base 0
+ 0x0,
+ 0x09A, // present, ring 0, data, expand-up, writable
+ 0x0CF, // page-granular, 32-bit
+ 0x0,
+ },
+ //
+ // LinearCode
+ //
+ {
+ 0x0FFFF, // limit 0xFFFFF
+ 0x0, // base 0
+ 0x0,
+ 0x092, // present, ring 0, data, expand-up, writable
+ 0x0CF, // page-granular, 32-bit
+ 0x0,
+ },
+ //
+ // TaskSegment
+ //
+ {
+ 0x0, // limit 0
+ 0x0, // base 0
+ 0x0,
+ 0x089, // ?
+ 0x080, // ?
+ 0x0,
+ },
+ //
+ // Spare4
+ //
+ {
+ 0x0, // limit 0
+ 0x0, // base 0
+ 0x0,
+ 0x0, // present, ring 0, data, expand-up, writable
+ 0x0, // page-granular, 32-bit
+ 0x0,
+ },
+ //
+ // Spare5
+ //
+ {
+ 0x0, // limit 0
+ 0x0, // base 0
+ 0x0,
+ 0x0, // present, ring 0, data, expand-up, writable
+ 0x0, // page-granular, 32-bit
+ 0x0,
+ },
+};
+
+/**
+ Initialize Global Descriptor Table.
+
+**/
+VOID
+InitLinuxDescriptorTables (
+ VOID
+ )
+{
+ //
+ // Allocate Runtime Data for the GDT
+ //
+ mGdt = AllocateRuntimePool (sizeof (GdtTemplate) + 8);
+ ASSERT (mGdt != NULL);
+ mGdt = ALIGN_POINTER (mGdt, 8);
+
+ //
+ // Initialize all GDT entries
+ //
+ CopyMem (mGdt, &GdtTemplate, sizeof (GdtTemplate));
+
+}
+
+/**
+ Initialize Global Descriptor Table.
+
+**/
+VOID
+SetLinuxDescriptorTables (
+ VOID
+ )
+{
+ IA32_DESCRIPTOR GdtPtr;
+ IA32_DESCRIPTOR IdtPtr;
+
+ //
+ // Write GDT register
+ //
+ GdtPtr.Base = (UINT32)(UINTN)(VOID*) mGdt;
+ GdtPtr.Limit = (UINT16) (sizeof (GdtTemplate) - 1);
+ AsmWriteGdtr (&GdtPtr);
+
+ IdtPtr.Base = (UINT32) 0;
+ IdtPtr.Limit = (UINT16) 0;
+ AsmWriteIdtr (&IdtPtr);
+}
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
new file mode 100644
index 0000000000..3d98291410
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
@@ -0,0 +1,507 @@
+/** @file
+ File System Access for NvVarsFileLib
+
+ Copyright (c) 2004 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "NvVarsFileLib.h"
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+
+/**
+ Open the NvVars file for reading or writing
+
+ @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
+ @param[in] ReadingFile - TRUE: open the file for reading. FALSE: writing
+ @param[out] NvVarsFile - If EFI_SUCCESS is returned, then this is updated
+ with the opened NvVars file.
+
+ @return EFI_SUCCESS if the file was opened
+
+**/
+EFI_STATUS
+GetNvVarsFile (
+ IN EFI_HANDLE FsHandle,
+ IN BOOLEAN ReadingFile,
+ OUT EFI_FILE_HANDLE *NvVarsFile
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs;
+ EFI_FILE_HANDLE Root;
+
+ //
+ // Get the FileSystem protocol on that handle
+ //
+ Status = gBS->HandleProtocol (
+ FsHandle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ (VOID **)&Fs
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get the volume (the root directory)
+ //
+ Status = Fs->OpenVolume (Fs, &Root);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Attempt to open the NvVars file in the root directory
+ //
+ Status = Root->Open (
+ Root,
+ NvVarsFile,
+ L"NvVars",
+ ReadingFile ?
+ EFI_FILE_MODE_READ :
+ (
+ EFI_FILE_MODE_CREATE |
+ EFI_FILE_MODE_READ |
+ EFI_FILE_MODE_WRITE
+ ),
+ 0
+ );
+
+ return Status;
+}
+
+
+/**
+ Open the NvVars file for reading or writing
+
+ @param[in] File - The file to inspect
+ @param[out] Exists - Returns whether the file exists
+ @param[out] Size - Returns the size of the file
+ (0 if the file does not exist)
+
+**/
+VOID
+NvVarsFileReadCheckup (
+ IN EFI_FILE_HANDLE File,
+ OUT BOOLEAN *Exists,
+ OUT UINTN *Size
+ )
+{
+ EFI_FILE_INFO *FileInfo;
+
+ *Exists = FALSE;
+ *Size = 0;
+
+ FileInfo = FileHandleGetInfo (File);
+ if (FileInfo == NULL) {
+ return;
+ }
+
+ if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) {
+ FreePool (FileInfo);
+ return;
+ }
+
+ *Exists = TRUE;
+ *Size = (UINTN) FileInfo->FileSize;
+
+ FreePool (FileInfo);
+}
+
+
+/**
+ Open the NvVars file for reading or writing
+
+ @param[in] File - The file to inspect
+ @param[out] Exists - Returns whether the file exists
+ @param[out] Size - Returns the size of the file
+ (0 if the file does not exist)
+
+**/
+EFI_STATUS
+FileHandleEmpty (
+ IN EFI_FILE_HANDLE File
+ )
+{
+ EFI_STATUS Status;
+ EFI_FILE_INFO *FileInfo;
+
+ //
+ // Retrieve the FileInfo structure
+ //
+ FileInfo = FileHandleGetInfo (File);
+ if (FileInfo == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // If the path is a directory, then return an error
+ //
+ if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) {
+ FreePool (FileInfo);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // If the file size is already 0, then it is empty, so
+ // we can return success.
+ //
+ if (FileInfo->FileSize == 0) {
+ FreePool (FileInfo);
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Set the file size to 0.
+ //
+ FileInfo->FileSize = 0;
+ Status = FileHandleSetInfo (File, FileInfo);
+
+ FreePool (FileInfo);
+
+ return Status;
+}
+
+
+/**
+ Reads a file to a newly allocated buffer
+
+ @param[in] File - The file to read
+ @param[in] ReadSize - The size of data to read from the file
+
+ @return Pointer to buffer allocated to hold the file
+ contents. NULL if an error occurred.
+
+**/
+VOID*
+FileHandleReadToNewBuffer (
+ IN EFI_FILE_HANDLE FileHandle,
+ IN UINTN ReadSize
+ )
+{
+ EFI_STATUS Status;
+ UINTN ActualReadSize;
+ VOID *FileContents;
+
+ ActualReadSize = ReadSize;
+ FileContents = AllocatePool (ReadSize);
+ if (FileContents != NULL) {
+ Status = FileHandleRead (
+ FileHandle,
+ &ReadSize,
+ FileContents
+ );
+ if (EFI_ERROR (Status) || (ActualReadSize != ReadSize)) {
+ FreePool (FileContents);
+ return NULL;
+ }
+ }
+
+ return FileContents;
+}
+
+
+/**
+ Reads the contents of the NvVars file on the file system
+
+ @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
+
+ @return EFI_STATUS based on the success or failure of the file read
+
+**/
+EFI_STATUS
+ReadNvVarsFile (
+ IN EFI_HANDLE FsHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_FILE_HANDLE File;
+ UINTN FileSize;
+ BOOLEAN FileExists;
+ VOID *FileContents;
+ EFI_HANDLE SerializedVariables;
+
+ Status = GetNvVarsFile (FsHandle, TRUE, &File);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "FsAccess.c: Could not open NV Variables file on this file system\n"));
+ return Status;
+ }
+
+ NvVarsFileReadCheckup (File, &FileExists, &FileSize);
+ if (FileSize == 0) {
+ FileHandleClose (File);
+ return EFI_UNSUPPORTED;
+ }
+
+ FileContents = FileHandleReadToNewBuffer (File, FileSize);
+ if (FileContents == NULL) {
+ FileHandleClose (File);
+ return EFI_UNSUPPORTED;
+ }
+
+ DEBUG ((
+ EFI_D_INFO,
+ "FsAccess.c: Read %Lu bytes from NV Variables file\n",
+ (UINT64)FileSize
+ ));
+
+ Status = SerializeVariablesNewInstanceFromBuffer (
+ &SerializedVariables,
+ FileContents,
+ FileSize
+ );
+ if (!RETURN_ERROR (Status)) {
+ Status = SerializeVariablesSetSerializedVariables (SerializedVariables);
+ }
+
+ FreePool (FileContents);
+ FileHandleClose (File);
+
+ return Status;
+}
+
+
+/**
+ Writes a variable to indicate that the NV variables
+ have been loaded from the file system.
+
+**/
+STATIC
+VOID
+SetNvVarsVariable (
+ VOID
+ )
+{
+ BOOLEAN VarData;
+ UINTN Size;
+
+ //
+ // Write a variable to indicate we've already loaded the
+ // variable data. If it is found, we skip the loading on
+ // subsequent attempts.
+ //
+ Size = sizeof (VarData);
+ VarData = TRUE;
+ gRT->SetVariable (
+ L"NvVars",
+ &gEfiSimpleFileSystemProtocolGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ Size,
+ (VOID*) &VarData
+ );
+}
+
+
+/**
+ Loads the non-volatile variables from the NvVars file on the
+ given file system.
+
+ @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
+
+ @return EFI_STATUS based on the success or failure of load operation
+
+**/
+EFI_STATUS
+LoadNvVarsFromFs (
+ EFI_HANDLE FsHandle
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN VarData;
+ UINTN Size;
+
+ DEBUG ((EFI_D_INFO, "FsAccess.c: LoadNvVarsFromFs\n"));
+
+ //
+ // We write a variable to indicate we've already loaded the
+ // variable data. If it is found, we skip the loading.
+ //
+ // This is relevant if the non-volatile variable have been
+ // able to survive a reboot operation. In that case, we don't
+ // want to re-load the file as it would overwrite newer changes
+ // made to the variables.
+ //
+ Size = sizeof (VarData);
+ VarData = TRUE;
+ Status = gRT->GetVariable (
+ L"NvVars",
+ &gEfiSimpleFileSystemProtocolGuid,
+ NULL,
+ &Size,
+ (VOID*) &VarData
+ );
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((EFI_D_INFO, "NV Variables were already loaded\n"));
+ return EFI_ALREADY_STARTED;
+ }
+
+ //
+ // Attempt to restore the variables from the NvVars file.
+ //
+ Status = ReadNvVarsFile (FsHandle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "Error while restoring NV variable data\n"));
+ return Status;
+ }
+
+ //
+ // Write a variable to indicate we've already loaded the
+ // variable data. If it is found, we skip the loading on
+ // subsequent attempts.
+ //
+ SetNvVarsVariable();
+
+ DEBUG ((
+ EFI_D_INFO,
+ "FsAccess.c: Read NV Variables file (size=%Lu)\n",
+ (UINT64)Size
+ ));
+
+ return Status;
+}
+
+
+STATIC
+RETURN_STATUS
+EFIAPI
+IterateVariablesCallbackAddAllNvVariables (
+ IN VOID *Context,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ EFI_HANDLE Instance;
+
+ Instance = (EFI_HANDLE) Context;
+
+ //
+ // Only save non-volatile variables
+ //
+ if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
+ return RETURN_SUCCESS;
+ }
+
+ return SerializeVariablesAddVariable (
+ Instance,
+ VariableName,
+ VendorGuid,
+ Attributes,
+ DataSize,
+ Data
+ );
+}
+
+
+/**
+ Saves the non-volatile variables into the NvVars file on the
+ given file system.
+
+ @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
+
+ @return EFI_STATUS based on the success or failure of load operation
+
+**/
+EFI_STATUS
+SaveNvVarsToFs (
+ EFI_HANDLE FsHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_FILE_HANDLE File;
+ UINTN WriteSize;
+ UINTN VariableDataSize;
+ VOID *VariableData;
+ EFI_HANDLE SerializedVariables;
+
+ SerializedVariables = NULL;
+
+ Status = SerializeVariablesNewInstance (&SerializedVariables);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = SerializeVariablesIterateSystemVariables (
+ IterateVariablesCallbackAddAllNvVariables,
+ (VOID*) SerializedVariables
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ VariableData = NULL;
+ VariableDataSize = 0;
+ Status = SerializeVariablesToBuffer (
+ SerializedVariables,
+ NULL,
+ &VariableDataSize
+ );
+ if (Status == RETURN_BUFFER_TOO_SMALL) {
+ VariableData = AllocatePool (VariableDataSize);
+ if (VariableData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ Status = SerializeVariablesToBuffer (
+ SerializedVariables,
+ VariableData,
+ &VariableDataSize
+ );
+ }
+ }
+
+ SerializeVariablesFreeInstance (SerializedVariables);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Open the NvVars file for writing.
+ //
+ Status = GetNvVarsFile (FsHandle, FALSE, &File);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "FsAccess.c: Unable to open file to saved NV Variables\n"));
+ return Status;
+ }
+
+ //
+ // Empty the starting file contents.
+ //
+ Status = FileHandleEmpty (File);
+ if (EFI_ERROR (Status)) {
+ FileHandleClose (File);
+ return Status;
+ }
+
+ WriteSize = VariableDataSize;
+ Status = FileHandleWrite (File, &WriteSize, VariableData);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ FileHandleClose (File);
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Write a variable to indicate we've already loaded the
+ // variable data. If it is found, we skip the loading on
+ // subsequent attempts.
+ //
+ SetNvVarsVariable();
+
+ DEBUG ((EFI_D_INFO, "Saved NV Variables to NvVars file\n"));
+ }
+
+ return Status;
+}
+
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c
new file mode 100644
index 0000000000..2e9618455d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.c
@@ -0,0 +1,77 @@
+/** @file
+ Save Non-Volatile Variables to a file system.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "NvVarsFileLib.h"
+#include <Library/DebugLib.h>
+#include <Library/NvVarsFileLib.h>
+
+EFI_HANDLE mNvVarsFileLibFsHandle = NULL;
+
+
+/**
+ Attempts to connect the NvVarsFileLib to the specified file system.
+
+ @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
+
+ @return The EFI_STATUS while attempting to connect the NvVarsFileLib
+ to the file system instance.
+ @retval EFI_SUCCESS - The given file system was connected successfully
+
+**/
+EFI_STATUS
+EFIAPI
+ConnectNvVarsToFileSystem (
+ IN EFI_HANDLE FsHandle
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // We might fail to load the variable, since the file system initially
+ // will not have the NvVars file.
+ //
+ LoadNvVarsFromFs (FsHandle);
+
+ //
+ // We must be able to save the variables successfully to the file system
+ // to have connected successfully.
+ //
+ Status = SaveNvVarsToFs (FsHandle);
+ if (!EFI_ERROR (Status)) {
+ mNvVarsFileLibFsHandle = FsHandle;
+ }
+
+ return Status;
+}
+
+
+/**
+ Update non-volatile variables stored on the file system.
+
+ @return The EFI_STATUS while attempting to update the variable on
+ the connected file system.
+ @retval EFI_SUCCESS - The non-volatile variables were saved to the disk
+ @retval EFI_NOT_STARTED - A file system has not been connected
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateNvVarsOnFileSystem (
+ )
+{
+ if (mNvVarsFileLibFsHandle == NULL) {
+ //
+ // A file system had not been connected to the library.
+ //
+ return EFI_NOT_STARTED;
+ } else {
+ return SaveNvVarsToFs (mNvVarsFileLibFsHandle);
+ }
+}
+
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
new file mode 100644
index 0000000000..53c421d40b
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -0,0 +1,419 @@
+/** @file
+ SIMICS QSP's instance of the PCI Host Bridge Library.
+
+ Copyright (C) 2016, Red Hat, Inc.
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiDxe.h>
+
+#include <IndustryStandard/Pci.h>
+#include <Register/X58Ich10.h>
+
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciHostBridgeLib.h>
+#include <Library/PciLib.h>
+#include "PciHostBridge.h"
+
+
+#pragma pack(1)
+typedef struct {
+ ACPI_HID_DEVICE_PATH AcpiDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
+} OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH;
+#pragma pack ()
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {
+ L"Mem", L"I/O", L"Bus"
+};
+
+
+STATIC
+CONST
+OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate = {
+ {
+ {
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ {
+ (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+ (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+ }
+ },
+ EISA_PNP_ID(0x0A03), // HID
+ 0 // UID
+ },
+
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+};
+
+STATIC PCI_ROOT_BRIDGE_APERTURE mNonExistAperture = { MAX_UINT64, 0 };
+
+/**
+ Initialize a PCI_ROOT_BRIDGE structure.
+
+ @param[in] Supports Supported attributes.
+
+ @param[in] Attributes Initial attributes.
+
+ @param[in] AllocAttributes Allocation attributes.
+
+ @param[in] RootBusNumber The bus number to store in RootBus.
+
+ @param[in] MaxSubBusNumber The inclusive maximum bus number that can be
+ assigned to any subordinate bus found behind any
+ PCI bridge hanging off this root bus.
+
+ The caller is repsonsible for ensuring that
+ RootBusNumber <= MaxSubBusNumber. If
+ RootBusNumber equals MaxSubBusNumber, then the
+ root bus has no room for subordinate buses.
+
+ @param[in] Io IO aperture.
+
+ @param[in] Mem MMIO aperture.
+
+ @param[in] MemAbove4G MMIO aperture above 4G.
+
+ @param[in] PMem Prefetchable MMIO aperture.
+
+ @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G.
+
+ @param[out] RootBus The PCI_ROOT_BRIDGE structure (allocated by the
+ caller) that should be filled in by this
+ function.
+
+ @retval EFI_SUCCESS Initialization successful. A device path
+ consisting of an ACPI device path node, with
+ UID = RootBusNumber, has been allocated and
+ linked into RootBus.
+
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
+**/
+EFI_STATUS
+InitRootBridge (
+ IN UINT64 Supports,
+ IN UINT64 Attributes,
+ IN UINT64 AllocAttributes,
+ IN UINT8 RootBusNumber,
+ IN UINT8 MaxSubBusNumber,
+ IN PCI_ROOT_BRIDGE_APERTURE *Io,
+ IN PCI_ROOT_BRIDGE_APERTURE *Mem,
+ IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,
+ IN PCI_ROOT_BRIDGE_APERTURE *PMem,
+ IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G,
+ OUT PCI_ROOT_BRIDGE *RootBus
+ )
+{
+ OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath;
+
+ //
+ // Be safe if other fields are added to PCI_ROOT_BRIDGE later.
+ //
+ ZeroMem (RootBus, sizeof *RootBus);
+
+ RootBus->Segment = 0;
+
+ RootBus->Supports = Supports;
+ RootBus->Attributes = Attributes;
+
+ RootBus->DmaAbove4G = FALSE;
+
+ RootBus->AllocationAttributes = AllocAttributes;
+ RootBus->Bus.Base = RootBusNumber;
+ RootBus->Bus.Limit = MaxSubBusNumber;
+ CopyMem (&RootBus->Io, Io, sizeof (*Io));
+ CopyMem (&RootBus->Mem, Mem, sizeof (*Mem));
+ CopyMem (&RootBus->MemAbove4G, MemAbove4G, sizeof (*MemAbove4G));
+ CopyMem (&RootBus->PMem, PMem, sizeof (*PMem));
+ CopyMem (&RootBus->PMemAbove4G, PMemAbove4G, sizeof (*PMemAbove4G));
+
+ RootBus->NoExtendedConfigSpace = (PcdGet16 (PcdSimicsX58HostBridgePciDevId) !=
+ INTEL_ICH10_DEVICE_ID);
+
+ DevicePath = AllocateCopyPool (sizeof mRootBridgeDevicePathTemplate,
+ &mRootBridgeDevicePathTemplate);
+ if (DevicePath == NULL) {
+ DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ DevicePath->AcpiDevicePath.UID = RootBusNumber;
+ RootBus->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;
+
+ DEBUG ((EFI_D_INFO,
+ "%a: populated root bus %d, with room for %d subordinate bus(es)\n",
+ __FUNCTION__, RootBusNumber, MaxSubBusNumber - RootBusNumber));
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Uninitialize a PCI_ROOT_BRIDGE structure set up with InitRootBridge().
+
+ param[in] RootBus The PCI_ROOT_BRIDGE structure, allocated by the caller and
+ initialized with InitRootBridge(), that should be
+ uninitialized. This function doesn't free RootBus.
+**/
+STATIC
+VOID
+UninitRootBridge (
+ IN PCI_ROOT_BRIDGE *RootBus
+ )
+{
+ FreePool (RootBus->DevicePath);
+}
+
+
+/**
+ Return all the root bridge instances in an array.
+
+ @param Count Return the count of root bridge instances.
+
+ @return All the root bridge instances in an array.
+ The array should be passed into PciHostBridgeFreeRootBridges()
+ when it's not used.
+**/
+PCI_ROOT_BRIDGE *
+EFIAPI
+PciHostBridgeGetRootBridges (
+ UINTN *Count
+ )
+{
+ EFI_STATUS Status;
+ UINT64 ExtraRootBridges;
+ PCI_ROOT_BRIDGE *Bridges;
+ UINTN Initialized;
+ UINTN LastRootBridgeNumber;
+ UINTN RootBridgeNumber;
+ UINT64 Attributes;
+ UINT64 AllocationAttributes;
+ PCI_ROOT_BRIDGE_APERTURE Io;
+ PCI_ROOT_BRIDGE_APERTURE Mem;
+ PCI_ROOT_BRIDGE_APERTURE MemAbove4G;
+
+ ZeroMem (&Io, sizeof (Io));
+ ZeroMem (&Mem, sizeof (Mem));
+ ZeroMem (&MemAbove4G, sizeof (MemAbove4G));
+
+ Attributes = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO |
+ EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO |
+ EFI_PCI_ATTRIBUTE_ISA_IO_16 |
+ EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO |
+ EFI_PCI_ATTRIBUTE_VGA_MEMORY |
+ EFI_PCI_ATTRIBUTE_VGA_IO_16 |
+ EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
+
+ AllocationAttributes = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM;
+ if (PcdGet64 (PcdPciMmio64Size) > 0) {
+ AllocationAttributes |= EFI_PCI_HOST_BRIDGE_MEM64_DECODE;
+ MemAbove4G.Base = PcdGet64 (PcdPciMmio64Base);
+ MemAbove4G.Limit = PcdGet64 (PcdPciMmio64Base) +
+ PcdGet64 (PcdPciMmio64Size) - 1;
+ } else {
+ CopyMem (&MemAbove4G, &mNonExistAperture, sizeof (mNonExistAperture));
+ }
+
+ Io.Base = PcdGet64 (PcdPciIoBase);
+ Io.Limit = PcdGet64 (PcdPciIoBase) + (PcdGet64 (PcdPciIoSize) - 1);
+ Mem.Base = PcdGet64 (PcdPciMmio32Base);
+ Mem.Limit = PcdGet64 (PcdPciMmio32Base) + (PcdGet64 (PcdPciMmio32Size) - 1);
+
+ *Count = 0;
+ ExtraRootBridges = 0;
+
+ //
+ // Allocate the "main" root bridge, and any extra root bridges.
+ //
+ Bridges = AllocatePool ((1 + (UINTN)ExtraRootBridges) * sizeof *Bridges);
+ if (Bridges == NULL) {
+ DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES));
+ return NULL;
+ }
+ Initialized = 0;
+
+ //
+ // The "main" root bus is always there.
+ //
+ LastRootBridgeNumber = 0;
+
+ //
+ // Scan all other root buses. If function 0 of any device on a bus returns a
+ // VendorId register value different from all-bits-one, then that bus is
+ // alive.
+ //
+ for (RootBridgeNumber = 1;
+ RootBridgeNumber <= PCI_MAX_BUS && Initialized < ExtraRootBridges;
+ ++RootBridgeNumber) {
+ UINTN Device;
+
+ for (Device = 0; Device <= PCI_MAX_DEVICE; ++Device) {
+ if (PciRead16 (PCI_LIB_ADDRESS (RootBridgeNumber, Device, 0,
+ PCI_VENDOR_ID_OFFSET)) != MAX_UINT16) {
+ break;
+ }
+ }
+ if (Device <= PCI_MAX_DEVICE) {
+ //
+ // Found the next root bus. We can now install the *previous* one,
+ // because now we know how big a bus number range *that* one has, for any
+ // subordinate buses that might exist behind PCI bridges hanging off it.
+ //
+ Status = InitRootBridge (
+ Attributes,
+ Attributes,
+ AllocationAttributes,
+ (UINT8) LastRootBridgeNumber,
+ (UINT8) (RootBridgeNumber - 1),
+ &Io,
+ &Mem,
+ &MemAbove4G,
+ &mNonExistAperture,
+ &mNonExistAperture,
+ &Bridges[Initialized]
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreeBridges;
+ }
+ ++Initialized;
+ LastRootBridgeNumber = RootBridgeNumber;
+ }
+ }
+
+ //
+ // Install the last root bus (which might be the only, ie. main, root bus, if
+ // we've found no extra root buses).
+ //
+ Status = InitRootBridge (
+ Attributes,
+ Attributes,
+ AllocationAttributes,
+ (UINT8) LastRootBridgeNumber,
+ PCI_MAX_BUS,
+ &Io,
+ &Mem,
+ &MemAbove4G,
+ &mNonExistAperture,
+ &mNonExistAperture,
+ &Bridges[Initialized]
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreeBridges;
+ }
+ ++Initialized;
+
+ *Count = Initialized;
+ return Bridges;
+
+FreeBridges:
+ while (Initialized > 0) {
+ --Initialized;
+ UninitRootBridge (&Bridges[Initialized]);
+ }
+
+ FreePool (Bridges);
+ return NULL;
+}
+
+
+/**
+ Free the root bridge instances array returned from
+ PciHostBridgeGetRootBridges().
+
+ @param The root bridge instances array.
+ @param The count of the array.
+**/
+VOID
+EFIAPI
+PciHostBridgeFreeRootBridges (
+ PCI_ROOT_BRIDGE *Bridges,
+ UINTN Count
+ )
+{
+ if (Bridges == NULL && Count == 0) {
+ return;
+ }
+ ASSERT (Bridges != NULL && Count > 0);
+
+ do {
+ --Count;
+ UninitRootBridge (&Bridges[Count]);
+ } while (Count > 0);
+
+ FreePool (Bridges);
+}
+
+
+/**
+ Inform the platform that the resource conflict happens.
+
+ @param HostBridgeHandle Handle of the Host Bridge.
+ @param Configuration Pointer to PCI I/O and PCI memory resource
+ descriptors. The Configuration contains the resources
+ for all the root bridges. The resource for each root
+ bridge is terminated with END descriptor and an
+ additional END is appended indicating the end of the
+ entire resources. The resource descriptor field
+ values follow the description in
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+ .SubmitResources().
+**/
+VOID
+EFIAPI
+PciHostBridgeResourceConflict (
+ EFI_HANDLE HostBridgeHandle,
+ VOID *Configuration
+ )
+{
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
+ UINTN RootBridgeIndex;
+ DEBUG ((EFI_D_ERROR, "PciHostBridge: Resource conflict happens!\n"));
+
+ RootBridgeIndex = 0;
+ Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
+ while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+ DEBUG ((EFI_D_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));
+ for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
+ ASSERT (Descriptor->ResType <
+ (sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr) /
+ sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr[0])
+ )
+ );
+ DEBUG ((EFI_D_ERROR, " %s: Length/Alignment = 0x%lx / 0x%lx\n",
+ mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType],
+ Descriptor->AddrLen, Descriptor->AddrRangeMax
+ ));
+ if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
+ DEBUG ((EFI_D_ERROR, " Granularity/SpecificFlag = %ld / %02x%s\n",
+ Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag,
+ ((Descriptor->SpecificFlag &
+ EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE
+ ) != 0) ? L" (Prefetchable)" : L""
+ ));
+ }
+ }
+ //
+ // Skip the END descriptor for root bridge
+ //
+ ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);
+ Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)(
+ (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1
+ );
+ }
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c
new file mode 100644
index 0000000000..4e3762465a
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/Fv.c
@@ -0,0 +1,100 @@
+/** @file
+ Build FV related hobs for platform.
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PiPei.h"
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+
+BOOLEAN mS3Supported = TRUE;
+
+/**
+ Publish PEI & DXE (Decompressed) Memory based FVs to let PEI
+ and DXE know about them.
+
+ @retval EFI_SUCCESS Platform PEI FVs were initialized successfully.
+
+**/
+EFI_STATUS
+PeiFvInitialization (
+ VOID
+ )
+{
+ BOOLEAN SecureS3Needed;
+
+ DEBUG ((EFI_D_INFO, "Platform PEI Firmware Volume Initialization\n"));
+
+ DEBUG (
+ (EFI_D_ERROR, "Firmware Volume HOB: 0x%x 0x%x\n",
+ PcdGet32 (PcdSimicsPeiMemFvBase),
+ PcdGet32 (PcdSimicsPeiMemFvSize)
+ )
+ );
+ //
+ // Create a memory allocation HOB for the PEI FV.
+ //
+ // Allocate as ACPI NVS is S3 is supported
+ //
+ BuildMemoryAllocationHob (
+ PcdGet32 (PcdSimicsPeiMemFvBase),
+ PcdGet32 (PcdSimicsPeiMemFvSize),
+ mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
+ );
+
+ //
+ // Let DXE know about the DXE FV
+ //
+ BuildFvHob (PcdGet32 (PcdSimicsDxeMemFvBase), PcdGet32 (PcdSimicsDxeMemFvSize));
+
+ SecureS3Needed = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire);
+
+ //
+ // Create a memory allocation HOB for the DXE FV.
+ //
+ // If "secure" S3 is needed, then SEC will decompress both PEI and DXE
+ // firmware volumes at S3 resume too, hence we need to keep away the OS from
+ // DXEFV as well. Otherwise we only need to keep away DXE itself from the
+ // DXEFV area.
+ //
+ BuildMemoryAllocationHob (
+ PcdGet32 (PcdSimicsDxeMemFvBase),
+ PcdGet32 (PcdSimicsDxeMemFvSize),
+ SecureS3Needed ? EfiACPIMemoryNVS : EfiBootServicesData
+ );
+
+ //
+ // Additionally, said decompression will use temporary memory above the end
+ // of DXEFV, so let's keep away the OS from there too.
+ //
+ if (SecureS3Needed) {
+ UINT32 DxeMemFvEnd;
+
+ DxeMemFvEnd = PcdGet32 (PcdSimicsDxeMemFvBase) +
+ PcdGet32 (PcdSimicsDxeMemFvSize);
+ BuildMemoryAllocationHob (
+ DxeMemFvEnd,
+ PcdGet32 (PcdSimicsDecompressionScratchEnd) - DxeMemFvEnd,
+ EfiACPIMemoryNVS
+ );
+ }
+
+ //
+ // Let PEI know about the DXE FV so it can find the DXE Core
+ //
+ PeiServicesInstallFvInfoPpi (
+ NULL,
+ (VOID *)(UINTN) PcdGet32 (PcdSimicsDxeMemFvBase),
+ PcdGet32 (PcdSimicsDxeMemFvSize),
+ NULL,
+ NULL
+ );
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
new file mode 100644
index 0000000000..1760eb954c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
@@ -0,0 +1,118 @@
+/** @file
+ Source code file for Report Firmware Volume (FV) library
+
+Copyright (c) 2018, 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/FirmwareVolumeInfo.h>
+#include <Library/IoLib.h>
+#include <Register/X58Ich10.h>
+
+EFI_STATUS
+PeiFvInitialization(
+ VOID
+);
+
+VOID
+ReportPreMemFv (
+ VOID
+ )
+{
+ if (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) != 0x5) { // not S3 resume
+ PeiFvInitialization();
+ }
+
+ DEBUG ((DEBUG_INFO, "Install FlashFvSecurity - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvSecurityBase), PcdGet32 (PcdFlashFvSecuritySize)));
+ PeiServicesInstallFvInfo2Ppi (
+ &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvSecurityBase))->FileSystemGuid),
+ (VOID *) (UINTN) PcdGet32 (PcdFlashFvSecurityBase),
+ PcdGet32 (PcdFlashFvSecuritySize),
+ NULL,
+ NULL,
+ 0
+ );
+ DEBUG ((DEBUG_INFO, "Install FlashFvAdvanced - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvAdvancedBase), PcdGet32 (PcdFlashFvAdvancedSize)));
+ PeiServicesInstallFvInfo2Ppi (
+ &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvAdvancedBase))->FileSystemGuid),
+ (VOID *) (UINTN) PcdGet32 (PcdFlashFvAdvancedBase),
+ PcdGet32 (PcdFlashFvAdvancedSize),
+ NULL,
+ NULL,
+ 0
+ );
+}
+
+VOID
+ReportPostMemFv (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+
+ Status = PeiServicesGetBootMode (&BootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Build HOB for DXE
+ ///
+ if (BootMode == BOOT_IN_RECOVERY_MODE) {
+ ///
+ /// Prepare the recovery service
+ ///
+ } else {
+ DEBUG ((DEBUG_INFO, "Install FlashFvPostMemory - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvPostMemoryBase), PcdGet32 (PcdFlashFvPostMemorySize)));
+ PeiServicesInstallFvInfo2Ppi (
+ &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvPostMemoryBase))->FileSystemGuid),
+ (VOID *) (UINTN) PcdGet32 (PcdFlashFvPostMemoryBase),
+ PcdGet32 (PcdFlashFvPostMemorySize),
+ NULL,
+ NULL,
+ 0
+ );
+ DEBUG ((DEBUG_INFO, "Install FlashFvUefiBoot - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvUefiBootBase), PcdGet32 (PcdFlashFvUefiBootSize)));
+ PeiServicesInstallFvInfo2Ppi (
+ &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvUefiBootBase))->FileSystemGuid),
+ (VOID *) (UINTN) PcdGet32 (PcdFlashFvUefiBootBase),
+ PcdGet32 (PcdFlashFvUefiBootSize),
+ NULL,
+ NULL,
+ 0
+ );
+ DEBUG ((DEBUG_INFO, "Install FlashFvOsBoot - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvOsBootBase), PcdGet32 (PcdFlashFvOsBootSize)));
+ PeiServicesInstallFvInfo2Ppi (
+ &(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFlashFvOsBootBase))->FileSystemGuid),
+ (VOID *) (UINTN) PcdGet32 (PcdFlashFvOsBootBase),
+ PcdGet32 (PcdFlashFvOsBootSize),
+ NULL,
+ NULL,
+ 0
+ );
+ }
+
+ //
+ // Report resource HOB for flash FV
+ //
+ 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/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatform.c
new file mode 100644
index 0000000000..117c72b35f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatform.c
@@ -0,0 +1,1553 @@
+/** @file
+ Platform BDS customizations.
+
+ Copyright (c) 2004 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BdsPlatform.h"
+#include <Guid/RootBridgesConnectedEventGroup.h>
+#include <Protocol/FirmwareVolume2.h>
+
+#define LEGACY_8259_MASK_REGISTER_MASTER 0x21
+#define LEGACY_8259_MASK_REGISTER_SLAVE 0xA1
+#define LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER 0x4D0
+#define LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE 0x4D1
+
+//
+// Global data
+//
+
+VOID *mEfiDevPathNotifyReg;
+EFI_EVENT mEfiDevPathEvent;
+VOID *mEmuVariableEventReg;
+EFI_EVENT mEmuVariableEvent;
+BOOLEAN mDetectVgaOnly;
+UINT16 mHostBridgeDevId;
+
+//
+// Table of host IRQs matching PCI IRQs A-D
+// (for configuring PCI Interrupt Line register)
+//
+CONST UINT8 PciHostIrqs[] = {
+ 0x0a, 0x0a, 0x0b, 0x0b
+};
+
+//
+// Type definitions
+//
+
+typedef
+EFI_STATUS
+(EFIAPI *PROTOCOL_INSTANCE_CALLBACK)(
+ IN EFI_HANDLE Handle,
+ IN VOID *Instance,
+ IN VOID *Context
+ );
+
+/**
+ @param[in] Handle - Handle of PCI device instance
+ @param[in] PciIo - PCI IO protocol instance
+ @param[in] Pci - PCI Header register block
+**/
+typedef
+EFI_STATUS
+(EFIAPI *VISIT_PCI_INSTANCE_CALLBACK)(
+ IN EFI_HANDLE Handle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN PCI_TYPE00 *Pci
+ );
+
+
+//
+// Function prototypes
+//
+
+EFI_STATUS
+VisitAllInstancesOfProtocol (
+ IN EFI_GUID *Id,
+ IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction,
+ IN VOID *Context
+ );
+
+EFI_STATUS
+VisitAllPciInstancesOfProtocol (
+ IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
+ );
+
+VOID
+InstallDevicePathCallback (
+ VOID
+ );
+
+VOID
+PlatformRegisterFvBootOption (
+ EFI_GUID *FileGuid,
+ CHAR16 *Description,
+ UINT32 Attributes
+ )
+{
+ EFI_STATUS Status;
+ INTN OptionIndex;
+ EFI_BOOT_MANAGER_LOAD_OPTION NewOption;
+ EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
+ UINTN BootOptionCount;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ Status = gBS->HandleProtocol (
+ gImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **) &LoadedImage
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
+ DevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);
+ ASSERT (DevicePath != NULL);
+ DevicePath = AppendDevicePathNode (
+ DevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
+ );
+ ASSERT (DevicePath != NULL);
+
+ Status = EfiBootManagerInitializeLoadOption (
+ &NewOption,
+ LoadOptionNumberUnassigned,
+ LoadOptionTypeBoot,
+ Attributes,
+ Description,
+ DevicePath,
+ NULL,
+ 0
+ );
+ ASSERT_EFI_ERROR (Status);
+ FreePool (DevicePath);
+
+ BootOptions = EfiBootManagerGetLoadOptions (
+ &BootOptionCount, LoadOptionTypeBoot
+ );
+
+ OptionIndex = EfiBootManagerFindLoadOption (
+ &NewOption, BootOptions, BootOptionCount
+ );
+
+ if (OptionIndex == -1) {
+ Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);
+ ASSERT_EFI_ERROR (Status);
+ }
+ EfiBootManagerFreeLoadOption (&NewOption);
+ EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+}
+
+/**
+ Remove all MemoryMapped(...)/FvFile(...) and Fv(...)/FvFile(...) boot options
+ whose device paths do not resolve exactly to an FvFile in the system.
+
+ This removes any boot options that point to binaries built into the firmware
+ and have become stale due to any of the following:
+ - DXEFV's base address or size changed (historical),
+ - DXEFV's FvNameGuid changed,
+ - the FILE_GUID of the pointed-to binary changed,
+ - the referenced binary is no longer built into the firmware.
+
+ EfiBootManagerFindLoadOption() used in PlatformRegisterFvBootOption() only
+ avoids exact duplicates.
+**/
+VOID
+RemoveStaleFvFileOptions (
+ VOID
+ )
+{
+ EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
+ UINTN BootOptionCount;
+ UINTN Index;
+
+ BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount,
+ LoadOptionTypeBoot);
+
+ for (Index = 0; Index < BootOptionCount; ++Index) {
+ EFI_DEVICE_PATH_PROTOCOL *Node1, *Node2, *SearchNode;
+ EFI_STATUS Status;
+ EFI_HANDLE FvHandle;
+
+ //
+ // If the device path starts with neither MemoryMapped(...) nor Fv(...),
+ // then keep the boot option.
+ //
+ Node1 = BootOptions[Index].FilePath;
+ if (!(DevicePathType (Node1) == HARDWARE_DEVICE_PATH &&
+ DevicePathSubType (Node1) == HW_MEMMAP_DP) &&
+ !(DevicePathType (Node1) == MEDIA_DEVICE_PATH &&
+ DevicePathSubType (Node1) == MEDIA_PIWG_FW_VOL_DP)) {
+ continue;
+ }
+
+ //
+ // If the second device path node is not FvFile(...), then keep the boot
+ // option.
+ //
+ Node2 = NextDevicePathNode (Node1);
+ if (DevicePathType (Node2) != MEDIA_DEVICE_PATH ||
+ DevicePathSubType (Node2) != MEDIA_PIWG_FW_FILE_DP) {
+ continue;
+ }
+
+ //
+ // Locate the Firmware Volume2 protocol instance that is denoted by the
+ // boot option. If this lookup fails (i.e., the boot option references a
+ // firmware volume that doesn't exist), then we'll proceed to delete the
+ // boot option.
+ //
+ SearchNode = Node1;
+ Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid,
+ &SearchNode, &FvHandle);
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // The firmware volume was found; now let's see if it contains the FvFile
+ // identified by GUID.
+ //
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFileNode;
+ UINTN BufferSize;
+ EFI_FV_FILETYPE FoundType;
+ EFI_FV_FILE_ATTRIBUTES FileAttributes;
+ UINT32 AuthenticationStatus;
+
+ Status = gBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID **)&FvProtocol);
+ ASSERT_EFI_ERROR (Status);
+
+ FvFileNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)Node2;
+ //
+ // Buffer==NULL means we request metadata only: BufferSize, FoundType,
+ // FileAttributes.
+ //
+ Status = FvProtocol->ReadFile (
+ FvProtocol,
+ &FvFileNode->FvFileName, // NameGuid
+ NULL, // Buffer
+ &BufferSize,
+ &FoundType,
+ &FileAttributes,
+ &AuthenticationStatus
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // The FvFile was found. Keep the boot option.
+ //
+ continue;
+ }
+ }
+
+ //
+ // Delete the boot option.
+ //
+ Status = EfiBootManagerDeleteLoadOptionVariable (
+ BootOptions[Index].OptionNumber, LoadOptionTypeBoot);
+ DEBUG_CODE (
+ CHAR16 *DevicePathString;
+
+ DevicePathString = ConvertDevicePathToText(BootOptions[Index].FilePath,
+ FALSE, FALSE);
+ DEBUG ((
+ EFI_ERROR (Status) ? EFI_D_WARN : EFI_D_VERBOSE,
+ "%a: removing stale Boot#%04x %s: %r\n",
+ __FUNCTION__,
+ (UINT32)BootOptions[Index].OptionNumber,
+ DevicePathString == NULL ? L"<unavailable>" : DevicePathString,
+ Status
+ ));
+ if (DevicePathString != NULL) {
+ FreePool (DevicePathString);
+ }
+ );
+ }
+
+ EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+}
+
+VOID
+PlatformRegisterOptionsAndKeys (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_INPUT_KEY Enter;
+ EFI_INPUT_KEY F2;
+ EFI_INPUT_KEY Esc;
+ EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
+
+ //
+ // Register ENTER as CONTINUE key
+ //
+ Enter.ScanCode = SCAN_NULL;
+ Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
+ Status = EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Map F2 to Boot Manager Menu
+ //
+ F2.ScanCode = SCAN_F2;
+ F2.UnicodeChar = CHAR_NULL;
+ Esc.ScanCode = SCAN_ESC;
+ Esc.UnicodeChar = CHAR_NULL;
+ Status = EfiBootManagerGetBootManagerMenu (&BootOption);
+ ASSERT_EFI_ERROR (Status);
+ Status = EfiBootManagerAddKeyOptionVariable (
+ NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL
+ );
+ ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
+ Status = EfiBootManagerAddKeyOptionVariable (
+ NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL
+ );
+ ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
+}
+
+EFI_STATUS
+EFIAPI
+ConnectRootBridge (
+ IN EFI_HANDLE RootBridgeHandle,
+ IN VOID *Instance,
+ IN VOID *Context
+ );
+
+STATIC
+VOID
+SaveS3BootScript (
+ VOID
+ );
+
+//
+// BDS Platform Functions
+//
+/**
+ Do the platform init, can be customized by OEM/IBV
+
+ Possible things that can be done in PlatformBootManagerBeforeConsole:
+
+ > Update console variable: 1. include hot-plug devices;
+ > 2. Clear ConIn and add SOL for AMT
+ > Register new Driver#### or Boot####
+ > Register new Key####: e.g.: F12
+ > Signal ReadyToLock event
+ > Authentication action: 1. connect Auth devices;
+ > 2. Identify auto logon user.
+**/
+VOID
+EFIAPI
+PlatformBootManagerBeforeConsole (
+ VOID
+ )
+{
+// EFI_HANDLE Handle;
+// EFI_STATUS Status;
+
+ DEBUG ((EFI_D_INFO, "PlatformBootManagerBeforeConsole\n"));
+ InstallDevicePathCallback ();
+
+ VisitAllInstancesOfProtocol (&gEfiPciRootBridgeIoProtocolGuid,
+ ConnectRootBridge, NULL);
+ //
+ // Enable LPC
+ //
+ PciOr16(POWER_MGMT_REGISTER_ICH10(0x04),
+ BIT0 | BIT1 | BIT2);
+ //
+ // We can't signal End-of-Dxe earlier than this. Namely, End-of-Dxe triggers
+ // the preparation of S3 system information. That logic has a hard dependency
+ // on the presence of the FACS ACPI table. Since our ACPI tables are only
+ // installed after PCI enumeration completes, we must not trigger the S3 save
+ // earlier, hence we can't signal End-of-Dxe earlier.
+ //
+ EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
+
+ PlatformInitializeConsole (gPlatformConsole);
+
+ PlatformRegisterOptionsAndKeys ();
+}
+
+
+EFI_STATUS
+EFIAPI
+ConnectRootBridge (
+ IN EFI_HANDLE RootBridgeHandle,
+ IN VOID *Instance,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Make the PCI bus driver connect the root bridge, non-recursively. This
+ // will produce a number of child handles with PciIo on them.
+ //
+ Status = gBS->ConnectController (
+ RootBridgeHandle, // ControllerHandle
+ NULL, // DriverImageHandle
+ NULL, // RemainingDevicePath -- produce all
+ // children
+ FALSE // Recursive
+ );
+ return Status;
+}
+
+
+/**
+ Add IsaKeyboard to ConIn; add IsaSerial to ConOut, ConIn, ErrOut.
+
+ @param[in] DeviceHandle Handle of the LPC Bridge device.
+
+ @retval EFI_SUCCESS Console devices on the LPC bridge have been added to
+ ConOut, ConIn, and ErrOut.
+
+ @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing
+ from DeviceHandle.
+**/
+EFI_STATUS
+PrepareLpcBridgeDevicePath (
+ IN EFI_HANDLE DeviceHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ CHAR16 *DevPathStr;
+
+ DevicePath = NULL;
+ Status = gBS->HandleProtocol (
+ DeviceHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID*)&DevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ TempDevicePath = DevicePath;
+
+ //
+ // Register Keyboard
+ //
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);
+
+ EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
+
+ //
+ // Register COM1
+ //
+ DevicePath = TempDevicePath;
+ gPnp16550ComPortDeviceNode.UID = 0;
+
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
+
+ //
+ // Print Device Path
+ //
+ DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
+ if (DevPathStr != NULL) {
+ DEBUG((
+ EFI_D_INFO,
+ "BdsPlatform.c+%d: COM%d DevPath: %s\n",
+ __LINE__,
+ gPnp16550ComPortDeviceNode.UID + 1,
+ DevPathStr
+ ));
+ FreePool(DevPathStr);
+ }
+
+ EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
+
+ //
+ // Register COM2
+ //
+ DevicePath = TempDevicePath;
+ gPnp16550ComPortDeviceNode.UID = 1;
+
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
+
+ //
+ // Print Device Path
+ //
+ DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
+ if (DevPathStr != NULL) {
+ DEBUG((
+ EFI_D_INFO,
+ "BdsPlatform.c+%d: COM%d DevPath: %s\n",
+ __LINE__,
+ gPnp16550ComPortDeviceNode.UID + 1,
+ DevPathStr
+ ));
+ FreePool(DevPathStr);
+ }
+
+ EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetGopDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,
+ OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath
+ )
+{
+ UINTN Index;
+ EFI_STATUS Status;
+ EFI_HANDLE PciDeviceHandle;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath;
+ UINTN GopHandleCount;
+ EFI_HANDLE *GopHandleBuffer;
+
+ if (PciDevicePath == NULL || GopDevicePath == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Initialize the GopDevicePath to be PciDevicePath
+ //
+ *GopDevicePath = PciDevicePath;
+ TempPciDevicePath = PciDevicePath;
+
+ Status = gBS->LocateDevicePath (
+ &gEfiDevicePathProtocolGuid,
+ &TempPciDevicePath,
+ &PciDeviceHandle
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Try to connect this handle, so that GOP driver could start on this
+ // device and create child handles with GraphicsOutput Protocol installed
+ // on them, then we get device paths of these child handles and select
+ // them as possible console device.
+ //
+ gBS->ConnectController (PciDeviceHandle, NULL, NULL, FALSE);
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiGraphicsOutputProtocolGuid,
+ NULL,
+ &GopHandleCount,
+ &GopHandleBuffer
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Add all the child handles as possible Console Device
+ //
+ for (Index = 0; Index < GopHandleCount; Index++) {
+ Status = gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+ if (CompareMem (
+ PciDevicePath,
+ TempDevicePath,
+ GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH
+ ) == 0) {
+ //
+ // In current implementation, we only enable one of the child handles
+ // as console device, i.e. sotre one of the child handle's device
+ // path to variable "ConOut"
+ // In future, we could select all child handles to be console device
+ //
+
+ *GopDevicePath = TempDevicePath;
+
+ //
+ // Delete the PCI device's path that added by
+ // GetPlugInPciVgaDevicePath(). Add the integrity GOP device path.
+ //
+ EfiBootManagerUpdateConsoleVariable (ConOutDev, NULL, PciDevicePath);
+ EfiBootManagerUpdateConsoleVariable (ConOutDev, TempDevicePath, NULL);
+ }
+ }
+ gBS->FreePool (GopHandleBuffer);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Add PCI display to ConOut.
+
+ @param[in] DeviceHandle Handle of the PCI display device.
+
+ @retval EFI_SUCCESS The PCI display device has been added to ConOut.
+
+ @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing
+ from DeviceHandle.
+**/
+EFI_STATUS
+PreparePciDisplayDevicePath (
+ IN EFI_HANDLE DeviceHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;
+
+ DevicePath = NULL;
+ GopDevicePath = NULL;
+ Status = gBS->HandleProtocol (
+ DeviceHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID*)&DevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ GetGopDevicePath (DevicePath, &GopDevicePath);
+ DevicePath = GopDevicePath;
+
+ EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Add PCI Serial to ConOut, ConIn, ErrOut.
+
+ @param[in] DeviceHandle Handle of the PCI serial device.
+
+ @retval EFI_SUCCESS The PCI serial device has been added to ConOut, ConIn,
+ ErrOut.
+
+ @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing
+ from DeviceHandle.
+**/
+EFI_STATUS
+PreparePciSerialDevicePath (
+ IN EFI_HANDLE DeviceHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ DevicePath = NULL;
+ Status = gBS->HandleProtocol (
+ DeviceHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID*)&DevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
+
+ EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+VisitAllInstancesOfProtocol (
+ IN EFI_GUID *Id,
+ IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Index;
+ VOID *Instance;
+
+ //
+ // Start to check all the PciIo to find all possible device
+ //
+ HandleCount = 0;
+ HandleBuffer = NULL;
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ Id,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = gBS->HandleProtocol (HandleBuffer[Index], Id, &Instance);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ Status = (*CallBackFunction) (
+ HandleBuffer[Index],
+ Instance,
+ Context
+ );
+ }
+
+ gBS->FreePool (HandleBuffer);
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+VisitingAPciInstance (
+ IN EFI_HANDLE Handle,
+ IN VOID *Instance,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ PCI_TYPE00 Pci;
+
+ PciIo = (EFI_PCI_IO_PROTOCOL*) Instance;
+
+ //
+ // Check for all PCI device
+ //
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ sizeof (Pci) / sizeof (UINT32),
+ &Pci
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return (*(VISIT_PCI_INSTANCE_CALLBACK)(UINTN) Context) (
+ Handle,
+ PciIo,
+ &Pci
+ );
+
+}
+
+
+
+EFI_STATUS
+VisitAllPciInstances (
+ IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
+ )
+{
+ return VisitAllInstancesOfProtocol (
+ &gEfiPciIoProtocolGuid,
+ VisitingAPciInstance,
+ (VOID*)(UINTN) CallBackFunction
+ );
+}
+
+
+/**
+ Do platform specific PCI Device check and add them to
+ ConOut, ConIn, ErrOut.
+
+ @param[in] Handle - Handle of PCI device instance
+ @param[in] PciIo - PCI IO protocol instance
+ @param[in] Pci - PCI Header register block
+
+ @retval EFI_SUCCESS - PCI Device check and Console variable update
+ successfully.
+ @retval EFI_STATUS - PCI Device check or Console variable update fail.
+
+**/
+EFI_STATUS
+EFIAPI
+DetectAndPreparePlatformPciDevicePath (
+ IN EFI_HANDLE Handle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN PCI_TYPE00 *Pci
+ )
+{
+ EFI_STATUS Status;
+
+ Status = PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationEnable,
+ EFI_PCI_DEVICE_ENABLE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (!mDetectVgaOnly) {
+ //
+ // Here we decide whether it is LPC Bridge
+ //
+ if ((IS_PCI_LPC (Pci)) ||
+ ((IS_PCI_ISA_PDECODE (Pci)) &&
+ (Pci->Hdr.VendorId == 0x8086) &&
+ (Pci->Hdr.DeviceId == 0x7000)
+ )
+ ) {
+ //
+ // Add IsaKeyboard to ConIn,
+ // add IsaSerial to ConOut, ConIn, ErrOut
+ //
+ DEBUG ((EFI_D_INFO, "Found LPC Bridge device\n"));
+ PrepareLpcBridgeDevicePath (Handle);
+ return EFI_SUCCESS;
+ }
+ //
+ // Here we decide which Serial device to enable in PCI bus
+ //
+ if (IS_PCI_16550SERIAL (Pci)) {
+ //
+ // Add them to ConOut, ConIn, ErrOut.
+ //
+ DEBUG ((EFI_D_INFO, "Found PCI 16550 SERIAL device\n"));
+ PreparePciSerialDevicePath (Handle);
+ return EFI_SUCCESS;
+ }
+ }
+
+ //
+ // Here we decide which display device to enable in PCI bus
+ //
+ if (IS_PCI_DISPLAY (Pci)) {
+ //
+ // Add them to ConOut.
+ //
+ DEBUG ((EFI_D_INFO, "Found PCI display device\n"));
+ PreparePciDisplayDevicePath (Handle);
+ return EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
+
+/**
+ Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
+
+ @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.
+
+ @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
+ @retval EFI_STATUS - PCI Device check or Console variable update fail.
+
+**/
+EFI_STATUS
+DetectAndPreparePlatformPciDevicePaths (
+ BOOLEAN DetectVgaOnly
+ )
+{
+ mDetectVgaOnly = DetectVgaOnly;
+ return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath);
+}
+
+/**
+ Connect the predefined platform default console device.
+
+ Always try to find and enable PCI display devices.
+
+ @param[in] PlatformConsole Predefined platform default console device array.
+**/
+VOID
+PlatformInitializeConsole (
+ IN PLATFORM_CONSOLE_CONNECT_ENTRY *PlatformConsole
+ )
+{
+ UINTN Index;
+ EFI_DEVICE_PATH_PROTOCOL *VarConout;
+ EFI_DEVICE_PATH_PROTOCOL *VarConin;
+
+ //
+ // Connect RootBridge
+ //
+ GetEfiGlobalVariable2 (EFI_CON_OUT_VARIABLE_NAME, (VOID **) &VarConout, NULL);
+ GetEfiGlobalVariable2 (EFI_CON_IN_VARIABLE_NAME, (VOID **) &VarConin, NULL);
+
+ if (VarConout == NULL || VarConin == NULL) {
+ //
+ // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
+ //
+ DetectAndPreparePlatformPciDevicePaths (FALSE);
+ DetectAndPreparePlatformPciDevicePaths(TRUE);
+ //
+ // Have chance to connect the platform default console,
+ // the platform default console is the minimue device group
+ // the platform should support
+ //
+ for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {
+ //
+ // Update the console variable with the connect type
+ //
+ if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
+ EfiBootManagerUpdateConsoleVariable (ConIn, PlatformConsole[Index].DevicePath, NULL);
+ }
+ if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
+ EfiBootManagerUpdateConsoleVariable (ConOut, PlatformConsole[Index].DevicePath, NULL);
+ }
+ if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
+ EfiBootManagerUpdateConsoleVariable (ErrOut, PlatformConsole[Index].DevicePath, NULL);
+ }
+ }
+ } else {
+ //
+ // Only detect VGA device and add them to ConOut
+ //
+ DetectAndPreparePlatformPciDevicePaths (TRUE);
+ }
+}
+
+
+/**
+ Configure PCI Interrupt Line register for applicable devices
+ Ported from SeaBIOS, src/fw/pciinit.c, *_pci_slot_get_irq()
+
+ @param[in] Handle - Handle of PCI device instance
+ @param[in] PciIo - PCI IO protocol instance
+ @param[in] PciHdr - PCI Header register block
+
+ @retval EFI_SUCCESS - PCI Interrupt Line register configured successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+SetPciIntLine (
+ IN EFI_HANDLE Handle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN PCI_TYPE00 *PciHdr
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+ UINTN RootSlot;
+ UINTN Idx;
+ UINT8 IrqLine;
+ EFI_STATUS Status;
+ UINT32 RootBusNumber;
+
+ Status = EFI_SUCCESS;
+
+ if (PciHdr->Device.InterruptPin != 0) {
+
+ DevPathNode = DevicePathFromHandle (Handle);
+ ASSERT (DevPathNode != NULL);
+ DevPath = DevPathNode;
+
+ RootBusNumber = 0;
+ if (DevicePathType (DevPathNode) == ACPI_DEVICE_PATH &&
+ DevicePathSubType (DevPathNode) == ACPI_DP &&
+ ((ACPI_HID_DEVICE_PATH *)DevPathNode)->HID == EISA_PNP_ID(0x0A03)) {
+ RootBusNumber = ((ACPI_HID_DEVICE_PATH *)DevPathNode)->UID;
+ }
+
+ //
+ // Compute index into PciHostIrqs[] table by walking
+ // the device path and adding up all device numbers
+ //
+ Status = EFI_NOT_FOUND;
+ RootSlot = 0;
+ Idx = PciHdr->Device.InterruptPin - 1;
+ while (!IsDevicePathEnd (DevPathNode)) {
+ if (DevicePathType (DevPathNode) == HARDWARE_DEVICE_PATH &&
+ DevicePathSubType (DevPathNode) == HW_PCI_DP) {
+
+ Idx += ((PCI_DEVICE_PATH *)DevPathNode)->Device;
+
+ //
+ // Unlike SeaBIOS, which starts climbing from the leaf device
+ // up toward the root, we traverse the device path starting at
+ // the root moving toward the leaf node.
+ // The slot number of the top-level parent bridge is needed
+ // with more than 24 slots on the root bus.
+ //
+ if (Status != EFI_SUCCESS) {
+ Status = EFI_SUCCESS;
+ RootSlot = ((PCI_DEVICE_PATH *)DevPathNode)->Device;
+ }
+ }
+
+ DevPathNode = NextDevicePathNode (DevPathNode);
+ }
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ if (RootBusNumber == 0 && RootSlot == 0) {
+ return Status; //bugbug: workaround; need SIMICS change B0/D0/F0 PCI_IntPin reg(0x3D) = 0X0
+// DEBUG((
+// EFI_D_ERROR,
+// "%a: PCI host bridge (00:00.0) should have no interrupts!\n",
+// __FUNCTION__
+// ));
+// ASSERT (FALSE);
+ }
+
+ //
+ // Final PciHostIrqs[] index calculation depends on the platform
+ // and should match SeaBIOS src/fw/pciinit.c *_pci_slot_get_irq()
+ //
+ switch (mHostBridgeDevId) {
+ case INTEL_82441_DEVICE_ID:
+ Idx -= 1;
+ break;
+ case INTEL_ICH10_DEVICE_ID:
+ //
+ // SeaBIOS contains the following comment:
+ // "Slots 0-24 rotate slot:pin mapping similar to piix above, but
+ // with a different starting index.
+ //
+ // Slots 25-31 all use LNKA mapping (or LNKE, but A:D = E:H)"
+ //
+ if (RootSlot > 24) {
+ //
+ // in this case, subtract back out RootSlot from Idx
+ // (SeaBIOS never adds it to begin with, but that would make our
+ // device path traversal loop above too awkward)
+ //
+ Idx -= RootSlot;
+ }
+ break;
+ default:
+ ASSERT (FALSE); // should never get here
+ }
+ Idx %= ARRAY_SIZE (PciHostIrqs);
+ IrqLine = PciHostIrqs[Idx];
+
+ DEBUG_CODE_BEGIN ();
+ {
+ CHAR16 *DevPathString;
+ STATIC CHAR16 Fallback[] = L"<failed to convert>";
+ UINTN Segment, Bus, Device, Function;
+
+ DevPathString = ConvertDevicePathToText (DevPath, FALSE, FALSE);
+ if (DevPathString == NULL) {
+ DevPathString = Fallback;
+ }
+ Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_VERBOSE, "%a: [%02x:%02x.%x] %s -> 0x%02x\n", __FUNCTION__,
+ (UINT32)Bus, (UINT32)Device, (UINT32)Function, DevPathString,
+ IrqLine));
+
+ if (DevPathString != Fallback) {
+ FreePool (DevPathString);
+ }
+ }
+ DEBUG_CODE_END ();
+
+ //
+ // Set PCI Interrupt Line register for this device to PciHostIrqs[Idx]
+ //
+ Status = PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint8,
+ PCI_INT_LINE_OFFSET,
+ 1,
+ &IrqLine
+ );
+ }
+
+ return Status;
+}
+
+/**
+Write to mask and edge/level triggered registers of master and slave 8259 PICs.
+
+@param[in] Mask low byte for master PIC mask register,
+high byte for slave PIC mask register.
+@param[in] EdgeLevel low byte for master PIC edge/level triggered register,
+high byte for slave PIC edge/level triggered register.
+
+**/
+VOID
+Interrupt8259WriteMask(
+ IN UINT16 Mask,
+ IN UINT16 EdgeLevel
+)
+{
+ IoWrite8(LEGACY_8259_MASK_REGISTER_MASTER, (UINT8)Mask);
+ IoWrite8(LEGACY_8259_MASK_REGISTER_SLAVE, (UINT8)(Mask >> 8));
+ IoWrite8(LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER, (UINT8)EdgeLevel);
+ IoWrite8(LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE, (UINT8)(EdgeLevel >> 8));
+}
+
+VOID
+PciAcpiInitialization (
+ )
+{
+ UINTN Pmba;
+
+ //
+ // Query Host Bridge DID to determine platform type
+ //
+ mHostBridgeDevId = PcdGet16 (PcdSimicsX58HostBridgePciDevId);
+ switch (mHostBridgeDevId) {
+ case INTEL_82441_DEVICE_ID:
+ Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
+ //
+ // 00:01.0 ISA Bridge (PIIX4) LNK routing targets
+ //
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // A
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // B
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // C
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // D
+ break;
+ case INTEL_ICH10_DEVICE_ID:
+ Pmba = POWER_MGMT_REGISTER_ICH10 (ICH10_PMBASE);
+ //
+ // 00:1f.0 LPC Bridge LNK routing targets
+ //
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x60), 0x0a); // A
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x61), 0x0a); // B
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x62), 0x0b); // C
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x63), 0x0b); // D
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x68), 0x0a); // E
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x69), 0x0a); // F
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6a), 0x0b); // G
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), 0x0b); // H
+ break;
+ default:
+ DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
+ __FUNCTION__, mHostBridgeDevId));
+ ASSERT (FALSE);
+ return;
+ }
+
+ //
+ // Initialize PCI_INTERRUPT_LINE for applicable present PCI devices
+ //
+ VisitAllPciInstances (SetPciIntLine);
+
+ //
+ // Set ACPI SCI_EN bit in PMCNTRL
+ //
+ IoOr16 ((PciRead32 (Pmba) & ~BIT0) + 4, BIT0);
+ //
+ // Set all 8259 interrupts to edge triggered and disabled
+ //
+ Interrupt8259WriteMask(0xFFFF, 0x0000);
+}
+
+EFI_STATUS
+EFIAPI
+ConnectRecursivelyIfPciMassStorage (
+ IN EFI_HANDLE Handle,
+ IN EFI_PCI_IO_PROTOCOL *Instance,
+ IN PCI_TYPE00 *PciHeader
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ CHAR16 *DevPathStr;
+
+ //
+ // Recognize PCI Mass Storage
+ //
+ if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE)) {
+ DevicePath = NULL;
+ Status = gBS->HandleProtocol (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID*)&DevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Print Device Path
+ //
+ DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
+ if (DevPathStr != NULL) {
+ DEBUG((
+ EFI_D_INFO,
+ "Found Mass Storage device: %s\n",
+ DevPathStr
+ ));
+ FreePool(DevPathStr);
+ }
+
+ Status = gBS->ConnectController (Handle, NULL, NULL, TRUE);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This notification function is invoked when the
+ EMU Variable FVB has been changed.
+
+ @param Event The event that occurred
+ @param Context For EFI compatibility. Not used.
+
+**/
+VOID
+EFIAPI
+EmuVariablesUpdatedCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ DEBUG ((EFI_D_INFO, "EmuVariablesUpdatedCallback\n"));
+ UpdateNvVarsOnFileSystem ();
+}
+
+
+EFI_STATUS
+EFIAPI
+VisitingFileSystemInstance (
+ IN EFI_HANDLE Handle,
+ IN VOID *Instance,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ STATIC BOOLEAN ConnectedToFileSystem = FALSE;
+
+ if (ConnectedToFileSystem) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ Status = ConnectNvVarsToFileSystem (Handle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ConnectedToFileSystem = TRUE;
+ mEmuVariableEvent =
+ EfiCreateProtocolNotifyEvent (
+ &gEfiDevicePathProtocolGuid,
+ TPL_CALLBACK,
+ EmuVariablesUpdatedCallback,
+ NULL,
+ &mEmuVariableEventReg
+ );
+ PcdSet64 (PcdEmuVariableEvent, (UINT64)(UINTN) mEmuVariableEvent);
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+PlatformBdsRestoreNvVarsFromHardDisk (
+ )
+{
+ VisitAllPciInstances (ConnectRecursivelyIfPciMassStorage);
+ VisitAllInstancesOfProtocol (
+ &gEfiSimpleFileSystemProtocolGuid,
+ VisitingFileSystemInstance,
+ NULL
+ );
+
+}
+
+/**
+ Connect with predefined platform connect sequence.
+
+ The OEM/IBV can customize with their own connect sequence.
+**/
+VOID
+PlatformBdsConnectSequence (
+ VOID
+ )
+{
+ UINTN Index;
+
+ DEBUG ((EFI_D_INFO, "PlatformBdsConnectSequence\n"));
+
+ Index = 0;
+
+ //
+ // Here we can get the customized platform connect sequence
+ // Notes: we can connect with new variable which record the
+ // last time boots connect device path sequence
+ //
+ while (gPlatformConnectSequence[Index] != NULL) {
+ //
+ // Build the platform boot option
+ //
+ EfiBootManagerConnectDevicePath (gPlatformConnectSequence[Index], NULL);
+ Index++;
+ }
+
+ //
+ // Just use the simple policy to connect all devices
+ //
+ DEBUG ((EFI_D_INFO, "EfiBootManagerConnectAll\n"));
+ EfiBootManagerConnectAll ();
+
+ PciAcpiInitialization ();
+}
+
+/**
+ Save the S3 boot script.
+
+ Note that DxeSmmReadyToLock must be signaled after this function returns;
+ otherwise the script wouldn't be saved actually.
+**/
+STATIC
+VOID
+SaveS3BootScript (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_S3_SAVE_STATE_PROTOCOL *BootScript;
+ STATIC CONST UINT8 Info[] = { 0xDE, 0xAD, 0xBE, 0xEF };
+
+ Status = gBS->LocateProtocol (&gEfiS3SaveStateProtocolGuid, NULL,
+ (VOID **) &BootScript);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Despite the opcode documentation in the PI spec, the protocol
+ // implementation embeds a deep copy of the info in the boot script, rather
+ // than storing just a pointer to runtime or NVS storage.
+ //
+ Status = BootScript->Write(BootScript, EFI_BOOT_SCRIPT_INFORMATION_OPCODE,
+ (UINT32) sizeof Info,
+ (EFI_PHYSICAL_ADDRESS)(UINTN) &Info);
+ ASSERT_EFI_ERROR (Status);
+}
+
+
+/**
+ Do the platform specific action after the console is ready
+
+ Possible things that can be done in PlatformBootManagerAfterConsole:
+
+ > Console post action:
+ > Dynamically switch output mode from 100x31 to 80x25 for certain senarino
+ > Signal console ready platform customized event
+ > Run diagnostics like memory testing
+ > Connect certain devices
+ > Dispatch aditional option roms
+ > Special boot: e.g.: USB boot, enter UI
+**/
+VOID
+EFIAPI
+PlatformBootManagerAfterConsole (
+ VOID
+ )
+{
+ EFI_BOOT_MODE BootMode;
+ EFI_HANDLE Handle;
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_INFO, "PlatformBootManagerAfterConsole\n"));
+
+ //
+ // Prevent further changes to LockBoxes or SMRAM.
+ //
+ Handle = NULL;
+ Status = gBS->InstallProtocolInterface(&Handle,
+ &gEfiDxeSmmReadyToLockProtocolGuid, EFI_NATIVE_INTERFACE,
+ NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ if (PcdGetBool (PcdOvmfFlashVariablesEnable)) {
+ DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior: not restoring NvVars "
+ "from disk since flash variables appear to be supported.\n"));
+ } else {
+ //
+ // Try to restore variables from the hard disk early so
+ // they can be used for the other BDS connect operations.
+ //
+ PlatformBdsRestoreNvVarsFromHardDisk ();
+ }
+
+ //
+ // Get current Boot Mode
+ //
+ BootMode = GetBootModeHob ();
+ DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode));
+
+ //
+ // Go the different platform policy with different boot mode
+ // Notes: this part code can be change with the table policy
+ //
+ ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);
+
+ // Perform some platform specific connect sequence
+ //
+ PlatformBdsConnectSequence ();
+ //
+ // Logo show
+ //
+ EnableBootLogo(PcdGetPtr(PcdLogoFile));
+
+ EfiBootManagerRefreshAllBootOption ();
+
+ //
+ // Register UEFI Shell
+ //
+ PlatformRegisterFvBootOption (
+ PcdGetPtr (PcdShellFile), L"EFI Internal Shell", LOAD_OPTION_ACTIVE
+ );
+
+ RemoveStaleFvFileOptions ();
+}
+
+/**
+ This notification function is invoked when an instance of the
+ EFI_DEVICE_PATH_PROTOCOL is produced.
+
+ @param Event The event that occurred
+ @param Context For EFI compatibility. Not used.
+
+**/
+VOID
+EFIAPI
+NotifyDevPath (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_HANDLE Handle;
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
+ ATAPI_DEVICE_PATH *Atapi;
+
+ //
+ // Examine all new handles
+ //
+ for (;;) {
+ //
+ // Get the next handle
+ //
+ BufferSize = sizeof (Handle);
+ Status = gBS->LocateHandle (
+ ByRegisterNotify,
+ NULL,
+ mEfiDevPathNotifyReg,
+ &BufferSize,
+ &Handle
+ );
+
+ //
+ // If not found, we're done
+ //
+ if (EFI_NOT_FOUND == Status) {
+ break;
+ }
+
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ //
+ // Get the DevicePath protocol on that handle
+ //
+ Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevPathNode);
+ ASSERT_EFI_ERROR (Status);
+
+ while (!IsDevicePathEnd (DevPathNode)) {
+ //
+ // Find the handler to dump this device path node
+ //
+ if (
+ (DevicePathType(DevPathNode) == MESSAGING_DEVICE_PATH) &&
+ (DevicePathSubType(DevPathNode) == MSG_ATAPI_DP)
+ ) {
+ Atapi = (ATAPI_DEVICE_PATH*) DevPathNode;
+ PciOr16 (
+ PCI_LIB_ADDRESS (
+ 0,
+ 1,
+ 1,
+ (Atapi->PrimarySecondary == 1) ? 0x42: 0x40
+ ),
+ BIT15
+ );
+ }
+
+ //
+ // Next device path node
+ //
+ DevPathNode = NextDevicePathNode (DevPathNode);
+ }
+ }
+
+ return;
+}
+
+
+VOID
+InstallDevicePathCallback (
+ VOID
+ )
+{
+ DEBUG ((EFI_D_INFO, "Registered NotifyDevPath Event\n"));
+ mEfiDevPathEvent = EfiCreateProtocolNotifyEvent (
+ &gEfiDevicePathProtocolGuid,
+ TPL_CALLBACK,
+ NotifyDevPath,
+ NULL,
+ &mEfiDevPathNotifyReg
+ );
+}
+
+/**
+ This function is called each second during the boot manager waits the
+ timeout.
+
+ @param TimeoutRemain The remaining timeout.
+**/
+VOID
+EFIAPI
+PlatformBootManagerWaitCallback (
+ UINT16 TimeoutRemain
+ )
+{
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White;
+ UINT16 Timeout;
+
+ Timeout = PcdGet16 (PcdPlatformBootTimeOut);
+
+ Black.Raw = 0x00000000;
+ White.Raw = 0x00FFFFFF;
+
+ BootLogoUpdateProgress (
+ White.Pixel,
+ Black.Pixel,
+ L"Start boot option",
+ White.Pixel,
+ (Timeout - TimeoutRemain) * 100 / Timeout,
+ 0
+ );
+}
+
+/**
+ The function is called when no boot option could be launched,
+ including platform recovery options and options pointing to applications
+ built into firmware volumes.
+
+ If this function returns, BDS attempts to enter an infinite loop.
+**/
+VOID
+EFIAPI
+PlatformBootManagerUnableToBoot (
+ VOID
+ )
+{
+ // BUGBUG- will do it if need
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/PlatformData.c b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/PlatformData.c
new file mode 100644
index 0000000000..768843a8bf
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/PlatformData.c
@@ -0,0 +1,35 @@
+/** @file
+ Defined the platform specific device path which will be used by
+ platform Bbd to perform the platform policy connect.
+
+ Copyright (c) 2004 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "BdsPlatform.h"
+
+ACPI_HID_DEVICE_PATH gPnpPs2KeyboardDeviceNode = gPnpPs2Keyboard;
+ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode = gPnp16550ComPort;
+UART_DEVICE_PATH gUartDeviceNode = gUart;
+VENDOR_DEVICE_PATH gTerminalTypeDeviceNode = gPcAnsiTerminal;
+
+//
+// Platform specific keyboard device path
+//
+
+//
+// Predefined platform default console device path
+//
+PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[] = {
+ {
+ NULL,
+ 0
+ }
+};
+
+//
+// Predefined platform connect sequence
+//
+EFI_DEVICE_PATH_PROTOCOL *gPlatformConnectSequence[] = { NULL };
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c
new file mode 100644
index 0000000000..be619c838a
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c
@@ -0,0 +1,869 @@
+/** @file
+ Serialize Variables Library implementation
+
+ Copyright (c) 2004 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SerializeVariablesLib.h"
+
+/**
+ Serialization format:
+
+ The SerializeVariablesLib interface does not specify a format
+ for the serialization of the variable data. This library uses
+ a packed array of a non-uniformly sized data structure elements.
+
+ Each variable is stored (packed) as:
+ UINT32 VendorNameSize; // Name size in bytes
+ CHAR16 VendorName[?]; // The variable unicode name including the
+ // null terminating character.
+ EFI_GUID VendorGuid; // The variable GUID
+ UINT32 DataSize; // The size of variable data in bytes
+ UINT8 Data[?]; // The variable data
+
+**/
+
+
+/**
+ Unpacks the next variable from the buffer
+
+ @param[in] Buffer - Buffer pointing to the next variable instance
+ On subsequent calls, the pointer should be incremented
+ by the returned SizeUsed value.
+ @param[in] MaxSize - Max allowable size for the variable data
+ On subsequent calls, this should be decremented
+ by the returned SizeUsed value.
+ @param[out] Name - Variable name string (address in Buffer)
+ @param[out] NameSize - Size of Name in bytes
+ @param[out] Guid - GUID of variable (address in Buffer)
+ @param[out] Attributes - Attributes of variable
+ @param[out] Data - Buffer containing Data for variable (address in Buffer)
+ @param[out] DataSize - Size of Data in bytes
+ @param[out] SizeUsed - Total size used for this variable instance in Buffer
+
+ @return EFI_STATUS based on the success or failure of the operation
+
+**/
+STATIC
+EFI_STATUS
+UnpackVariableFromBuffer (
+ IN VOID *Buffer,
+ IN UINTN MaxSize,
+ OUT CHAR16 **Name,
+ OUT UINT32 *NameSize,
+ OUT EFI_GUID **Guid,
+ OUT UINT32 *Attributes,
+ OUT UINT32 *DataSize,
+ OUT VOID **Data,
+ OUT UINTN *SizeUsed
+ )
+{
+ UINT8 *BytePtr;
+ UINTN Offset;
+
+ BytePtr = (UINT8*)Buffer;
+ Offset = 0;
+
+ *NameSize = *(UINT32*) (BytePtr + Offset);
+ Offset = Offset + sizeof (UINT32);
+
+ if (Offset > MaxSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Name = (CHAR16*) (BytePtr + Offset);
+ Offset = Offset + *(UINT32*)BytePtr;
+ if (Offset > MaxSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Guid = (EFI_GUID*) (BytePtr + Offset);
+ Offset = Offset + sizeof (EFI_GUID);
+ if (Offset > MaxSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Attributes = *(UINT32*) (BytePtr + Offset);
+ Offset = Offset + sizeof (UINT32);
+ if (Offset > MaxSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *DataSize = *(UINT32*) (BytePtr + Offset);
+ Offset = Offset + sizeof (UINT32);
+ if (Offset > MaxSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Data = (VOID*) (BytePtr + Offset);
+ Offset = Offset + *DataSize;
+ if (Offset > MaxSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *SizeUsed = Offset;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Iterates through the variables in the buffer, and calls a callback
+ function for each variable found.
+
+ @param[in] CallbackFunction - Function called for each variable instance
+ @param[in] Context - Passed to each call of CallbackFunction
+ @param[in] Buffer - Buffer containing serialized variables
+ @param[in] MaxSize - Size of Buffer in bytes
+
+ @return EFI_STATUS based on the success or failure of the operation
+
+**/
+STATIC
+EFI_STATUS
+IterateVariablesInBuffer (
+ IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
+ IN VOID *CallbackContext,
+ IN VOID *Buffer,
+ IN UINTN MaxSize
+ )
+{
+ RETURN_STATUS Status;
+ UINTN TotalSizeUsed;
+ UINTN SizeUsed;
+
+ CHAR16 *Name;
+ UINT32 NameSize;
+ CHAR16 *AlignedName;
+ UINT32 AlignedNameMaxSize;
+ EFI_GUID *Guid;
+ UINT32 Attributes;
+ UINT32 DataSize;
+ VOID *Data;
+
+ SizeUsed = 0;
+ AlignedName = NULL;
+ AlignedNameMaxSize = 0;
+ Name = NULL;
+ Guid = NULL;
+ Attributes = 0;
+ DataSize = 0;
+ Data = NULL;
+
+ for (
+ Status = EFI_SUCCESS, TotalSizeUsed = 0;
+ !EFI_ERROR (Status) && (TotalSizeUsed < MaxSize);
+ ) {
+ Status = UnpackVariableFromBuffer (
+ (VOID*) ((UINT8*) Buffer + TotalSizeUsed),
+ (MaxSize - TotalSizeUsed),
+ &Name,
+ &NameSize,
+ &Guid,
+ &Attributes,
+ &DataSize,
+ &Data,
+ &SizeUsed
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // We copy the name to a separately allocated buffer,
+ // to be sure it is 16-bit aligned.
+ //
+ if (NameSize > AlignedNameMaxSize) {
+ if (AlignedName != NULL) {
+ FreePool (AlignedName);
+ }
+ AlignedName = AllocatePool (NameSize);
+ }
+ if (AlignedName == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CopyMem (AlignedName, Name, NameSize);
+
+ TotalSizeUsed = TotalSizeUsed + SizeUsed;
+
+ //
+ // Run the callback function
+ //
+ Status = (*CallbackFunction) (
+ CallbackContext,
+ AlignedName,
+ Guid,
+ Attributes,
+ DataSize,
+ Data
+ );
+
+ }
+
+ if (AlignedName != NULL) {
+ FreePool (AlignedName);
+ }
+
+ //
+ // Make sure the entire buffer was used, or else return an error
+ //
+ if (TotalSizeUsed != MaxSize) {
+ DEBUG ((
+ EFI_D_ERROR,
+ "Deserialize variables error: TotalSizeUsed(%Lu) != MaxSize(%Lu)\n",
+ (UINT64)TotalSizeUsed,
+ (UINT64)MaxSize
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+STATIC
+RETURN_STATUS
+EFIAPI
+IterateVariablesCallbackNop (
+ IN VOID *Context,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ return RETURN_SUCCESS;
+}
+
+
+STATIC
+RETURN_STATUS
+EFIAPI
+IterateVariablesCallbackSetInInstance (
+ IN VOID *Context,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ EFI_HANDLE Instance;
+
+ Instance = (EFI_HANDLE) Context;
+
+ return SerializeVariablesAddVariable (
+ Instance,
+ VariableName,
+ VendorGuid,
+ Attributes,
+ DataSize,
+ Data
+ );
+}
+
+
+STATIC
+RETURN_STATUS
+EFIAPI
+IterateVariablesCallbackSetSystemVariable (
+ IN VOID *Context,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ EFI_STATUS Status;
+ STATIC CONST UINT32 AuthMask =
+ EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS |
+ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
+
+ Status = gRT->SetVariable (
+ VariableName,
+ VendorGuid,
+ Attributes,
+ DataSize,
+ Data
+ );
+
+ if (Status == EFI_SECURITY_VIOLATION && (Attributes & AuthMask) != 0) {
+ DEBUG ((DEBUG_WARN, "%a: setting authenticated variable \"%s\" "
+ "failed with EFI_SECURITY_VIOLATION, ignoring\n", __FUNCTION__,
+ VariableName));
+ Status = EFI_SUCCESS;
+ } else if (Status == EFI_WRITE_PROTECTED) {
+ DEBUG ((DEBUG_WARN, "%a: setting ReadOnly variable \"%s\" "
+ "failed with EFI_WRITE_PROTECTED, ignoring\n", __FUNCTION__,
+ VariableName));
+ Status = EFI_SUCCESS;
+ }
+ return Status;
+}
+
+
+STATIC
+RETURN_STATUS
+EnsureExtraBufferSpace (
+ IN SV_INSTANCE *Instance,
+ IN UINTN Size
+ )
+{
+ VOID *NewBuffer;
+ UINTN NewSize;
+
+ NewSize = Instance->DataSize + Size;
+ if (NewSize <= Instance->BufferSize) {
+ return RETURN_SUCCESS;
+ }
+
+ //
+ // Double the required size to lessen the need to re-allocate in the future
+ //
+ NewSize = 2 * NewSize;
+
+ NewBuffer = AllocatePool (NewSize);
+ if (NewBuffer == NULL) {
+ return RETURN_OUT_OF_RESOURCES;
+ }
+
+ if (Instance->BufferPtr != NULL) {
+ CopyMem (NewBuffer, Instance->BufferPtr, Instance->DataSize);
+ FreePool (Instance->BufferPtr);
+ }
+
+ Instance->BufferPtr = NewBuffer;
+ Instance->BufferSize = NewSize;
+
+ return RETURN_SUCCESS;
+}
+
+
+STATIC
+VOID
+AppendToBuffer (
+ IN SV_INSTANCE *Instance,
+ IN VOID *Data,
+ IN UINTN Size
+ )
+{
+ UINTN NewSize;
+
+ ASSERT (Instance != NULL);
+ ASSERT (Data != NULL);
+
+ NewSize = Instance->DataSize + Size;
+ ASSERT ((Instance->DataSize + Size) <= Instance->BufferSize);
+
+ CopyMem (
+ (VOID*) (((UINT8*) (Instance->BufferPtr)) + Instance->DataSize),
+ Data,
+ Size
+ );
+
+ Instance->DataSize = NewSize;
+}
+
+
+/**
+ Creates a new variable serialization instance
+
+ @param[out] Handle - Handle for a variable serialization instance
+
+ @retval RETURN_SUCCESS - The variable serialization instance was
+ successfully created.
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ create the variable serialization instance.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesNewInstance (
+ OUT EFI_HANDLE *Handle
+ )
+{
+ SV_INSTANCE *New;
+
+ New = AllocateZeroPool (sizeof (*New));
+ if (New == NULL) {
+ return RETURN_OUT_OF_RESOURCES;
+ }
+
+ New->Signature = SV_SIGNATURE;
+
+ *Handle = (EFI_HANDLE) New;
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Free memory associated with a variable serialization instance
+
+ @param[in] Handle - Handle for a variable serialization instance
+
+ @retval RETURN_SUCCESS - The variable serialization instance was
+ successfully freed.
+ @retval RETURN_INVALID_PARAMETER - Handle was not a valid
+ variable serialization instance.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesFreeInstance (
+ IN EFI_HANDLE Handle
+ )
+{
+ SV_INSTANCE *Instance;
+
+ Instance = SV_FROM_HANDLE (Handle);
+
+ if (Instance->Signature != SV_SIGNATURE) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ Instance->Signature = 0;
+
+ if (Instance->BufferPtr != NULL) {
+ FreePool (Instance->BufferPtr);
+ }
+
+ FreePool (Instance);
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Creates a new variable serialization instance using the given
+ binary representation of the variables to fill the new instance
+
+ @param[out] Handle - Handle for a variable serialization instance
+ @param[in] Buffer - A buffer with the serialized representation
+ of the variables. Must be the same format as produced
+ by SerializeVariablesToBuffer.
+ @param[in] Size - This is the size of the binary representation
+ of the variables.
+
+ @retval RETURN_SUCCESS - The binary representation was successfully
+ imported into a new variable serialization instance
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ create the new variable serialization instance
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesNewInstanceFromBuffer (
+ OUT EFI_HANDLE *Handle,
+ IN VOID *Buffer,
+ IN UINTN Size
+ )
+{
+ RETURN_STATUS Status;
+
+ Status = SerializeVariablesNewInstance (Handle);
+ if (RETURN_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = IterateVariablesInBuffer (
+ IterateVariablesCallbackNop,
+ NULL,
+ Buffer,
+ Size
+ );
+ if (RETURN_ERROR (Status)) {
+ SerializeVariablesFreeInstance (*Handle);
+ return Status;
+ }
+
+ Status = IterateVariablesInBuffer (
+ IterateVariablesCallbackSetInInstance,
+ (VOID*) *Handle,
+ Buffer,
+ Size
+ );
+ if (RETURN_ERROR (Status)) {
+ SerializeVariablesFreeInstance (*Handle);
+ return Status;
+ }
+
+ return Status;
+}
+
+
+/**
+ Iterates all variables found with RuntimeServices GetNextVariableName
+
+ @param[in] CallbackFunction - Function called for each variable instance
+ @param[in] Context - Passed to each call of CallbackFunction
+
+ @retval RETURN_SUCCESS - All variables were iterated without the
+ CallbackFunction returning an error
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ iterate through the variables
+ @return Any of RETURN_ERROR indicates an error reading the variable
+ or an error was returned from CallbackFunction
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesIterateSystemVariables (
+ IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
+ IN VOID *Context
+ )
+{
+ RETURN_STATUS Status;
+ UINTN VariableNameBufferSize;
+ UINTN VariableNameSize;
+ CHAR16 *VariableName;
+ EFI_GUID VendorGuid;
+ UINTN VariableDataBufferSize;
+ UINTN VariableDataSize;
+ VOID *VariableData;
+ UINT32 VariableAttributes;
+ VOID *NewBuffer;
+
+ //
+ // Initialize the variable name and data buffer variables.
+ //
+ VariableNameBufferSize = sizeof (CHAR16);
+ VariableName = AllocateZeroPool (VariableNameBufferSize);
+
+ VariableDataBufferSize = 0;
+ VariableData = NULL;
+
+ for (;;) {
+ //
+ // Get the next variable name and guid
+ //
+ VariableNameSize = VariableNameBufferSize;
+ Status = gRT->GetNextVariableName (
+ &VariableNameSize,
+ VariableName,
+ &VendorGuid
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ //
+ // The currently allocated VariableName buffer is too small,
+ // so we allocate a larger buffer, and copy the old buffer
+ // to it.
+ //
+ NewBuffer = AllocatePool (VariableNameSize);
+ if (NewBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ CopyMem (NewBuffer, VariableName, VariableNameBufferSize);
+ if (VariableName != NULL) {
+ FreePool (VariableName);
+ }
+ VariableName = NewBuffer;
+ VariableNameBufferSize = VariableNameSize;
+
+ //
+ // Try to get the next variable name again with the larger buffer.
+ //
+ Status = gRT->GetNextVariableName (
+ &VariableNameSize,
+ VariableName,
+ &VendorGuid
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_NOT_FOUND) {
+ Status = EFI_SUCCESS;
+ }
+ break;
+ }
+
+ //
+ // Get the variable data and attributes
+ //
+ VariableDataSize = VariableDataBufferSize;
+ Status = gRT->GetVariable (
+ VariableName,
+ &VendorGuid,
+ &VariableAttributes,
+ &VariableDataSize,
+ VariableData
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ //
+ // The currently allocated VariableData buffer is too small,
+ // so we allocate a larger buffer.
+ //
+ if (VariableDataBufferSize != 0) {
+ FreePool (VariableData);
+ VariableData = NULL;
+ VariableDataBufferSize = 0;
+ }
+ VariableData = AllocatePool (VariableDataSize);
+ if (VariableData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ VariableDataBufferSize = VariableDataSize;
+
+ //
+ // Try to read the variable again with the larger buffer.
+ //
+ Status = gRT->GetVariable (
+ VariableName,
+ &VendorGuid,
+ &VariableAttributes,
+ &VariableDataSize,
+ VariableData
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ //
+ // Run the callback function
+ //
+ Status = (*CallbackFunction) (
+ Context,
+ VariableName,
+ &VendorGuid,
+ VariableAttributes,
+ VariableDataSize,
+ VariableData
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ }
+
+ if (VariableName != NULL) {
+ FreePool (VariableName);
+ }
+
+ if (VariableData != NULL) {
+ FreePool (VariableData);
+ }
+
+ return Status;
+}
+
+
+/**
+ Iterates all variables found in the variable serialization instance
+
+ @param[in] Handle - Handle for a variable serialization instance
+ @param[in] CallbackFunction - Function called for each variable instance
+ @param[in] Context - Passed to each call of CallbackFunction
+
+ @retval RETURN_SUCCESS - All variables were iterated without the
+ CallbackFunction returning an error
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ iterate through the variables
+ @return Any of RETURN_ERROR indicates an error reading the variable
+ or an error was returned from CallbackFunction
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesIterateInstanceVariables (
+ IN EFI_HANDLE Handle,
+ IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
+ IN VOID *Context
+ )
+{
+ SV_INSTANCE *Instance;
+
+ Instance = SV_FROM_HANDLE (Handle);
+
+ if ((Instance->BufferPtr != NULL) && (Instance->DataSize != 0)) {
+ return IterateVariablesInBuffer (
+ CallbackFunction,
+ Context,
+ Instance->BufferPtr,
+ Instance->DataSize
+ );
+ } else {
+ return RETURN_SUCCESS;
+ }
+}
+
+
+/**
+ Sets all variables found in the variable serialization instance
+
+ @param[in] Handle - Handle for a variable serialization instance
+
+ @retval RETURN_SUCCESS - All variables were set successfully
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ set all the variables
+ @return Any of RETURN_ERROR indicates an error reading the variables
+ or in attempting to set a variable
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesSetSerializedVariables (
+ IN EFI_HANDLE Handle
+ )
+{
+ return SerializeVariablesIterateInstanceVariables (
+ Handle,
+ IterateVariablesCallbackSetSystemVariable,
+ NULL
+ );
+}
+
+
+/**
+ Adds a variable to the variable serialization instance
+
+ @param[in] Handle - Handle for a variable serialization instance
+ @param[in] VariableName - Refer to RuntimeServices GetVariable
+ @param[in] VendorGuid - Refer to RuntimeServices GetVariable
+ @param[in] Attributes - Refer to RuntimeServices GetVariable
+ @param[in] DataSize - Refer to RuntimeServices GetVariable
+ @param[in] Data - Refer to RuntimeServices GetVariable
+
+ @retval RETURN_SUCCESS - All variables were set successfully
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ add the variable
+ @retval RETURN_INVALID_PARAMETER - Handle was not a valid
+ variable serialization instance or
+ VariableName, VariableGuid or Data are NULL.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesAddVariable (
+ IN EFI_HANDLE Handle,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ RETURN_STATUS Status;
+ SV_INSTANCE *Instance;
+ UINT32 SerializedNameSize;
+ UINT32 SerializedDataSize;
+ UINTN SerializedSize;
+
+ Instance = SV_FROM_HANDLE (Handle);
+
+ if ((Instance->Signature != SV_SIGNATURE) ||
+ (VariableName == NULL) || (VendorGuid == NULL) || (Data == NULL)) {
+ }
+
+ SerializedNameSize = (UINT32) StrSize (VariableName);
+
+ SerializedSize =
+ sizeof (SerializedNameSize) +
+ SerializedNameSize +
+ sizeof (*VendorGuid) +
+ sizeof (Attributes) +
+ sizeof (SerializedDataSize) +
+ DataSize;
+
+ Status = EnsureExtraBufferSpace (
+ Instance,
+ SerializedSize
+ );
+ if (RETURN_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Add name size (UINT32)
+ //
+ AppendToBuffer (Instance, (VOID*) &SerializedNameSize, sizeof (SerializedNameSize));
+
+ //
+ // Add variable unicode name string
+ //
+ AppendToBuffer (Instance, (VOID*) VariableName, SerializedNameSize);
+
+ //
+ // Add variable GUID
+ //
+ AppendToBuffer (Instance, (VOID*) VendorGuid, sizeof (*VendorGuid));
+
+ //
+ // Add variable attributes
+ //
+ AppendToBuffer (Instance, (VOID*) &Attributes, sizeof (Attributes));
+
+ //
+ // Add variable data size (UINT32)
+ //
+ SerializedDataSize = (UINT32) DataSize;
+ AppendToBuffer (Instance, (VOID*) &SerializedDataSize, sizeof (SerializedDataSize));
+
+ //
+ // Add variable data
+ //
+ AppendToBuffer (Instance, Data, DataSize);
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Serializes the variables known to this instance into the
+ provided buffer.
+
+ @param[in] Handle - Handle for a variable serialization instance
+ @param[out] Buffer - A buffer to store the binary representation
+ of the variables.
+ @param[in,out] Size - On input this is the size of the buffer.
+ On output this is the size of the binary representation
+ of the variables.
+
+ @retval RETURN_SUCCESS - The binary representation was successfully
+ completed and returned in the buffer.
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ save the variables to the buffer.
+ @retval RETURN_INVALID_PARAMETER - Handle was not a valid
+ variable serialization instance or
+ Size or Buffer were NULL.
+ @retval RETURN_BUFFER_TOO_SMALL - The Buffer size as indicated by
+ the Size parameter was too small for the serialized
+ variable data. Size is returned with the required size.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesToBuffer (
+ IN EFI_HANDLE Handle,
+ OUT VOID *Buffer,
+ IN OUT UINTN *Size
+ )
+{
+ SV_INSTANCE *Instance;
+
+ Instance = SV_FROM_HANDLE (Handle);
+
+ if (Size == NULL) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ if (*Size < Instance->DataSize) {
+ *Size = Instance->DataSize;
+ return RETURN_BUFFER_TOO_SMALL;
+ }
+
+ if (Buffer == NULL) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ *Size = Instance->DataSize;
+ CopyMem (Buffer, Instance->BufferPtr, Instance->DataSize);
+
+ return RETURN_SUCCESS;
+}
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c
new file mode 100644
index 0000000000..383501898d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c
@@ -0,0 +1,108 @@
+/** @file
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+/**
+ Performs silicon pre-mem policy initialization.
+
+ The meaning of Policy is defined by silicon code.
+ It could be the raw data, a handle, a PPI, etc.
+
+ The returned data must be used as input data for SiliconPolicyDonePreMem(),
+ and SiliconPolicyUpdateLib.SiliconPolicyUpdatePreMem().
+
+ 1) In FSP path, the input Policy should be FspmUpd.
+ Value of FspmUpd has been initialized by FSP binary default value.
+ Only a subset of FspmUpd needs to be updated for different silicon sku.
+ The return data is same FspmUpd.
+
+ 2) In non-FSP path, the input policy could be NULL.
+ The return data is the initialized policy.
+
+ @param[in, out] Policy Pointer to policy.
+
+ @return the initialized policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyInitPreMem (
+ IN OUT VOID *Policy OPTIONAL
+ )
+{
+ return Policy;
+}
+
+/*
+ The silicon pre-mem policy is finalized.
+ Silicon code can do initialization based upon the policy data.
+
+ The input Policy must be returned by SiliconPolicyInitPreMem().
+
+ @param[in] Policy Pointer to policy.
+
+ @retval RETURN_SUCCESS The policy is handled consumed by silicon code.
+*/
+RETURN_STATUS
+EFIAPI
+SiliconPolicyDonePreMem (
+ IN VOID *Policy
+ )
+{
+ return RETURN_SUCCESS;
+}
+
+/**
+ Performs silicon post-mem policy initialization.
+
+ The meaning of Policy is defined by silicon code.
+ It could be the raw data, a handle, a PPI, etc.
+
+ The returned data must be used as input data for SiliconPolicyDonePostMem(),
+ and SiliconPolicyUpdateLib.SiliconPolicyUpdatePostMem().
+
+ 1) In FSP path, the input Policy should be FspsUpd.
+ Value of FspsUpd has been initialized by FSP binary default value.
+ Only a subset of FspsUpd needs to be updated for different silicon sku.
+ The return data is same FspsUpd.
+
+ 2) In non-FSP path, the input policy could be NULL.
+ The return data is the initialized policy.
+
+ @param[in, out] Policy Pointer to policy.
+
+ @return the initialized policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyInitPostMem (
+ IN OUT VOID *Policy OPTIONAL
+ )
+{
+ return Policy;
+}
+
+/*
+ The silicon post-mem policy is finalized.
+ Silicon code can do initialization based upon the policy data.
+
+ The input Policy must be returned by SiliconPolicyInitPostMem().
+
+ @param[in] Policy Pointer to policy.
+
+ @retval RETURN_SUCCESS The policy is handled consumed by silicon code.
+*/
+RETURN_STATUS
+EFIAPI
+SiliconPolicyDonePostMem (
+ IN VOID *Policy
+ )
+{
+ return RETURN_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c
new file mode 100644
index 0000000000..3b207a4e78
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c
@@ -0,0 +1,70 @@
+/** @file
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Library/PeiServicesLib.h>
+
+/**
+ Performs silicon pre-mem policy update.
+
+ The meaning of Policy is defined by silicon code.
+ It could be the raw data, a handle, a PPI, etc.
+
+ The input Policy must be returned by SiliconPolicyDonePreMem().
+
+ 1) In FSP path, the input Policy should be FspmUpd.
+ A platform may use this API to update the FSPM UPD policy initialized
+ by the silicon module or the default UPD data.
+ The output of FSPM UPD data from this API is the final UPD data.
+
+ 2) In non-FSP path, the board may use additional way to get
+ the silicon policy data field based upon the input Policy.
+
+ @param[in, out] Policy Pointer to policy.
+
+ @return the updated policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyUpdatePreMem (
+ IN OUT VOID *Policy
+ )
+{
+ return Policy;
+}
+
+/**
+ Performs silicon post-mem policy update.
+
+ The meaning of Policy is defined by silicon code.
+ It could be the raw data, a handle, a PPI, etc.
+
+ The input Policy must be returned by SiliconPolicyDonePostMem().
+
+ 1) In FSP path, the input Policy should be FspsUpd.
+ A platform may use this API to update the FSPS UPD policy initialized
+ by the silicon module or the default UPD data.
+ The output of FSPS UPD data from this API is the final UPD data.
+
+ 2) In non-FSP path, the board may use additional way to get
+ the silicon policy data field based upon the input Policy.
+
+ @param[in, out] Policy Pointer to policy.
+
+ @return the updated policy.
+**/
+VOID *
+EFIAPI
+SiliconPolicyUpdatePostMem (
+ IN OUT VOID *Policy
+ )
+{
+ return Policy;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c b/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c
new file mode 100644
index 0000000000..826fc965c9
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c
@@ -0,0 +1,956 @@
+/** @file
+ Main SEC phase code. Transitions to PEI.
+
+ Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+
+#include <Library/PeimEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiCpuLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/IoLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/PeCoffExtraActionLib.h>
+#include <Library/ExtractGuidedSectionLib.h>
+#include <Library/LocalApicLib.h>
+#include <Library/PciCf8Lib.h>
+
+#include <Ppi/TemporaryRamSupport.h>
+#include <Register/X58Ich10.h>
+
+#define SEC_IDT_ENTRY_COUNT 34
+
+typedef struct _SEC_IDT_TABLE {
+ EFI_PEI_SERVICES *PeiService;
+ IA32_IDT_GATE_DESCRIPTOR IdtTable[SEC_IDT_ENTRY_COUNT];
+} SEC_IDT_TABLE;
+
+VOID
+EFIAPI
+SecStartupPhase2 (
+ IN VOID *Context
+ );
+
+EFI_STATUS
+EFIAPI
+TemporaryRamMigration (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ );
+
+EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
+ TemporaryRamMigration
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiTemporaryRamSupportPpiGuid,
+ &mTemporaryRamSupportPpi
+ },
+};
+
+//
+// Template of an IDT entry pointing to 10:FFFFFFE4h.
+//
+IA32_IDT_GATE_DESCRIPTOR mIdtEntryTemplate = {
+ { // Bits
+ 0xffe4, // OffsetLow
+ 0x10, // Selector
+ 0x0, // Reserved_0
+ IA32_IDT_GATE_TYPE_INTERRUPT_32, // GateType
+ 0xffff // OffsetHigh
+ }
+};
+
+/**
+ Locates the main boot firmware volume.
+
+ @param[in,out] BootFv On input, the base of the BootFv
+ On output, the decompressed main firmware volume
+
+ @retval EFI_SUCCESS The main firmware volume was located and decompressed
+ @retval EFI_NOT_FOUND The main firmware volume was not found
+
+**/
+EFI_STATUS
+FindMainFv (
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv
+ )
+{
+ EFI_FIRMWARE_VOLUME_HEADER *Fv;
+ UINTN Distance;
+
+ ASSERT (((UINTN) *BootFv & EFI_PAGE_MASK) == 0);
+
+ Fv = *BootFv;
+ Distance = (UINTN) (*BootFv)->FvLength;
+ do {
+ Fv = (EFI_FIRMWARE_VOLUME_HEADER*) ((UINT8*) Fv - EFI_PAGE_SIZE);
+ Distance += EFI_PAGE_SIZE;
+ if (Distance > SIZE_32MB) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (Fv->Signature != EFI_FVH_SIGNATURE) {
+ continue;
+ }
+
+ if ((UINTN) Fv->FvLength > Distance) {
+ continue;
+ }
+
+ *BootFv = Fv;
+ return EFI_SUCCESS;
+
+ } while (TRUE);
+}
+
+/**
+ Locates a section within a series of sections
+ with the specified section type.
+
+ The Instance parameter indicates which instance of the section
+ type to return. (0 is first instance, 1 is second...)
+
+ @param[in] Sections The sections to search
+ @param[in] SizeOfSections Total size of all sections
+ @param[in] SectionType The section type to locate
+ @param[in] Instance The section instance number
+ @param[out] FoundSection The FFS section if found
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindFfsSectionInstance (
+ IN VOID *Sections,
+ IN UINTN SizeOfSections,
+ IN EFI_SECTION_TYPE SectionType,
+ IN UINTN Instance,
+ OUT EFI_COMMON_SECTION_HEADER **FoundSection
+ )
+{
+ EFI_PHYSICAL_ADDRESS CurrentAddress;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS EndOfSections;
+ EFI_COMMON_SECTION_HEADER *Section;
+ EFI_PHYSICAL_ADDRESS EndOfSection;
+
+ //
+ // Loop through the FFS file sections within the PEI Core FFS file
+ //
+ EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) Sections;
+ EndOfSections = EndOfSection + SizeOfSections;
+ for (;;) {
+ if (EndOfSection == EndOfSections) {
+ break;
+ }
+ CurrentAddress = (EndOfSection + 3) & ~(3ULL);
+ if (CurrentAddress >= EndOfSections) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
+ DEBUG ((EFI_D_VERBOSE, "Section->Type: 0x%x\n", Section->Type));
+
+ Size = SECTION_SIZE (Section);
+ if (Size < sizeof (*Section)) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ EndOfSection = CurrentAddress + Size;
+ if (EndOfSection > EndOfSections) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ //
+ // Look for the requested section type
+ //
+ if (Section->Type == SectionType) {
+ if (Instance == 0) {
+ *FoundSection = Section;
+ return EFI_SUCCESS;
+ } else {
+ Instance--;
+ }
+ }
+ DEBUG ((EFI_D_VERBOSE, "Section->Type (0x%x) != SectionType (0x%x)\n", Section->Type, SectionType));
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Locates a section within a series of sections
+ with the specified section type.
+
+ @param[in] Sections The sections to search
+ @param[in] SizeOfSections Total size of all sections
+ @param[in] SectionType The section type to locate
+ @param[out] FoundSection The FFS section if found
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindFfsSectionInSections (
+ IN VOID *Sections,
+ IN UINTN SizeOfSections,
+ IN EFI_SECTION_TYPE SectionType,
+ OUT EFI_COMMON_SECTION_HEADER **FoundSection
+ )
+{
+ return FindFfsSectionInstance (
+ Sections,
+ SizeOfSections,
+ SectionType,
+ 0,
+ FoundSection
+ );
+}
+
+/**
+ Locates a FFS file with the specified file type and a section
+ within that file with the specified section type.
+
+ @param[in] Fv The firmware volume to search
+ @param[in] FileType The file type to locate
+ @param[in] SectionType The section type to locate
+ @param[out] FoundSection The FFS section if found
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindFfsFileAndSection (
+ IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
+ IN EFI_FV_FILETYPE FileType,
+ IN EFI_SECTION_TYPE SectionType,
+ OUT EFI_COMMON_SECTION_HEADER **FoundSection
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS CurrentAddress;
+ EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
+ EFI_FFS_FILE_HEADER *File;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS EndOfFile;
+
+ if (Fv->Signature != EFI_FVH_SIGNATURE) {
+ DEBUG ((EFI_D_ERROR, "FV at %p does not have FV header signature\n", Fv));
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Fv;
+ EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
+
+ //
+ // Loop through the FFS files in the Boot Firmware Volume
+ //
+ for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
+
+ CurrentAddress = (EndOfFile + 7) & ~(7ULL);
+ if (CurrentAddress > EndOfFirmwareVolume) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
+ Size = *(UINT32*) File->Size & 0xffffff;
+ if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+ DEBUG ((EFI_D_VERBOSE, "File->Type: 0x%x\n", File->Type));
+
+ EndOfFile = CurrentAddress + Size;
+ if (EndOfFile > EndOfFirmwareVolume) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ //
+ // Look for the request file type
+ //
+ if (File->Type != FileType) {
+ DEBUG ((EFI_D_VERBOSE, "File->Type (0x%x) != FileType (0x%x)\n", File->Type, FileType));
+ continue;
+ }
+
+ Status = FindFfsSectionInSections (
+ (VOID*) (File + 1),
+ (UINTN) EndOfFile - (UINTN) (File + 1),
+ SectionType,
+ FoundSection
+ );
+ if (!EFI_ERROR (Status) || (Status == EFI_VOLUME_CORRUPTED)) {
+ return Status;
+ }
+ }
+}
+
+/**
+ Locates the compressed main firmware volume and decompresses it.
+
+ @param[in,out] Fv On input, the firmware volume to search
+ On output, the decompressed BOOT/PEI FV
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+EFI_STATUS
+DecompressMemFvs (
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **Fv
+ )
+{
+ EFI_STATUS Status;
+ EFI_GUID_DEFINED_SECTION *Section;
+ UINT32 OutputBufferSize;
+ UINT32 ScratchBufferSize;
+ UINT16 SectionAttribute;
+ UINT32 AuthenticationStatus;
+ VOID *OutputBuffer;
+ VOID *ScratchBuffer;
+ EFI_COMMON_SECTION_HEADER *FvSection;
+ EFI_FIRMWARE_VOLUME_HEADER *PeiMemFv;
+ EFI_FIRMWARE_VOLUME_HEADER *DxeMemFv;
+ UINT32 FvHeaderSize;
+ UINT32 FvSectionSize;
+
+ FvSection = (EFI_COMMON_SECTION_HEADER*) NULL;
+
+ DEBUG ((EFI_D_VERBOSE, "Find and decompress FV image.\n"));
+ Status = FindFfsFileAndSection (
+ *Fv,
+ EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
+ EFI_SECTION_GUID_DEFINED,
+ (EFI_COMMON_SECTION_HEADER**) &Section
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to find GUID defined section\n"));
+ return Status;
+ }
+
+ Status = ExtractGuidedSectionGetInfo (
+ Section,
+ &OutputBufferSize,
+ &ScratchBufferSize,
+ &SectionAttribute
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to GetInfo for GUIDed section\n"));
+ return Status;
+ }
+
+ OutputBuffer = (VOID*) ((UINT8*)(UINTN) PcdGet32 (PcdSimicsDxeMemFvBase) + SIZE_1MB);
+ ScratchBuffer = ALIGN_POINTER ((UINT8*) OutputBuffer + OutputBufferSize, SIZE_1MB);
+
+ DEBUG ((EFI_D_VERBOSE, "PcdSimicsDxeMemFvBase: 0x%x\n", PcdGet32 (PcdSimicsDxeMemFvBase)));
+ DEBUG ((EFI_D_VERBOSE, "OutputBuffer: 0x%x\n", OutputBuffer));
+ DEBUG ((EFI_D_VERBOSE, "OutputBufferSize: 0x%x\n", OutputBufferSize));
+ DEBUG ((EFI_D_VERBOSE, "ScratchBuffer: 0x%x\n", ScratchBuffer));
+ DEBUG ((EFI_D_VERBOSE, "ScratchBufferSize: 0x%x\n", ScratchBufferSize));
+ DEBUG ((EFI_D_VERBOSE, "PcdSimicsDecompressionScratchEnd: 0x%x\n", PcdGet32 (PcdSimicsDecompressionScratchEnd)));
+
+ DEBUG ((EFI_D_VERBOSE, "%a: OutputBuffer@%p+0x%x ScratchBuffer@%p+0x%x "
+ "PcdSimicsDecompressionScratchEnd=0x%x\n", __FUNCTION__, OutputBuffer,
+ OutputBufferSize, ScratchBuffer, ScratchBufferSize,
+ PcdGet32 (PcdSimicsDecompressionScratchEnd)));
+ ASSERT ((UINTN)ScratchBuffer + ScratchBufferSize ==
+ PcdGet32 (PcdSimicsDecompressionScratchEnd));
+
+ Status = ExtractGuidedSectionDecode (
+ Section,
+ &OutputBuffer,
+ ScratchBuffer,
+ &AuthenticationStatus
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Error during GUID section decode\n"));
+ return Status;
+ }
+
+ Status = FindFfsSectionInstance (
+ OutputBuffer,
+ OutputBufferSize,
+ EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
+ 0,
+ &FvSection
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to find PEI FV section\n"));
+ return Status;
+ }
+
+ ASSERT (SECTION_SIZE (FvSection) ==
+ (PcdGet32 (PcdSimicsPeiMemFvSize) + sizeof (*FvSection)));
+ ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
+
+ PeiMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdSimicsPeiMemFvBase);
+ CopyMem (PeiMemFv, (VOID*) (FvSection + 1), PcdGet32 (PcdSimicsPeiMemFvSize));
+
+ if (PeiMemFv->Signature != EFI_FVH_SIGNATURE) {
+ DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", PeiMemFv));
+ CpuDeadLoop ();
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ Status = FindFfsSectionInstance (
+ OutputBuffer,
+ OutputBufferSize,
+ EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
+ 1,
+ &FvSection
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to find DXE FV section\n"));
+ return Status;
+ }
+
+ ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
+
+ if (IS_SECTION2 (FvSection)) {
+ FvSectionSize = SECTION2_SIZE (FvSection);
+ FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);
+ } else {
+ FvSectionSize = SECTION_SIZE (FvSection);
+ FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);
+ }
+
+ ASSERT (FvSectionSize == (PcdGet32 (PcdSimicsDxeMemFvSize) + FvHeaderSize));
+
+ DxeMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdSimicsDxeMemFvBase);
+ CopyMem (DxeMemFv, (VOID*) ((UINTN)FvSection + FvHeaderSize), PcdGet32 (PcdSimicsDxeMemFvSize));
+
+ if (DxeMemFv->Signature != EFI_FVH_SIGNATURE) {
+ DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", DxeMemFv));
+ CpuDeadLoop ();
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ *Fv = PeiMemFv;
+ return EFI_SUCCESS;
+}
+
+/**
+ Locates the PEI Core entry point address
+
+ @param[in] Fv The firmware volume to search
+ @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindPeiCoreImageBaseInFv (
+ IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
+ OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
+ )
+{
+ EFI_STATUS Status;
+ EFI_COMMON_SECTION_HEADER *Section;
+
+ DEBUG ((EFI_D_VERBOSE, "Find PEI Core image.\n"));
+ Status = FindFfsFileAndSection (
+ Fv,
+ EFI_FV_FILETYPE_PEI_CORE,
+ EFI_SECTION_PE32,
+ &Section
+ );
+ if (EFI_ERROR (Status)) {
+ Status = FindFfsFileAndSection (
+ Fv,
+ EFI_FV_FILETYPE_PEI_CORE,
+ EFI_SECTION_TE,
+ &Section
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to find PEI Core image\n"));
+ return Status;
+ }
+ }
+
+ *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);
+ DEBUG ((EFI_D_VERBOSE, "PEI core image base 0x%016LX.\n", *PeiCoreImageBase));
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Reads 8-bits of CMOS data.
+
+ Reads the 8-bits of CMOS data at the location specified by Index.
+ The 8-bit read value is returned.
+
+ @param Index The CMOS location to read.
+
+ @return The value read.
+
+**/
+STATIC
+UINT8
+CmosRead8 (
+ IN UINTN Index
+ )
+{
+ IoWrite8 (0x70, (UINT8) Index);
+ return IoRead8 (0x71);
+}
+
+
+STATIC
+BOOLEAN
+IsS3Resume (
+ VOID
+ )
+{
+ DEBUG((EFI_D_VERBOSE, "modeValue = %x\n", IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12)));
+ return (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) == 0x5);
+}
+
+
+STATIC
+EFI_STATUS
+GetS3ResumePeiFv (
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **PeiFv
+ )
+{
+ *PeiFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdSimicsPeiMemFvBase);
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Locates the PEI Core entry point address
+
+ @param[in,out] Fv The firmware volume to search
+ @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+VOID
+FindPeiCoreImageBase (
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv,
+ OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
+ )
+{
+ BOOLEAN S3Resume;
+
+ *PeiCoreImageBase = 0;
+
+ S3Resume = IsS3Resume ();
+ if (S3Resume && !FeaturePcdGet (PcdSmmSmramRequire)) {
+ //
+ // A malicious runtime OS may have injected something into our previously
+ // decoded PEI FV, but we don't care about that unless SMM/SMRAM is required.
+ //
+ DEBUG ((EFI_D_VERBOSE, "SEC: S3 resume\n"));
+ GetS3ResumePeiFv (BootFv);
+ } else {
+ //
+ // We're either not resuming, or resuming "securely" -- we'll decompress
+ // both PEI FV and DXE FV from pristine flash.
+ //
+ DEBUG ((EFI_D_VERBOSE, "SEC: %a\n",
+ S3Resume ? "S3 resume (with PEI decompression)" : "Normal boot"));
+ FindMainFv (BootFv);
+
+ DecompressMemFvs (BootFv);
+ }
+
+ FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);
+}
+
+/**
+ Find core image base.
+
+**/
+EFI_STATUS
+FindImageBase (
+ IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,
+ OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase
+ )
+{
+ EFI_PHYSICAL_ADDRESS CurrentAddress;
+ EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
+ EFI_FFS_FILE_HEADER *File;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS EndOfFile;
+ EFI_COMMON_SECTION_HEADER *Section;
+ EFI_PHYSICAL_ADDRESS EndOfSection;
+
+ *SecCoreImageBase = 0;
+
+ CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) BootFirmwareVolumePtr;
+ EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr->FvLength;
+
+ //
+ // Loop through the FFS files in the Boot Firmware Volume
+ //
+ for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; ) {
+
+ CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
+ if (CurrentAddress > EndOfFirmwareVolume) {
+ return EFI_NOT_FOUND;
+ }
+
+ File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
+ Size = *(UINT32*) File->Size & 0xffffff;
+ if (Size < sizeof (*File)) {
+ return EFI_NOT_FOUND;
+ }
+
+ EndOfFile = CurrentAddress + Size;
+ if (EndOfFile > EndOfFirmwareVolume) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Look for SEC Core
+ //
+ if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE) {
+ continue;
+ }
+
+ //
+ // Loop through the FFS file sections within the FFS file
+ //
+ EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) (File + 1);
+ for (;;) {
+ CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL;
+ Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
+
+ Size = *(UINT32*) Section->Size & 0xffffff;
+ if (Size < sizeof (*Section)) {
+ return EFI_NOT_FOUND;
+ }
+
+ EndOfSection = CurrentAddress + Size;
+ if (EndOfSection > EndOfFile) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Look for executable sections
+ //
+ if (Section->Type == EFI_SECTION_PE32 || Section->Type == EFI_SECTION_TE) {
+ if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) {
+ *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) (Section + 1);
+ }
+ break;
+ }
+ }
+
+ //
+ // SEC Core image found
+ //
+ if (*SecCoreImageBase != 0) {
+ return EFI_SUCCESS;
+ }
+ }
+}
+
+/*
+ Find and return Pei Core entry point.
+
+ It also find SEC and PEI Core file debug information. It will report them if
+ remote debug is enabled.
+
+**/
+VOID
+FindAndReportEntryPoints (
+ IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr,
+ OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS SecCoreImageBase;
+ EFI_PHYSICAL_ADDRESS PeiCoreImageBase;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+
+ //
+ // Find SEC Core and PEI Core image base
+ //
+ Status = FindImageBase (*BootFirmwareVolumePtr, &SecCoreImageBase);
+ ASSERT_EFI_ERROR (Status);
+
+ FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);
+
+ ZeroMem ((VOID *) &ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
+ //
+ // Report SEC Core debug information when remote debug is enabled
+ //
+ ImageContext.ImageAddress = SecCoreImageBase;
+ ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);
+ PeCoffLoaderRelocateImageExtraAction (&ImageContext);
+
+ //
+ // Report PEI Core debug information when remote debug is enabled
+ //
+ ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageBase;
+ ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);
+ PeCoffLoaderRelocateImageExtraAction (&ImageContext);
+
+ //
+ // Find PEI Core entry point
+ //
+ Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, (VOID**) PeiCoreEntryPoint);
+ if (EFI_ERROR (Status)) {
+ *PeiCoreEntryPoint = 0;
+ }
+
+ return;
+}
+
+VOID
+EFIAPI
+SecCoreStartupWithStack (
+ IN EFI_FIRMWARE_VOLUME_HEADER *BootFv,
+ IN VOID *TopOfCurrentStack
+ )
+{
+ EFI_SEC_PEI_HAND_OFF SecCoreData;
+ SEC_IDT_TABLE IdtTableInStack;
+ IA32_DESCRIPTOR IdtDescriptor;
+ UINT32 Index;
+ volatile UINT8 *Table;
+
+ //
+ // Initialize floating point operating environment
+ // to be compliant with UEFI spec.
+ //
+ InitializeFloatingPointUnits ();
+
+ //
+ // Initialize the PCIe Configuration base register.
+ //
+ PciCf8Write32 (PCI_CF8_LIB_ADDRESS (0xFF, 0, 1, 0x50), 0xE0000001);
+
+ //
+ // To ensure SMM can't be compromised on S3 resume, we must force re-init of
+ // the BaseExtractGuidedSectionLib. Since this is before library contructors
+ // are called, we must use a loop rather than SetMem.
+ //
+ Table = (UINT8*)(UINTN)FixedPcdGet64 (PcdGuidedExtractHandlerTableAddress);
+ for (Index = 0;
+ Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize);
+ ++Index) {
+ Table[Index] = 0;
+ }
+
+ ProcessLibraryConstructorList (NULL, NULL);
+
+ DEBUG ((EFI_D_INFO,
+ "SecCoreStartupWithStack(0x%x, 0x%x)\n",
+ (UINT32)(UINTN)BootFv,
+ (UINT32)(UINTN)TopOfCurrentStack
+ ));
+
+ //
+ // Initialize IDT
+ //
+ IdtTableInStack.PeiService = NULL;
+ for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
+ CopyMem (&IdtTableInStack.IdtTable[Index], &mIdtEntryTemplate, sizeof (mIdtEntryTemplate));
+ }
+
+ IdtDescriptor.Base = (UINTN)&IdtTableInStack.IdtTable;
+ IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
+
+ AsmWriteIdtr (&IdtDescriptor);
+
+#if defined (MDE_CPU_X64)
+ //
+ // ASSERT that the Page Tables were set by the reset vector code to
+ // the address we expect.
+ //
+ ASSERT (AsmReadCr3 () == (UINTN) PcdGet32 (PcdSimicsSecPageTablesBase));
+#endif
+
+ //
+ // |-------------| <-- TopOfCurrentStack
+ // | Stack | 32k
+ // |-------------|
+ // | Heap | 32k
+ // |-------------| <-- SecCoreData.TemporaryRamBase
+ //
+
+ ASSERT ((UINTN) (PcdGet32 (PcdSimicsSecPeiTempRamBase) +
+ PcdGet32 (PcdSimicsSecPeiTempRamSize)) ==
+ (UINTN) TopOfCurrentStack);
+
+ //
+ // Initialize SEC hand-off state
+ //
+ SecCoreData.DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
+
+ SecCoreData.TemporaryRamSize = (UINTN) PcdGet32 (PcdSimicsSecPeiTempRamSize);
+ SecCoreData.TemporaryRamBase = (VOID*)((UINT8 *)TopOfCurrentStack - SecCoreData.TemporaryRamSize);
+
+ SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;
+ SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize >> 1;
+
+ SecCoreData.StackBase = (UINT8 *)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize;
+ SecCoreData.StackSize = SecCoreData.TemporaryRamSize >> 1;
+
+ SecCoreData.BootFirmwareVolumeBase = BootFv;
+ SecCoreData.BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
+
+ //
+ // Make sure the 8259 is masked before initializing the Debug Agent and the debug timer is enabled
+ //
+ IoWrite8 (0x21, 0xff);
+ IoWrite8 (0xA1, 0xff);
+
+ //
+ // Initialize Local APIC Timer hardware and disable Local APIC Timer
+ // interrupts before initializing the Debug Agent and the debug timer is
+ // enabled.
+ //
+ InitializeApicTimer (0, MAX_UINT32, TRUE, 5);
+ DisableApicTimerInterrupt ();
+
+ //
+ // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.
+ //
+ InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2);
+}
+
+/**
+ Caller provided function to be invoked at the end of InitializeDebugAgent().
+
+ Entry point to the C language phase of SEC. After the SEC assembly
+ code has initialized some temporary memory and set up the stack,
+ the control is transferred to this function.
+
+ @param[in] Context The first input parameter of InitializeDebugAgent().
+
+**/
+VOID
+EFIAPI
+SecStartupPhase2(
+ IN VOID *Context
+ )
+{
+ EFI_SEC_PEI_HAND_OFF *SecCoreData;
+ EFI_FIRMWARE_VOLUME_HEADER *BootFv;
+ EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;
+
+ SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context;
+
+ //
+ // Find PEI Core entry point. It will report SEC and Pei Core debug information if remote debug
+ // is enabled.
+ //
+ BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;
+ FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint);
+ SecCoreData->BootFirmwareVolumeBase = BootFv;
+ SecCoreData->BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
+
+ //
+ // Transfer the control to the PEI core
+ //
+ (*PeiCoreEntryPoint) (SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTable);
+
+ //
+ // If we get here then the PEI Core returned, which is not recoverable.
+ //
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+}
+
+EFI_STATUS
+EFIAPI
+TemporaryRamMigration (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ )
+{
+ IA32_DESCRIPTOR IdtDescriptor;
+ VOID *OldHeap;
+ VOID *NewHeap;
+ VOID *OldStack;
+ VOID *NewStack;
+ DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext;
+ BOOLEAN OldStatus;
+ BASE_LIBRARY_JUMP_BUFFER JumpBuffer;
+
+ DEBUG ((EFI_D_INFO,
+ "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",
+ TemporaryMemoryBase,
+ PermanentMemoryBase,
+ (UINT64)CopySize
+ ));
+
+ OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
+ NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));
+
+ OldStack = (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
+ NewStack = (VOID*)(UINTN)PermanentMemoryBase;
+
+ DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap - (UINTN)OldHeap;
+ DebugAgentContext.StackMigrateOffset = (UINTN)NewStack - (UINTN)OldStack;
+
+ OldStatus = SaveAndSetDebugTimerInterrupt (FALSE);
+ InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *) &DebugAgentContext, NULL);
+
+ //
+ // Migrate Heap
+ //
+ CopyMem (NewHeap, OldHeap, CopySize >> 1);
+
+ //
+ // Migrate Stack
+ //
+ CopyMem (NewStack, OldStack, CopySize >> 1);
+
+ //
+ // Rebase IDT table in permanent memory
+ //
+ AsmReadIdtr (&IdtDescriptor);
+ IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;
+
+ AsmWriteIdtr (&IdtDescriptor);
+
+ //
+ // Use SetJump()/LongJump() to switch to a new stack.
+ //
+ if (SetJump (&JumpBuffer) == 0) {
+#if defined (MDE_CPU_IA32)
+ JumpBuffer.Esp = JumpBuffer.Esp + DebugAgentContext.StackMigrateOffset;
+#endif
+#if defined (MDE_CPU_X64)
+ JumpBuffer.Rsp = JumpBuffer.Rsp + DebugAgentContext.StackMigrateOffset;
+#endif
+ LongJump (&JumpBuffer, (UINTN)-1);
+ }
+
+ SaveAndSetDebugTimerInterrupt (OldStatus);
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c
new file mode 100644
index 0000000000..c7b5237bd3
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.c
@@ -0,0 +1,865 @@
+/** @file
+ This driver effectuates QSP platform configuration settings and exposes
+ them via HII.
+
+ Copyright (C) 2014, Red Hat, Inc.
+ Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiHiiServicesLib.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/HiiConfigAccess.h>
+#include <Guid/MdeModuleHii.h>
+#include <Guid/SimicsBoardConfig.h>
+
+#include "Platform.h"
+#include "PlatformConfig.h"
+#include <Library/DxeServicesTableLib.h>
+//
+// The HiiAddPackages() library function requires that any controller (or
+// image) handle, to be associated with the HII packages under installation, be
+// "decorated" with a device path. The tradition seems to be a vendor device
+// path.
+//
+// We'd like to associate our HII packages with the driver's image handle. The
+// first idea is to use the driver image's device path. Unfortunately, loaded
+// images only come with an EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL (not the
+// usual EFI_DEVICE_PATH_PROTOCOL), ie. a different GUID. In addition, even the
+// EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL interface may be NULL, if the image
+// has been loaded from an "unnamed" memory source buffer.
+//
+// Hence let's just stick with the tradition -- use a dedicated vendor device
+// path, with the driver's FILE_GUID.
+//
+#pragma pack(1)
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PKG_DEVICE_PATH;
+#pragma pack()
+
+STATIC PKG_DEVICE_PATH mPkgDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH) ),
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH) >> 8)
+ }
+ },
+ EFI_CALLER_ID_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8) (END_DEVICE_PATH_LENGTH ),
+ (UINT8) (END_DEVICE_PATH_LENGTH >> 8)
+ }
+ }
+};
+
+//
+// The configuration interface between the HII engine (form display etc) and
+// this driver.
+//
+STATIC EFI_HII_CONFIG_ACCESS_PROTOCOL mConfigAccess;
+
+//
+// The handle representing our list of packages after installation.
+//
+STATIC EFI_HII_HANDLE mInstalledPackages;
+
+//
+// The arrays below constitute our HII package list. They are auto-generated by
+// the VFR compiler and linked into the driver image during the build.
+//
+// - The strings package receives its C identifier from the driver's BASE_NAME,
+// plus "Strings".
+//
+// - The forms package receives its C identifier from the VFR file's basename,
+// plus "Bin".
+//
+//
+extern UINT8 SimicsDxeStrings[];
+extern UINT8 PlatformFormsBin[];
+
+//
+// We want to be notified about GOP installations until we find one GOP
+// interface that lets us populate the form.
+//
+STATIC EFI_EVENT mGopEvent;
+
+//
+// The registration record underneath this pointer allows us to iterate through
+// the GOP instances one by one.
+//
+STATIC VOID *mGopTracker;
+
+//
+// Cache the resolutions we get from the GOP.
+//
+typedef struct {
+ UINT32 X;
+ UINT32 Y;
+} GOP_MODE;
+
+STATIC UINTN mNumGopModes;
+STATIC GOP_MODE *mGopModes;
+
+
+/**
+ Load the persistent platform configuration and translate it to binary form
+ state.
+
+ If the platform configuration is missing, then the function fills in a
+ default state.
+
+ @param[out] MainFormState Binary form/widget state after translation.
+
+ @retval EFI_SUCCESS Form/widget state ready.
+ @return Error codes from underlying functions.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+PlatformConfigToFormState (
+ OUT MAIN_FORM_STATE *MainFormState
+ )
+{
+ EFI_STATUS Status;
+ PLATFORM_CONFIG PlatformConfig;
+ UINT64 OptionalElements;
+ UINTN ModeNumber;
+
+ ZeroMem (MainFormState, sizeof *MainFormState);
+
+ Status = PlatformConfigLoad (&PlatformConfig, &OptionalElements);
+ switch (Status) {
+ case EFI_SUCCESS:
+ if (OptionalElements & PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION) {
+ //
+ // Format the preferred resolution as text.
+ //
+ UnicodeSPrintAsciiFormat (
+ (CHAR16 *) MainFormState->CurrentPreferredResolution,
+ sizeof MainFormState->CurrentPreferredResolution,
+ "%Ldx%Ld",
+ (INT64) PlatformConfig.HorizontalResolution,
+ (INT64) PlatformConfig.VerticalResolution);
+
+ //
+ // Try to locate it in the drop-down list too. This may not succeed, but
+ // that's fine.
+ //
+ for (ModeNumber = 0; ModeNumber < mNumGopModes; ++ModeNumber) {
+ if (mGopModes[ModeNumber].X == PlatformConfig.HorizontalResolution &&
+ mGopModes[ModeNumber].Y == PlatformConfig.VerticalResolution) {
+ MainFormState->NextPreferredResolution = (UINT32) ModeNumber;
+ break;
+ }
+ }
+
+ break;
+ }
+ //
+ // fall through otherwise
+ //
+
+ case EFI_NOT_FOUND:
+ UnicodeSPrintAsciiFormat (
+ (CHAR16 *) MainFormState->CurrentPreferredResolution,
+ sizeof MainFormState->CurrentPreferredResolution,
+ "Unset");
+ break;
+
+ default:
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function is called by the HII machinery when it fetches the form state.
+
+ See the precise documentation in the UEFI spec.
+
+ @param[in] This The Config Access Protocol instance.
+
+ @param[in] Request A <ConfigRequest> format UCS-2 string describing the
+ query.
+
+ @param[out] Progress A pointer into Request on output, identifying the query
+ element where processing failed.
+
+ @param[out] Results A <MultiConfigAltResp> format UCS-2 string that has
+ all values filled in for the names in the Request
+ string.
+
+ @retval EFI_SUCCESS Extraction of form state in <MultiConfigAltResp>
+ encoding successful.
+ @return Status codes from underlying functions.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ExtractConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+)
+{
+ MAIN_FORM_STATE MainFormState;
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_VERBOSE, "%a: Request=\"%s\"\n", __FUNCTION__, Request));
+
+ Status = PlatformConfigToFormState (&MainFormState);
+ if (EFI_ERROR (Status)) {
+ *Progress = Request;
+ return Status;
+ }
+
+ //
+ // Answer the textual request keying off the binary form state.
+ //
+ Status = gHiiConfigRouting->BlockToConfig (gHiiConfigRouting, Request,
+ (VOID *) &MainFormState, sizeof MainFormState,
+ Results, Progress);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: BlockToConfig(): %r, Progress=\"%s\"\n",
+ __FUNCTION__, Status, (Status == EFI_DEVICE_ERROR) ? NULL : *Progress));
+ } else {
+ DEBUG ((EFI_D_VERBOSE, "%a: Results=\"%s\"\n", __FUNCTION__, *Results));
+ }
+ return Status;
+}
+
+
+/**
+ Interpret the binary form state and save it as persistent platform
+ configuration.
+
+ @param[in] MainFormState Binary form/widget state to verify and save.
+
+ @retval EFI_SUCCESS Platform configuration saved.
+ @return Error codes from underlying functions.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+FormStateToPlatformConfig (
+ IN CONST MAIN_FORM_STATE *MainFormState
+ )
+{
+ EFI_STATUS Status;
+ PLATFORM_CONFIG PlatformConfig;
+ CONST GOP_MODE *GopMode;
+
+ //
+ // There's nothing to do with the textual CurrentPreferredResolution field.
+ // We verify and translate the selection in the drop-down list.
+ //
+ if (MainFormState->NextPreferredResolution >= mNumGopModes) {
+ return EFI_INVALID_PARAMETER;
+ }
+ GopMode = mGopModes + MainFormState->NextPreferredResolution;
+
+ ZeroMem (&PlatformConfig, sizeof PlatformConfig);
+ PlatformConfig.HorizontalResolution = GopMode->X;
+ PlatformConfig.VerticalResolution = GopMode->Y;
+
+ Status = PlatformConfigSave (&PlatformConfig);
+ return Status;
+}
+
+
+/**
+ This function is called by the HII machinery when it wants the driver to
+ interpret and persist the form state.
+
+ See the precise documentation in the UEFI spec.
+
+ @param[in] This The Config Access Protocol instance.
+
+ @param[in] Configuration A <ConfigResp> format UCS-2 string describing the
+ form state.
+
+ @param[out] Progress A pointer into Configuration on output,
+ identifying the element where processing failed.
+
+ @retval EFI_SUCCESS Configuration verified, state permanent.
+
+ @return Status codes from underlying functions.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+RouteConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+)
+{
+ MAIN_FORM_STATE MainFormState;
+ UINTN BlockSize;
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_VERBOSE, "%a: Configuration=\"%s\"\n", __FUNCTION__,
+ Configuration));
+
+ //
+ // the "read" step in RMW
+ //
+ Status = PlatformConfigToFormState (&MainFormState);
+ if (EFI_ERROR (Status)) {
+ *Progress = Configuration;
+ return Status;
+ }
+
+ //
+ // the "modify" step in RMW
+ //
+ // (Update the binary form state. This update may be partial, which is why in
+ // general we must pre-load the form state from the platform config.)
+ //
+ BlockSize = sizeof MainFormState;
+ Status = gHiiConfigRouting->ConfigToBlock (gHiiConfigRouting, Configuration,
+ (VOID *) &MainFormState, &BlockSize, Progress);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: ConfigToBlock(): %r, Progress=\"%s\"\n",
+ __FUNCTION__, Status,
+ (Status == EFI_BUFFER_TOO_SMALL) ? NULL : *Progress));
+ return Status;
+ }
+
+ //
+ // the "write" step in RMW
+ //
+ Status = FormStateToPlatformConfig (&MainFormState);
+ if (EFI_ERROR (Status)) {
+ *Progress = Configuration;
+ }
+ return Status;
+}
+
+
+STATIC
+EFI_STATUS
+EFIAPI
+Callback (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID QuestionId,
+ IN UINT8 Type,
+ IN OUT EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+ )
+{
+ DEBUG ((EFI_D_VERBOSE, "%a: Action=0x%Lx QuestionId=%d Type=%d\n",
+ __FUNCTION__, (UINT64) Action, QuestionId, Type));
+
+ if (Action != EFI_BROWSER_ACTION_CHANGED) {
+ return EFI_UNSUPPORTED;
+ }
+
+ switch (QuestionId) {
+ case QUESTION_SAVE_EXIT:
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
+ break;
+
+ case QUESTION_DISCARD_EXIT:
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
+ break;
+
+ default:
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Query and save all resolutions supported by the GOP.
+
+ @param[in] Gop The Graphics Output Protocol instance to query.
+
+ @param[out] NumGopModes The number of modes supported by the GOP. On output,
+ this parameter will be positive.
+
+ @param[out] GopModes On output, a dynamically allocated array containing
+ the resolutions returned by the GOP. The caller is
+ responsible for freeing the array after use.
+
+ @retval EFI_UNSUPPORTED No modes found.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate GopModes.
+ @return Error codes from Gop->QueryMode().
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+QueryGopModes (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop,
+ OUT UINTN *NumGopModes,
+ OUT GOP_MODE **GopModes
+ )
+{
+ EFI_STATUS Status;
+ UINT32 ModeNumber;
+
+ if (Gop->Mode->MaxMode == 0) {
+ return EFI_UNSUPPORTED;
+ }
+ *NumGopModes = Gop->Mode->MaxMode;
+
+ *GopModes = AllocatePool (Gop->Mode->MaxMode * sizeof **GopModes);
+ if (*GopModes == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ for (ModeNumber = 0; ModeNumber < Gop->Mode->MaxMode; ++ModeNumber) {
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
+ UINTN SizeOfInfo;
+
+ Status = Gop->QueryMode (Gop, ModeNumber, &SizeOfInfo, &Info);
+ if (EFI_ERROR (Status)) {
+ goto FreeGopModes;
+ }
+
+ (*GopModes)[ModeNumber].X = Info->HorizontalResolution;
+ (*GopModes)[ModeNumber].Y = Info->VerticalResolution;
+ FreePool (Info);
+ }
+
+ return EFI_SUCCESS;
+
+FreeGopModes:
+ FreePool (*GopModes);
+
+ return Status;
+}
+
+
+/**
+ Create a set of "one-of-many" (ie. "drop down list") option IFR opcodes,
+ based on available GOP resolutions, to be placed under a "one-of-many" (ie.
+ "drop down list") opcode.
+
+ @param[in] PackageList The package list with the formset and form for
+ which the drop down options are produced. Option
+ names are added as new strings to PackageList.
+
+ @param[out] OpCodeBuffer On output, a dynamically allocated opcode buffer
+ with drop down list options corresponding to GOP
+ resolutions. The caller is responsible for freeing
+ OpCodeBuffer with HiiFreeOpCodeHandle() after use.
+
+ @param[in] NumGopModes Number of entries in GopModes.
+
+ @param[in] GopModes Array of resolutions retrieved from the GOP.
+
+ @retval EFI_SUCESS Opcodes have been successfully produced.
+
+ @return Status codes from underlying functions. PackageList may
+ have been extended with new strings. OpCodeBuffer is
+ unchanged.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CreateResolutionOptions (
+ IN EFI_HII_HANDLE *PackageList,
+ OUT VOID **OpCodeBuffer,
+ IN UINTN NumGopModes,
+ IN GOP_MODE *GopModes
+ )
+{
+ EFI_STATUS Status;
+ VOID *OutputBuffer;
+ UINTN ModeNumber;
+
+ OutputBuffer = HiiAllocateOpCodeHandle ();
+ if (OutputBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ for (ModeNumber = 0; ModeNumber < NumGopModes; ++ModeNumber) {
+ CHAR16 Desc[MAXSIZE_RES_CUR];
+ EFI_STRING_ID NewString;
+ VOID *OpCode;
+
+ UnicodeSPrintAsciiFormat (Desc, sizeof Desc, "%Ldx%Ld",
+ (INT64) GopModes[ModeNumber].X, (INT64) GopModes[ModeNumber].Y);
+ NewString = HiiSetString (PackageList, 0 /* new string */, Desc,
+ NULL /* for all languages */);
+ if (NewString == 0) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FreeOutputBuffer;
+ }
+ OpCode = HiiCreateOneOfOptionOpCode (OutputBuffer, NewString,
+ 0 /* Flags */, EFI_IFR_NUMERIC_SIZE_4, ModeNumber);
+ if (OpCode == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FreeOutputBuffer;
+ }
+ }
+
+ *OpCodeBuffer = OutputBuffer;
+ return EFI_SUCCESS;
+
+FreeOutputBuffer:
+ HiiFreeOpCodeHandle (OutputBuffer);
+
+ return Status;
+}
+
+
+/**
+ Populate the form identified by the (PackageList, FormSetGuid, FormId)
+ triplet.
+
+ The drop down list of video resolutions is generated from (NumGopModes,
+ GopModes).
+
+ @retval EFI_SUCESS Form successfully updated.
+ @return Status codes from underlying functions.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+PopulateForm (
+ IN EFI_HII_HANDLE *PackageList,
+ IN EFI_GUID *FormSetGuid,
+ IN EFI_FORM_ID FormId,
+ IN UINTN NumGopModes,
+ IN GOP_MODE *GopModes
+ )
+{
+ EFI_STATUS Status;
+ VOID *OpCodeBuffer;
+ VOID *OpCode;
+ EFI_IFR_GUID_LABEL *Anchor;
+ VOID *OpCodeBuffer2;
+
+ OpCodeBuffer2 = NULL;
+
+ //
+ // 1. Allocate an empty opcode buffer.
+ //
+ OpCodeBuffer = HiiAllocateOpCodeHandle ();
+ if (OpCodeBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // 2. Create a label opcode (which is a Tiano extension) inside the buffer.
+ // The label's number must match the "anchor" label in the form.
+ //
+ OpCode = HiiCreateGuidOpCode (OpCodeBuffer, &gEfiIfrTianoGuid,
+ NULL /* optional copy origin */, sizeof *Anchor);
+ if (OpCode == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FreeOpCodeBuffer;
+ }
+ Anchor = OpCode;
+ Anchor->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ Anchor->Number = LABEL_RES_NEXT;
+
+ //
+ // 3. Create the opcodes inside the buffer that are to be inserted into the
+ // form.
+ //
+ // 3.1. Get a list of resolutions.
+ //
+ Status = CreateResolutionOptions (PackageList, &OpCodeBuffer2,
+ NumGopModes, GopModes);
+ if (EFI_ERROR (Status)) {
+ goto FreeOpCodeBuffer;
+ }
+
+ //
+ // 3.2. Create a one-of-many question with the above options.
+ //
+ OpCode = HiiCreateOneOfOpCode (
+ OpCodeBuffer, // create opcode inside this
+ // opcode buffer,
+ QUESTION_RES_NEXT, // ID of question,
+ FORMSTATEID_MAIN_FORM, // identifies form state
+ // storage,
+ (UINT16) OFFSET_OF (MAIN_FORM_STATE, // value of question stored
+ NextPreferredResolution), // at this offset,
+ STRING_TOKEN (STR_RES_NEXT), // Prompt,
+ STRING_TOKEN (STR_RES_NEXT_HELP), // Help,
+ 0, // QuestionFlags,
+ EFI_IFR_NUMERIC_SIZE_4, // see sizeof
+ // NextPreferredResolution,
+ OpCodeBuffer2, // buffer with possible
+ // choices,
+ NULL // DEFAULT opcodes
+ );
+ if (OpCode == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FreeOpCodeBuffer2;
+ }
+
+ //
+ // 4. Update the form with the opcode buffer.
+ //
+ Status = HiiUpdateForm (PackageList, FormSetGuid, FormId,
+ OpCodeBuffer, // buffer with head anchor, and new contents to be
+ // inserted at it
+ NULL // buffer with tail anchor, for deleting old
+ // contents up to it
+ );
+
+FreeOpCodeBuffer2:
+ HiiFreeOpCodeHandle (OpCodeBuffer2);
+
+FreeOpCodeBuffer:
+ HiiFreeOpCodeHandle (OpCodeBuffer);
+
+ return Status;
+}
+
+
+/**
+ Load and execute the platform configuration.
+
+ @retval EFI_SUCCESS Configuration loaded and executed.
+ @return Status codes from PlatformConfigLoad().
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ExecutePlatformConfig (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ PLATFORM_CONFIG PlatformConfig;
+ UINT64 OptionalElements;
+
+ Status = PlatformConfigLoad (&PlatformConfig, &OptionalElements);
+ if (EFI_ERROR (Status)) {
+ DEBUG (((Status == EFI_NOT_FOUND) ? EFI_D_VERBOSE : EFI_D_ERROR,
+ "%a: failed to load platform config: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ if (OptionalElements & PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION) {
+ //
+ // Pass the preferred resolution to GraphicsConsoleDxe via dynamic PCDs.
+ //
+ PcdSet32 (PcdVideoHorizontalResolution,
+ PlatformConfig.HorizontalResolution);
+ PcdSet32 (PcdVideoVerticalResolution,
+ PlatformConfig.VerticalResolution);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Notification callback for GOP interface installation.
+
+ @param[in] Event Event whose notification function is being invoked.
+
+ @param[in] Context The pointer to the notification function's context, which
+ is implementation-dependent.
+**/
+STATIC
+VOID
+EFIAPI
+GopInstalled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
+
+ ASSERT (Event == mGopEvent);
+
+ //
+ // Check further GOPs.
+ //
+ for (;;) {
+ mNumGopModes = 0;
+ mGopModes = NULL;
+
+ Status = gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid, mGopTracker,
+ (VOID **) &Gop);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ Status = QueryGopModes (Gop, &mNumGopModes, &mGopModes);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ Status = PopulateForm (mInstalledPackages, &gSimicsBoardConfigGuid,
+ FORMID_MAIN_FORM, mNumGopModes, mGopModes);
+ if (EFI_ERROR (Status)) {
+ FreePool (mGopModes);
+ continue;
+ }
+
+ break;
+ }
+
+ //
+ // Success -- so uninstall this callback. Closing the event removes all
+ // pending notifications and all protocol registrations.
+ //
+ Status = gBS->CloseEvent (mGopEvent);
+ ASSERT_EFI_ERROR (Status);
+ mGopEvent = NULL;
+ mGopTracker = NULL;
+}
+
+
+/**
+ Entry point for this driver.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Pointer to SystemTable.
+
+ @retval EFI_SUCESS Driver has loaded successfully.
+ @retval EFI_OUT_OF_RESOURCES Failed to install HII packages.
+ @return Error codes from lower level functions.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ ExecutePlatformConfig ();
+
+ mConfigAccess.ExtractConfig = &ExtractConfig;
+ mConfigAccess.RouteConfig = &RouteConfig;
+ mConfigAccess.Callback = &Callback;
+
+ //
+ // Declare ourselves suitable for HII communication.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
+ &gEfiDevicePathProtocolGuid, &mPkgDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess,
+ NULL);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Publish the HII package list to HII Database.
+ //
+ mInstalledPackages = HiiAddPackages (
+ &gEfiCallerIdGuid, // PackageListGuid
+ ImageHandle, // associated DeviceHandle
+ SimicsDxeStrings, // 1st package
+ PlatformFormsBin, // 2nd package
+ NULL // terminator
+ );
+ if (mInstalledPackages == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto UninstallProtocols;
+ }
+
+ Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, &GopInstalled,
+ NULL /* Context */, &mGopEvent);
+ if (EFI_ERROR (Status)) {
+ goto RemovePackages;
+ }
+
+ Status = gBS->RegisterProtocolNotify (&gEfiGraphicsOutputProtocolGuid,
+ mGopEvent, &mGopTracker);
+ if (EFI_ERROR (Status)) {
+ goto CloseGopEvent;
+ }
+
+ //
+ // Check already installed GOPs.
+ //
+ Status = gBS->SignalEvent (mGopEvent);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+
+CloseGopEvent:
+ gBS->CloseEvent (mGopEvent);
+
+RemovePackages:
+ HiiRemovePackages (mInstalledPackages);
+
+UninstallProtocols:
+ gBS->UninstallMultipleProtocolInterfaces (ImageHandle,
+ &gEfiDevicePathProtocolGuid, &mPkgDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess,
+ NULL);
+ return Status;
+}
+
+/**
+ Unload the driver.
+
+ @param[in] ImageHandle Handle that identifies the image to evict.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+**/
+EFI_STATUS
+EFIAPI
+PlatformUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ if (mGopEvent == NULL) {
+ //
+ // The GOP callback ran successfully and unregistered itself. Release the
+ // resources allocated there.
+ //
+ ASSERT (mGopModes != NULL);
+ FreePool (mGopModes);
+ } else {
+ //
+ // Otherwise we need to unregister the callback.
+ //
+ ASSERT (mGopModes == NULL);
+ gBS->CloseEvent (mGopEvent);
+ }
+
+ //
+ // Release resources allocated by the entry point.
+ //
+ HiiRemovePackages (mInstalledPackages);
+ gBS->UninstallMultipleProtocolInterfaces (ImageHandle,
+ &gEfiDevicePathProtocolGuid, &mPkgDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess,
+ NULL);
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c
new file mode 100644
index 0000000000..b1e017bbb0
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.c
@@ -0,0 +1,123 @@
+/** @file
+ Utility functions for serializing (persistently storing) and deserializing
+ SIMICS QSP's platform configuration.
+
+ Copyright (C) 2014, Red Hat, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Guid/SimicsBoardConfig.h>
+
+#include "PlatformConfig.h"
+
+//
+// Name of the UEFI variable that we use for persistent storage.
+//
+STATIC CHAR16 mVariableName[] = L"PlatformConfig";
+
+
+/**
+ Serialize and persistently save platform configuration.
+
+ @param[in] PlatformConfig The platform configuration to serialize and save.
+
+ @return Status codes returned by gRT->SetVariable().
+**/
+EFI_STATUS
+EFIAPI
+PlatformConfigSave (
+ IN PLATFORM_CONFIG *PlatformConfig
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // We could implement any kind of translation here, as part of serialization.
+ // For example, we could expose the platform configuration in separate
+ // variables with human-readable contents, allowing other tools to access
+ // them more easily. For now, just save a binary dump.
+ //
+ Status = gRT->SetVariable (mVariableName, &gSimicsBoardConfigGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof *PlatformConfig, PlatformConfig);
+ return Status;
+}
+
+
+/**
+ Load and deserialize platform configuration.
+
+ When the function fails, output parameters are indeterminate.
+
+ @param[out] PlatformConfig The platform configuration to receive the
+ loaded data.
+
+ @param[out] OptionalElements This bitmap describes the presence of optional
+ configuration elements that have been loaded.
+ PLATFORM_CONFIG_F_DOWNGRADE means that some
+ unknown elements, present in the wire format,
+ have been ignored.
+
+ @retval EFI_SUCCESS Loading & deserialization successful.
+ @return Error codes returned by GetVariable2().
+**/
+EFI_STATUS
+EFIAPI
+PlatformConfigLoad (
+ OUT PLATFORM_CONFIG *PlatformConfig,
+ OUT UINT64 *OptionalElements
+ )
+{
+ VOID *Data;
+ UINTN DataSize;
+ EFI_STATUS Status;
+
+ //
+ // Any translation done in PlatformConfigSave() would have to be mirrored
+ // here. For now, just load the binary dump.
+ //
+ // Versioning of the binary wire format is implemented based on size
+ // (only incremental changes, ie. new fields), and on GUID.
+ // (Incompatible changes require a GUID change.)
+ //
+ Status = GetVariable2 (mVariableName, &gSimicsBoardConfigGuid, &Data,
+ &DataSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ *OptionalElements = 0;
+ if (DataSize > sizeof *PlatformConfig) {
+ //
+ // Handle firmware downgrade -- keep only leading part.
+ //
+ CopyMem (PlatformConfig, Data, sizeof *PlatformConfig);
+ *OptionalElements |= PLATFORM_CONFIG_F_DOWNGRADE;
+ } else {
+ CopyMem (PlatformConfig, Data, DataSize);
+
+ //
+ // Handle firmware upgrade -- zero out missing fields.
+ //
+ ZeroMem ((UINT8 *)PlatformConfig + DataSize,
+ sizeof *PlatformConfig - DataSize);
+ }
+
+ //
+ // Based on DataSize, report the optional features that we recognize.
+ //
+ if (DataSize >= (OFFSET_OF (PLATFORM_CONFIG, VerticalResolution) +
+ sizeof PlatformConfig->VerticalResolution)) {
+ *OptionalElements |= PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION;
+ }
+
+ FreePool (Data);
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c
new file mode 100644
index 0000000000..b34ba9283b
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.c
@@ -0,0 +1,57 @@
+/** @file
+ PC/AT CMOS access routines
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Cmos.h"
+#include "Library/IoLib.h"
+
+/**
+ Reads 8-bits of CMOS data.
+
+ Reads the 8-bits of CMOS data at the location specified by Index.
+ The 8-bit read value is returned.
+
+ @param Index The CMOS location to read.
+
+ @return The value read.
+
+**/
+UINT8
+EFIAPI
+CmosRead8 (
+ IN UINTN Index
+ )
+{
+ IoWrite8 (0x70, (UINT8) Index);
+ return IoRead8 (0x71);
+}
+
+
+/**
+ Writes 8-bits of CMOS data.
+
+ Writes 8-bits of CMOS data to the location specified by Index
+ with the value specified by Value and returns Value.
+
+ @param Index The CMOS location to write.
+ @param Value The value to write to CMOS.
+
+ @return The value written to CMOS.
+
+**/
+UINT8
+EFIAPI
+CmosWrite8 (
+ IN UINTN Index,
+ IN UINT8 Value
+ )
+{
+ IoWrite8 (0x70, (UINT8) Index);
+ IoWrite8 (0x71, Value);
+ return Value;
+}
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/FeatureControl.c b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/FeatureControl.c
new file mode 100644
index 0000000000..692405e417
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/FeatureControl.c
@@ -0,0 +1,114 @@
+/** @file
+ Install a callback when necessary for setting the Feature Control MSR on all
+ processors.
+
+ Copyright (C) 2016, Red Hat, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/MpServices.h>
+#include <Register/Intel/Msr/Core2Msr.h>
+
+#include "Platform.h"
+
+//
+// The value to be written to the Feature Control MSR, retrieved from fw_cfg.
+//
+STATIC UINT64 mFeatureControlValue = 0x00000005;
+
+/**
+ Write the Feature Control MSR on an Application Processor or the Boot
+ Processor.
+
+ All APs execute this function in parallel. The BSP executes the function
+ separately.
+
+ @param[in,out] WorkSpace Pointer to the input/output argument workspace
+ shared by all processors.
+**/
+STATIC
+VOID
+EFIAPI
+WriteFeatureControl (
+ IN OUT VOID *WorkSpace
+ )
+{
+ AsmWriteMsr64 (MSR_CORE2_FEATURE_CONTROL, mFeatureControlValue);
+}
+
+/**
+ Notification function called when EFI_PEI_MP_SERVICES_PPI becomes available.
+
+ @param[in] PeiServices Indirect reference to the PEI Services Table.
+ @param[in] NotifyDescriptor Address of the notification descriptor data
+ structure.
+ @param[in] Ppi Address of the PPI that was installed.
+
+ @return Status of the notification. The status code returned from this
+ function is ignored.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+OnMpServicesAvailable (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_PEI_MP_SERVICES_PPI *MpServices;
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_VERBOSE, "%a: %a\n", gEfiCallerBaseName, __FUNCTION__));
+ //
+ // Write the MSR on all the APs in parallel.
+ //
+ MpServices = Ppi;
+ Status = MpServices->StartupAllAPs (
+ (CONST EFI_PEI_SERVICES **)PeiServices,
+ MpServices,
+ WriteFeatureControl, // Procedure
+ FALSE, // SingleThread
+ 0, // TimeoutInMicroSeconds: inf.
+ NULL // ProcedureArgument
+ );
+ if (EFI_ERROR (Status) && Status != EFI_NOT_STARTED) {
+ DEBUG ((EFI_D_ERROR, "%a: StartupAllAps(): %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ //
+ // Now write the MSR on the BSP too.
+ //
+ WriteFeatureControl (NULL);
+
+ return EFI_SUCCESS;
+}
+
+//
+// Notification object for registering the callback, for when
+// EFI_PEI_MP_SERVICES_PPI becomes available.
+//
+STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mMpServicesNotify = {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | // Flags
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiMpServicesPpiGuid, // Guid
+ OnMpServicesAvailable // Notify
+};
+
+VOID
+InstallFeatureControlCallback (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = PeiServicesNotifyPpi (&mMpServicesNotify);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: failed to set up MP Services callback: %r\n",
+ __FUNCTION__, Status));
+ }
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c
new file mode 100644
index 0000000000..90e6d1d3cf
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/MemDetect.c
@@ -0,0 +1,568 @@
+/** @file
+ Memory Detection for Virtual Machines.
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/ResourcePublicationLib.h>
+#include <Library/MtrrLib.h>
+#include <SimicsPlatforms.h>
+#include <Guid/SmramMemoryReserve.h>
+
+#include "Platform.h"
+#include "Cmos.h"
+
+UINT8 mPhysMemAddressWidth;
+
+STATIC UINT32 mS3AcpiReservedMemoryBase;
+STATIC UINT32 mS3AcpiReservedMemorySize;
+
+STATIC UINT16 mX58TsegMbytes;
+
+VOID
+X58TsegMbytesInitialization(
+ VOID
+)
+{
+
+ if (mHostBridgeDevId != INTEL_ICH10_DEVICE_ID) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: no TSEG (SMRAM) on host bridge DID=0x%04x; "
+ "only DID=0x%04x (X58) is supported\n",
+ __FUNCTION__,
+ mHostBridgeDevId,
+ INTEL_ICH10_DEVICE_ID
+ ));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+
+ //
+ // Check if QEMU offers an extended TSEG.
+ //
+ // This can be seen from writing MCH_EXT_TSEG_MB_QUERY to the MCH_EXT_TSEG_MB
+ // register, and reading back the register.
+ //
+ // On a QEMU machine type that does not offer an extended TSEG, the initial
+ // write overwrites whatever value a malicious guest OS may have placed in
+ // the (unimplemented) register, before entering S3 or rebooting.
+ // Subsequently, the read returns MCH_EXT_TSEG_MB_QUERY unchanged.
+ //
+ // On a QEMU machine type that offers an extended TSEG, the initial write
+ // triggers an update to the register. Subsequently, the value read back
+ // (which is guaranteed to differ from MCH_EXT_TSEG_MB_QUERY) tells us the
+ // number of megabytes.
+ //
+ mX58TsegMbytes = FixedPcdGet8(PcdX58TsegMbytes);
+ return;
+}
+
+
+UINT32
+GetSystemMemorySizeBelow4gb (
+ VOID
+ )
+{
+ UINT8 Cmos0x34;
+ UINT8 Cmos0x35;
+
+ //
+ // CMOS 0x34/0x35 specifies the system memory above 16 MB.
+ // * CMOS(0x35) is the high byte
+ // * CMOS(0x34) is the low byte
+ // * The size is specified in 64kb chunks
+ // * Since this is memory above 16MB, the 16MB must be added
+ // into the calculation to get the total memory size.
+ //
+
+ Cmos0x34 = (UINT8) CmosRead8 (0x34);
+ Cmos0x35 = (UINT8) CmosRead8 (0x35);
+
+ return (UINT32) (((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);
+}
+
+
+STATIC
+UINT64
+GetSystemMemorySizeAbove4gb (
+ )
+{
+ UINT32 Size;
+ UINTN CmosIndex;
+
+ //
+ // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
+ // * CMOS(0x5d) is the most significant size byte
+ // * CMOS(0x5c) is the middle size byte
+ // * CMOS(0x5b) is the least significant size byte
+ // * The size is specified in 64kb chunks
+ //
+
+ Size = 0;
+ for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {
+ Size = (UINT32) (Size << 8) + (UINT32) CmosRead8 (CmosIndex);
+ }
+
+ return LShiftU64 (Size, 16);
+}
+
+
+/**
+ Return the highest address that DXE could possibly use, plus one.
+**/
+STATIC
+UINT64
+GetFirstNonAddress (
+ VOID
+ )
+{
+ UINT64 FirstNonAddress;
+ UINT64 Pci64Base, Pci64Size;
+
+ FirstNonAddress = BASE_4GB + GetSystemMemorySizeAbove4gb ();
+
+ //
+ // If DXE is 32-bit, then we're done; PciBusDxe will degrade 64-bit MMIO
+ // resources to 32-bit anyway. See DegradeResource() in
+ // "PciResourceSupport.c".
+ //
+#ifdef MDE_CPU_IA32
+ if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+ return FirstNonAddress;
+ }
+#endif
+
+ //
+ // Otherwise, in order to calculate the highest address plus one, we must
+ // consider the 64-bit PCI host aperture too. Fetch the default size.
+ //
+ Pci64Size = PcdGet64 (PcdPciMmio64Size);
+
+ if (Pci64Size == 0) {
+ if (mBootMode != BOOT_ON_S3_RESUME) {
+ DEBUG ((EFI_D_INFO, "%a: disabling 64-bit PCI host aperture\n",
+ __FUNCTION__));
+ PcdSet64 (PcdPciMmio64Size, 0);
+ }
+
+ //
+ // There's nothing more to do; the amount of memory above 4GB fully
+ // determines the highest address plus one. The memory hotplug area (see
+ // below) plays no role for the firmware in this case.
+ //
+ return FirstNonAddress;
+ }
+
+ //
+ // SeaBIOS aligns both boundaries of the 64-bit PCI host aperture to 1GB, so
+ // that the host can map it with 1GB hugepages. Follow suit.
+ //
+ Pci64Base = ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB);
+ Pci64Size = ALIGN_VALUE (Pci64Size, (UINT64)SIZE_1GB);
+
+ //
+ // The 64-bit PCI host aperture should also be "naturally" aligned. The
+ // alignment is determined by rounding the size of the aperture down to the
+ // next smaller or equal power of two. That is, align the aperture by the
+ // largest BAR size that can fit into it.
+ //
+ Pci64Base = ALIGN_VALUE (Pci64Base, GetPowerOfTwo64 (Pci64Size));
+
+ if (mBootMode != BOOT_ON_S3_RESUME) {
+ //
+ // The core PciHostBridgeDxe driver will automatically add this range to
+ // the GCD memory space map through our PciHostBridgeLib instance; here we
+ // only need to set the PCDs.
+ //
+ PcdSet64 (PcdPciMmio64Base, Pci64Base);
+ PcdSet64 (PcdPciMmio64Size, Pci64Size);
+ DEBUG ((EFI_D_INFO, "%a: Pci64Base=0x%Lx Pci64Size=0x%Lx\n",
+ __FUNCTION__, Pci64Base, Pci64Size));
+ }
+
+ //
+ // The useful address space ends with the 64-bit PCI host aperture.
+ //
+ FirstNonAddress = Pci64Base + Pci64Size;
+ return FirstNonAddress;
+}
+
+
+/**
+ Initialize the mPhysMemAddressWidth variable, based on guest RAM size.
+**/
+VOID
+AddressWidthInitialization (
+ VOID
+ )
+{
+ UINT64 FirstNonAddress;
+
+ //
+ // As guest-physical memory size grows, the permanent PEI RAM requirements
+ // are dominated by the identity-mapping page tables built by the DXE IPL.
+ // The DXL IPL keys off of the physical address bits advertized in the CPU
+ // HOB. To conserve memory, we calculate the minimum address width here.
+ //
+ FirstNonAddress = GetFirstNonAddress ();
+ mPhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress);
+
+ //
+ // If FirstNonAddress is not an integral power of two, then we need an
+ // additional bit.
+ //
+ if ((FirstNonAddress & (FirstNonAddress - 1)) != 0) {
+ ++mPhysMemAddressWidth;
+ }
+
+ //
+ // The minimum address width is 36 (covers up to and excluding 64 GB, which
+ // is the maximum for Ia32 + PAE). The theoretical architecture maximum for
+ // X64 long mode is 52 bits, but the DXE IPL clamps that down to 48 bits. We
+ // can simply assert that here, since 48 bits are good enough for 256 TB.
+ //
+ if (mPhysMemAddressWidth <= 36) {
+ mPhysMemAddressWidth = 36;
+ }
+ ASSERT (mPhysMemAddressWidth <= 48);
+}
+
+
+/**
+ Calculate the cap for the permanent PEI memory.
+**/
+STATIC
+UINT32
+GetPeiMemoryCap (
+ VOID
+ )
+{
+ BOOLEAN Page1GSupport;
+ UINT32 RegEax;
+ UINT32 RegEdx;
+ UINT32 Pml4Entries;
+ UINT32 PdpEntries;
+ UINTN TotalPages;
+
+ //
+ // If DXE is 32-bit, then just return the traditional 64 MB cap.
+ //
+#ifdef MDE_CPU_IA32
+ if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+ return SIZE_64MB;
+ }
+#endif
+
+ //
+ // Dependent on physical address width, PEI memory allocations can be
+ // dominated by the page tables built for 64-bit DXE. So we key the cap off
+ // of those. The code below is based on CreateIdentityMappingPageTables() in
+ // "MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c".
+ //
+ Page1GSupport = FALSE;
+ if (PcdGetBool (PcdUse1GPageTable)) {
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= 0x80000001) {
+ AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
+ if ((RegEdx & BIT26) != 0) {
+ Page1GSupport = TRUE;
+ }
+ }
+ }
+
+ if (mPhysMemAddressWidth <= 39) {
+ Pml4Entries = 1;
+ PdpEntries = 1 << (mPhysMemAddressWidth - 30);
+ ASSERT (PdpEntries <= 0x200);
+ } else {
+ Pml4Entries = 1 << (mPhysMemAddressWidth - 39);
+ ASSERT (Pml4Entries <= 0x200);
+ PdpEntries = 512;
+ }
+
+ TotalPages = Page1GSupport ? Pml4Entries + 1 :
+ (PdpEntries + 1) * Pml4Entries + 1;
+ ASSERT (TotalPages <= 0x40201);
+
+ //
+ // Add 64 MB for miscellaneous allocations. Note that for
+ // mPhysMemAddressWidth values close to 36, the cap will actually be
+ // dominated by this increment.
+ //
+ return (UINT32)(EFI_PAGES_TO_SIZE (TotalPages) + SIZE_64MB);
+}
+
+
+/**
+ Publish PEI core memory
+
+ @return EFI_SUCCESS The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+PublishPeiMemory (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS MemoryBase;
+ UINT64 MemorySize;
+ UINT32 LowerMemorySize;
+ UINT32 PeiMemoryCap;
+
+ LowerMemorySize = GetSystemMemorySizeBelow4gb ();
+ if (FeaturePcdGet (PcdSmmSmramRequire)) {
+ //
+ // TSEG is chipped from the end of low RAM
+ //
+ LowerMemorySize -= mX58TsegMbytes * SIZE_1MB;
+ }
+
+ //
+ // If S3 is supported, then the S3 permanent PEI memory is placed next,
+ // downwards. Its size is primarily dictated by CpuMpPei. The formula below
+ // is an approximation.
+ //
+ if (mS3Supported) {
+ mS3AcpiReservedMemorySize = SIZE_512KB +
+ mMaxCpuCount *
+ PcdGet32 (PcdCpuApStackSize);
+ mS3AcpiReservedMemoryBase = LowerMemorySize - mS3AcpiReservedMemorySize;
+ LowerMemorySize = mS3AcpiReservedMemoryBase;
+ }
+
+ if (mBootMode == BOOT_ON_S3_RESUME) {
+ MemoryBase = mS3AcpiReservedMemoryBase;
+ MemorySize = mS3AcpiReservedMemorySize;
+ } else {
+ PeiMemoryCap = GetPeiMemoryCap ();
+ DEBUG ((EFI_D_INFO, "%a: mPhysMemAddressWidth=%d PeiMemoryCap=%u KB\n",
+ __FUNCTION__, mPhysMemAddressWidth, PeiMemoryCap >> 10));
+
+ //
+ // Determine the range of memory to use during PEI
+ //
+ // Technically we could lay the permanent PEI RAM over SEC's temporary
+ // decompression and scratch buffer even if "secure S3" is needed, since
+ // their lifetimes don't overlap. However, PeiFvInitialization() will cover
+ // RAM up to PcdOvmfDecompressionScratchEnd with an EfiACPIMemoryNVS memory
+ // allocation HOB, and other allocations served from the permanent PEI RAM
+ // shouldn't overlap with that HOB.
+ //
+ MemoryBase = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire) ?
+ PcdGet32 (PcdSimicsDecompressionScratchEnd) :
+ PcdGet32 (PcdSimicsDxeMemFvBase) + PcdGet32 (PcdSimicsDxeMemFvSize);
+ MemorySize = LowerMemorySize - MemoryBase;
+ }
+ DEBUG((EFI_D_INFO, "MemoryBase=0x%lx MemorySize=0x%lx\n", MemoryBase, MemorySize));
+ //
+ // Publish this memory to the PEI Core
+ //
+ Status = PublishSystemMemory(MemoryBase, MemorySize);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+
+/**
+ Peform Memory Detection for QEMU / KVM
+
+**/
+STATIC
+VOID
+QemuInitializeRam (
+ VOID
+ )
+{
+ UINT64 LowerMemorySize;
+ UINT64 UpperMemorySize;
+ UINTN BufferSize;
+ UINT8 SmramIndex;
+ UINT8 SmramRanges;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *SmramHobDescriptorBlock;
+ UINT8 Index;
+
+ DEBUG ((EFI_D_INFO, "%a called\n", __FUNCTION__));
+
+ //
+ // Determine total memory size available
+ //
+ LowerMemorySize = GetSystemMemorySizeBelow4gb ();
+ UpperMemorySize = GetSystemMemorySizeAbove4gb ();
+
+ if (mBootMode == BOOT_ON_S3_RESUME) {
+ //
+ // Create the following memory HOB as an exception on the S3 boot path.
+ //
+ // Normally we'd create memory HOBs only on the normal boot path. However,
+ // CpuMpPei specifically needs such a low-memory HOB on the S3 path as
+ // well, for "borrowing" a subset of it temporarily, for the AP startup
+ // vector.
+ //
+ // CpuMpPei saves the original contents of the borrowed area in permanent
+ // PEI RAM, in a backup buffer allocated with the normal PEI services.
+ // CpuMpPei restores the original contents ("returns" the borrowed area) at
+ // End-of-PEI. End-of-PEI in turn is emitted by S3Resume2Pei before
+ // transferring control to the OS's wakeup vector in the FACS.
+ //
+ // We expect any other PEIMs that "borrow" memory similarly to CpuMpPei to
+ // restore the original contents. Furthermore, we expect all such PEIMs
+ // (CpuMpPei included) to claim the borrowed areas by producing memory
+ // allocation HOBs, and to honor preexistent memory allocation HOBs when
+ // looking for an area to borrow.
+ //
+ AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
+ } else {
+ //
+ // Create memory HOBs
+ //
+ AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
+
+ if (FeaturePcdGet (PcdSmmSmramRequire)) {
+ UINT32 TsegSize;
+
+ TsegSize = mX58TsegMbytes * SIZE_1MB;
+ AddMemoryRangeHob (BASE_1MB, LowerMemorySize - TsegSize);
+ AddReservedMemoryBaseSizeHob (LowerMemorySize - TsegSize, TsegSize,
+ TRUE);
+
+ BufferSize = sizeof(EFI_SMRAM_HOB_DESCRIPTOR_BLOCK);
+ SmramRanges = 1;
+
+ Hob.Raw = BuildGuidHob(
+ &gEfiSmmPeiSmramMemoryReserveGuid,
+ BufferSize
+ );
+ ASSERT(Hob.Raw);
+
+ SmramHobDescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *)(Hob.Raw);
+ SmramHobDescriptorBlock->NumberOfSmmReservedRegions = SmramRanges;
+
+ SmramIndex = 0;
+ for (Index = 0; Index < SmramRanges; Index++) {
+ //
+ // This is an SMRAM range, create an SMRAM descriptor
+ //
+ SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalStart = LowerMemorySize - TsegSize;
+ SmramHobDescriptorBlock->Descriptor[SmramIndex].CpuStart = LowerMemorySize - TsegSize;
+ SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalSize = TsegSize;
+ SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState = EFI_SMRAM_CLOSED | EFI_CACHEABLE;
+ SmramIndex++;
+ }
+
+ } else {
+ AddMemoryRangeHob (BASE_1MB, LowerMemorySize);
+ }
+
+ //
+ // If QEMU presents an E820 map, then create memory HOBs for the >=4GB RAM
+ // entries. Otherwise, create a single memory HOB with the flat >=4GB
+ // memory size read from the CMOS.
+ //
+ if (UpperMemorySize != 0) {
+ AddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);
+ }
+ }
+}
+
+/**
+ Publish system RAM and reserve memory regions
+
+**/
+VOID
+InitializeRamRegions (
+ VOID
+ )
+{
+ QemuInitializeRam ();
+
+ if (mS3Supported && mBootMode != BOOT_ON_S3_RESUME) {
+ //
+ // This is the memory range that will be used for PEI on S3 resume
+ //
+ BuildMemoryAllocationHob (
+ mS3AcpiReservedMemoryBase,
+ mS3AcpiReservedMemorySize,
+ EfiACPIMemoryNVS
+ );
+
+ //
+ // Cover the initial RAM area used as stack and temporary PEI heap.
+ //
+ // This is reserved as ACPI NVS so it can be used on S3 resume.
+ //
+ BuildMemoryAllocationHob (
+ PcdGet32 (PcdSimicsSecPeiTempRamBase),
+ PcdGet32 (PcdSimicsSecPeiTempRamSize),
+ EfiACPIMemoryNVS
+ );
+
+ //
+ // SEC stores its table of GUIDed section handlers here.
+ //
+ BuildMemoryAllocationHob (
+ PcdGet64 (PcdGuidedExtractHandlerTableAddress),
+ PcdGet32 (PcdGuidedExtractHandlerTableSize),
+ EfiACPIMemoryNVS
+ );
+
+ }
+
+ if (mBootMode != BOOT_ON_S3_RESUME) {
+ if (!FeaturePcdGet (PcdSmmSmramRequire)) {
+ //
+ // Reserve the lock box storage area
+ //
+ // Since this memory range will be used on S3 resume, it must be
+ // reserved as ACPI NVS.
+ //
+ // If S3 is unsupported, then various drivers might still write to the
+ // LockBox area. We ought to prevent DXE from serving allocation requests
+ // such that they would overlap the LockBox storage.
+ //
+ ZeroMem (
+ (VOID*)(UINTN) PcdGet32 (PcdSimicsLockBoxStorageBase),
+ (UINTN) PcdGet32 (PcdSimicsLockBoxStorageSize)
+ );
+ BuildMemoryAllocationHob (
+ (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdSimicsLockBoxStorageBase),
+ (UINT64)(UINTN) PcdGet32 (PcdSimicsLockBoxStorageSize),
+ mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
+ );
+ }
+
+ if (FeaturePcdGet (PcdSmmSmramRequire)) {
+ UINT32 TsegSize;
+
+ //
+ // Make sure the TSEG area that we reported as a reserved memory resource
+ // cannot be used for reserved memory allocations.
+ //
+ TsegSize = mX58TsegMbytes * SIZE_1MB;
+ BuildMemoryAllocationHob (
+ GetSystemMemorySizeBelow4gb() - TsegSize,
+ TsegSize,
+ EfiReservedMemoryType
+ );
+ }
+ }
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c
new file mode 100644
index 0000000000..140a38f27f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.c
@@ -0,0 +1,630 @@
+/** @file
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/ResourcePublicationLib.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Ppi/MasterBootMode.h>
+#include <IndustryStandard/Pci22.h>
+#include <SimicsPlatforms.h>
+
+#include "Platform.h"
+#include "Cmos.h"
+
+EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
+ { EfiACPIMemoryNVS, 0x004 },
+ { EfiACPIReclaimMemory, 0x008 },
+ { EfiReservedMemoryType, 0x004 },
+ { EfiRuntimeServicesData, 0x024 },
+ { EfiRuntimeServicesCode, 0x030 },
+ { EfiBootServicesCode, 0x180 },
+ { EfiBootServicesData, 0xF00 },
+ { EfiMaxMemoryType, 0x000 }
+};
+
+
+EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiMasterBootModePpiGuid,
+ NULL
+ }
+};
+
+
+UINT16 mHostBridgeDevId;
+
+EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION;
+
+BOOLEAN mS3Supported = FALSE;
+
+UINT32 mMaxCpuCount;
+
+VOID
+AddIoMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize
+ )
+{
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_MAPPED_IO,
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_TESTED,
+ MemoryBase,
+ MemorySize
+ );
+}
+
+VOID
+AddReservedMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize,
+ BOOLEAN Cacheable
+ )
+{
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_RESERVED,
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ (Cacheable ?
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE :
+ 0
+ ) |
+ EFI_RESOURCE_ATTRIBUTE_TESTED,
+ MemoryBase,
+ MemorySize
+ );
+}
+
+VOID
+AddIoMemoryRangeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ EFI_PHYSICAL_ADDRESS MemoryLimit
+ )
+{
+ AddIoMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
+}
+
+
+VOID
+AddMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize
+ )
+{
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ 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,
+ MemoryBase,
+ MemorySize
+ );
+}
+
+
+VOID
+AddMemoryRangeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ EFI_PHYSICAL_ADDRESS MemoryLimit
+ )
+{
+ AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
+}
+
+
+VOID
+AddUntestedMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize
+ )
+{
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ 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,
+ MemoryBase,
+ MemorySize
+ );
+}
+
+
+VOID
+AddUntestedMemoryRangeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ EFI_PHYSICAL_ADDRESS MemoryLimit
+ )
+{
+ AddUntestedMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
+}
+
+VOID
+AddFlashDeviceRange (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize
+ )
+{
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_FIRMWARE_DEVICE,
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+ MemoryBase,
+ MemorySize
+ );
+
+ BuildMemoryAllocationHob (
+ MemoryBase,
+ MemorySize,
+ EfiMemoryMappedIO
+ );
+}
+
+VOID
+MemMapInitialization (
+ VOID
+ )
+{
+ UINT64 PciIoBase;
+ UINT64 PciIoSize;
+
+ UINT32 TopOfLowRam;
+ UINT64 PciExBarBase;
+ UINT32 PciBase;
+ UINT32 PciSize;
+
+ PciIoBase = 0xC000;
+ PciIoSize = 0x4000;
+
+ //
+ // Create Memory Type Information HOB
+ //
+ BuildGuidDataHob (
+ &gEfiMemoryTypeInformationGuid,
+ mDefaultMemoryTypeInformation,
+ sizeof(mDefaultMemoryTypeInformation)
+ );
+
+ //
+ // Video memory + Legacy BIOS region
+ //
+ AddIoMemoryRangeHob (0x0A0000, BASE_1MB);
+
+ TopOfLowRam = GetSystemMemorySizeBelow4gb ();
+ PciExBarBase = 0;
+ if (mHostBridgeDevId == INTEL_ICH10_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 = FixedPcdGet64 (PcdPciExpressBaseAddress);
+ ASSERT (TopOfLowRam <= PciExBarBase);
+ ASSERT (PciExBarBase <= MAX_UINT32 - SIZE_256MB);
+ PciBase = (UINT32)(PciExBarBase + SIZE_256MB);
+ } else {
+ PciBase = (TopOfLowRam < BASE_2GB) ? BASE_2GB : TopOfLowRam;
+ }
+
+ //
+ // address purpose size
+ // ------------ -------- -------------------------
+ // 0x00000000 TopOfLowRam 0xDF000000
+ // 0xDF000000 Tseg+UMA 0x01000000
+ // 0xE0000000 PciExBarBase 0x10000000
+ // 0xF0000000 PciBase 0x0C000000
+ // -------------------------------------------------
+ // 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 = 0xFC000000 - PciBase;
+ AddIoMemoryBaseSizeHob (PciBase, PciSize);
+ PcdSet64 (PcdPciMmio32Base, PciBase);
+ PcdSet64 (PcdPciMmio32Size, PciSize);
+ AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);
+ AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);
+ if (mHostBridgeDevId == INTEL_ICH10_DEVICE_ID) {
+ AddIoMemoryBaseSizeHob (ICH10_ROOT_COMPLEX_BASE, SIZE_16KB);
+ //
+ // Note: there should be an
+ //
+ // AddIoMemoryBaseSizeHob (PciExBarBase, SIZE_256MB);
+ // BuildMemoryAllocationHob (PciExBarBase, SIZE_256MB, EfiMemoryMappedIO);
+ //
+ // 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 can
+ // *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 area
+ // is most definitely not RAM; so, as an exception, cover it with
+ // uncacheable reserved memory right here.
+ //
+ AddReservedMemoryBaseSizeHob (PciExBarBase, SIZE_256MB, FALSE);
+ BuildMemoryAllocationHob (PciExBarBase, SIZE_256MB,
+ EfiReservedMemoryType);
+ }
+ AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress), SIZE_1MB);
+
+ // Add PCI IO Port space available for PCI resource allocations.
+ //
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_IO,
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED,
+ PciIoBase,
+ PciIoSize
+ );
+ PcdSet64 (PcdPciIoBase, PciIoBase);
+ PcdSet64 (PcdPciIoSize, PciIoSize);
+
+ //
+ // Add flash range.
+ //
+ AddFlashDeviceRange (PcdGet32(PcdFlashAreaBaseAddress), PcdGet32(PcdFlashAreaSize));
+ //
+ // Video memory / ABSEG
+ //
+ AddIoMemoryBaseSizeHob (0x0A0000, 0x20000);
+ //
+ // Legacy BIOS region.
+ //
+ AddReservedMemoryBaseSizeHob (0xC0000, 0x40000, TRUE);
+}
+
+VOID
+MiscInitialization (
+ VOID
+ )
+{
+ 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 during
+ // S3 resume as well, so we build it unconditionally.)
+ //
+ BuildCpuHob (mPhysMemAddressWidth, 16);
+
+ //
+ // Determine platform type and save Host Bridge DID to PCD
+ //
+ switch (mHostBridgeDevId) {
+ case INTEL_82441_DEVICE_ID:
+ PmCmd = POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET);
+ Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
+ PmbaAndVal = ~(UINT32)PIIX4_PMBA_MASK;
+ PmbaOrVal = PIIX4_PMBA_VALUE;
+ AcpiCtlReg = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC);
+ AcpiEnBit = PIIX4_PMREGMISC_PMIOSE;
+ break;
+ case INTEL_ICH10_DEVICE_ID:
+ PmCmd = POWER_MGMT_REGISTER_ICH10 (PCI_COMMAND_OFFSET);
+ Pmba = POWER_MGMT_REGISTER_ICH10 (ICH10_PMBASE);
+ PmbaAndVal = ~(UINT32)ICH10_PMBASE_MASK;
+ PmbaOrVal = ICH10_PMBASE_VALUE;
+ AcpiCtlReg = POWER_MGMT_REGISTER_ICH10 (ICH10_ACPI_CNTL);
+ AcpiEnBit = ICH10_ACPI_CNTL_ACPI_EN;
+ break;
+ default:
+ DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
+ __FUNCTION__, mHostBridgeDevId));
+ ASSERT (FALSE);
+ return;
+ }
+ PcdSet16 (PcdSimicsX58HostBridgePciDevId, mHostBridgeDevId);
+
+ //
+ // 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) == 0) {
+ //
+ // The PEI phase should be exited with fully accessibe ACPI PM IO space:
+ // 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 (mHostBridgeDevId == INTEL_ICH10_DEVICE_ID) {
+ //
+ // Set Root Complex Register Block BAR
+ //
+ PciWrite32 (
+ POWER_MGMT_REGISTER_ICH10 (ICH10_RCBA),
+ ICH10_ROOT_COMPLEX_BASE | ICH10_RCBA_EN
+ );
+
+ }
+ //
+ // Set the PM I/O base address to 0x400
+ //
+ PciAndThenOr32 (
+ PCI_LIB_ADDRESS (
+ 0,
+ 31,
+ 0,
+ 0x40
+ ),
+ (UINT32) ~0xfc0, ICH10_PMBASE_VALUE
+ );
+ //
+ // Enable AHCI and all ports on the SATA controller.
+ //
+ // Address MAP Reg, setting AHCI mode
+ //
+ PciOr16 (PCI_LIB_ADDRESS (0, 31, 2, 0x90), 0x0060);
+ //
+ //Enabling Ports 0-5
+ //
+ PciOr16 (PCI_LIB_ADDRESS (0, 31, 2, 0x92), 0x003F);
+ //
+ //Disabling Sata Controller 2, bit 25 = 1, bit 0 = 1
+ //
+ MmioWrite32(0xFED1F418, 0x02000001);
+ //
+ //Enable HPET at FED0_0000h – FED0_03FFh
+ //
+ MmioWrite8(ICH10_ROOT_COMPLEX_BASE + 0x3404, 0x80);
+ //
+ //Config and enable APIC
+ //
+ MmioWrite32(0xFEC00000 + 0X0, 0);
+ MmioWrite32(0xFEC00000 + 0X10, PcdGet8(PcdIoApicId)<<24);
+ MmioWrite8(ICH10_ROOT_COMPLEX_BASE + 0x31FF, 0x01);
+}
+
+
+VOID
+BootModeInitialization (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG((EFI_D_INFO, "modeValue = %x\n", IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12)));
+ if (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) == 0x5) {
+ mBootMode = BOOT_ON_S3_RESUME;
+ }
+
+ Status = PeiServicesSetBootMode (mBootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PeiServicesInstallPpi (mPpiBootMode);
+ ASSERT_EFI_ERROR (Status);
+}
+
+
+VOID
+ReserveEmuVariableNvStore (
+ )
+{
+ EFI_PHYSICAL_ADDRESS VariableStore;
+
+ //
+ // Allocate storage for NV variables early on so it will be
+ // at a consistent address. Since VM memory is preserved
+ // across reboots, this allows the NV variable storage to survive
+ // a VM reboot.
+ //
+ VariableStore =
+ (EFI_PHYSICAL_ADDRESS)(UINTN)
+ AllocateRuntimePages (
+ EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize))
+ );
+ DEBUG ((EFI_D_INFO,
+ "Reserved variable store memory: 0x%lX; size: %dkb\n",
+ VariableStore,
+ (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / 1024
+ ));
+ PcdSet64 (PcdEmuVariableNvStoreReserved, VariableStore);
+}
+
+
+VOID
+SimicsVersionCheck(
+ VOID
+ )
+{
+
+ UINTN PciAddrPtr;
+ UINT8 CapOffset;
+ STATIC CHAR8 SimicsStr[0x100];
+ UINTN i;
+ UINT32 MajorVersion;
+ UINT32 MinorVersion;
+ UINT32 ModelNumber;
+
+ PciAddrPtr = PCI_LIB_ADDRESS(0, SIMICS_SIDEBANDPCI_DEV, SIMICS_SIDEBANDPCI_FUNC, 0);
+ CapOffset = PciRead8(PciAddrPtr + PCI_CAPBILITY_POINTER_OFFSET);
+ if (CapOffset != 0xFF) {
+ ModelNumber = PciRead32(PciAddrPtr + CapOffset + 4);
+ MajorVersion = PciRead32(PciAddrPtr + CapOffset + 8);
+ MinorVersion = PciRead32(PciAddrPtr + CapOffset + 0xc);
+ for (i = 0; i < 0x80; i++) {
+ SimicsStr[i] = PciRead8(PciAddrPtr + CapOffset + 0x10 + i);
+ }
+ DEBUG((EFI_D_INFO, "=============SIMICS Version info=============\n"));
+ DEBUG((EFI_D_INFO, "Model number = %d\n", ModelNumber));
+ DEBUG((EFI_D_INFO, "Major version = %d\n", MajorVersion));
+ DEBUG((EFI_D_INFO, "Minor version = %d\n", MinorVersion));
+ DEBUG((EFI_D_INFO, "%a\n", SimicsStr));
+ DEBUG((EFI_D_INFO, "=============================================\n"));
+ }
+}
+
+VOID
+DebugDumpCmos (
+ VOID
+ )
+{
+ UINT32 Loop;
+
+ DEBUG ((EFI_D_INFO, "CMOS:\n"));
+
+ for (Loop = 0; Loop < 0x80; Loop++) {
+ if ((Loop % 0x10) == 0) {
+ DEBUG ((EFI_D_INFO, "%02x:", Loop));
+ }
+ DEBUG ((EFI_D_INFO, " %02x", CmosRead8 (Loop)));
+ if ((Loop % 0x10) == 0xf) {
+ DEBUG ((EFI_D_INFO, "\n"));
+ }
+ }
+}
+
+
+/**
+ Fetch the number of boot CPUs from QEMU and expose it to UefiCpuPkg modules.
+ Set the mMaxCpuCount variable.
+**/
+VOID
+MaxCpuCountInitialization (
+ VOID
+ )
+{
+ mMaxCpuCount = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
+ return;
+}
+
+/**
+ Determine if S3 support is explicitly enabled.
+
+ @retval TRUE If S3 support is explicitly enabled. Other functions in this
+ library may be called (subject to their individual
+ restrictions).
+
+ FALSE Otherwise. This includes unavailability of the firmware
+ configuration interface. No other function in this library
+ must be called.
+**/
+BOOLEAN
+EFIAPI
+QemuFwCfgS3Enabled(
+ VOID
+)
+{
+ //TO DO IF NEEDED
+ return TRUE;
+}
+
+/**
+ Perform Platform PEI initialization.
+
+ @param FileHandle Handle of the file being invoked.
+ @param PeiServices Describes the list of possible PEI Services.
+
+ @return EFI_SUCCESS The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializePlatform (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_ERROR, "Platform PEIM Loaded\n"));
+
+ SimicsVersionCheck ();
+ DebugDumpCmos ();
+
+ if (QemuFwCfgS3Enabled ()) {
+ DEBUG ((EFI_D_INFO, "S3 support was detected on SIMICS\n"));
+ mS3Supported = TRUE;
+ Status = PcdSetBoolS (PcdAcpiS3Enable, TRUE);
+ ASSERT_EFI_ERROR (Status);
+ }
+ AddressWidthInitialization ();
+ MaxCpuCountInitialization ();
+
+ mHostBridgeDevId = PciRead16(SIMICS_HOSTBRIDGE_DID);
+
+ if (FeaturePcdGet (PcdSmmSmramRequire)) {
+ X58TsegMbytesInitialization ();
+ }
+
+ PublishPeiMemory ();
+
+ InitializeRamRegions ();
+
+ if (mBootMode != BOOT_ON_S3_RESUME) {
+ if (!FeaturePcdGet (PcdSmmSmramRequire)) {
+ ReserveEmuVariableNvStore ();
+ }
+ MemMapInitialization ();
+ }
+
+ MiscInitialization ();
+ InstallFeatureControlCallback ();
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
new file mode 100644
index 0000000000..bbd96b4e36
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
@@ -0,0 +1,148 @@
+/** @file
+ This driver installs SMBIOS information for QSP
+
+ Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>
+ Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SmbiosPlatformDxe.h"
+
+
+/**
+Reads 8-bits of CMOS data.
+
+Reads the 8-bits of CMOS data at the location specified by Index.
+The 8-bit read value is returned.
+
+@param Index The CMOS location to read.
+
+@return The value read.
+
+**/
+UINT8
+EFIAPI
+CmosRead8(
+ IN UINTN Index
+ )
+{
+ IoWrite8(0x70, (UINT8)Index);
+ return IoRead8(0x71);
+}
+
+UINT32
+GetSystemMemorySizeBelow4gb(
+ VOID
+ )
+{
+ UINT8 Cmos0x34;
+ UINT8 Cmos0x35;
+
+ //
+ // CMOS 0x34/0x35 specifies the system memory above 16 MB.
+ // * CMOS(0x35) is the high byte
+ // * CMOS(0x34) is the low byte
+ // * The size is specified in 64kb chunks
+ // * Since this is memory above 16MB, the 16MB must be added
+ // into the calculation to get the total memory size.
+ //
+
+ Cmos0x34 = (UINT8)CmosRead8(0x34);
+ Cmos0x35 = (UINT8)CmosRead8(0x35);
+
+ return (UINT32)(((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);
+}
+
+STATIC
+UINT64
+GetSystemMemorySizeAbove4gb(
+ VOID
+)
+{
+ UINT32 Size;
+ UINTN CmosIndex;
+
+ //
+ // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
+ // * CMOS(0x5d) is the most significant size byte
+ // * CMOS(0x5c) is the middle size byte
+ // * CMOS(0x5b) is the least significant size byte
+ // * The size is specified in 64kb chunks
+ //
+
+ Size = 0;
+ for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {
+ Size = (UINT32)(Size << 8) + (UINT32)CmosRead8(CmosIndex);
+ }
+
+ return LShiftU64(Size, 16);
+}
+
+/**
+ Installs SMBIOS information for SIMICS QSP
+
+ @param ImageHandle Module's image handle
+ @param SystemTable Pointer of EFI_SYSTEM_TABLE
+
+ @retval EFI_SUCCESS Smbios data successfully installed
+ @retval Other Smbios data was not installed
+
+**/
+EFI_STATUS
+EFIAPI
+SmbiosTablePublishEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMBIOS_PROTOCOL *Smbios;
+ SMBIOS_TABLE_TYPE19 *Type19Record;
+ EFI_SMBIOS_HANDLE MemArrayMappedAddrSmbiosHandle;
+ UINT8 NumSlots;
+ UINT64 TotalMemorySize;
+
+ //
+ // Find the SMBIOS protocol
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiSmbiosProtocolGuid,
+ NULL,
+ (VOID**)&Smbios
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Generate Memory Array Mapped Address info
+ //
+ NumSlots = 2;
+ TotalMemorySize = 0;
+ TotalMemorySize = GetSystemMemorySizeBelow4gb();
+ Type19Record = AllocatePool(sizeof(SMBIOS_TABLE_TYPE19));
+ ZeroMem(Type19Record, sizeof(SMBIOS_TABLE_TYPE19));
+ Type19Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS;
+ Type19Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE19);
+ Type19Record->Hdr.Handle = 0;
+ Type19Record->StartingAddress = 0;
+ Type19Record->EndingAddress = (UINT32)RShiftU64(TotalMemorySize, 10) - 1;
+ Type19Record->MemoryArrayHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Type19Record->PartitionWidth = (UINT8)(NumSlots);
+
+ MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios->Add(Smbios, NULL, &MemArrayMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*)Type19Record);
+ ASSERT_EFI_ERROR(Status);
+
+ TotalMemorySize = GetSystemMemorySizeAbove4gb();
+ Type19Record->StartingAddress = 0xFFFFFFFF;
+ Type19Record->ExtendedStartingAddress = 0xFFFFFFFF;
+ Type19Record->ExtendedEndingAddress = TotalMemorySize + 0xFFFFFFFF - 1;
+
+ MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios->Add(Smbios, NULL, &MemArrayMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*)Type19Record);
+ FreePool(Type19Record);
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf
new file mode 100644
index 0000000000..b8d326cdb6
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf
@@ -0,0 +1,31 @@
+## @file
+# Component description file for PlatformAcpiTables module.
+#
+# ACPI table data and ASL sources required to boot the platform.
+#
+# Copyright (c) 2008 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformAcpiTables
+ FILE_GUID = 7E374E25-8E01-4FEE-87F2-390C23C606CD
+ MODULE_TYPE = USER_DEFINED
+ VERSION_STRING = 1.0
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ Platform.h
+ Dsdt.asl
+
+[Packages]
+ MdePkg/MdePkg.dec
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl
new file mode 100644
index 0000000000..8a6c3792ba
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl
@@ -0,0 +1,821 @@
+/** @file
+ Contains root level name space objects for the platform
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+DefinitionBlock ("Dsdt.aml", "DSDT", 1, "INTEL ", "SIMICS ", 4) {
+ //
+ // System Sleep States
+ //
+ Name (\_S3, Package () {5, 5, 0, 0})
+ Name (\_S4, Package () {6, 6, 0, 0})
+ Name (\_S5, Package () {7, 7, 0, 0})
+
+ Name (GPIC, Zero)
+ Method (_PIC, 1, NotSerialized) // _PIC: Interrupt Model
+ {
+ GPIC = Arg0
+ }
+ //
+ // System Bus
+ //
+ Scope (\_SB) {
+ //
+ // PCI Root Bridge
+ //
+ Device (PCI0) {
+ Name (_HID, EISAID ("PNP0A03"))
+ Name (_ADR, 0x00000000)
+ Name (_BBN, 0x00)
+ Name (_UID, 0x00)
+
+
+ // Current resource settings
+ Name (_CRS, ResourceTemplate () {
+ WORDBusNumber ( // Bus number resource (0); the bridge produces bus numbers for its subsequent buses
+ ResourceProducer, // bit 0 of general flags is 1
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is fixed
+ PosDecode, // PosDecode
+ 0x0000, // Granularity
+ 0x0000, // Min
+ 0x00FF, // Max
+ 0x0000, // Translation
+ 0x0100 // Range Length = Max-Min+1
+ )
+
+ IO (Decode16, 0xCF8, 0xCF8, 0x01, 0x08) //Consumed resource (0xCF8-0xCFF)
+
+ WORDIO ( // Consumed-and-produced resource (all I/O below CF8)
+ ResourceProducer, // bit 0 of general flags is 0
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is fixed
+ PosDecode,
+ EntireRange,
+ 0x0000, // Granularity
+ 0x0000, // Min
+ 0x0CF7, // Max
+ 0x0000, // Translation
+ 0x0CF8 // Range Length
+ )
+
+ WORDIO ( // Consumed-and-produced resource (all I/O above CFF)
+ ResourceProducer, // bit 0 of general flags is 0
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is fixed
+ PosDecode,
+ EntireRange,
+ 0x0000, // Granularity
+ 0x0D00, // Min
+ 0xFFFF, // Max
+ 0x0000, // Translation
+ 0xF300 // Range Length
+ )
+
+ DWORDMEMORY ( // Descriptor for legacy VGA video RAM
+ ResourceProducer, // bit 0 of general flags is 0
+ PosDecode,
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is Fixed
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ 0x000A0000, // Min
+ 0x000BFFFF, // Max
+ 0x00000000, // Translation
+ 0x00020000 // Range Length
+ )
+
+ DWORDMEMORY ( // Descriptor for 32-bit MMIO
+ ResourceProducer, // bit 0 of general flags is 0
+ PosDecode,
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is Fixed
+ NonCacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ 0xF0000000, // Min
+ 0xFBFFFFFF, // Max
+ 0x00000000, // Translation
+ 0x0C000000, // Range Length
+ , // ResourceSourceIndex
+ , // ResourceSource
+ PW32 // DescriptorName
+ )
+ })
+
+ //
+ // PCI Interrupt Routing Table - PIC Mode Only
+ //
+ // If you change the IRQ mapping here you also need
+ // to change the mapping in the south bridge
+ // (pci-conf.py) and in the BIOS.
+ // INTA -> 0xa (10)
+ // INTB -> 0xb (11)
+ // INTC -> 0xa (10)
+ // INTD -> 0xb (11)
+
+ Method (_PRT, 0, NotSerialized) {
+ If (GPIC) {
+ Return (AR00) // APIC Mode
+ }
+ Return (PR00) // PIC Mode
+ }
+
+ Name (PR00, Package(){
+ Package () {0x000FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x000FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x000FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x000FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ //
+ // Bus 0, Device 1
+ //
+ Package () {0x0001FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0001FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0001FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0001FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0002FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0002FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0002FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0002FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+ //
+ // Bus 0, Device 3
+ //
+ Package () {0x0003FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0003FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0003FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0003FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0004FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0004FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0004FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0004FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0005FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0005FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0005FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0005FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0006FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0006FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0006FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0006FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0007FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0007FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0007FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0007FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0008FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0008FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0008FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0008FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0009FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0009FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0009FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0009FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x000AFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x000AFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x000AFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x000AFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x000BFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x000BFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x000BFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x000BFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x000CFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x000CFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x000CFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x000CFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x000DFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x000DFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x000DFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x000DFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x000EFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x000EFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x000EFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x000EFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x000FFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x000FFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x000FFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x000FFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00010FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00010FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00010FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00010FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00011FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00011FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00011FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00011FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00012FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00012FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00012FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00012FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00013FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00013FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00013FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00013FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00014FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00014FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00014FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00014FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00015FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00015FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00015FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00015FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00016FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00016FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00016FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00016FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00017FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00017FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00017FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00017FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00018FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00018FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00018FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00018FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0001EFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0001EFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0001EFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0001EFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x00019FFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x00019FFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x00019FFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x00019FFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0001AFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0001AFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0001AFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0001AFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0001BFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0001BFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0001BFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0001BFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0001CFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0001CFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0001CFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0001CFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0001DFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0001DFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0001DFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0001DFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+
+ Package () {0x0001FFFFF, 0x00, \_SB.PCI0.LPC.LNKA, 0x00},
+ Package () {0x0001FFFFF, 0x01, \_SB.PCI0.LPC.LNKB, 0x00},
+ Package () {0x0001FFFFF, 0x02, \_SB.PCI0.LPC.LNKC, 0x00},
+ Package () {0x0001FFFFF, 0x03, \_SB.PCI0.LPC.LNKD, 0x00},
+ }
+ )
+
+ Name(AR00, Package(){
+
+ Package () {0x000FFFF, 0x00, 0, 16},
+ Package () {0x000FFFF, 0x01, 0, 17},
+ Package () {0x000FFFF, 0x02, 0, 18},
+ Package () {0x000FFFF, 0x03, 0, 19},
+
+ //
+ // Bus 0, Device 1
+ //
+ Package () {0x0001FFFF, 0x00, 0, 16},
+ Package () {0x0001FFFF, 0x01, 0, 17},
+ Package () {0x0001FFFF, 0x02, 0, 18},
+ Package () {0x0001FFFF, 0x03, 0, 19},
+
+ Package () {0x0002FFFF, 0x00, 0, 16},
+ Package () {0x0002FFFF, 0x01, 0, 17},
+ Package () {0x0002FFFF, 0x02, 0, 18},
+ Package () {0x0002FFFF, 0x03, 0, 19},
+ //
+ // Bus 0, Device 3
+ //
+ Package () {0x0003FFFF, 0x00, 0, 16},
+ Package () {0x0003FFFF, 0x01, 0, 17},
+ Package () {0x0003FFFF, 0x02, 0, 18},
+ Package () {0x0003FFFF, 0x03, 0, 19},
+
+ Package () {0x0004FFFF, 0x00, 0, 16},
+ Package () {0x0004FFFF, 0x01, 0, 17},
+ Package () {0x0004FFFF, 0x02, 0, 18},
+ Package () {0x0004FFFF, 0x03, 0, 19},
+
+ Package () {0x0005FFFF, 0x00, 0, 16},
+ Package () {0x0005FFFF, 0x01, 0, 17},
+ Package () {0x0005FFFF, 0x02, 0, 18},
+ Package () {0x0005FFFF, 0x03, 0, 19},
+
+ Package () {0x0006FFFF, 0x00, 0, 16},
+ Package () {0x0006FFFF, 0x01, 0, 17},
+ Package () {0x0006FFFF, 0x02, 0, 18},
+ Package () {0x0006FFFF, 0x03, 0, 19},
+
+ Package () {0x0007FFFF, 0x00, 0, 16},
+ Package () {0x0007FFFF, 0x01, 0, 17},
+ Package () {0x0007FFFF, 0x02, 0, 18},
+ Package () {0x0007FFFF, 0x03, 0, 19},
+
+ Package () {0x0008FFFF, 0x00, 0, 16},
+ Package () {0x0008FFFF, 0x01, 0, 17},
+ Package () {0x0008FFFF, 0x02, 0, 18},
+ Package () {0x0008FFFF, 0x03, 0, 19},
+
+ Package () {0x0009FFFF, 0x00, 0, 16},
+ Package () {0x0009FFFF, 0x01, 0, 17},
+ Package () {0x0009FFFF, 0x02, 0, 18},
+ Package () {0x0009FFFF, 0x03, 0, 19},
+
+ Package () {0x000AFFFF, 0x00, 0, 16},
+ Package () {0x000AFFFF, 0x01, 0, 17},
+ Package () {0x000AFFFF, 0x02, 0, 18},
+ Package () {0x000AFFFF, 0x03, 0, 19},
+
+ Package () {0x000BFFFF, 0x00, 0, 16},
+ Package () {0x000BFFFF, 0x01, 0, 17},
+ Package () {0x000BFFFF, 0x02, 0, 18},
+ Package () {0x000BFFFF, 0x03, 0, 19},
+
+ Package () {0x000CFFFF, 0x00, 0, 16},
+ Package () {0x000CFFFF, 0x01, 0, 17},
+ Package () {0x000CFFFF, 0x02, 0, 18},
+ Package () {0x000CFFFF, 0x03, 0, 19},
+
+ Package () {0x000DFFFF, 0x00, 0, 16},
+ Package () {0x000DFFFF, 0x01, 0, 17},
+ Package () {0x000DFFFF, 0x02, 0, 18},
+ Package () {0x000DFFFF, 0x03, 0, 19},
+
+ Package () {0x000EFFFF, 0x00, 0, 16},
+ Package () {0x000EFFFF, 0x01, 0, 17},
+ Package () {0x000EFFFF, 0x02, 0C, 18},
+ Package () {0x000EFFFF, 0x03, 0, 19},
+
+ Package () {0x000FFFFF, 0x00, 0, 16},
+ Package () {0x000FFFFF, 0x01, 0, 17},
+ Package () {0x000FFFFF, 0x02, 0, 18},
+ Package () {0x000FFFFF, 0x03, 0, 19},
+
+ Package () {0x00010FFFF, 0x00, 0, 16},
+ Package () {0x00010FFFF, 0x01, 0, 17},
+ Package () {0x00010FFFF, 0x02, 0, 18},
+ Package () {0x00010FFFF, 0x03, 0, 19},
+
+ Package () {0x00011FFFF, 0x00, 0, 16},
+ Package () {0x00011FFFF, 0x01, 0, 17},
+ Package () {0x00011FFFF, 0x02, 0, 18},
+ Package () {0x00011FFFF, 0x03, 0, 19},
+
+ Package () {0x00012FFFF, 0x00, 0, 16},
+ Package () {0x00012FFFF, 0x01, 0, 17},
+ Package () {0x00012FFFF, 0x02, 0, 18},
+ Package () {0x00012FFFF, 0x03, 0, 19},
+
+ Package () {0x00013FFFF, 0x00, 0, 16},
+ Package () {0x00013FFFF, 0x01, 0, 17},
+ Package () {0x00013FFFF, 0x02, 0, 18},
+ Package () {0x00013FFFF, 0x03, 0, 19},
+
+ Package () {0x00014FFFF, 0x00, 0, 16},
+ Package () {0x00014FFFF, 0x01, 0, 17},
+ Package () {0x00014FFFF, 0x02, 0, 18},
+ Package () {0x00014FFFF, 0x03, 0, 19},
+
+ Package () {0x00015FFFF, 0x00, 0, 16},
+ Package () {0x00015FFFF, 0x01, 0, 17},
+ Package () {0x00015FFFF, 0x02, 0, 18},
+ Package () {0x00015FFFF, 0x03, 0, 19},
+
+ Package () {0x00016FFFF, 0x00, 0, 16},
+ Package () {0x00016FFFF, 0x01, 0, 17},
+ Package () {0x00016FFFF, 0x02, 0, 18},
+ Package () {0x00016FFFF, 0x03, 0, 19},
+
+ Package () {0x00017FFFF, 0x00, 0, 16},
+ Package () {0x00017FFFF, 0x01, 0, 17},
+ Package () {0x00017FFFF, 0x02, 0, 18},
+ Package () {0x00017FFFF, 0x03, 0, 19},
+
+ Package () {0x00018FFFF, 0x00, 0, 16},
+ Package () {0x00018FFFF, 0x01, 0, 17},
+ Package () {0x00018FFFF, 0x02, 0, 18},
+ Package () {0x00018FFFF, 0x03, 0, 19},
+
+ Package () {0x0001EFFFF, 0x00, 0, 16},
+ Package () {0x0001EFFFF, 0x01, 0, 17},
+ Package () {0x0001EFFFF, 0x02, 0, 18},
+ Package () {0x0001EFFFF, 0x03, 0, 19},
+
+ Package () {0x00019FFFF, 0x00, 0, 16},
+ Package () {0x00019FFFF, 0x01, 0, 17},
+ Package () {0x00019FFFF, 0x02, 0, 18},
+ Package () {0x00019FFFF, 0x03, 0, 19},
+
+ Package () {0x0001AFFFF, 0x00, 0, 16},
+ Package () {0x0001AFFFF, 0x01, 0, 17},
+ Package () {0x0001AFFFF, 0x02, 0, 18},
+ Package () {0x0001AFFFF, 0x03, 0, 19},
+
+ Package () {0x0001BFFFF, 0x00, 0, 16},
+ Package () {0x0001BFFFF, 0x01, 0, 17},
+ Package () {0x0001BFFFF, 0x02, 0, 18},
+ Package () {0x0001BFFFF, 0x03, 0, 19},
+
+ Package () {0x0001CFFFF, 0x00, 0, 16},
+ Package () {0x0001CFFFF, 0x01, 0, 17},
+ Package () {0x0001CFFFF, 0x02, 0, 18},
+ Package () {0x0001CFFFF, 0x03, 0, 19},
+
+ Package () {0x0001DFFFF, 0x00, 0, 16},
+ Package () {0x0001DFFFF, 0x01, 0, 17},
+ Package () {0x0001DFFFF, 0x02, 0, 18},
+ Package () {0x0001DFFFF, 0x03, 0, 19},
+
+ Package () {0x0001FFFFF, 0x00, 0, 16},
+ Package () {0x0001FFFFF, 0x01, 0, 17},
+ Package () {0x0001FFFFF, 0x02, 0, 18},
+ Package () {0x0001FFFFF, 0x03, 0, 19},
+ }
+ )
+
+ //
+ // PCI to ISA Bridge (Bus 0, Device 7, Function 0)
+ //
+ Device (LPC) {
+ Name (_ADR, 0x001F0000)
+
+ //
+ // PCI Interrupt Routing Configuration Registers
+ //
+ OperationRegion (PRR0, PCI_Config, 0x60, 0x0C)
+ Field (PRR0, ANYACC, NOLOCK, PRESERVE) {
+ PIRA, 8,
+ PIRB, 8,
+ PIRC, 8,
+ PIRD, 8,
+ Offset (0x04),
+ PIRE, 8,
+ PIRF, 8,
+ PIRG, 8,
+ PIRH, 8
+ }
+
+ //
+ // _STA method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH
+ //
+ Method (PSTA, 1, NotSerialized) {
+ If (And (Arg0, 0x80)) {
+ Return (0x9)
+ } Else {
+ Return (0xB)
+ }
+ }
+
+ //
+ // _DIS method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH
+ //
+ Method (PDIS, 1, NotSerialized) {
+ Or (Arg0, 0x80, Arg0)
+ }
+
+ //
+ // _CRS method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH
+ //
+ Method (PCRS, 1, NotSerialized) {
+ Name (BUF0, ResourceTemplate () {IRQ (Level, ActiveLow, Shared){0}})
+ //
+ // Define references to buffer elements
+ //
+ CreateWordField (BUF0, 0x01, IRQW) // IRQ low
+ //
+ // Write current settings into IRQ descriptor
+ //
+ If (And (Arg0, 0x80)) {
+ Store (Zero, Local0)
+ } Else {
+ Store (One, Local0)
+ }
+ //
+ // Shift 1 by value in register 70
+ //
+ ShiftLeft (Local0, And (Arg0, 0x0F), IRQW) // Save in buffer
+ Return (BUF0) // Return Buf0
+ }
+
+ //
+ // _PRS resource for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH
+ //
+ Name (PPRS, ResourceTemplate () {
+ IRQ (Level, ActiveLow, Shared) {3, 4, 5, 7, 9, 10, 11, 12, 14, 15}
+ })
+
+ //
+ // _SRS method for LNKA, LNKB, LNKC, LNKD, LNKE, LNKF, LNKG, LNKH
+ //
+ Method (PSRS, 2, NotSerialized) {
+ CreateWordField (Arg1, 0x01, IRQW) // IRQ low
+ FindSetRightBit (IRQW, Local0) // Set IRQ
+ If (LNotEqual (IRQW, Zero)) {
+ And (Local0, 0x7F, Local0)
+ Decrement (Local0)
+ } Else {
+ Or (Local0, 0x80, Local0)
+ }
+ Store (Local0, Arg0)
+ }
+
+ //
+ // PCI IRQ Link A
+ //
+ Device (LNKA) {
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 1)
+
+ Method (_STA, 0, NotSerialized) { Return (PSTA (PIRA)) }
+ Method (_DIS, 0, NotSerialized) { PDIS (PIRA) }
+ Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRA)) }
+ Method (_PRS, 0, NotSerialized) { Return (PPRS) }
+ Method (_SRS, 1, NotSerialized) { PSRS (PIRA, Arg0) }
+ }
+
+ //
+ // PCI IRQ Link B
+ //
+ Device (LNKB) {
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 2)
+
+ Method (_STA, 0, NotSerialized) { Return (PSTA (PIRB)) }
+ Method (_DIS, 0, NotSerialized) { PDIS (PIRB) }
+ Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRB)) }
+ Method (_PRS, 0, NotSerialized) { Return (PPRS) }
+ Method (_SRS, 1, NotSerialized) { PSRS (PIRB, Arg0) }
+ }
+
+ //
+ // PCI IRQ Link C
+ //
+ Device (LNKC) {
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 3)
+
+ Method (_STA, 0, NotSerialized) { Return (PSTA (PIRC)) }
+ Method (_DIS, 0, NotSerialized) { PDIS (PIRC) }
+ Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRC)) }
+ Method (_PRS, 0, NotSerialized) { Return (PPRS) }
+ Method (_SRS, 1, NotSerialized) { PSRS (PIRC, Arg0) }
+ }
+
+ //
+ // PCI IRQ Link D
+ //
+ Device (LNKD) {
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 4)
+
+ Method (_STA, 0, NotSerialized) { Return (PSTA (PIRD)) }
+ Method (_DIS, 0, NotSerialized) { PDIS (PIRD) }
+ Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRD)) }
+ Method (_PRS, 0, NotSerialized) { Return (PPRS) }
+ Method (_SRS, 1, NotSerialized) { PSRS (PIRD, Arg0) }
+ }
+
+ //
+ // PCI IRQ Link E
+ //
+ Device (LNKE) {
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 5)
+
+ Method (_STA, 0, NotSerialized) { Return (PSTA (PIRE)) }
+ Method (_DIS, 0, NotSerialized) { PDIS (PIRE) }
+ Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRE)) }
+ Method (_PRS, 0, NotSerialized) { Return (PPRS) }
+ Method (_SRS, 1, NotSerialized) { PSRS (PIRE, Arg0) }
+ }
+
+ //
+ // PCI IRQ Link F
+ //
+ Device (LNKF) {
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 6)
+
+ Method (_STA, 0, NotSerialized) { Return (PSTA (PIRF)) }
+ Method (_DIS, 0, NotSerialized) { PDIS (PIRF) }
+ Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRF)) }
+ Method (_PRS, 0, NotSerialized) { Return (PPRS) }
+ Method (_SRS, 1, NotSerialized) { PSRS (PIRF, Arg0) }
+ }
+
+ //
+ // PCI IRQ Link G
+ //
+ Device (LNKG) {
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 7)
+
+ Method (_STA, 0, NotSerialized) { Return (PSTA (PIRG)) }
+ Method (_DIS, 0, NotSerialized) { PDIS (PIRG) }
+ Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRG)) }
+ Method (_PRS, 0, NotSerialized) { Return (PPRS) }
+ Method (_SRS, 1, NotSerialized) { PSRS (PIRG, Arg0) }
+ }
+
+ //
+ // PCI IRQ Link H
+ //
+ Device (LNKH) {
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 8)
+
+ Method (_STA, 0, NotSerialized) { Return (PSTA (PIRH)) }
+ Method (_DIS, 0, NotSerialized) { PDIS (PIRH) }
+ Method (_CRS, 0, NotSerialized) { Return (PCRS (PIRH)) }
+ Method (_PRS, 0, NotSerialized) { Return (PPRS) }
+ Method (_SRS, 1, NotSerialized) { PSRS (PIRH, Arg0) }
+ }
+
+ //
+ // Programmable Interrupt Controller (PIC)
+ //
+ Device(PIC) {
+ Name (_HID, EISAID ("PNP0000"))
+ Name (_CRS, ResourceTemplate () {
+ IO (Decode16, 0x020, 0x020, 0x00, 0x02)
+ IO (Decode16, 0x0A0, 0x0A0, 0x00, 0x02)
+ IO (Decode16, 0x4D0, 0x4D0, 0x00, 0x02)
+ IRQNoFlags () {2}
+ })
+ }
+
+ //
+ // ISA DMA
+ //
+ Device (DMAC) {
+ Name (_HID, EISAID ("PNP0200"))
+ Name (_CRS, ResourceTemplate () {
+ IO (Decode16, 0x00, 0x00, 0, 0x10)
+ IO (Decode16, 0x81, 0x81, 0, 0x03)
+ IO (Decode16, 0x87, 0x87, 0, 0x01)
+ IO (Decode16, 0x89, 0x89, 0, 0x03)
+ IO (Decode16, 0x8f, 0x8f, 0, 0x01)
+ IO (Decode16, 0xc0, 0xc0, 0, 0x20)
+ DMA (Compatibility, NotBusMaster, Transfer8) {4}
+ })
+ }
+
+ //
+ // 8254 Timer
+ //
+ Device(TMR) {
+ Name(_HID,EISAID("PNP0100"))
+ Name(_CRS, ResourceTemplate () {
+ IO (Decode16, 0x40, 0x40, 0x00, 0x04)
+ IRQNoFlags () {0}
+ })
+ }
+
+ //
+ // Real Time Clock
+ //
+ Device (RTC) {
+ Name (_HID, EISAID ("PNP0B00"))
+ Name (_CRS, ResourceTemplate () {
+ IO (Decode16, 0x70, 0x70, 0x00, 0x02)
+ IRQNoFlags () {8}
+ })
+ }
+
+ //
+ // PCAT Speaker
+ //
+ Device(SPKR) {
+ Name (_HID, EISAID("PNP0800"))
+ Name (_CRS, ResourceTemplate () {
+ IO (Decode16, 0x61, 0x61, 0x01, 0x01)
+ })
+ }
+
+ //
+ // Floating Point Coprocessor
+ //
+ Device(FPU) {
+ Name (_HID, EISAID("PNP0C04"))
+ Name (_CRS, ResourceTemplate () {
+ IO (Decode16, 0xF0, 0xF0, 0x00, 0x10)
+ IRQNoFlags () {13}
+ })
+ }
+
+ //
+ // Generic motherboard devices and pieces that don't fit anywhere else
+ //
+ Device(XTRA) {
+ Name (_HID, EISAID ("PNP0C02"))
+ Name (_UID, 0x01)
+ Name (_CRS, ResourceTemplate () {
+ IO (Decode16, 0x010, 0x010, 0x00, 0x10)
+ IO (Decode16, 0x022, 0x022, 0x00, 0x1E)
+ IO (Decode16, 0x044, 0x044, 0x00, 0x1C)
+ IO (Decode16, 0x062, 0x062, 0x00, 0x02)
+ IO (Decode16, 0x065, 0x065, 0x00, 0x0B)
+ IO (Decode16, 0x072, 0x072, 0x00, 0x0E)
+ IO (Decode16, 0x080, 0x080, 0x00, 0x01)
+ IO (Decode16, 0x084, 0x084, 0x00, 0x03)
+ IO (Decode16, 0x088, 0x088, 0x00, 0x01)
+ IO (Decode16, 0x08c, 0x08c, 0x00, 0x03)
+ IO (Decode16, 0x090, 0x090, 0x00, 0x10)
+ IO (Decode16, 0x0A2, 0x0A2, 0x00, 0x1E)
+ IO (Decode16, 0x0E0, 0x0E0, 0x00, 0x10)
+ IO (Decode16, 0x1E0, 0x1E0, 0x00, 0x10)
+ IO (Decode16, 0x160, 0x160, 0x00, 0x10)
+ IO (Decode16, 0x278, 0x278, 0x00, 0x08)
+ IO (Decode16, 0x370, 0x370, 0x00, 0x02)
+ IO (Decode16, 0x378, 0x378, 0x00, 0x08)
+ IO (Decode16, 0x400, 0x400, 0x00, 0x40) // PMBLK1
+ IO (Decode16, 0x440, 0x440, 0x00, 0x10)
+ IO (Decode16, 0x678, 0x678, 0x00, 0x08)
+ IO (Decode16, 0x778, 0x778, 0x00, 0x08)
+ Memory32Fixed (ReadOnly, 0xFEC00000, 0x1000) // IO APIC
+ Memory32Fixed (ReadOnly, 0xFEE00000, 0x100000) // LAPIC
+ })
+ }
+
+ //
+ // PS/2 Keyboard and PC/AT Enhanced Keyboard 101/102
+ //
+ Device (PS2K) {
+ Name (_HID, EISAID ("PNP0303"))
+ Name (_CID, EISAID ("PNP030B"))
+ Name(_CRS,ResourceTemplate() {
+ IO (Decode16, 0x60, 0x60, 0x00, 0x01)
+ IO (Decode16, 0x64, 0x64, 0x00, 0x01)
+ IRQNoFlags () {1}
+ })
+ }
+
+ //
+ // PS/2 Mouse and Microsoft Mouse
+ //
+ Device (PS2M) { // PS/2 stype mouse port
+ Name (_HID, EISAID ("PNP0F03"))
+ Name (_CID, EISAID ("PNP0F13"))
+ Name (_CRS, ResourceTemplate() {
+ IRQNoFlags () {12}
+ })
+ }
+
+ //
+ // UART Serial Port - COM1
+ //
+ Device (UAR1) {
+ Name (_HID, EISAID ("PNP0501"))
+ Name (_DDN, "COM1")
+ Name (_UID, 0x01)
+ Name(_CRS,ResourceTemplate() {
+ IO (Decode16, 0x3F8, 0x3F8, 0x00, 0x08)
+ IRQ (Edge, ActiveHigh, Exclusive, ) {4}
+ })
+ }
+
+ //
+ // UART Serial Port - COM2
+ //
+ Device (UAR2) {
+ Name (_HID, EISAID ("PNP0501"))
+ Name (_DDN, "COM2")
+ Name (_UID, 0x02)
+ Name(_CRS,ResourceTemplate() {
+ IO (Decode16, 0x2F8, 0x2F8, 0x00, 0x08)
+ IRQ (Edge, ActiveHigh, Exclusive, ) {3}
+ })
+ }
+ }
+ }
+ }
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h
new file mode 100644
index 0000000000..6a4fcb172b
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h
@@ -0,0 +1,75 @@
+/** @file
+ Platform specific defines for constructing ACPI tables
+
+ Copyright (c) 2013 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ACPI_PLATFORM_H_
+#define _ACPI_PLATFORM_H_
+
+#include <PiDxe.h>
+#include <IndustryStandard/Acpi.h>
+
+//
+// ACPI table information used to initialize tables.
+//
+#define EFI_ACPI_OEM_ID 'S','I','M','I','C','S' // OEMID 6 bytes long
+#define EFI_ACPI_OEM_TABLE_ID SIGNATURE_64('S','I','M','I','C','S','T','B') // OEM table id 8 bytes long
+#define EFI_ACPI_OEM_REVISION 0x02000820
+#define EFI_ACPI_CREATOR_ID SIGNATURE_32('Q','S','P',' ')
+#define EFI_ACPI_CREATOR_REVISION 0x00000097
+
+#define INT_MODEL 0x01
+#define SCI_INT_VECTOR 0x0009
+#define SMI_CMD_IO_PORT 0xB2
+#define ACPI_ENABLE 0x0E1
+#define ACPI_DISABLE 0x01E
+#define S4BIOS_REQ 0x00
+#define PM1a_EVT_BLK 0x00000400
+#define PM1b_EVT_BLK 0x00000000
+#define PM1a_CNT_BLK 0x00000404
+#define PM1b_CNT_BLK 0x00000000
+#define PM2_CNT_BLK 0x00000450
+#define PM_TMR_BLK 0x00000408
+#define GPE0_BLK 0x00000420
+#define GPE1_BLK 0x00000000
+#define PM1_EVT_LEN 0x04
+#define PM1_CNT_LEN 0x04
+#define PM2_CNT_LEN 0x01
+#define PM_TM_LEN 0x04
+#define GPE0_BLK_LEN 0x10
+#define GPE1_BLK_LEN 0x00
+#define GPE1_BASE 0x00
+#define RESERVED 0x00
+#define P_LVL2_LAT 0x0065
+#define P_LVL3_LAT 0x03E9
+#define FLUSH_SIZE 0x0400
+#define FLUSH_STRIDE 0x0010
+#define DUTY_OFFSET 0x00
+#define DUTY_WIDTH 0x00
+#define DAY_ALRM 0x0D
+#define MON_ALRM 0x00
+#define CENTURY 0x00
+#define FLAG (EFI_ACPI_2_0_WBINVD | \
+ EFI_ACPI_2_0_PROC_C1 | \
+ EFI_ACPI_2_0_SLP_BUTTON | \
+ EFI_ACPI_2_0_RTC_S4 | \
+ EFI_ACPI_2_0_RESET_REG_SUP)
+#define RESET_REG 0xCF9
+#define RESET_VALUE (BIT2 | BIT1) // PIIX3 Reset CPU + System Reset
+
+//
+// Byte-aligned IO port register block initializer for
+// EFI_ACPI_2_0_GENERIC_ADDRESS_STRUCTURE
+//
+#define GAS2_IO(Base, Size) { \
+ EFI_ACPI_2_0_SYSTEM_IO, /* AddressSpaceId */ \
+ (Size) * 8, /* RegisterBitWidth */ \
+ 0, /* RegisterBitOffset */ \
+ 0, /* Reserved */ \
+ (Base) /* Address */ \
+ }
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsBoardConfig.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsBoardConfig.h
new file mode 100644
index 0000000000..dfbb1c0f3c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsBoardConfig.h
@@ -0,0 +1,17 @@
+/** @file
+ GUID for UEFI variables that are specific to Simics Board configuration.
+
+ Copyright (C) 2014, Red Hat, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __SIMICS_BOARD_CONFIG_H__
+#define __SIMICS_BOARD_CONFIG_H__
+
+#define SIMICS_BOARD_CONFIG_GUID \
+{0x8a318e00, 0xfaf5, 0x499f, { 0x91,0x75, 0xce, 0x4d, 0x8d, 0xa6, 0x70, 0xae}}
+
+extern EFI_GUID gSimicsBoardConfigGuid;
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/I440FxPiix4.h b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/I440FxPiix4.h
new file mode 100644
index 0000000000..e7d7fde14c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/I440FxPiix4.h
@@ -0,0 +1,49 @@
+/** @file
+ Various register numbers and value bits based on the following publications:
+ - Intel(R) datasheet 290549-001
+ - Intel(R) datasheet 290562-001
+ - Intel(R) datasheet 297654-006
+ - Intel(R) datasheet 297738-017
+
+ Copyright (C) 2015, Red Hat, Inc.
+ Copyright (c) 2014, Gabriel L. Somlo <somlo@cmu.edu>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __I440FX_PIIX4_H__
+#define __I440FX_PIIX4_H__
+
+#include <Library/PciLib.h>
+
+//
+// Host Bridge Device ID (DID) value for I440FX
+//
+#define INTEL_82441_DEVICE_ID 0x1237
+
+//
+// B/D/F/Type: 0/0/0/PCI
+//
+#define PMC_REGISTER_PIIX4(Offset) PCI_LIB_ADDRESS (0, 0, 0, (Offset))
+
+#define PIIX4_PAM0 0x59
+#define PIIX4_PAM1 0x5A
+#define PIIX4_PAM2 0x5B
+#define PIIX4_PAM3 0x5C
+#define PIIX4_PAM4 0x5D
+#define PIIX4_PAM5 0x5E
+#define PIIX4_PAM6 0x5F
+
+//
+// B/D/F/Type: 0/1/3/PCI
+//
+#define POWER_MGMT_REGISTER_PIIX4(Offset) PCI_LIB_ADDRESS (0, 1, 3, (Offset))
+
+#define PIIX4_PMBA 0x40
+#define PIIX4_PMBA_MASK (BIT15 | BIT14 | BIT13 | BIT12 | BIT11 | \
+ BIT10 | BIT9 | BIT8 | BIT7 | BIT6)
+
+#define PIIX4_PMREGMISC 0x80
+#define PIIX4_PMREGMISC_PMIOSE BIT0
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/LinuxBzImage.h b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/LinuxBzImage.h
new file mode 100644
index 0000000000..58a49e47be
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/LinuxBzImage.h
@@ -0,0 +1,158 @@
+/** @file
+
+ Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __LINUX_BZIMAGE_H__
+#define __LINUX_BZIMAGE_H__
+
+#define BOOTSIG 0x1FE
+#define SETUP_HDR 0x53726448 /* 0x53726448 == "HdrS" */
+
+#define E820_RAM 1
+#define E820_RESERVED 2
+#define E820_ACPI 3
+#define E820_NVS 4
+#define E820_UNUSABLE 5
+
+#pragma pack(1)
+
+struct setup_header {
+ UINT8 setup_secs; /* Sectors for setup code */
+ UINT16 root_flags;
+ UINT32 sys_size;
+ UINT16 ram_size;
+ UINT16 video_mode;
+ UINT16 root_dev;
+ UINT16 signature; /* Boot signature */
+ UINT16 jump;
+ UINT32 header;
+ UINT16 version;
+ UINT16 su_switch;
+ UINT16 setup_seg;
+ UINT16 start_sys;
+ UINT16 kernel_ver;
+ UINT8 loader_id;
+ UINT8 load_flags;
+ UINT16 movesize;
+ UINT32 code32_start; /* Start of code loaded high */
+ UINT32 ramdisk_start; /* Start of initial ramdisk */
+ UINT32 ramdisk_len; /* Length of initial ramdisk */
+ UINT32 bootsect_kludge;
+ UINT16 heap_end;
+ UINT8 ext_loader_ver; /* Extended boot loader version */
+ UINT8 ext_loader_type; /* Extended boot loader ID */
+ UINT32 cmd_line_ptr; /* 32-bit pointer to the kernel command line */
+ UINT32 ramdisk_max; /* Highest legal initrd address */
+ UINT32 kernel_alignment; /* Physical addr alignment required for kernel */
+ UINT8 relocatable_kernel; /* Whether kernel is relocatable or not */
+ UINT8 min_alignment;
+ UINT16 xloadflags;
+ UINT32 cmdline_size;
+ UINT32 hardware_subarch;
+ UINT64 hardware_subarch_data;
+ UINT32 payload_offset;
+ UINT32 payload_length;
+ UINT64 setup_data;
+ UINT64 pref_address;
+ UINT32 init_size;
+ UINT32 handover_offset;
+};
+
+struct efi_info {
+ UINT32 efi_loader_signature;
+ UINT32 efi_systab;
+ UINT32 efi_memdesc_size;
+ UINT32 efi_memdesc_version;
+ UINT32 efi_memmap;
+ UINT32 efi_memmap_size;
+ UINT32 efi_systab_hi;
+ UINT32 efi_memmap_hi;
+};
+
+struct e820_entry {
+ UINT64 addr; /* start of memory segment */
+ UINT64 size; /* size of memory segment */
+ UINT32 type; /* type of memory segment */
+};
+
+struct screen_info {
+ UINT8 orig_x; /* 0x00 */
+ UINT8 orig_y; /* 0x01 */
+ UINT16 ext_mem_k; /* 0x02 */
+ UINT16 orig_video_page; /* 0x04 */
+ UINT8 orig_video_mode; /* 0x06 */
+ UINT8 orig_video_cols; /* 0x07 */
+ UINT8 flags; /* 0x08 */
+ UINT8 unused2; /* 0x09 */
+ UINT16 orig_video_ega_bx;/* 0x0a */
+ UINT16 unused3; /* 0x0c */
+ UINT8 orig_video_lines; /* 0x0e */
+ UINT8 orig_video_isVGA; /* 0x0f */
+ UINT16 orig_video_points;/* 0x10 */
+
+ /* VESA graphic mode -- linear frame buffer */
+ UINT16 lfb_width; /* 0x12 */
+ UINT16 lfb_height; /* 0x14 */
+ UINT16 lfb_depth; /* 0x16 */
+ UINT32 lfb_base; /* 0x18 */
+ UINT32 lfb_size; /* 0x1c */
+ UINT16 cl_magic, cl_offset; /* 0x20 */
+ UINT16 lfb_linelength; /* 0x24 */
+ UINT8 red_size; /* 0x26 */
+ UINT8 red_pos; /* 0x27 */
+ UINT8 green_size; /* 0x28 */
+ UINT8 green_pos; /* 0x29 */
+ UINT8 blue_size; /* 0x2a */
+ UINT8 blue_pos; /* 0x2b */
+ UINT8 rsvd_size; /* 0x2c */
+ UINT8 rsvd_pos; /* 0x2d */
+ UINT16 vesapm_seg; /* 0x2e */
+ UINT16 vesapm_off; /* 0x30 */
+ UINT16 pages; /* 0x32 */
+ UINT16 vesa_attributes; /* 0x34 */
+ UINT32 capabilities; /* 0x36 */
+ UINT8 _reserved[6]; /* 0x3a */
+};
+
+struct boot_params {
+struct screen_info screen_info;
+ UINT8 apm_bios_info[0x14];
+ UINT8 _pad2[4];
+ UINT64 tboot_addr;
+ UINT8 ist_info[0x10];
+ UINT8 _pad3[16];
+ UINT8 hd0_info[16];
+ UINT8 hd1_info[16];
+ UINT8 sys_desc_table[0x10];
+ UINT8 olpc_ofw_header[0x10];
+ UINT8 _pad4[128];
+ UINT8 edid_info[0x80];
+ struct efi_info efi_info;
+ UINT32 alt_mem_k;
+ UINT32 scratch;
+ UINT8 e820_entries;
+ UINT8 eddbuf_entries;
+ UINT8 edd_mbr_sig_buf_entries;
+ UINT8 _pad6[6];
+ struct setup_header hdr;
+ UINT8 _pad7[0x290-0x1f1-sizeof(struct setup_header)];
+ UINT32 edd_mbr_sig_buffer[16];
+ struct e820_entry e820_map[128];
+ UINT8 _pad8[48];
+ UINT8 eddbuf[0x1ec];
+ UINT8 _pad9[276];
+};
+
+typedef struct {
+ UINT16 limit;
+ UINT64 *base;
+} dt_addr_t;
+
+#pragma pack()
+
+extern EFI_STATUS setup_graphics(struct boot_params *buf);
+
+#endif /* __LINUX_BZIMAGE_H__ */
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Library/LoadLinuxLib.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Library/LoadLinuxLib.h
new file mode 100644
index 0000000000..483f8d4b9c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Library/LoadLinuxLib.h
@@ -0,0 +1,205 @@
+/** @file
+ Load/boot UEFI Linux.
+
+ Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __LOAD_LINUX_LIB__
+#define __LOAD_LINUX_LIB__
+
+
+/**
+ Verifies that the kernel setup image is valid and supported.
+ The kernel setup image should be checked before using other library
+ routines which take the kernel setup as an input.
+
+ @param[in] KernelSetup - The kernel setup image
+ @param[in] KernelSetupSize - The kernel setup size
+
+ @retval EFI_SUCCESS - The Linux kernel setup is valid and supported
+ @retval EFI_INVALID_PARAMETER - KernelSetup was NULL
+ @retval EFI_UNSUPPORTED - The Linux kernel is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+LoadLinuxCheckKernelSetup (
+ IN VOID *KernelSetup,
+ IN UINTN KernelSetupSize
+ );
+
+
+/**
+ Gets the initial runtime size of the Linux kernel image by examining
+ the kernel setup image.
+
+ @param[in] KernelSetup - The kernel setup image
+ @param[in] KernelSize - The kernel size on disk.
+
+ @retval 0 An error occurred
+ @retval !0 The initial size required by the kernel to
+ begin execution.
+
+**/
+UINTN
+EFIAPI
+LoadLinuxGetKernelSize (
+ IN VOID *KernelSetup,
+ IN UINTN KernelSize
+ );
+
+
+/**
+ Loads and boots UEFI Linux.
+
+ Note: If successful, then this routine will not return
+
+ @param[in] Kernel - The main kernel image
+ @param[in,out] KernelSetup - The kernel setup image
+
+ @retval EFI_NOT_FOUND - The Linux kernel was not found
+ @retval EFI_INVALID_PARAMETER - Kernel or KernelSetup was NULL
+ @retval EFI_UNSUPPORTED - The Linux kernel version is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+LoadLinux (
+ IN VOID *Kernel,
+ IN OUT VOID *KernelSetup
+ );
+
+
+/**
+ Allocates pages for the kernel setup image.
+
+ @param[in] Pages - The number of pages
+
+ @retval NULL - Unable to allocate pages
+ @retval !NULL - The address of the pages allocated
+
+**/
+VOID*
+EFIAPI
+LoadLinuxAllocateKernelSetupPages (
+ IN UINTN Pages
+ );
+
+
+/**
+ Clears the uninitialised space before and after the struct setup_header
+ in the kernel setup image. The kernel requires that these be zeroed
+ unless explicitly initialised, so this function should be called after
+ the setup_header has been copied in from a bzImage, before setting up
+ anything else.
+
+ @param[in] KernelSetup - The kernel setup image
+
+ @retval EFI_SUCCESS - The Linux kernel setup was successfully initialized
+ @retval EFI_INVALID_PARAMETER - KernelSetup was NULL
+ @retval EFI_UNSUPPORTED - The Linux kernel is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+LoadLinuxInitializeKernelSetup (
+ IN VOID *KernelSetup
+ );
+
+/**
+ Allocates pages for the kernel.
+
+ @param[in] KernelSetup - The kernel setup image
+ @param[in] Pages - The number of pages. (It is recommended to use the
+ size returned from LoadLinuxGetKernelSize.)
+
+ @retval NULL - Unable to allocate pages
+ @retval !NULL - The address of the pages allocated
+
+**/
+VOID*
+EFIAPI
+LoadLinuxAllocateKernelPages (
+ IN VOID *KernelSetup,
+ IN UINTN Pages
+ );
+
+
+/**
+ Allocates pages for the kernel command line.
+
+ @param[in] Pages - The number of pages.
+
+ @retval NULL - Unable to allocate pages
+ @retval !NULL - The address of the pages allocated
+
+**/
+VOID*
+EFIAPI
+LoadLinuxAllocateCommandLinePages (
+ IN UINTN Pages
+ );
+
+
+/**
+ Allocates pages for the initrd image.
+
+ @param[in,out] KernelSetup - The kernel setup image
+ @param[in] Pages - The number of pages.
+
+ @retval NULL - Unable to allocate pages
+ @retval !NULL - The address of the pages allocated
+
+**/
+VOID*
+EFIAPI
+LoadLinuxAllocateInitrdPages (
+ IN VOID *KernelSetup,
+ IN UINTN Pages
+ );
+
+
+/**
+ Sets the kernel command line parameter within the setup image.
+
+ @param[in,out] KernelSetup - The kernel setup image
+ @param[in] CommandLine - The kernel command line
+
+ @retval EFI_SUCCESS - The Linux kernel setup is valid and supported
+ @retval EFI_INVALID_PARAMETER - KernelSetup was NULL
+ @retval EFI_UNSUPPORTED - The Linux kernel is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+LoadLinuxSetCommandLine (
+ IN OUT VOID *KernelSetup,
+ IN CHAR8 *CommandLine
+ );
+
+
+/**
+ Sets the kernel initial ram disk pointer within the setup image.
+
+ @param[in,out] KernelSetup - The kernel setup image
+ @param[in] Initrd - Pointer to the initial ram disk
+ @param[in] InitrdSize - The initial ram disk image size
+
+ @retval EFI_SUCCESS - The Linux kernel setup is valid and supported
+ @retval EFI_INVALID_PARAMETER - KernelSetup was NULL
+ @retval EFI_UNSUPPORTED - The Linux kernel is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+LoadLinuxSetInitrd (
+ IN OUT VOID *KernelSetup,
+ IN VOID *Initrd,
+ IN UINTN InitrdSize
+ );
+
+
+#endif
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Library/SerializeVariablesLib.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Library/SerializeVariablesLib.h
new file mode 100644
index 0000000000..8e74b718f1
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Library/SerializeVariablesLib.h
@@ -0,0 +1,223 @@
+/** @file
+ Serialize & Deserialize UEFI Variables
+
+ Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __SERIALIZE_VARIABLES_LIB__
+#define __SERIALIZE_VARIABLES_LIB__
+
+
+/**
+ Callback function for each variable
+
+ @param[in] Context - Context as sent to the iteration function
+ @param[in] VariableName - Refer to RuntimeServices GetNextVariableName
+ @param[in] VendorGuid - Refer to RuntimeServices GetNextVariableName
+ @param[in] Attributes - Refer to RuntimeServices GetVariable
+ @param[in] DataSize - Refer to RuntimeServices GetVariable
+ @param[in] Data - Refer to RuntimeServices GetVariable
+
+ @retval RETURN_SUCCESS Continue iterating through the variables
+ @return Any RETURN_ERROR Stop iterating through the variables
+
+**/
+typedef
+RETURN_STATUS
+(EFIAPI *VARIABLE_SERIALIZATION_ITERATION_CALLBACK)(
+ IN VOID *Context,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ );
+
+
+/**
+ Creates a new variable serialization instance
+
+ @param[out] Handle - Handle for a variable serialization instance
+
+ @retval RETURN_SUCCESS - The variable serialization instance was
+ successfully created.
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ create the variable serialization instance.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesNewInstance (
+ OUT EFI_HANDLE *Handle
+ );
+
+
+/**
+ Free memory associated with a variable serialization instance
+
+ @param[in] Handle - Handle for a variable serialization instance
+
+ @retval RETURN_SUCCESS - The variable serialization instance was
+ successfully freed.
+ @retval RETURN_INVALID_PARAMETER - Handle was not a valid
+ variable serialization instance.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesFreeInstance (
+ IN EFI_HANDLE Handle
+ );
+
+
+/**
+ Creates a new variable serialization instance using the given
+ binary representation of the variables to fill the new instance
+
+ @param[out] Handle - Handle for a variable serialization instance
+ @param[in] Buffer - A buffer with the serialized representation
+ of the variables. Must be the same format as produced
+ by SerializeVariablesToBuffer.
+ @param[in] Size - This is the size of the binary representation
+ of the variables.
+
+ @retval RETURN_SUCCESS - The binary representation was successfully
+ imported into a new variable serialization instance
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ create the new variable serialization instance
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesNewInstanceFromBuffer (
+ OUT EFI_HANDLE *Handle,
+ IN VOID *Buffer,
+ IN UINTN Size
+ );
+
+
+/**
+ Iterates all variables found with RuntimeServices GetNextVariableName
+
+ @param[in] CallbackFunction - Function called for each variable instance
+ @param[in] Context - Passed to each call of CallbackFunction
+
+ @retval RETURN_SUCCESS - All variables were iterated without the
+ CallbackFunction returning an error
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ iterate through the variables
+ @return Any of RETURN_ERROR indicates an error reading the variable
+ or an error was returned from CallbackFunction
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesIterateSystemVariables (
+ IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
+ IN VOID *Context
+ );
+
+
+/**
+ Iterates all variables found in the variable serialization instance
+
+ @param[in] Handle - Handle for a variable serialization instance
+ @param[in] CallbackFunction - Function called for each variable instance
+ @param[in] Context - Passed to each call of CallbackFunction
+
+ @retval RETURN_SUCCESS - All variables were iterated without the
+ CallbackFunction returning an error
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ iterate through the variables
+ @return Any of RETURN_ERROR indicates an error reading the variable
+ or an error was returned from CallbackFunction
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesIterateInstanceVariables (
+ IN EFI_HANDLE Handle,
+ IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
+ IN VOID *Context
+ );
+
+
+/**
+ Sets all variables found in the variable serialization instance
+
+ @param[in] Handle - Handle for a variable serialization instance
+
+ @retval RETURN_SUCCESS - All variables were set successfully
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ set all the variables
+ @return Any of RETURN_ERROR indicates an error reading the variables
+ or in attempting to set a variable
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesSetSerializedVariables (
+ IN EFI_HANDLE Handle
+ );
+
+
+/**
+ Adds a variable to the variable serialization instance
+
+ @param[in] Handle - Handle for a variable serialization instance
+ @param[in] VariableName - Refer to RuntimeServices GetVariable
+ @param[in] VendorGuid - Refer to RuntimeServices GetVariable
+ @param[in] Attributes - Refer to RuntimeServices GetVariable
+ @param[in] DataSize - Refer to RuntimeServices GetVariable
+ @param[in] Data - Refer to RuntimeServices GetVariable
+
+ @retval RETURN_SUCCESS - All variables were set successfully
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ add the variable
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesAddVariable (
+ IN EFI_HANDLE Handle,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ );
+
+
+/**
+ Serializes the variables known to this instance into the
+ provided buffer.
+
+ @param[in] Handle - Handle for a variable serialization instance
+ @param[out] Buffer - A buffer to store the binary representation
+ of the variables.
+ @param[in,out] Size - On input this is the size of the buffer.
+ On output this is the size of the binary representation
+ of the variables.
+
+ @retval RETURN_SUCCESS - The binary representation was successfully
+ completed and returned in the buffer.
+ @retval RETURN_OUT_OF_RESOURCES - There we not enough resources to
+ save the variables to the buffer.
+ @retval RETURN_INVALID_PARAMETER - Handle was not a valid
+ variable serialization instance or
+ Size or Buffer were NULL.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerializeVariablesToBuffer (
+ IN EFI_HANDLE Handle,
+ OUT VOID *Buffer,
+ IN OUT UINTN *Size
+ );
+
+
+#endif
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
new file mode 100644
index 0000000000..67bb3af584
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
@@ -0,0 +1,55 @@
+/** @file
+ Simics Platform definitions
+
+ Copyright (C) 2015, Red Hat, Inc.
+ Copyright (c) 2014, Gabriel L. Somlo <somlo@cmu.edu>
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __SIMICS_PLATFORMS_H__
+#define __SIMICS_PLATFORMS_H__
+
+#include <Library/PciLib.h>
+#include <IndustryStandard/Pci22.h>
+#include <Register/X58Ich10.h>
+#include <IndustryStandard/I440FxPiix4.h>
+
+//
+// Simics Host Bridge DID Address
+//
+#define SIMICS_HOSTBRIDGE_DID \
+ PCI_LIB_ADDRESS (0, 0, 0, PCI_DEVICE_ID_OFFSET)
+
+//
+// Simics SideBand PCI device registers
+//
+#define SIMICS_SIDEBANDPCI_DEV 0
+#define SIMICS_SIDEBANDPCI_FUNC 7
+#define SIMICS_SIDEBANDPCI_SVID \
+ PCI_LIB_ADDRESS (0, 0, 7, PCI_SVID_OFFSET)
+#define SIMICS_SIDEBANDPCI_SDID \
+ PCI_LIB_ADDRESS (0, 0, 7, PCI_SID_OFFSET)
+#define SIMICS_SIDEBANDPCI_CAP \
+ PCI_LIB_ADDRESS (0, 0, 7, PCI_CAPBILITY_POINTER_OFFSET)
+#define SIMICS_SIDEBANDPCI_CAP_Offset 0x40
+#define SIMICS_SIDEBANDPCI_CAP_ID 0xFF
+
+//
+// Values we program into the PM base address registers
+//
+#define PIIX4_PMBA_VALUE 0xB000
+#define ICH10_PMBASE_VALUE 0x0400
+
+//
+// Common bits in same-purpose registers
+//
+#define PMBA_RTE BIT0
+
+//
+// Common IO ports relative to the Power Management Base Address
+//
+#define ACPI_TIMER_OFFSET 0x8
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/DxeLogoLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/DxeLogoLib.inf
new file mode 100644
index 0000000000..1cf91f02c2
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/DxeLogoLib.inf
@@ -0,0 +1,55 @@
+### @file
+# Module that show progress bar and title above it.
+#
+# General BDS defines and produce general interfaces for platform BDS driver including:
+# 1) BDS boot policy interface;
+# 2) BDS boot device connect interface;
+# 3) BDS Misc interfaces for mainting boot variable, ouput string, etc.
+#
+# Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = DxeLogoLib
+ FILE_GUID = F5AE5B5C-42E8-4A9B-829D-5B631CD5367A
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_DRIVER
+ LIBRARY_CLASS = LogoLib|DXE_DRIVER UEFI_APPLICATION
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+ BaseLib
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ UefiLib
+ BaseMemoryLib
+ DebugLib
+ PrintLib
+ PcdLib
+ DxeServicesLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+
+[FeaturePcd]
+ gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport
+
+[Sources]
+ Logo.c
+
+[Protocols]
+ gEfiGraphicsOutputProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiUgaDrawProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiBootLogoProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiUserManagerProtocolGuid ## CONSUMES
+ gEfiOEMBadgingProtocolGuid ## CONSUMES
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/OEMBadging.h b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/OEMBadging.h
new file mode 100644
index 0000000000..4f06bae5d1
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/DxeLogoLib/OEMBadging.h
@@ -0,0 +1,83 @@
+/** @file
+ The OEM Badging Protocol defines the interface to get the OEM badging
+ image with the display attribute. This protocol can be produced based on OEM badging images.
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EFI_OEM_BADGING_H__
+#define __EFI_OEM_BADGING_H__
+
+//
+// GUID for EFI OEM Badging Protocol
+//
+#define EFI_OEM_BADGING_PROTOCOL_GUID \
+ { 0x170e13c0, 0xbf1b, 0x4218, {0x87, 0x1d, 0x2a, 0xbd, 0xc6, 0xf8, 0x87, 0xbc } }
+
+
+typedef struct _EFI_OEM_BADGING_PROTOCOL EFI_OEM_BADGING_PROTOCOL;
+
+typedef enum {
+ EfiBadgingFormatBMP,
+ EfiBadgingFormatJPEG,
+ EfiBadgingFormatTIFF,
+ EfiBadgingFormatGIF,
+ EfiBadgingFormatUnknown
+} EFI_BADGING_FORMAT;
+
+typedef enum {
+ EfiBadgingDisplayAttributeLeftTop,
+ EfiBadgingDisplayAttributeCenterTop,
+ EfiBadgingDisplayAttributeRightTop,
+ EfiBadgingDisplayAttributeCenterRight,
+ EfiBadgingDisplayAttributeRightBottom,
+ EfiBadgingDisplayAttributeCenterBottom,
+ EfiBadgingDisplayAttributeLeftBottom,
+ EfiBadgingDisplayAttributeCenterLeft,
+ EfiBadgingDisplayAttributeCenter,
+ EfiBadgingDisplayAttributeCustomized
+} EFI_BADGING_DISPLAY_ATTRIBUTE;
+
+/**
+
+ Load an OEM badge image and return its data and attributes.
+
+ @param This The pointer to this protocol instance.
+ @param Instance The visible image instance is found.
+ @param Format The format of the image. Examples: BMP, JPEG.
+ @param ImageData The image data for the badge file. Currently only
+ supports the .bmp file format.
+ @param ImageSize The size of the image returned.
+ @param Attribute The display attributes of the image returned.
+ @param CoordinateX The X coordinate of the image.
+ @param CoordinateY The Y coordinate of the image.
+
+ @retval EFI_SUCCESS The image was fetched successfully.
+ @retval EFI_NOT_FOUND The specified image could not be found.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_BADGING_GET_IMAGE)(
+ IN EFI_OEM_BADGING_PROTOCOL *This,
+ IN OUT UINT32 *Instance,
+ OUT EFI_BADGING_FORMAT *Format,
+ OUT UINT8 **ImageData,
+ OUT UINTN *ImageSize,
+ OUT EFI_BADGING_DISPLAY_ATTRIBUTE *Attribute,
+ OUT UINTN *CoordinateX,
+ OUT UINTN *CoordinateY
+);
+
+
+struct _EFI_OEM_BADGING_PROTOCOL {
+ EFI_BADGING_GET_IMAGE GetImage;
+};
+
+
+extern EFI_GUID gEfiOEMBadgingProtocolGuid;
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/DxeLoadLinuxLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/DxeLoadLinuxLib.inf
new file mode 100644
index 0000000000..cdefeebbdd
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/DxeLoadLinuxLib.inf
@@ -0,0 +1,42 @@
+## @file
+#
+# Copyright (c) 2008 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxeLoadLinuxLib
+ FILE_GUID = 63CC8497-C9D0-46A8-AC08-49DF92A2FF62
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = DxeLoadLinuxLib|DXE_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.common]
+ Linux.c
+ LinuxGdt.c
+
+[Sources.IA32]
+ Ia32/JumpToKernel.nasm
+
+[Sources.X64]
+ X64/JumpToKernel.nasm
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ MemoryAllocationLib
+ BaseMemoryLib
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.nasm b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.nasm
new file mode 100644
index 0000000000..c6f1c31a59
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.nasm
@@ -0,0 +1,41 @@
+; @file
+; Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; JumpToKernel (
+; VOID *KernelStart,
+; VOID *KernelBootParams
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(JumpToKernel)
+ASM_PFX(JumpToKernel):
+
+ mov esi, [esp + 8]
+ call DWORD [esp + 4]
+ ret
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; JumpToUefiKernel (
+; EFI_HANDLE ImageHandle,
+; EFI_SYSTEM_TABLE *SystemTable,
+; VOID *KernelBootParams,
+; VOID *KernelStart
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(JumpToUefiKernel)
+ASM_PFX(JumpToUefiKernel):
+
+ mov eax, [esp + 12]
+ mov eax, [eax + 0x264]
+ add eax, [esp + 16]
+ jmp eax
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
new file mode 100644
index 0000000000..9c0ab80904
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
@@ -0,0 +1,52 @@
+/** @file
+ Boot UEFI Linux.
+
+ Copyright (c) 2008 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _LOAD_LINUX_LIB_INCLUDED_
+#define _LOAD_LINUX_LIB_INCLUDED_
+
+#include <Uefi.h>
+#include <Library/LoadLinuxLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#include <IndustryStandard/LinuxBzImage.h>
+
+#include <Protocol/GraphicsOutput.h>
+
+VOID
+EFIAPI
+JumpToKernel (
+ VOID *KernelStart,
+ VOID *KernelBootParams
+ );
+
+VOID
+EFIAPI
+JumpToUefiKernel (
+ EFI_HANDLE ImageHandle,
+ EFI_SYSTEM_TABLE *SystemTable,
+ VOID *KernelBootParams,
+ VOID *KernelStart
+ );
+
+VOID
+InitLinuxDescriptorTables (
+ VOID
+ );
+
+VOID
+SetLinuxDescriptorTables (
+ VOID
+ );
+
+#endif
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel.nasm b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel.nasm
new file mode 100644
index 0000000000..2b5395f6f8
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel.nasm
@@ -0,0 +1,85 @@
+; @file
+; Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+
+ DEFAULT REL
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; JumpToKernel (
+; VOID *KernelStart, // rcx
+; VOID *KernelBootParams // rdx
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(JumpToKernel)
+ASM_PFX(JumpToKernel):
+
+ ; Set up for executing kernel. BP in %esi, entry point on the stack
+ ; (64-bit when the 'ret' will use it as 32-bit, but we're little-endian)
+ mov rsi, rdx
+ push rcx
+
+ ; Jump into the compatibility mode CS
+ push 0x10
+ lea rax, [.0]
+ push rax
+ DB 0x48, 0xcb ; retfq
+
+.0:
+ ; Now in compatibility mode.
+
+ DB 0xb8, 0x18, 0x0, 0x0, 0x0 ; movl $0x18, %eax
+ DB 0x8e, 0xd8 ; movl %eax, %ds
+ DB 0x8e, 0xc0 ; movl %eax, %es
+ DB 0x8e, 0xe0 ; movl %eax, %fs
+ DB 0x8e, 0xe8 ; movl %eax, %gs
+ DB 0x8e, 0xd0 ; movl %eax, %ss
+
+ ; Disable paging
+ DB 0xf, 0x20, 0xc0 ; movl %cr0, %eax
+ DB 0xf, 0xba, 0xf8, 0x1f ; btcl $31, %eax
+ DB 0xf, 0x22, 0xc0 ; movl %eax, %cr0
+
+ ; Disable long mode in EFER
+ DB 0xb9, 0x80, 0x0, 0x0, 0xc0 ; movl $0x0c0000080, %ecx
+ DB 0xf, 0x32 ; rdmsr
+ DB 0xf, 0xba, 0xf8, 0x8 ; btcl $8, %eax
+ DB 0xf, 0x30 ; wrmsr
+
+ ; Disable PAE
+ DB 0xf, 0x20, 0xe0 ; movl %cr4, %eax
+ DB 0xf, 0xba, 0xf8, 0x5 ; btcl $5, %eax
+ DB 0xf, 0x22, 0xe0 ; movl %eax, %cr4
+
+ DB 0x31, 0xed ; xor %ebp, %ebp
+ DB 0x31, 0xff ; xor %edi, %edi
+ DB 0x31, 0xdb ; xor %ebx, %ebx
+ DB 0xc3 ; ret
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; JumpToUefiKernel (
+; EFI_HANDLE ImageHandle, // rcx
+; EFI_SYSTEM_TABLE *SystemTable, // rdx
+; VOID *KernelBootParams // r8
+; VOID *KernelStart, // r9
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(JumpToUefiKernel)
+ASM_PFX(JumpToUefiKernel):
+
+ mov rdi, rcx
+ mov rsi, rdx
+ mov rdx, r8
+ xor rax, rax
+ mov eax, [r8 + 0x264]
+ add r9, rax
+ add r9, 0x200
+ call r9
+ ret
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h
new file mode 100644
index 0000000000..80776fd003
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.h
@@ -0,0 +1,55 @@
+/** @file
+ Save Non-Volatile Variables to a file system.
+
+ Copyright (c) 2009 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __NV_VARS_FILE_LIB_INSTANCE__
+#define __NV_VARS_FILE_LIB_INSTANCE__
+
+#include <Uefi.h>
+
+#include <Guid/FileInfo.h>
+
+#include <Protocol/SimpleFileSystem.h>
+
+#include <Library/BaseLib.h>
+#include <Library/FileHandleLib.h>
+#include <Library/SerializeVariablesLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+/**
+ Loads the non-volatile variables from the NvVars file on the
+ given file system.
+
+ @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
+
+ @return EFI_STATUS based on the success or failure of load operation
+
+**/
+EFI_STATUS
+LoadNvVarsFromFs (
+ EFI_HANDLE FsHandle
+ );
+
+
+/**
+ Saves the non-volatile variables into the NvVars file on the
+ given file system.
+
+ @param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
+
+ @return EFI_STATUS based on the success or failure of load operation
+
+**/
+EFI_STATUS
+SaveNvVarsToFs (
+ EFI_HANDLE FsHandle
+ );
+
+#endif
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
new file mode 100644
index 0000000000..4731e77865
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
@@ -0,0 +1,53 @@
+## @file
+# NvVarsFileLib
+#
+# This library saves and restores non-volatile variables in a
+# file within a file system.
+#
+# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = NvVarsFileLib
+ FILE_GUID = 8ECD4CC0-1772-4583-8A74-83633A15FAA0
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = NvVarsFileLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ FsAccess.c
+ NvVarsFileLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ShellPkg/ShellPkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ FileHandleLib
+ MemoryAllocationLib
+ SerializeVariablesLib
+
+[Protocols]
+ gEfiSimpleFileSystemProtocolGuid ## CONSUMES
+
+[Guids]
+ gEfiFileInfoGuid
+
+[Depex]
+ gEfiVariableWriteArchProtocolGuid
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridge.h b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridge.h
new file mode 100644
index 0000000000..0c75430260
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridge.h
@@ -0,0 +1,68 @@
+/** @file
+ Header file of OVMF instance of PciHostBridgeLib.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+PCI_ROOT_BRIDGE *
+ScanForRootBridges (
+ UINTN *NumberOfRootBridges
+);
+
+/**
+ Initialize a PCI_ROOT_BRIDGE structure.
+
+ @param[in] Supports Supported attributes.
+
+ @param[in] Attributes Initial attributes.
+
+ @param[in] AllocAttributes Allocation attributes.
+
+ @param[in] RootBusNumber The bus number to store in RootBus.
+
+ @param[in] MaxSubBusNumber The inclusive maximum bus number that can be
+ assigned to any subordinate bus found behind any
+ PCI bridge hanging off this root bus.
+
+ The caller is repsonsible for ensuring that
+ RootBusNumber <= MaxSubBusNumber. If
+ RootBusNumber equals MaxSubBusNumber, then the
+ root bus has no room for subordinate buses.
+
+ @param[in] Io IO aperture.
+
+ @param[in] Mem MMIO aperture.
+
+ @param[in] MemAbove4G MMIO aperture above 4G.
+
+ @param[in] PMem Prefetchable MMIO aperture.
+
+ @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G.
+
+ @param[out] RootBus The PCI_ROOT_BRIDGE structure (allocated by the
+ caller) that should be filled in by this
+ function.
+
+ @retval EFI_SUCCESS Initialization successful. A device path
+ consisting of an ACPI device path node, with
+ UID = RootBusNumber, has been allocated and
+ linked into RootBus.
+
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
+**/
+EFI_STATUS
+InitRootBridge (
+ IN UINT64 Supports,
+ IN UINT64 Attributes,
+ IN UINT64 AllocAttributes,
+ IN UINT8 RootBusNumber,
+ IN UINT8 MaxSubBusNumber,
+ IN PCI_ROOT_BRIDGE_APERTURE *Io,
+ IN PCI_ROOT_BRIDGE_APERTURE *Mem,
+ IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,
+ IN PCI_ROOT_BRIDGE_APERTURE *PMem,
+ IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G,
+ OUT PCI_ROOT_BRIDGE *RootBus
+ );
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
new file mode 100644
index 0000000000..b22531bb56
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
@@ -0,0 +1,51 @@
+## @file
+# OVMF's instance of the PCI Host Bridge Library.
+#
+# Copyright (C) 2016, Red Hat, Inc.
+# Copyright (c) 2016 - 2018 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PciHostBridgeLib
+ FILE_GUID = 2F04EC41-C3A0-43EB-AC6A-409F973F4439
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PciHostBridgeLib
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ PciHostBridgeLib.c
+ PciHostBridge.h
+
+[Packages]
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ DevicePathLib
+ MemoryAllocationLib
+ PciLib
+
+[Pcd]
+ gBoardModuleTokenSpaceGuid.PcdPciIoBase
+ gBoardModuleTokenSpaceGuid.PcdPciIoSize
+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Base
+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Size
+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Base
+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Size
+ gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf
new file mode 100644
index 0000000000..6465f39fb4
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf
@@ -0,0 +1,56 @@
+### @file
+# Component information file for the Report Firmware Volume (FV) library.
+#
+# Copyright (c) 2018, 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
+ PcdLib
+ IoLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+ SimicsX58SktPkg/SktPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[Sources]
+ PeiReportFvLib.c
+ Fv.c
+
+[Pcd]
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## 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.PcdFlashFvAdvancedBase ## CONSUMES
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize ## CONSUMES
+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize
+ gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize
+ gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatform.h b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatform.h
new file mode 100644
index 0000000000..01ba20d2da
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/BdsPlatform.h
@@ -0,0 +1,172 @@
+/** @file
+ Platform BDS customizations include file.
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
+#define _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
+
+
+#include <PiDxe.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/SmBios.h>
+#include <IndustryStandard/PeImage.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/UefiBootManagerLib.h>
+#include <Library/BootLogoLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/NvVarsFileLib.h>
+
+#include <Protocol/Decompress.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/S3SaveState.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Protocol/LoadedImage.h>
+
+#include <Guid/Acpi.h>
+#include <Guid/SmBios.h>
+#include <Guid/Mps.h>
+#include <Guid/HobList.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/EventGroup.h>
+
+#include <SimicsPlatforms.h>
+
+extern EFI_DEVICE_PATH_PROTOCOL *gPlatformConnectSequence[];
+extern ACPI_HID_DEVICE_PATH gPnpPs2KeyboardDeviceNode;
+extern ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode;
+extern UART_DEVICE_PATH gUartDeviceNode;
+extern VENDOR_DEVICE_PATH gTerminalTypeDeviceNode;
+
+#define PCI_DEVICE_PATH_NODE(Func, Dev) \
+ { \
+ { \
+ HARDWARE_DEVICE_PATH, \
+ HW_PCI_DP, \
+ { \
+ (UINT8) (sizeof (PCI_DEVICE_PATH)), \
+ (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \
+ } \
+ }, \
+ (Func), \
+ (Dev) \
+ }
+
+#define PNPID_DEVICE_PATH_NODE(PnpId) \
+ { \
+ { \
+ ACPI_DEVICE_PATH, \
+ ACPI_DP, \
+ { \
+ (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
+ (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
+ }, \
+ }, \
+ EISA_PNP_ID((PnpId)), \
+ 0 \
+ }
+
+#define gPciIsaBridge \
+ PCI_DEVICE_PATH_NODE(0, 0x1f)
+
+#define gP2PBridge \
+ PCI_DEVICE_PATH_NODE(0, 0x1e)
+
+#define gPnpPs2Keyboard \
+ PNPID_DEVICE_PATH_NODE(0x0303)
+
+#define gPnp16550ComPort \
+ PNPID_DEVICE_PATH_NODE(0x0501)
+
+#define gUart \
+ { \
+ { \
+ MESSAGING_DEVICE_PATH, \
+ MSG_UART_DP, \
+ { \
+ (UINT8) (sizeof (UART_DEVICE_PATH)), \
+ (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8) \
+ } \
+ }, \
+ 0, \
+ 115200, \
+ 8, \
+ 1, \
+ 1 \
+ }
+
+#define gPcAnsiTerminal \
+ { \
+ { \
+ MESSAGING_DEVICE_PATH, \
+ MSG_VENDOR_DP, \
+ { \
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \
+ } \
+ }, \
+ DEVICE_PATH_MESSAGING_PC_ANSI \
+ }
+
+#define PCI_CLASS_SCC 0x07
+#define PCI_SUBCLASS_SERIAL 0x00
+#define PCI_IF_16550 0x02
+#define IS_PCI_16550SERIAL(_p) IS_CLASS3 (_p, PCI_CLASS_SCC, PCI_SUBCLASS_SERIAL, PCI_IF_16550)
+#define IS_PCI_ISA_PDECODE(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA_PDECODE, 0)
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ UINTN ConnectType;
+} PLATFORM_CONSOLE_CONNECT_ENTRY;
+
+#define CONSOLE_OUT BIT0
+#define CONSOLE_IN BIT1
+#define STD_ERROR BIT2
+extern PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[];
+
+//
+// Platform BDS Functions
+//
+
+VOID
+PlatformInitializeConsole (
+ IN PLATFORM_CONSOLE_CONNECT_ENTRY *PlatformConsole
+ );
+
+/**
+ Use SystemTable ConOut to stop video based Simple Text Out consoles from going
+ to the video device. Put up LogoFile on every video device that is a console.
+
+ @param[in] LogoFile The file name of logo to display on the center of the screen.
+
+ @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed.
+ @retval EFI_UNSUPPORTED Logo not found.
+
+**/
+EFI_STATUS
+EFIAPI
+EnableBootLogo(
+ IN EFI_GUID *LogoFile
+);
+
+#endif // _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
new file mode 100644
index 0000000000..cdb6e242e8
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
@@ -0,0 +1,72 @@
+## @file
+# Platform BDS customizations library.
+#
+# Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformBootManagerLib
+ FILE_GUID = 8AE4756F-0C71-4C06-84D4-4C71F204D514
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PlatformBootManagerLib|DXE_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ BdsPlatform.c
+ PlatformData.c
+ BdsPlatform.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+ OvmfPkg/OvmfPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[LibraryClasses]
+ BaseLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ BaseMemoryLib
+ DebugLib
+ PcdLib
+ UefiBootManagerLib
+ BootLogoLib
+ DevicePathLib
+ PciLib
+ NvVarsFileLib
+ DxeLoadLinuxLib
+ UefiLib
+ LogoLib
+
+[Pcd]
+ gBoardModuleTokenSpaceGuid.PcdEmuVariableEvent
+ gBoardModuleTokenSpaceGuid.PcdOvmfFlashVariablesEnable
+ gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
+ gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
+ gBoardModuleTokenSpaceGuid.PcdShellFile
+ gBoardModuleTokenSpaceGuid.PcdLogoFile
+
+[Pcd.IA32, Pcd.X64]
+ gEfiMdePkgTokenSpaceGuid.PcdFSBClock
+
+[Protocols]
+ gEfiDecompressProtocolGuid
+ gEfiPciRootBridgeIoProtocolGuid
+ gEfiS3SaveStateProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
+ gEfiDxeSmmReadyToLockProtocolGuid # PROTOCOL SOMETIMES_PRODUCED
+ gEfiLoadedImageProtocolGuid # PROTOCOL SOMETIMES_PRODUCED
+ gEfiFirmwareVolume2ProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
+
+[Guids]
+ gEfiEndOfDxeEventGroupGuid
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h
new file mode 100644
index 0000000000..9b4c2a629a
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h
@@ -0,0 +1,33 @@
+/** @file
+ Serialize Variables Library implementation
+
+ Copyright (c) 2009 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __SERIALIZE_VARIABLES_LIB_INSTANCE__
+#define __SERIALIZE_VARIABLES_LIB_INSTANCE__
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/SerializeVariablesLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#define SV_FROM_HANDLE(a) CR (a, SV_INSTANCE, Signature, SV_SIGNATURE)
+#define SV_SIGNATURE SIGNATURE_32 ('S', 'V', 'A', 'R')
+
+typedef struct {
+ UINT32 Signature;
+ VOID *BufferPtr;
+ UINTN BufferSize;
+ UINTN DataSize;
+} SV_INSTANCE;
+
+#endif
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
new file mode 100644
index 0000000000..08c561f586
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
@@ -0,0 +1,36 @@
+## @file
+# Serialize Variables Library implementation
+#
+# This library serializes and deserializes UEFI variables
+#
+# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxeSerializeVariablesLib
+ FILE_GUID = 266A1434-6B22-441F-A8D2-D54AA8FDF95C
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = SerializeVariablesLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER
+
+[Sources]
+ SerializeVariablesLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ShellPkg/ShellPkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf
new file mode 100644
index 0000000000..6be3b301ad
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf
@@ -0,0 +1,38 @@
+## @file
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SiliconPolicyInitLib
+ FILE_GUID = B494DF39-A5F8-48A1-B2D0-EF523AD91C55
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = SiliconPolicyInitLib
+
+[Sources]
+ SiliconPolicyInitLib.c
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+# this module.
+#
+################################################################################
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ BaseLib
+ DebugLib
+ DebugPrintErrorLevelLib
+ HobLib
+ IoLib
+ MemoryAllocationLib
+ PeiServicesLib
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf
new file mode 100644
index 0000000000..4fde3c75a6
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf
@@ -0,0 +1,35 @@
+## @file
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SiliconPolicyUpdateLib
+ FILE_GUID = 6EA9585C-3C15-47da-9FFC-25E9E4EA4D0C
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = SiliconPolicyUpdateLib
+
+[Sources]
+ SiliconPolicyUpdateLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ HobLib
+ IoLib
+ PcdLib
+
+[Pcd]
+
+[FixedPcd]
+
+[Ppis]
+
+[Guids]
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm b/Platform/Intel/SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm
new file mode 100644
index 0000000000..adb87de943
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SecCore/Ia32/SecEntry.nasm
@@ -0,0 +1,45 @@
+; @file
+; Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+
+#include <Base.h>
+
+ SECTION .text
+
+extern ASM_PFX(SecCoreStartupWithStack)
+
+;
+; SecCore Entry Point
+;
+; Processor is in flat protected mode
+;
+; @param[in] EAX Initial value of the EAX register (BIST: Built-in Self Test)
+; @param[in] DI 'BP': boot-strap processor, or 'AP': application processor
+; @param[in] EBP Pointer to the start of the Boot Firmware Volume
+;
+; @return None This routine does not return
+;
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+
+ ;
+ ; Load temporary RAM stack based on PCDs
+ ;
+ %define SEC_TOP_OF_STACK (FixedPcdGet32 (PcdSimicsSecPeiTempRamBase) + \
+ FixedPcdGet32 (PcdSimicsSecPeiTempRamSize))
+ mov eax, SEC_TOP_OF_STACK
+ mov esp, eax
+ nop
+
+ ;
+ ; Setup parameters and call SecCoreStartupWithStack
+ ; [esp] return address for call
+ ; [esp+4] BootFirmwareVolumePtr
+ ; [esp+8] TopOfCurrentStack
+ ;
+ push eax
+ push ebp
+ call ASM_PFX(SecCoreStartupWithStack)
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf b/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf
new file mode 100644
index 0000000000..b1d319c5ea
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.inf
@@ -0,0 +1,73 @@
+## @file
+# SEC Driver
+#
+# Copyright (c) 2008 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SecMain
+ FILE_GUID = e67f156f-54c5-47f3-a35d-07c045881e14
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SecMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ SecMain.c
+
+[Sources.IA32]
+ Ia32/SecEntry.nasm
+
+[Sources.X64]
+ X64/SecEntry.nasm
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ SimicsX58SktPkg/SktPkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ BaseMemoryLib
+ PeiServicesLib
+ PcdLib
+ UefiCpuLib
+ DebugAgentLib
+ IoLib
+ PeCoffLib
+ PeCoffGetEntryPointLib
+ PeCoffExtraActionLib
+ ExtractGuidedSectionLib
+ LocalApicLib
+ PciCf8Lib
+
+[Ppis]
+ gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
+
+[Pcd]
+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize
+ gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
+ gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
+ gBoardModuleTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+ gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
+
+[FeaturePcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm b/Platform/Intel/SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm
new file mode 100644
index 0000000000..2e6d8f618c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SecCore/X64/SecEntry.nasm
@@ -0,0 +1,45 @@
+; @file
+; Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+
+#include <Base.h>
+
+DEFAULT REL
+SECTION .text
+
+extern ASM_PFX(SecCoreStartupWithStack)
+
+;
+; SecCore Entry Point
+;
+; Processor is in flat protected mode
+;
+; @param[in] RAX Initial value of the EAX register (BIST: Built-in Self Test)
+; @param[in] DI 'BP': boot-strap processor, or 'AP': application processor
+; @param[in] RBP Pointer to the start of the Boot Firmware Volume
+;
+; @return None This routine does not return
+;
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+
+ ;
+ ; Load temporary RAM stack based on PCDs
+ ;
+ %define SEC_TOP_OF_STACK (FixedPcdGet32 (PcdSimicsSecPeiTempRamBase) + \
+ FixedPcdGet32 (PcdSimicsSecPeiTempRamSize))
+ mov rsp, SEC_TOP_OF_STACK
+ nop
+
+ ;
+ ; Setup parameters and call SecCoreStartupWithStack
+ ; rcx: BootFirmwareVolumePtr
+ ; rdx: TopOfCurrentStack
+ ;
+ mov rcx, rbp
+ mov rdx, rsp
+ sub rsp, 0x20
+ call ASM_PFX(SecCoreStartupWithStack)
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h
new file mode 100644
index 0000000000..bef801bd64
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.h
@@ -0,0 +1,37 @@
+/** @file
+ This driver effectuates QSP platform configuration settings and exposes
+ them via HII.
+
+ Copyright (C) 2014, Red Hat, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_H_
+#define _PLATFORM_H_
+
+//
+// Macro and type definitions that connect the form with the HII driver code.
+//
+#define FORMSTATEID_MAIN_FORM 1
+#define FORMID_MAIN_FORM 1
+
+#define QUESTION_RES_CUR 1
+#define MAXSIZE_RES_CUR 16
+
+#define LABEL_RES_NEXT 1
+#define QUESTION_RES_NEXT 2
+
+#define QUESTION_SAVE_EXIT 3
+#define QUESTION_DISCARD_EXIT 4
+
+//
+// This structure describes the form state. Its fields relate strictly to the
+// visual widgets on the form.
+//
+typedef struct {
+ UINT16 CurrentPreferredResolution[MAXSIZE_RES_CUR];
+ UINT32 NextPreferredResolution;
+} MAIN_FORM_STATE;
+
+#endif // _PLATFORM_H_
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.uni b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.uni
new file mode 100644
index 0000000000..6d68cbeb4f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/Platform.uni
@@ -0,0 +1,31 @@
+// *++
+//
+// Copyright (C) 2014, Red Hat, Inc.
+// Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Module Name:
+//
+// Platform.uni
+//
+// Abstract:
+//
+// String definitions for PlatformForms.vfr
+//
+// --*/
+
+/=#
+
+#langdef en-US "English"
+
+#string STR_FORMSET_TITLE #language en-US "QSP Platform Configuration"
+#string STR_FORMSET_HELP #language en-US "Change various QSP platform settings."
+#string STR_MAIN_FORM_TITLE #language en-US "QSP Settings"
+#string STR_RES_CUR #language en-US "Preferred Resolution at Next Boot"
+#string STR_RES_CUR_HELP #language en-US "The preferred resolution of the Graphics Console at next boot. It might be unset, or even invalid (hence ignored) wrt. the video RAM size."
+#string STR_RES_NEXT #language en-US "Change Preferred Resolution for Next Boot"
+#string STR_RES_NEXT_HELP #language en-US "You can specify a new preference for the Graphics Console here. The list is filtered against the video RAM size."
+#string STR_SAVE_EXIT #language en-US "Commit Changes and Exit"
+#string STR_DISCARD_EXIT #language en-US "Discard Changes and Exit"
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h
new file mode 100644
index 0000000000..d3f041ddea
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformConfig.h
@@ -0,0 +1,51 @@
+/** @file
+ Utility functions for serializing (persistently storing) and deserializing
+ OVMF's platform configuration.
+
+ Copyright (C) 2014, Red Hat, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_CONFIG_H_
+#define _PLATFORM_CONFIG_H_
+
+#include <Base.h>
+
+//
+// This structure participates in driver configuration. It does not
+// (necessarily) reflect the wire format in the persistent store.
+//
+#pragma pack(1)
+typedef struct {
+ //
+ // preferred graphics console resolution when booting
+ //
+ UINT32 HorizontalResolution;
+ UINT32 VerticalResolution;
+} PLATFORM_CONFIG;
+#pragma pack()
+
+//
+// Please see the API documentation near the function definitions.
+//
+EFI_STATUS
+EFIAPI
+PlatformConfigSave (
+ IN PLATFORM_CONFIG *PlatformConfig
+ );
+
+EFI_STATUS
+EFIAPI
+PlatformConfigLoad (
+ OUT PLATFORM_CONFIG *PlatformConfig,
+ OUT UINT64 *OptionalElements
+ );
+
+//
+// Feature flags for OptionalElements.
+//
+#define PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION BIT0
+#define PLATFORM_CONFIG_F_DOWNGRADE BIT63
+
+#endif // _PLATFORM_CONFIG_H_
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr
new file mode 100644
index 0000000000..21bf9f5854
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/PlatformForms.vfr
@@ -0,0 +1,67 @@
+// *++
+//
+// Copyright (C) 2014, Red Hat, Inc.
+// Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Module Name:
+//
+// PlatformForms.vfr
+//
+// Abstract:
+//
+// Form definitions for exposing some of OVMF's platform knobs via HII.
+//
+// --*/
+
+#include <Guid/SimicsBoardConfig.h>
+#include "Platform.h"
+
+formset
+ guid = SIMICS_BOARD_CONFIG_GUID,
+ title = STRING_TOKEN(STR_FORMSET_TITLE),
+ help = STRING_TOKEN(STR_FORMSET_HELP),
+
+ varstore MAIN_FORM_STATE,
+ varid = FORMSTATEID_MAIN_FORM,
+ name = MainFormState,
+ guid = SIMICS_BOARD_CONFIG_GUID;
+
+ form
+ formid = FORMID_MAIN_FORM,
+ title = STRING_TOKEN(STR_MAIN_FORM_TITLE);
+
+ //
+ // Display the current preference in a read-only string field.
+ //
+ string
+ varid = MainFormState.CurrentPreferredResolution,
+ questionid = QUESTION_RES_CUR,
+ prompt = STRING_TOKEN(STR_RES_CUR),
+ help = STRING_TOKEN(STR_RES_CUR_HELP),
+ flags = READ_ONLY,
+ minsize = 0,
+ maxsize = MAXSIZE_RES_CUR,
+ endstring;
+
+ //
+ // We'll dynamically generate a one-of-many selection at this label.
+ //
+ label LABEL_RES_NEXT;
+
+ text
+ help = STRING_TOKEN(STR_SAVE_EXIT),
+ text = STRING_TOKEN(STR_SAVE_EXIT),
+ flags = INTERACTIVE,
+ key = QUESTION_SAVE_EXIT;
+
+ text
+ help = STRING_TOKEN(STR_DISCARD_EXIT),
+ text = STRING_TOKEN(STR_DISCARD_EXIT),
+ flags = INTERACTIVE,
+ key = QUESTION_DISCARD_EXIT;
+
+ endform;
+
+endformset;
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf
new file mode 100644
index 0000000000..39028e1a70
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsDxe/SimicsDxe.inf
@@ -0,0 +1,65 @@
+## @file
+# This driver effectuates Simics X58 platform configuration settings and exposes
+# them via HII.
+#
+# Copyright (C) 2014, Red Hat, Inc.
+# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SimicsDxe
+ FILE_GUID = 74B64DC1-B0B6-4853-A6BD-C6426059AB1E
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PlatformInit
+ UNLOAD_IMAGE = PlatformUnload
+
+[Sources]
+ Platform.c
+ Platform.uni
+ PlatformConfig.c
+ PlatformForms.vfr
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ DevicePathLib
+ HiiLib
+ MemoryAllocationLib
+ PrintLib
+ UefiBootServicesTableLib
+ UefiHiiServicesLib
+ UefiLib
+ UefiRuntimeServicesTableLib
+ UefiDriverEntryPoint
+ DxeServicesTableLib
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution
+
+[Protocols]
+ gEfiDevicePathProtocolGuid ## PRODUCES
+ gEfiGraphicsOutputProtocolGuid ## CONSUMES
+ gEfiHiiConfigAccessProtocolGuid ## PRODUCES
+
+[Guids]
+ gEfiIfrTianoGuid
+ gSimicsBoardConfigGuid
+
+[Depex]
+ gEfiHiiConfigRoutingProtocolGuid AND
+ gEfiHiiDatabaseProtocolGuid AND
+ gEfiVariableArchProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h
new file mode 100644
index 0000000000..07fa2e2d11
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Cmos.h
@@ -0,0 +1,50 @@
+/** @file
+ PC/AT CMOS access routines
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __CMOS_H__
+#define __CMOS_H__
+
+/**
+ Reads 8-bits of CMOS data.
+
+ Reads the 8-bits of CMOS data at the location specified by Index.
+ The 8-bit read value is returned.
+
+ @param Index The CMOS location to read.
+
+ @return The value read.
+
+**/
+UINT8
+EFIAPI
+CmosRead8 (
+ IN UINTN Index
+ );
+
+/**
+ Writes 8-bits of CMOS data.
+
+ Writes 8-bits of CMOS data to the location specified by Index
+ with the value specified by Value and returns Value.
+
+ @param Index The CMOS location to write.
+ @param Value The value to write to CMOS.
+
+ @return The value written to CMOS.
+
+**/
+UINT8
+EFIAPI
+CmosWrite8 (
+ IN UINTN Index,
+ IN UINT8 Value
+ );
+
+
+#endif
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h
new file mode 100644
index 0000000000..102d21cd64
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/Platform.h
@@ -0,0 +1,88 @@
+/** @file
+ Platform PEI module include file.
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PLATFORM_PEI_H_INCLUDED_
+#define _PLATFORM_PEI_H_INCLUDED_
+
+VOID
+AddIoMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize
+ );
+
+VOID
+AddIoMemoryRangeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ EFI_PHYSICAL_ADDRESS MemoryLimit
+ );
+
+VOID
+AddMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize
+ );
+
+VOID
+AddMemoryRangeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ EFI_PHYSICAL_ADDRESS MemoryLimit
+ );
+
+VOID
+AddUntestedMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize
+ );
+
+VOID
+AddReservedMemoryBaseSizeHob (
+ EFI_PHYSICAL_ADDRESS MemoryBase,
+ UINT64 MemorySize,
+ BOOLEAN Cacheable
+ );
+
+VOID
+AddressWidthInitialization (
+ VOID
+ );
+
+VOID
+X58TsegMbytesInitialization (
+ VOID
+ );
+
+EFI_STATUS
+PublishPeiMemory (
+ VOID
+ );
+
+UINT32
+GetSystemMemorySizeBelow4gb (
+ VOID
+ );
+
+VOID
+InitializeRamRegions (
+ VOID
+ );
+
+VOID
+InstallFeatureControlCallback (
+ VOID
+ );
+
+extern EFI_BOOT_MODE mBootMode;
+
+extern BOOLEAN mS3Supported;
+
+extern UINT8 mPhysMemAddressWidth;
+
+extern UINT32 mMaxCpuCount;
+
+extern UINT16 mHostBridgeDevId;
+#endif // _PLATFORM_PEI_H_INCLUDED_
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf
new file mode 100644
index 0000000000..ccc7037d75
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsPei/SimicsPei.inf
@@ -0,0 +1,104 @@
+## @file
+# Platform PEI driver
+#
+# This module provides platform specific function to detect boot mode.
+# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SimicsPei
+ FILE_GUID = 05116218-f9f1-41f8-8d17-c2207006ffff
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializePlatform
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ Cmos.c
+ FeatureControl.c
+ MemDetect.c
+ Platform.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ SimicsX58SktPkg/SktPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[Guids]
+ gEfiMemoryTypeInformationGuid
+ gEfiSmmPeiSmramMemoryReserveGuid ## CONSUMES
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ HobLib
+ IoLib
+ PciLib
+ PeiResourcePublicationLib
+ PeiServicesLib
+ PeiServicesTablePointerLib
+ PeimEntryPoint
+ MtrrLib
+ PcdLib
+
+[Pcd]
+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize
+ gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize
+ gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageSize
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
+ gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
+ gBoardModuleTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+ gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
+ gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
+ gBoardModuleTokenSpaceGuid.PcdPciIoBase
+ gBoardModuleTokenSpaceGuid.PcdPciIoSize
+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Base
+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Size
+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Base
+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Size
+ gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
+ gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
+ gMinPlatformPkgTokenSpaceGuid.PcdIoApicId
+
+[FixedPcd]
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+
+[Ppis]
+ gEfiPeiMasterBootModePpiGuid
+ gEfiPeiMpServicesPpiGuid
+
+[Depex]
+ TRUE
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h
new file mode 100644
index 0000000000..d679bcd631
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h
@@ -0,0 +1,38 @@
+/** @file
+ This driver installs SMBIOS information for QSP
+
+ Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>
+ Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SMBIOS_PLATFORM_DXE_H_
+#define _SMBIOS_PLATFORM_DXE_H_
+
+#include <PiDxe.h>
+
+#include <Protocol/Smbios.h>
+#include <IndustryStandard/SmBios.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/IoLib.h>
+
+/**
+ Validates the SMBIOS entry point structure
+
+ @param EntryPointStructure SMBIOS entry point structure
+
+ @retval TRUE The entry point structure is valid
+ @retval FALSE The entry point structure is not valid
+
+**/
+BOOLEAN
+IsEntryPointStructureValid (
+ IN SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure
+ );
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
new file mode 100644
index 0000000000..c5986049f1
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
@@ -0,0 +1,51 @@
+## @file
+# This driver installs SMBIOS information for QSP
+#
+# Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmbiosPlatformDxe
+ FILE_GUID = 4b18323d-2d42-4afa-b9e5-91516a6fe505
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = SmbiosTablePublishEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64
+#
+
+[Sources]
+ SmbiosPlatformDxe.h
+ SmbiosPlatformDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+ AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ BaseMemoryLib
+ BaseLib
+ UefiDriverEntryPoint
+ DebugLib
+ HobLib
+ MemoryAllocationLib
+ IoLib
+
+[Protocols]
+ gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+
+[Depex]
+ gEfiSmbiosProtocolGuid
+
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [edk2-platforms PATCH v2 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio
2019-08-28 0:40 ` [edk2-platforms PATCH v2 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio David Wei
@ 2019-08-28 22:56 ` Nate DeSimone
0 siblings, 0 replies; 16+ messages in thread
From: Nate DeSimone @ 2019-08-28 22:56 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Kubacki, Michael A, Kinney, Michael D
Reviewed-by: Nate DeSimone <nathaniel.l.desimone@intel.com>
-----Original Message-----
From: Wei, David Y
Sent: Tuesday, August 27, 2019 5:40 PM
To: devel@edk2.groups.io
Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Kubacki, Michael A <michael.a.kubacki@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: [edk2-platforms PATCH v2 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio
Add DXE driver for Legacy Sio support
Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../LegacySioDxe/ComponentName.c | 173 ++++++
.../SimicsOpenBoardPkg/LegacySioDxe/SioChip.c | 272 ++++++++++
.../SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c | 600 +++++++++++++++++++++
.../SimicsOpenBoardPkg/LegacySioDxe/SioService.c | 249 +++++++++
.../LegacySioDxe/ComponentName.h | 87 +++
.../LegacySioDxe/LegacySioDxe.inf | 54 ++
.../SimicsOpenBoardPkg/LegacySioDxe/Register.h | 15 +
.../SimicsOpenBoardPkg/LegacySioDxe/SioChip.h | 195 +++++++
.../SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h | 134 +++++
.../SimicsOpenBoardPkg/LegacySioDxe/SioService.h | 143 +++++
10 files changed, 1922 insertions(+)
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/LegacySioDxe.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.c b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.c
new file mode 100644
index 0000000000..4ba02f92c0
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.c
@@ -0,0 +1,173 @@
+/** @file
+ Install Base and Size Info Ppi for Firmware Volume Recovery.
+
+ Copyright (c) 2013 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SioDriver.h"
+
+///
+/// Component Name Protocol instance
+///
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL mSioComponentName = {
+ SioComponentNameGetDriverName,
+ SioComponentNameGetControllerName,
+ "eng"
+};
+
+///
+/// Component Name 2 Protocol instance
+///
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL mSioComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) SioComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)SioComponentNameGetControllerName,
+ "en"
+};
+
+///
+/// Table of driver names
+///
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSioDriverNameTable[] = {
+ {
+ "eng;en",
+ L"Super I/O Driver"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+///
+/// Table of Controller names
+///
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSioControllerNameTable[] = {
+ {
+ "eng;en",
+ L"Super I/O Controller"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+/**
+ Retrieves a Unicode string that is the user-readable name of the EFI Driver.
+
+ @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param Language A pointer to a three-character ISO 639-2 language identifier.
+ This is the language of the driver name that that the caller
+ is requesting, and it must match one of the languages specified
+ in SupportedLanguages. The number of languages supported by a
+ driver is up to the driver writer.
+ @param DriverName A pointer to the Unicode string to return. This Unicode string
+ is the name of the driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the
+ language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+SioComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mSioDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &mSioComponentName)
+ );
+}
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param ControllerHandle The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ @param ChildHandle The handle of the child controller to retrieve the name
+ of. This is an optional parameter that may be NULL. It
+ will be NULL for device drivers. It will also be NULL
+ for a bus drivers that wish to retrieve the name of the
+ bus controller. It will not be NULL for a bus driver
+ that wishes to retrieve the name of a child controller.
+ @param Language A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that the caller is requesting, and it must match one
+ of the languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up to the
+ driver writer.
+ @param ControllerName A pointer to the Unicode string to return. This Unicode
+ string is the name of the controller specified by
+ ControllerHandle and ChildHandle in the language specified
+ by Language, from the point of view of the driver specified
+ by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user-readable name in the
+ language specified by Language for the driver
+ specified by This was returned in DriverName.
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently managing
+ the controller specified by ControllerHandle and
+ ChildHandle.
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the
+ language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+SioComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Make sure this driver is currently managing ControllHandle
+ //
+ Status = EfiTestManagedDevice (
+ ControllerHandle,
+ mSioDriver.DriverBindingHandle,
+ &gEfiPciIoProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // ChildHandle must be NULL for a Device Driver
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mSioControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &mSioComponentName)
+ );
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c
new file mode 100644
index 0000000000..b9a7b9cd24
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c
@@ -0,0 +1,272 @@
+/** @file
+ Super I/O specific implementation.
+
+ Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SioDriver.h"
+#include <Library/S3IoLib.h>
+
+LOCAL_IO_WRITE8 mIoWrite8 = IoWrite8;
+//
+// System configuration (setup) information
+//
+// SYSTEM_CONFIGURATION mSystemConfiguration;
+
+//
+// COM 1 UART Controller
+//
+ACPI_SIO_RESOURCES_IO_IRQ mCom1Resources = {
+ {
+ { ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR },
+ 0x3f8,
+ 8
+ },
+ {
+ { ACPI_IRQ_NOFLAG_DESCRIPTOR },
+ BIT4 // IRQ4
+ },
+ {
+ ACPI_END_TAG_DESCRIPTOR,
+ 0
+ }
+};
+
+//
+// PS/2 Keyboard Controller
+//
+ACPI_SIO_RESOURCES_IO_IRQ mKeyboardResources = {
+ {
+ { ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR },
+ 0x60,
+ 5
+ },
+ {
+ { ACPI_IRQ_NOFLAG_DESCRIPTOR },
+ BIT1
+ },
+ {
+ ACPI_END_TAG_DESCRIPTOR,
+ 0
+ }
+};
+
+//
+// PS/2 Mouse Controller
+//
+ACPI_SIO_RESOURCES_IO_IRQ mMouseResources = {
+ {
+ { ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR },
+ 0x60,
+ 5
+ },
+ {
+ { ACPI_IRQ_NOFLAG_DESCRIPTOR },
+ BIT12
+ },
+ {
+ ACPI_END_TAG_DESCRIPTOR,
+ 0
+ }
+};
+
+//
+// Table of SIO Controllers
+//
+DEVICE_INFO mDeviceInfo[] = {
+ {
+ {
+ EISA_PNP_ID(0x501),
+ 0
+ },
+ 0,
+ RESOURCE_IO | RESOURCE_IRQ,
+ { (ACPI_SMALL_RESOURCE_HEADER *) &mCom1Resources },
+ { (ACPI_SMALL_RESOURCE_HEADER *) &mCom1Resources }
+ }, // COM 1 UART Controller
+ {
+ {
+ EISA_PNP_ID(0x303),
+ 0
+ },
+ 0,
+ 0, // Cannot change resource
+ { (ACPI_SMALL_RESOURCE_HEADER *) &mKeyboardResources },
+ { (ACPI_SMALL_RESOURCE_HEADER *) &mKeyboardResources }
+ }, // PS/2 Keyboard Controller
+ {
+ {
+ EISA_PNP_ID(0xF03),
+ 0
+ },
+ 0,
+ 0, // Cannot change resource
+ { (ACPI_SMALL_RESOURCE_HEADER *) &mMouseResources },
+ { (ACPI_SMALL_RESOURCE_HEADER *) &mMouseResources }
+ } // PS/2 Mouse Controller
+};
+
+
+/**
+ Return the supported devices.
+
+ @param[out] Devices Pointer to pointer of EFI_SIO_ACPI_DEVICE_ID.
+ Caller is responsible to free the buffer.
+ @param[out] Count Pointer to UINTN holding the device count.
+**/
+VOID
+DeviceGetList (
+ OUT EFI_SIO_ACPI_DEVICE_ID **Devices,
+ OUT UINTN *Count
+ )
+{
+ EFI_SIO_ACPI_DEVICE_ID *LocalDevices;
+ UINTN LocalCount;
+ UINTN DeviceCount;
+ UINTN Index;
+
+ //
+ // Allocate enough memory for simplicity
+ //
+ DeviceCount = sizeof (mDeviceInfo) / sizeof (mDeviceInfo[0]);
+ LocalDevices = AllocatePool (sizeof (EFI_SIO_ACPI_DEVICE_ID) * DeviceCount);
+ ASSERT (LocalDevices != NULL);
+ if (LocalDevices == NULL) {
+ return;
+ }
+ LocalCount = 0;
+
+ for (Index = 0; Index < DeviceCount; Index++) {
+ CopyMem (&LocalDevices[LocalCount], &mDeviceInfo[Index].Device, sizeof (EFI_SIO_ACPI_DEVICE_ID));
+ LocalCount++;
+ }
+
+ *Devices = LocalDevices;
+ *Count = LocalCount;
+}
+
+
+/**
+ Super I/O controller initialization.
+
+ @retval EFI_SUCCESS The super I/O controller is found and initialized.
+ @retval EFI_UNSUPPORTED The super I/O controller is not found.
+**/
+EFI_STATUS
+SioInit (
+ VOID
+ )
+{
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Find the DEVICE_INFO for specified Device.
+
+ @param[in] Device Pointer to the EFI_SIO_ACPI_DEVICE_ID.
+
+ @retval DEVICE_INFO* Pointer to the DEVICE_INFO.
+**/
+DEVICE_INFO *
+DeviceSearch (
+ IN EFI_SIO_ACPI_DEVICE_ID *Device
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < sizeof (mDeviceInfo) / sizeof (mDeviceInfo[0]); Index++) {
+ if (CompareMem (Device, &mDeviceInfo[Index].Device, sizeof (*Device)) == 0) {
+ return &mDeviceInfo[Index];
+ }
+ }
+
+ ASSERT (FALSE);
+ return NULL;
+}
+
+
+/**
+ Program the SIO chip to enable the specified device using the default resource.
+
+ @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID.
+**/
+VOID
+DeviceEnable (
+ IN EFI_SIO_ACPI_DEVICE_ID *Device
+ )
+{
+}
+
+
+/**
+ Get the ACPI resources for specified device.
+
+ @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID.
+ @param[out] Resources Pointer to ACPI_RESOURCE_HEADER_PTR.
+
+ @retval EFI_SUCCESS The resources are returned successfully.
+**/
+EFI_STATUS
+DeviceGetResources (
+ IN EFI_SIO_ACPI_DEVICE_ID *Device,
+ OUT ACPI_RESOURCE_HEADER_PTR *Resources
+ )
+{
+ DEVICE_INFO *DeviceInfo;
+
+ DeviceInfo = DeviceSearch (Device);
+
+ *Resources = DeviceInfo->Resources;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Set the ACPI resources for specified device.
+
+ The SIO chip is programmed to use the new resources and the
+ resources setting are saved. The function assumes the resources
+ are valid.
+
+ @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID.
+ @param[in] Resources ACPI_RESOURCE_HEADER_PTR.
+
+ @retval EFI_UNSUPPORTED
+**/
+EFI_STATUS
+DeviceSetResources (
+ IN EFI_SIO_ACPI_DEVICE_ID *Device,
+ IN ACPI_RESOURCE_HEADER_PTR Resources
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+/**
+ Get the possible ACPI resources for specified device.
+
+ @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID.
+ @param[out] Resources Pointer to ACPI_RESOURCE_HEADER_PTR.
+
+ @retval EFI_SUCCESS The resources are returned successfully.
+**/
+EFI_STATUS
+DevicePossibleResources (
+ IN EFI_SIO_ACPI_DEVICE_ID *Device,
+ OUT ACPI_RESOURCE_HEADER_PTR *Resources
+ )
+{
+ DEVICE_INFO *DeviceInfo;
+
+ DeviceInfo = DeviceSearch (Device);
+
+ *Resources = DeviceInfo->PossibleResources;
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c
new file mode 100644
index 0000000000..408c6ff301
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c
@@ -0,0 +1,600 @@
+/** @file
+ EFI Driver following Driver Binding Protocol.
+
+ Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SioDriver.h"
+
+
+//
+// This driver is for ACPI(PNP0A03,0)/PCI(0x1f,0)
+//
+//
+// Sio Driver Global Variables
+//
+EFI_DRIVER_BINDING_PROTOCOL mSioDriver = {
+ SioDriverSupported,
+ SioDriverStart,
+ SioDriverStop,
+ 1,
+ NULL,
+ NULL
+};
+
+//
+// The list of the created SIO_DEV
+//
+LIST_ENTRY mSioDevPool = INITIALIZE_LIST_HEAD_VARIABLE (mSioDevPool);
+
+//
+// Template structure to create SIO_DEV
+//
+SIO_DEV mSioDevTemplate = {
+ SIO_DEV_SIGNATURE, // Signature
+ NULL, // PciHandle
+ {
+ 0x00000000, // HID
+ 0x00000000 // UID
+ },
+ NULL, // Handle
+ { // Sio Instance
+ SioRegisterAccess,
+ SioGetResources,
+ SioSetResources,
+ SioPossibleResources,
+ SioModify
+ },
+ NULL, // DevicePath
+ {
+ NULL, // ForwardLink
+ NULL, // BackLink
+ }
+};
+
+//
+// Template ACPI_HID_DEVICE_PATH structure to create device path
+//
+ACPI_HID_DEVICE_PATH mAcpiNodeTemplate = {
+ {
+ ACPI_DEVICE_PATH, // Type
+ ACPI_DP, // SubType
+ {
+ sizeof (ACPI_HID_DEVICE_PATH), // Length[0]
+ 0 // Length[1]
+ }
+ },
+ 0x00000000, // HID
+ 0x00000000 // UID
+};
+
+
+/**
+ The user Entry Point for module Lpc47m17x. The user code starts with this function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+**/
+EFI_STATUS
+EFIAPI
+SioDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ if (EFI_ERROR (SioInit())) {
+ return EFI_UNSUPPORTED;
+ } else {
+
+ //
+ // Install protocols
+ //
+ return EfiLibInstallDriverBindingComponentName2 (
+ ImageHandle,
+ SystemTable,
+ &mSioDriver,
+ ImageHandle,
+ &mSioComponentName,
+ &mSioComponentName2
+ );
+ }
+}
+
+
+/**
+ Test to see if this driver supports Controller Handle.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] Controller Handle of device to test
+ @param[in] RemainingDevicePath Optional parameter use to pick a specific child
+ device to start.
+
+ @retval EFI_SUCCESS This driver supports this device
+ @retval EFI_ALREADY_STARTED This driver is already running on this device
+ @retval other This driver does not support this device
+**/
+EFI_STATUS
+EFIAPI
+SioDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ ACPI_HID_DEVICE_PATH *AcpiNode;
+ PCI_TYPE00 Pci;
+ UINTN Index;
+ EFI_SIO_ACPI_DEVICE_ID *Devices;
+ UINTN Count;
+ UINTN SegmentNumber;
+ UINTN BusNumber;
+ UINTN DeviceNumber;
+ UINTN FunctionNumber;
+
+ //
+ // If RemainingDevicePath is not NULL, it should verify that the first device
+ // path node in RemainingDevicePath is an ACPI Device path node which is a
+ // legal Device Path Node for this bus driver's children.
+ //
+ if (RemainingDevicePath != NULL) {
+ if (!IsDevicePathEnd (RemainingDevicePath)) {
+ if ((RemainingDevicePath->Type != ACPI_DEVICE_PATH) ||
+ (((RemainingDevicePath->SubType != ACPI_DP) || (DevicePathNodeLength (RemainingDevicePath) != sizeof (ACPI_HID_DEVICE_PATH))) &&
+ ((RemainingDevicePath->SubType != ACPI_EXTENDED_DP) || (DevicePathNodeLength (RemainingDevicePath) != sizeof (ACPI_EXTENDED_HID_DEVICE_PATH))))
+ ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ DeviceGetList (&Devices, &Count);
+ if (Devices == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ AcpiNode = (ACPI_HID_DEVICE_PATH *) RemainingDevicePath;
+ for (Index = 0; Index < Count; Index++) {
+ if ((AcpiNode->HID == Devices[Index].HID) &&
+ (AcpiNode->UID == Devices[Index].UID)) {
+ break;
+ }
+ }
+ FreePool (Devices);
+ if (Index == Count) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+ }
+
+ //
+ // See if the parent device path can be opened BY_DRIVER
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &ParentDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
+ return Status;
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ //
+ // Get PciIo protocol instance
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (!EFI_ERROR (Status)) {
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ sizeof (Pci) / sizeof (UINT32),
+ &Pci
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = EFI_UNSUPPORTED;
+ if ((Pci.Hdr.Command & (EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_MEMORY_SPACE))
+ == (EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_MEMORY_SPACE)
+ ) {
+ if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {
+ //
+ // See if this is a standard PCI to ISA Bridge from the Base Code and Class Code
+ //
+ if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA) {
+ Status = EFI_SUCCESS;
+ }
+
+ //
+ // See if this is an Intel PCI to ISA Bridge in Positive Decode Mode
+ //
+ if ((Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE) &&
+ (Pci.Hdr.VendorId == 0x8086)) {
+ //
+ // See if this is on Function #0 to avoid false positive on
+ // PCI_CLASS_BRIDGE_OTHER that has the same value as
+ // PCI_CLASS_BRIDGE_ISA_PDECODE
+ //
+ Status = PciIo->GetLocation (
+ PciIo,
+ &SegmentNumber,
+ &BusNumber,
+ &DeviceNumber,
+ &FunctionNumber
+ );
+ if (!EFI_ERROR (Status) && (FunctionNumber == 0)) {
+ Status = EFI_SUCCESS;
+ } else {
+ Status = EFI_UNSUPPORTED;
+ }
+ }
+ }
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ }
+ if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Destroy the SIO controller handle.
+
+ @param[in] ChildHandle The SIO controller handle.
+
+ @retval EFI_SUCCESS The SIO controller handle is destroyed successfully.
+**/
+EFI_STATUS
+SioDestroyDevice (
+ IN EFI_HANDLE ChildHandle
+ )
+{
+ EFI_STATUS Status;
+ SIO_DEV *SioDev;
+ EFI_SIO_PROTOCOL *Sio;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+
+ Status = gBS->HandleProtocol (
+ ChildHandle,
+ &gEfiSioProtocolGuid,
+ (VOID **) &Sio
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ SioDev = SIO_DEV_FROM_THIS (Sio);
+
+ Status = gBS->CloseProtocol (
+ SioDev->PciHandle,
+ &gEfiPciIoProtocolGuid,
+ mSioDriver.DriverBindingHandle,
+ ChildHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ ChildHandle,
+ &gEfiDevicePathProtocolGuid,
+ SioDev->DevicePath,
+ &gEfiSioProtocolGuid,
+ &SioDev->Sio,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->OpenProtocol (
+ SioDev->PciHandle,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ mSioDriver.DriverBindingHandle,
+ ChildHandle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ return Status;
+ }
+
+ RemoveEntryList (&SioDev->Link);
+ FreePool (SioDev->DevicePath);
+ FreePool (SioDev);
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Create the SIO controller handle.
+
+ @param[in] Controller The parent PCI controller handle.
+ @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID.
+ @param[in] ParentDevicePath The device path of the parent controller.
+ @param[out] PciIo The PciIo instance of the parent controller.
+**/
+VOID
+SioCreateDevice (
+ IN EFI_HANDLE Controller,
+ IN EFI_SIO_ACPI_DEVICE_ID *Device,
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
+ OUT EFI_PCI_IO_PROTOCOL *PciIo
+ )
+{
+ EFI_STATUS Status;
+ SIO_DEV *SioDev;
+
+ DeviceEnable (Device);
+ SioDev = AllocateCopyPool (sizeof (SIO_DEV), &mSioDevTemplate);
+ ASSERT (SioDev != NULL);
+ if (SioDev == NULL) {
+ return;
+ }
+ InsertHeadList (&mSioDevPool, &SioDev->Link);
+
+ SioDev->PciHandle = Controller;
+
+ CopyMem (&SioDev->Device, Device, sizeof (*Device));
+
+ mAcpiNodeTemplate.HID = Device->HID;
+ mAcpiNodeTemplate.UID = Device->UID;
+ SioDev->DevicePath = AppendDevicePathNode (ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &mAcpiNodeTemplate);
+ ASSERT (SioDev->DevicePath != NULL);
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &SioDev->Handle,
+ &gEfiSioProtocolGuid, &SioDev->Sio,
+ &gEfiDevicePathProtocolGuid, SioDev->DevicePath,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ mSioDriver.DriverBindingHandle,
+ SioDev->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
+
+/**
+ Start this driver on ControllerHandle.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] Controller Handle of device to bind driver to
+ @param[in] RemainingDevicePath Optional parameter use to pick a specific child
+ device to start.
+
+ @retval EFI_SUCCESS This driver is added to ControllerHandle
+ @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
+ @retval other This driver does not support this device
+**/
+EFI_STATUS
+EFIAPI
+SioDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_SIO_ACPI_DEVICE_ID *Devices;
+ SIO_DEV *SioDev;
+ UINTN Count;
+ UINTN Index;
+ ACPI_HID_DEVICE_PATH *AcpiNode;
+ BOOLEAN *HasCreated;
+ BOOLEAN *RequestCreate;
+ LIST_ENTRY *Node;
+
+ HasCreated = NULL;
+ RequestCreate = NULL;
+ //
+ // Get the ISA bridge's Device Path
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &ParentDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+ return Status;
+ }
+
+ //
+ // Get Pci IO
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ return Status;
+ }
+
+ if ((RemainingDevicePath != NULL) && IsDevicePathEnd (RemainingDevicePath)) {
+ return EFI_SUCCESS;
+ }
+
+ DeviceGetList (&Devices, &Count);
+ if (Devices == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit_Start;
+ }
+ HasCreated = AllocatePool (sizeof (BOOLEAN) * Count);
+ ASSERT (HasCreated != NULL);
+ if (HasCreated == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit_Start;
+ }
+ RequestCreate = AllocatePool (sizeof (BOOLEAN) * Count);
+ ASSERT (RequestCreate != NULL);
+ if (RequestCreate == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit_Start;
+ }
+
+ //
+ // Assume no children has been created.
+ // Assume the SIO interface hasn't been initialized.
+ //
+ ZeroMem (HasCreated, sizeof (BOOLEAN) * Count);
+
+ if (Status == EFI_ALREADY_STARTED) {
+ for (Node = GetFirstNode (&mSioDevPool);
+ !IsNull (&mSioDevPool, Node);
+ Node = GetNextNode (&mSioDevPool, Node)
+ ) {
+ SioDev = CR (Node, SIO_DEV, Link, SIO_DEV_SIGNATURE);
+ Status = gBS->HandleProtocol (
+ SioDev->PciHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &DevicePath
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // See if they are under the same PCI to ISA Bridge
+ //
+ if (CompareMem (DevicePath, ParentDevicePath, GetDevicePathSize (DevicePath)) == 0) {
+ for (Index = 0; Index < Count; Index++) {
+ if (CompareMem (&SioDev->Device, &Devices[Index], sizeof (EFI_SIO_ACPI_DEVICE_ID)) == 0) {
+ HasCreated[Index] = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ AcpiNode = (ACPI_HID_DEVICE_PATH *) RemainingDevicePath;
+ for (Index = 0; Index < Count; Index++) {
+ if ((AcpiNode == NULL) ||
+ ((AcpiNode->HID == Devices[Index].HID) && (AcpiNode->UID == Devices[Index].UID))
+ ) {
+ RequestCreate[Index] = TRUE;
+ } else {
+ RequestCreate[Index] = FALSE;
+ }
+ }
+
+ for (Index = 0; Index < Count; Index++) {
+ if (RequestCreate[Index] && !HasCreated[Index]) {
+ SioCreateDevice (Controller, &Devices[Index], ParentDevicePath, PciIo);
+ }
+ }
+Exit_Start:
+ if (Devices != NULL) {
+ FreePool (Devices);
+ }
+ if (HasCreated != NULL) {
+ FreePool (HasCreated);
+ }
+ if (RequestCreate != NULL) {
+ FreePool (RequestCreate);
+ }
+
+ return Status;
+}
+
+
+/**
+ Stop this driver on ControllerHandle.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] Controller Handle of device to stop driver on
+ @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
+ children is zero stop the entire bus driver.
+ @param[in] ChildHandleBuffer List of Child Handles to Stop.
+
+ @retval EFI_SUCCESS This driver is removed ControllerHandle
+ @retval other This driver was not removed from this device
+**/
+EFI_STATUS
+EFIAPI
+SioDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ BOOLEAN AllChildrenStopped;
+
+ if (NumberOfChildren == 0) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ return EFI_SUCCESS;
+ }
+
+ AllChildrenStopped = TRUE;
+ for (Index = 0; Index < NumberOfChildren; Index++) {
+ Status = SioDestroyDevice (ChildHandleBuffer[Index]);
+ if (EFI_ERROR (Status)) {
+ AllChildrenStopped = FALSE;
+ }
+ }
+
+ if (AllChildrenStopped) {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_DEVICE_ERROR;
+ }
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c
new file mode 100644
index 0000000000..379002b833
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c
@@ -0,0 +1,249 @@
+/** @file
+ Super I/O Interface implementation.
+
+ Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "SioDriver.h"
+
+
+/**
+ Provides an interface to get a list of the current resources consumed by the device in the ACPI
+ Resource Descriptor format.
+
+ GetResources() returns a list of resources currently consumed by the device. The
+ ResourceList is a pointer to the buffer containing resource descriptors for the device. The
+ descriptors are in the format of Small or Large ACPI resource descriptor as defined by ACPI
+ specification (2.0 & 3.0). The buffer of resource descriptors is terminated with the 'End tag'
+ resource descriptor.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[out] ResourceList A pointer to an ACPI resource descriptor list that defines the current resources
+ used by the device. Type ACPI_RESOURCE_HEADER_PTR is defined in the "Related
+ Definitions" below.
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER ResourceList is NULL
+**/
+EFI_STATUS
+EFIAPI
+SioGetResources (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ OUT ACPI_RESOURCE_HEADER_PTR *ResourceList
+ )
+{
+ SIO_DEV *SioDev;
+
+ if (ResourceList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SioDev = SIO_DEV_FROM_THIS (This);
+
+ return DeviceGetResources (&SioDev->Device, ResourceList);
+}
+
+
+/**
+ Provides a collection of resource descriptor lists. Each resource descriptor list in the collection
+ defines a combination of resources that can potentially be used by the device.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[out] ResourceCollection Collection of the resource descriptor lists.
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER ResourceCollection is NULL
+**/
+EFI_STATUS
+EFIAPI
+SioPossibleResources (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ OUT ACPI_RESOURCE_HEADER_PTR *ResourceCollection
+ )
+{
+ SIO_DEV *SioDev;
+
+ if (ResourceCollection == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SioDev = SIO_DEV_FROM_THIS (This);
+
+ return DevicePossibleResources (&SioDev->Device, ResourceCollection);
+}
+
+
+/**
+ Sets the resources for the device.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] ResourceList Pointer to the ACPI resource descriptor list. Type ACPI_RESOURCE_HEADER_PTR
+ is defined in the "Related Definitions" section of
+ EFI_SIO_PROTOCOL.GetResources().
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER ResourceList is invalid
+ @retval EFI_ACCESS_DENIED Some of the resources in ResourceList are in use
+**/
+EFI_STATUS
+EFIAPI
+SioSetResources (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ IN ACPI_RESOURCE_HEADER_PTR ResourceList
+ )
+{
+ SIO_DEV *SioDev;
+ ACPI_RESOURCE_HEADER_PTR ResourcePtr;
+ ACPI_RESOURCE_HEADER_PTR ResourceCollection;
+ ACPI_RESOURCE_HEADER_PTR ResourcePtr2;
+ BOOLEAN Found;
+
+ ResourcePtr = ResourceList;
+ SioDev = SIO_DEV_FROM_THIS (This);
+
+ //
+ // Check whether the resource is in the possible resource collection
+ //
+ DevicePossibleResources (&SioDev->Device, &ResourceCollection);
+
+ while (ResourcePtr.SmallHeader->Byte != ACPI_END_TAG_DESCRIPTOR) {
+
+ Found = FALSE;
+ ResourcePtr2 = ResourceCollection;
+ while (ResourcePtr2.SmallHeader->Byte != ACPI_END_TAG_DESCRIPTOR) {
+ if (ResourcePtr2.SmallHeader->Bits.Type == 0) {
+ //
+ // Small Header
+ //
+ if (CompareMem (
+ ResourcePtr2.SmallHeader,
+ ResourcePtr.SmallHeader,
+ ResourcePtr2.SmallHeader->Bits.Length + sizeof (*ResourcePtr2.SmallHeader)
+ ) == 0) {
+ Found = TRUE;
+ break;
+ }
+
+ ResourcePtr2.SmallHeader = (ACPI_SMALL_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr2.SmallHeader
+ + ResourcePtr2.SmallHeader->Bits.Length
+ + sizeof (*ResourcePtr2.SmallHeader));
+
+ } else {
+ //
+ // Large Header
+ //
+ if (CompareMem (
+ ResourcePtr2.LargeHeader,
+ ResourcePtr.LargeHeader,
+ ResourcePtr2.LargeHeader->Length + sizeof (*ResourcePtr2.LargeHeader)
+ ) == 0) {
+ Found = TRUE;
+ break;
+ }
+
+ ResourcePtr2.LargeHeader = (ACPI_LARGE_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr2.LargeHeader
+ + ResourcePtr2.LargeHeader->Length
+ + sizeof (*ResourcePtr2.LargeHeader));
+ }
+ }
+
+ if (!Found) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ if (ResourcePtr.SmallHeader->Bits.Type == 0) {
+ ResourcePtr.SmallHeader = (ACPI_SMALL_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr.SmallHeader
+ + ResourcePtr.SmallHeader->Bits.Length
+ + sizeof (*ResourcePtr.SmallHeader));
+ } else {
+ ResourcePtr.LargeHeader = (ACPI_LARGE_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr.LargeHeader
+ + ResourcePtr.LargeHeader->Length
+ + sizeof (*ResourcePtr.LargeHeader));
+ }
+ }
+
+ //
+ // ResourceList can be set
+ //
+ return DeviceSetResources (&SioDev->Device, ResourceList);
+}
+
+
+/**
+ Provides a low level access to the registers for the Super I/O.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] Write Specifies the type of the register operation. If this parameter is TRUE,
+ Value is interpreted as an input parameter and the operation is a register write.
+ If this parameter is FALSE, Value is interpreted as an output parameter and the
+ operation is a register read.
+ @param[in] ExitCfgMode Exit Configuration Mode Indicator. If this parameter is set to TRUE, the
+ Super I/O driver will turn off configuration mode of the Super I/O prior to returning
+ from this function. If this parameter is set to FALSE, the Super I/O driver will
+ leave Super I/O in the configuration mode.
+ The Super I/O driver must track the current state of the Super I/O and enable the
+ configuration mode of Super I/O if necessary prior to register access.
+ @param[in] Register Register number.
+ @param[in, out] Value If Write is TRUE, Value is a pointer to the buffer containing the byte of data to be
+ written to the Super I/O register. If Write is FALSE, Value is a pointer to the
+ destination buffer for the byte of data to be read from the Super I/O register.
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER The Value is NULL
+ @retval EFI_INVALID_PARAMETER Invalid Register number
+**/
+EFI_STATUS
+EFIAPI
+SioRegisterAccess (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ IN BOOLEAN Write,
+ IN BOOLEAN ExitCfgMode,
+ IN UINT8 Register,
+ IN OUT UINT8 *Value
+ )
+{
+ if (Value == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Provides an interface for a table based programming of the Super I/O registers.
+
+ The Modify() function provides an interface for table based programming of the Super I/O
+ registers. This function can be used to perform programming of multiple Super I/O registers with a
+ single function call. For each table entry, the Register is read, its content is bitwise ANDed with
+ AndMask, and then ORed with OrMask before being written back to the Register. The Super
+ I/O driver must track the current state of the Super I/O and enable the configuration mode of Super I/
+ O if necessary prior to table processing. Once the table is processed, the Super I/O device has to be
+ returned to the original state.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] Command A pointer to an array of NumberOfCommands EFI_SIO_REGISTER_MODIFY
+ structures. Each structure specifies a single Super I/O register modify operation.
+ Type EFI_SIO_REGISTER_MODIFY is defined in the "Related Definitions" below.
+ @param[in] NumberOfCommands Number of elements in the Command array.
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER Command is NULL
+**/
+EFI_STATUS
+EFIAPI
+SioModify (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ IN CONST EFI_SIO_REGISTER_MODIFY *Command,
+ IN UINTN NumberOfCommands
+ )
+{
+
+ if (Command == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.h b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.h
new file mode 100644
index 0000000000..5368f94bcd
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/ComponentName.h
@@ -0,0 +1,87 @@
+/** @file
+ Install Base and Size Info Ppi for Firmware Volume Recovery.
+
+ Copyright (c) 2013 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+/**
+ Retrieves a Unicode string that is the user-readable name of the EFI Driver.
+
+ @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param Language A pointer to a three-character ISO 639-2 language identifier.
+ This is the language of the driver name that that the caller
+ is requesting, and it must match one of the languages specified
+ in SupportedLanguages. The number of languages supported by a
+ driver is up to the driver writer.
+ @param DriverName A pointer to the Unicode string to return. This Unicode string
+ is the name of the driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the
+ language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+SioComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param ControllerHandle The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ @param ChildHandle The handle of the child controller to retrieve the name
+ of. This is an optional parameter that may be NULL. It
+ will be NULL for device drivers. It will also be NULL
+ for a bus drivers that wish to retrieve the name of the
+ bus controller. It will not be NULL for a bus driver
+ that wishes to retrieve the name of a child controller.
+ @param Language A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that the caller is requesting, and it must match one
+ of the languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up to the
+ driver writer.
+ @param ControllerName A pointer to the Unicode string to return. This Unicode
+ string is the name of the controller specified by
+ ControllerHandle and ChildHandle in the language specified
+ by Language, from the point of view of the driver specified
+ by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user-readable name in the
+ language specified by Language for the driver
+ specified by This was returned in DriverName.
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently managing
+ the controller specified by ControllerHandle and
+ ChildHandle.
+ @retval EFI_UNSUPPORTED The driver specified by This does not support the
+ language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+SioComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/LegacySioDxe.inf b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/LegacySioDxe.inf
new file mode 100644
index 0000000000..275f36ca47
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/LegacySioDxe.inf
@@ -0,0 +1,54 @@
+## @file
+# Module information that produces the
+# EFI_SIO_PROTOCOL.
+#
+# Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = HitachiH8s2113Dxe
+ FILE_GUID = 7807E404-8281-4FF1-8457-0B54BABE263F
+ VERSION_STRING = 1.0
+ MODULE_TYPE = UEFI_DRIVER
+ ENTRY_POINT = SioDriverEntryPoint
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+ BaseLib
+ UefiLib
+ DebugLib
+ MemoryAllocationLib
+ PcdLib
+ DevicePathLib
+ IoLib
+ UefiDriverEntryPoint
+ UefiBootServicesTableLib
+ S3BootScriptLib
+ S3IoLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[Sources]
+ SioChip.c
+ SioChip.h
+ SioService.c
+ SioService.h
+ SioDriver.c
+ SioDriver.h
+ ComponentName.c
+
+[Protocols]
+ gEfiPciIoProtocolGuid ## CONSUMES
+ gEfiDevicePathProtocolGuid ## PRODUCES
+ gEfiSioProtocolGuid ## PRODUCES
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register.h b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register.h
new file mode 100644
index 0000000000..f61f713cf2
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register.h
@@ -0,0 +1,15 @@
+/** @file
+ Super I/O register definitions
+
+ Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _REGISTER_H_
+#define _REGISTER_H_
+
+#define EC_COMMAND_PORT 0x66
+#define EC_DATA_PORT 0x62
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h
new file mode 100644
index 0000000000..48e28c44b0
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h
@@ -0,0 +1,195 @@
+/** @file
+ Super I/O specific header.
+
+ Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SIO_H_
+#define _SIO_H_
+
+
+#include "Register.h"
+
+typedef
+UINT8
+(EFIAPI *LOCAL_IO_WRITE8) (
+ IN UINTN Port,
+ IN UINT8 Value
+ );
+
+#define RESOURCE_IO BIT0
+#define RESOURCE_IRQ BIT1
+#define RESOURCE_DMA BIT2
+#define RESOURCE_MEM BIT3
+
+#pragma pack(1)
+
+typedef struct {
+ EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR Io;
+ EFI_ACPI_IRQ_NOFLAG_DESCRIPTOR Irq;
+ EFI_ACPI_END_TAG_DESCRIPTOR End;
+} ACPI_SIO_RESOURCES_IO_IRQ;
+#pragma pack()
+
+typedef struct {
+ UINT32 HID;
+ UINT32 UID;
+} EFI_SIO_ACPI_DEVICE_ID;
+
+typedef struct {
+ EFI_SIO_ACPI_DEVICE_ID Device;
+ UINT8 DeviceId;
+ UINT8 ResourceMask;
+ ACPI_RESOURCE_HEADER_PTR Resources;
+ ACPI_RESOURCE_HEADER_PTR PossibleResources;
+} DEVICE_INFO;
+
+
+/**
+ Initialize the SIO chip for S3.
+**/
+VOID
+SioInitForS3 (
+ VOID
+ );
+
+
+/**
+ Return the supported devices.
+
+ @param[out] Devices Pointer to pointer of EFI_SIO_ACPI_DEVICE_ID.
+ Caller is responsible to free the buffer.
+ @param[out] Count Pointer to UINTN holding the device count.
+**/
+VOID
+DeviceGetList (
+ OUT EFI_SIO_ACPI_DEVICE_ID **Devices,
+ OUT UINTN *Count
+ );
+
+
+/**
+ Program the SIO chip to enable the specified device using the default resource.
+
+ @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID.
+**/
+VOID
+DeviceEnable (
+ IN EFI_SIO_ACPI_DEVICE_ID *Device
+ );
+
+
+/**
+ Get the possible ACPI resources for specified device.
+
+ @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID.
+ @param[out] Resources Pointer to ACPI_RESOURCE_HEADER_PTR.
+
+ @retval EFI_SUCCESS The resources are returned successfully.
+**/
+EFI_STATUS
+DevicePossibleResources (
+ IN EFI_SIO_ACPI_DEVICE_ID *Device,
+ OUT ACPI_RESOURCE_HEADER_PTR *Resources
+ );
+
+
+/**
+ Set the ACPI resources for specified device.
+
+ The SIO chip is programmed to use the new resources and the
+ resources setting are saved. The function assumes the resources
+ are valid.
+
+ @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID.
+ @param[in] Resources ACPI_RESOURCE_HEADER_PTR.
+
+ @retval EFI_SUCCESS The resources are set successfully.
+**/
+EFI_STATUS
+DeviceSetResources (
+ IN EFI_SIO_ACPI_DEVICE_ID *Device,
+ IN ACPI_RESOURCE_HEADER_PTR Resources
+ );
+
+
+/**
+ Get the ACPI resources for specified device.
+
+ @param[in] Device Pointer to EFI_SIO_ACPI_DEVICE_ID.
+ @param[out] Resources Pointer to ACPI_RESOURCE_HEADER_PTR.
+
+ @retval EFI_SUCCESS The resources are returned successfully.
+**/
+EFI_STATUS
+DeviceGetResources (
+ IN EFI_SIO_ACPI_DEVICE_ID *Device,
+ OUT ACPI_RESOURCE_HEADER_PTR *Resources
+ );
+
+
+/**
+ Program the SIO chip to enter the configure mode.
+**/
+VOID
+EnterConfigMode (
+ VOID
+ );
+
+
+/**
+ Program the SIO chip to exit the configure mode.
+**/
+VOID
+ExitConfigMode (
+ VOID
+ );
+
+
+/**
+ Perform a 8-bit I/O write to SIO register.
+
+ @param[in] Index The register index.
+ @param[in] Data The value to write to register.
+**/
+VOID
+WriteRegister (
+ IN UINT8 Index,
+ IN UINT8 Data
+ );
+
+
+/**
+ Perform a 8-bit I/O read from SIO register.
+
+ @param[in] Index The register index.
+
+ @retval Value The value written to the register.
+**/
+UINT8
+ReadRegister (
+ IN UINT8 Index
+ );
+
+//
+// Prototypes for the sio internal function
+//
+//
+// Internal function
+//
+
+
+/**
+ Find Super I/O controller.
+
+ @retval EFI_SUCCESS Super I/O controller exists.
+ @retval EFI_UNSUPPORTED Super I/O controller does not exist.
+**/
+EFI_STATUS
+SioInit (
+ VOID
+ );
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h
new file mode 100644
index 0000000000..2e75871f7f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h
@@ -0,0 +1,134 @@
+/** @file
+ Header file for Driver Binding Protocol.
+
+ Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SIO_DRIVER_H_
+#define _SIO_DRIVER_H_
+
+#include <PiDxe.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/PciLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+
+//
+// Driver Consumed Protocol Prototypes
+//
+#include <Protocol/DriverBinding.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/DevicePath.h>
+
+//
+// Driver Produced Protocol Prototypes
+//
+#include <Protocol/SuperIo.h>
+
+
+#include "SioChip.h"
+#include "SioService.h"
+#include "ComponentName.h"
+
+//
+// Global Variables definitions
+//
+extern EFI_DRIVER_BINDING_PROTOCOL mSioDriver;
+extern EFI_COMPONENT_NAME_PROTOCOL mSioComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL mSioComponentName2;
+
+//
+// SIO device private data structure
+//
+#define SIO_DEV_SIGNATURE SIGNATURE_32 ('_', 'S', 'I', 'O')
+
+typedef struct _SIO_DEV {
+ UINT32 Signature;
+ EFI_HANDLE PciHandle;
+ EFI_SIO_ACPI_DEVICE_ID Device;
+ EFI_HANDLE Handle;
+ EFI_SIO_PROTOCOL Sio;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ LIST_ENTRY Link;
+} SIO_DEV;
+
+#define SIO_DEV_FROM_THIS(a) CR (a, SIO_DEV, Sio, SIO_DEV_SIGNATURE)
+
+//
+// Prototypes for Driver model protocol interface
+//
+
+
+/**
+ Test to see if this driver supports Controller Handle.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] Controller Handle of device to test
+ @param[in] RemainingDevicePath Optional parameter use to pick a specific child
+ device to start.
+
+ @retval EFI_SUCCESS This driver supports this device
+ @retval EFI_ALREADY_STARTED This driver is already running on this device
+ @retval other This driver does not support this device
+**/
+EFI_STATUS
+EFIAPI
+SioDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+
+/**
+ Start this driver on ControllerHandle.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] Controller Handle of device to bind driver to
+ @param[in] RemainingDevicePath Optional parameter use to pick a specific child
+ device to start.
+
+ @retval EFI_SUCCESS This driver is added to ControllerHandle
+ @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
+ @retval other This driver does not support this device
+**/
+EFI_STATUS
+EFIAPI
+SioDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+
+/**
+ Stop this driver on ControllerHandle.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] Controller Handle of device to stop driver on
+ @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
+ children is zero stop the entire bus driver.
+ @param[in] ChildHandleBuffer List of Child Handles to Stop.
+
+ @retval EFI_SUCCESS This driver is removed ControllerHandle
+ @retval other This driver was not removed from this device
+**/
+EFI_STATUS
+EFIAPI
+SioDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h
new file mode 100644
index 0000000000..6a8081dc6e
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h
@@ -0,0 +1,143 @@
+/** @file
+ Super I/O Interface function declarations.
+
+ Copyright (c) 2010 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SIO_ACPI_H_
+#define _SIO_ACPI_H_
+
+//
+// Prototypes for the SIO protocol interface
+//
+
+
+/**
+ Provides an interface to get a list of the current resources consumed by the device in the ACPI
+ Resource Descriptor format.
+
+ GetResources() returns a list of resources currently consumed by the device. The
+ ResourceList is a pointer to the buffer containing resource descriptors for the device. The
+ descriptors are in the format of Small or Large ACPI resource descriptor as defined by ACPI
+ specification (2.0 & 3.0). The buffer of resource descriptors is terminated with the 'End tag'
+ resource descriptor.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[out] ResourceList A pointer to an ACPI resource descriptor list that defines the current resources
+ used by the device. Type ACPI_RESOURCE_HEADER_PTR is defined in the "Related
+ Definitions" below.
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER ResourceList is NULL
+**/
+EFI_STATUS
+EFIAPI
+SioGetResources (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ OUT ACPI_RESOURCE_HEADER_PTR *ResourceList
+ );
+
+
+/**
+ Sets the resources for the device.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] ResourceList Pointer to the ACPI resource descriptor list. Type ACPI_RESOURCE_HEADER_PTR
+ is defined in the "Related Definitions" section of
+ EFI_SIO_PROTOCOL.GetResources().
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER ResourceList is invalid
+ @retval EFI_ACCESS_DENIED Some of the resources in ResourceList are in use
+**/
+EFI_STATUS
+EFIAPI
+SioSetResources (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ IN ACPI_RESOURCE_HEADER_PTR ResourceList
+ );
+
+
+/**
+ Provides a collection of resource descriptor lists. Each resource descriptor list in the collection
+ defines a combination of resources that can potentially be used by the device.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[out] ResourceCollection Collection of the resource descriptor lists.
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER ResourceCollection is NULL
+**/
+EFI_STATUS
+EFIAPI
+SioPossibleResources (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ OUT ACPI_RESOURCE_HEADER_PTR *ResourceCollection
+ );
+
+
+/**
+ Provides a low level access to the registers for the Super I/O.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] Write Specifies the type of the register operation. If this parameter is TRUE,
+ Value is interpreted as an input parameter and the operation is a register write.
+ If this parameter is FALSE, Value is interpreted as an output parameter and the
+ operation is a register read.
+ @param[in] ExitCfgMode Exit Configuration Mode Indicator. If this parameter is set to TRUE, the
+ Super I/O driver will turn off configuration mode of the Super I/O prior to returning
+ from this function. If this parameter is set to FALSE, the Super I/O driver will
+ leave Super I/O in the configuration mode.
+ The Super I/O driver must track the current state of the Super I/O and enable the
+ configuration mode of Super I/O if necessary prior to register access.
+ @param[in] Register Register number.
+ @param[in, out] Value If Write is TRUE, Value is a pointer to the buffer containing the byte of data to be
+ written to the Super I/O register. If Write is FALSE, Value is a pointer to the
+ destination buffer for the byte of data to be read from the Super I/O register.
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER The Value is NULL
+ @retval EFI_INVALID_PARAMETER Invalid Register number
+**/
+EFI_STATUS
+EFIAPI
+SioRegisterAccess (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ IN BOOLEAN Write,
+ IN BOOLEAN ExitCfgMode,
+ IN UINT8 Register,
+ IN OUT UINT8 *Value
+ );
+
+
+/**
+ Provides an interface for a table based programming of the Super I/O registers.
+
+ The Modify() function provides an interface for table based programming of the Super I/O
+ registers. This function can be used to perform programming of multiple Super I/O registers with a
+ single function call. For each table entry, the Register is read, its content is bitwise ANDed with
+ AndMask, and then ORed with OrMask before being written back to the Register. The Super
+ I/O driver must track the current state of the Super I/O and enable the configuration mode of Super I/
+ O if necessary prior to table processing. Once the table is processed, the Super I/O device has to be
+ returned to the original state.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] Command A pointer to an array of NumberOfCommands EFI_SIO_REGISTER_MODIFY
+ structures. Each structure specifies a single Super I/O register modify operation.
+ Type EFI_SIO_REGISTER_MODIFY is defined in the "Related Definitions" below.
+ @param[in] NumberOfCommands Number of elements in the Command array.
+
+ @retval EFI_SUCCESS The operation completed successfully
+ @retval EFI_INVALID_PARAMETER Command is NULL
+**/
+EFI_STATUS
+EFIAPI
+SioModify (
+ IN CONST EFI_SIO_PROTOCOL *This,
+ IN CONST EFI_SIO_REGISTER_MODIFY *Command,
+ IN UINTN NumberOfCommands
+ );
+
+#endif
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [edk2-platforms PATCH v2 5/7] SimicsOpenBoardPkg: Add Overrides modules and Logo image for SIMICS QSP Platform
2019-08-28 0:40 ` [edk2-platforms PATCH v2 5/7] SimicsOpenBoardPkg: Add Overrides modules and Logo image for SIMICS QSP Platform David Wei
2019-08-28 3:01 ` Liming Gao
@ 2019-08-28 23:02 ` Nate DeSimone
1 sibling, 0 replies; 16+ messages in thread
From: Nate DeSimone @ 2019-08-28 23:02 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Kubacki, Michael A, Kinney, Michael D
1. Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec - Please use Pascal casing: gEfiOemBadgingProtocolGuid
2. Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c - Remove interspersed trailing white-space
-----Original Message-----
From: Wei, David Y
Sent: Tuesday, August 27, 2019 5:40 PM
To: devel@edk2.groups.io
Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Kubacki, Michael A <michael.a.kubacki@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: [edk2-platforms PATCH v2 5/7] SimicsOpenBoardPkg: Add Overrides modules and Logo image for SIMICS QSP Platform
Add overridden modules specific for SIMICS support.
Add SIMICS customized Logo image
Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c | 1579 ++++++++++++++++++++
.../MinPlatformPkg/Acpi/AcpiTables/Facs/Facs.c | 84 ++
.../MinPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.c | 359 +++++
.../MinPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.c | 78 +
.../MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c | 46 +
.../Overrides/OvmfPkg/QemuVideoDxe/ComponentName.c | 205 +++
.../Overrides/OvmfPkg/QemuVideoDxe/Driver.c | 1011 +++++++++++++
.../QemuVideoDxe/DriverSupportedEfiVersion.c | 15 +
.../Overrides/OvmfPkg/QemuVideoDxe/Gop.c | 416 ++++++
.../Overrides/OvmfPkg/QemuVideoDxe/Initialize.c | 341 +++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c | 302 ++++
Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp | Bin 0 -> 141078 bytes
Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec | 152 ++
.../MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h | 45 +
.../Acpi/AcpiTables/AcpiPlatform.inf | 105 ++
.../Overrides/OvmfPkg/QemuVideoDxe/Qemu.h | 507 +++++++
.../OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | 74 +
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm | 279 ++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h | 701 +++++++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh | 79 +
20 files changed, 6378 insertions(+)
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Facs/Facs.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/ComponentName.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driver.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/DriverSupportedEfiVersion.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Initialize.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qemu.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c
new file mode 100644
index 0000000000..f050d8afc0
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c
@@ -0,0 +1,1579 @@
+/** @file
+ ACPI Platform Driver
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "AcpiPlatform.h"
+
+#define MAX_CPU_NUM (FixedPcdGet32(PcdMaxCpuThreadCount) * FixedPcdGet32(PcdMaxCpuCoreCount) * FixedPcdGet32(PcdMaxCpuSocketCount))
+
+#pragma pack(1)
+
+typedef struct {
+ UINT32 AcpiProcessorId;
+ UINT32 ApicId;
+ UINT32 Flags;
+ UINT32 SwProcApicId;
+ UINT32 SocketNum;
+} EFI_CPU_ID_ORDER_MAP;
+
+//
+// Private Driver Data
+//
+//
+// Define Union of IO APIC & Local APIC structure;
+//
+typedef union {
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE AcpiLocalApic;
+ EFI_ACPI_4_0_IO_APIC_STRUCTURE AcpiIoApic;
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE AcpiLocalx2Apic;
+ struct {
+ UINT8 Type;
+ UINT8 Length;
+ } AcpiApicCommon;
+} ACPI_APIC_STRUCTURE_PTR;
+
+#pragma pack()
+
+extern EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE Facs;
+extern EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE Fadt;
+extern EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER Hpet;
+extern EFI_ACPI_WSMT_TABLE Wsmt;
+
+VOID *mLocalTable[] = {
+ &Facs,
+ &Fadt,
+ &Hpet,
+ &Wsmt,
+};
+
+EFI_ACPI_TABLE_PROTOCOL *mAcpiTable;
+
+UINT32 mNumOfBitShift = 6;
+BOOLEAN mForceX2ApicId;
+BOOLEAN mX2ApicEnabled;
+
+EFI_MP_SERVICES_PROTOCOL *mMpService;
+BOOLEAN mCpuOrderSorted;
+EFI_CPU_ID_ORDER_MAP mCpuApicIdOrderTable[MAX_CPU_NUM];
+UINTN mNumberOfCPUs = 0;
+UINTN mNumberOfEnabledCPUs = 0;
+//
+// following are possible APICID Map for SKX
+//
+static const UINT32 ApicIdMapA[] = { //for SKUs have number of core > 16
+ //it is 14 + 14 + 14 + 14 format
+ 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007,
+ 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x00000010, 0x00000011,
+ 0x00000012, 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, 0x00000018, 0x00000019,
+ 0x0000001A, 0x0000001B, 0x0000001C, 0x0000001D, 0x00000020, 0x00000021, 0x00000022, 0x00000023,
+ 0x00000024, 0x00000025, 0x00000026, 0x00000027, 0x00000028, 0x00000029, 0x0000002A, 0x0000002B,
+ 0x0000002C, 0x0000002D, 0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, 0x00000035,
+ 0x00000036, 0x00000037, 0x00000038, 0x00000039, 0x0000003A, 0x0000003B, 0x0000003C, 0x0000003D
+};
+
+static const UINT32 ApicIdMapB[] = { //for SKUs have number of cores <= 16 use 32 ID space
+ //
+ //it is 16+16 format
+ //
+ 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007,
+ 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F,
+ 0x00000010, 0x00000011, 0x00000012, 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017,
+ 0x00000018, 0x00000019, 0x0000001A, 0x0000001B, 0x0000001C, 0x0000001D, 0x0000001E, 0x0000001F,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+
+static const UINT32 ApicIdMapC[] = { //for SKUs have number of cores <= 16 use 64 ID space
+ //
+ //it is 16+0+16+0 format
+ //
+ 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007,
+ 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F,
+ 0x00000020, 0x00000021, 0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000026, 0x00000027,
+ 0x00000028, 0x00000029, 0x0000002A, 0x0000002B, 0x0000002C, 0x0000002D, 0x0000002E, 0x0000002F,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+static const UINT32 ApicIdMapD[] = { //for SKUs have number of cores <= 8 use 16 ID space
+ //
+ //it is 16 format
+ //
+ 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007,
+ 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+const UINT32 *mApicIdMap = NULL;
+
+/**
+ This function detect the APICID map and update ApicID Map pointer
+
+ @param None
+
+ @retval VOID
+
+**/
+VOID DetectApicIdMap(VOID)
+{
+ UINTN CoreCount;
+
+ CoreCount = 0;
+
+ if(mApicIdMap != NULL) {
+ return; //aleady initialized
+ }
+
+ mApicIdMap = ApicIdMapA; // default to > 16C SKUs
+
+ CoreCount = mNumberOfEnabledCPUs / 2;
+ DEBUG ((DEBUG_INFO, "CoreCount - %d\n", CoreCount));
+
+ if(CoreCount <= 16) {
+
+ if(mNumOfBitShift == 4) {
+ mApicIdMap = ApicIdMapD;
+ }
+
+ if(mNumOfBitShift == 5) {
+ mApicIdMap = ApicIdMapB;
+ }
+
+ if(mNumOfBitShift == 6) {
+ mApicIdMap = ApicIdMapC;
+ }
+
+ }
+
+ return;
+}
+
+/**
+ This function return the CoreThreadId of ApicId from ACPI ApicId Map array
+
+ @param ApicId
+
+ @retval Index of ACPI ApicId Map array
+
+**/
+UINT32
+GetIndexFromApicId (
+ UINT32 ApicId
+ )
+{
+ UINT32 CoreThreadId;
+ UINT32 i;
+
+ ASSERT (mApicIdMap != NULL);
+
+ CoreThreadId = ApicId & ((1 << mNumOfBitShift) - 1);
+
+ for(i = 0; i < (FixedPcdGet32(PcdMaxCpuCoreCount) * FixedPcdGet32(PcdMaxCpuThreadCount)); i++) {
+ if(mApicIdMap[i] == CoreThreadId) {
+ break;
+ }
+ }
+
+ ASSERT (i <= (FixedPcdGet32(PcdMaxCpuCoreCount) * FixedPcdGet32(PcdMaxCpuThreadCount)));
+
+ return i;
+}
+
+UINT32
+ApicId2SwProcApicId (
+ UINT32 ApicId
+ )
+{
+ UINT32 Index;
+
+ for (Index = 0; Index < MAX_CPU_NUM; Index++) {
+ if ((mCpuApicIdOrderTable[Index].Flags == 1) && (mCpuApicIdOrderTable[Index].ApicId == ApicId)) {
+ return Index;
+ }
+ }
+
+ return (UINT32) -1;
+
+}
+
+VOID
+DebugDisplayReOrderTable(
+ VOID
+ )
+{
+ UINT32 Index;
+
+ DEBUG ((EFI_D_ERROR, "Index AcpiProcId ApicId Flags SwApicId Skt\n"));
+ for (Index=0; Index<MAX_CPU_NUM; Index++) {
+ DEBUG ((EFI_D_ERROR, " %02d 0x%02X 0x%02X %d 0x%02X %d\n",
+ Index, mCpuApicIdOrderTable[Index].AcpiProcessorId,
+ mCpuApicIdOrderTable[Index].ApicId,
+ mCpuApicIdOrderTable[Index].Flags,
+ mCpuApicIdOrderTable[Index].SwProcApicId,
+ mCpuApicIdOrderTable[Index].SocketNum));
+ }
+}
+
+EFI_STATUS
+AppendCpuMapTableEntry (
+ IN VOID *ApicPtr,
+ IN UINT32 LocalApicCounter
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *LocalApicPtr;
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE *LocalX2ApicPtr;
+ UINT8 Type;
+
+ Status = EFI_SUCCESS;
+ Type = ((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiApicCommon.Type;
+ LocalApicPtr = (EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE *)(&((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiLocalApic);
+ LocalX2ApicPtr = (EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE *)(&((ACPI_APIC_STRUCTURE_PTR *)ApicPtr)->AcpiLocalx2Apic);
+
+ if(Type == EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC) {
+ if(!mX2ApicEnabled) {
+ LocalApicPtr->Flags = (UINT8)mCpuApicIdOrderTable[LocalApicCounter].Flags;
+ LocalApicPtr->ApicId = (UINT8)mCpuApicIdOrderTable[LocalApicCounter].ApicId;
+ LocalApicPtr->AcpiProcessorId = (UINT8)mCpuApicIdOrderTable[LocalApicCounter].AcpiProcessorId;
+ } else {
+ LocalApicPtr->Flags = 0;
+ LocalApicPtr->ApicId = 0xFF;
+ LocalApicPtr->AcpiProcessorId = (UINT8)0xFF;
+ Status = EFI_UNSUPPORTED;
+ }
+ } else if(Type == EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC) {
+ if(mX2ApicEnabled) {
+ LocalX2ApicPtr->Flags = (UINT8)mCpuApicIdOrderTable[LocalApicCounter].Flags;
+ LocalX2ApicPtr->X2ApicId = mCpuApicIdOrderTable[LocalApicCounter].ApicId;
+ LocalX2ApicPtr->AcpiProcessorUid = mCpuApicIdOrderTable[LocalApicCounter].AcpiProcessorId;
+ } else {
+ LocalX2ApicPtr->Flags = 0;
+ LocalX2ApicPtr->X2ApicId = (UINT32)-1;
+ LocalX2ApicPtr->AcpiProcessorUid = (UINT32)-1;
+ Status = EFI_UNSUPPORTED;
+ }
+ } else {
+ Status = EFI_UNSUPPORTED;
+ }
+
+ return Status;
+
+}
+
+EFI_STATUS
+SortCpuLocalApicInTable (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;
+ UINT32 Index;
+ UINT32 CurrProcessor;
+ UINT32 BspApicId;
+ UINT32 TempVal = 0;
+ EFI_CPU_ID_ORDER_MAP *CpuIdMapPtr;
+ UINT32 CoreThreadMask;
+
+ Index = 0;
+ Status = EFI_SUCCESS;
+
+ CoreThreadMask = (UINT32) ((1 << mNumOfBitShift) - 1);
+
+ if(!mCpuOrderSorted) {
+
+ Index = 0;
+
+ for (CurrProcessor = 0; CurrProcessor < mNumberOfCPUs; CurrProcessor++) {
+ Status = mMpService->GetProcessorInfo (
+ mMpService,
+ CurrProcessor,
+ &ProcessorInfoBuffer
+ );
+
+ if ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) != 0) {
+ if(ProcessorInfoBuffer.ProcessorId & 1) { //is 2nd thread
+ CpuIdMapPtr = (EFI_CPU_ID_ORDER_MAP *)&mCpuApicIdOrderTable[(Index - 1) + MAX_CPU_NUM / 2];
+ } else { //is primary thread
+ CpuIdMapPtr = (EFI_CPU_ID_ORDER_MAP *)&mCpuApicIdOrderTable[Index];
+ Index++;
+ }
+ CpuIdMapPtr->ApicId = (UINT32)ProcessorInfoBuffer.ProcessorId;
+ CpuIdMapPtr->Flags = ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) != 0);
+ CpuIdMapPtr->SocketNum = (UINT32)ProcessorInfoBuffer.Location.Package;
+ CpuIdMapPtr->AcpiProcessorId = (CpuIdMapPtr->SocketNum * FixedPcdGet32(PcdMaxCpuCoreCount) * FixedPcdGet32(PcdMaxCpuThreadCount)) + GetIndexFromApicId(CpuIdMapPtr->ApicId); //CpuIdMapPtr->ApicId;
+ CpuIdMapPtr->SwProcApicId = ((UINT32)(ProcessorInfoBuffer.Location.Package << mNumOfBitShift) + (((UINT32)ProcessorInfoBuffer.ProcessorId) & CoreThreadMask));
+ if(mX2ApicEnabled) { //if X2Apic, re-order the socket # so it starts from base 0 and contiguous
+ //may not necessory!!!!!
+ }
+
+ //update processorbitMask
+ if (CpuIdMapPtr->Flags == 1) {
+
+ if(mForceX2ApicId) {
+ CpuIdMapPtr->SocketNum &= 0x7;
+ CpuIdMapPtr->AcpiProcessorId &= 0xFF; //keep lower 8bit due to use Proc obj in dsdt
+ CpuIdMapPtr->SwProcApicId &= 0xFF;
+ }
+ }
+ } else { //not enabled
+ CpuIdMapPtr = (EFI_CPU_ID_ORDER_MAP *)&mCpuApicIdOrderTable[Index];
+ CpuIdMapPtr->ApicId = (UINT32)-1;
+ CpuIdMapPtr->Flags = 0;
+ CpuIdMapPtr->AcpiProcessorId = (UINT32)-1;
+ CpuIdMapPtr->SwProcApicId = (UINT32)-1;
+ CpuIdMapPtr->SocketNum = (UINT32)-1;
+ } //end if PROC ENABLE
+ } //end for CurrentProcessor
+ //
+ //keep for debug purpose
+ //
+ DEBUG(( EFI_D_ERROR, "::ACPI:: APIC ID Order Table Init. CoreThreadMask = %x, mNumOfBitShift = %x\n", CoreThreadMask, mNumOfBitShift));
+ DebugDisplayReOrderTable();
+ //
+ //make sure 1st entry is BSP
+ //
+ if(mX2ApicEnabled) {
+ BspApicId = (UINT32)AsmReadMsr64(0x802);
+ } else {
+ BspApicId = (*(volatile UINT32 *)(UINTN)0xFEE00020) >> 24;
+ }
+ DEBUG ((EFI_D_INFO, "BspApicId - 0x%x\n", BspApicId));
+
+ if(mCpuApicIdOrderTable[0].ApicId != BspApicId) {
+ //
+ //check to see if 1st entry is BSP, if not swap it
+ //
+ Index = ApicId2SwProcApicId(BspApicId);
+
+ if(MAX_CPU_NUM <= Index) {
+ DEBUG ((EFI_D_ERROR, "Asserting the SortCpuLocalApicInTable Index Bufferflow\n"));
+ ASSERT_EFI_ERROR(EFI_INVALID_PARAMETER);
+ }
+
+ TempVal = mCpuApicIdOrderTable[Index].ApicId;
+ mCpuApicIdOrderTable[Index].ApicId = mCpuApicIdOrderTable[0].ApicId;
+ mCpuApicIdOrderTable[0].ApicId = TempVal;
+ mCpuApicIdOrderTable[Index].Flags = mCpuApicIdOrderTable[0].Flags;
+ mCpuApicIdOrderTable[0].Flags = 1;
+ TempVal = mCpuApicIdOrderTable[Index].SwProcApicId;
+ mCpuApicIdOrderTable[Index].SwProcApicId = mCpuApicIdOrderTable[0].SwProcApicId;
+ mCpuApicIdOrderTable[0].SwProcApicId = TempVal;
+ //
+ //swap AcpiProcId
+ //
+ TempVal = mCpuApicIdOrderTable[Index].AcpiProcessorId;
+ mCpuApicIdOrderTable[Index].AcpiProcessorId = mCpuApicIdOrderTable[0].AcpiProcessorId;
+ mCpuApicIdOrderTable[0].AcpiProcessorId = TempVal;
+
+ }
+ //
+ //Make sure no holes between enabled threads
+ //
+ for(CurrProcessor = 0; CurrProcessor < MAX_CPU_NUM; CurrProcessor++) {
+
+ if(mCpuApicIdOrderTable[CurrProcessor].Flags == 0) {
+ //
+ //make sure disabled entry has ProcId set to FFs
+ //
+ mCpuApicIdOrderTable[CurrProcessor].ApicId = (UINT32)-1;
+ mCpuApicIdOrderTable[CurrProcessor].AcpiProcessorId = (UINT32)-1;
+ mCpuApicIdOrderTable[CurrProcessor].SwProcApicId = (UINT32)-1;
+
+ for(Index = CurrProcessor+1; Index < MAX_CPU_NUM; Index++) {
+ if(mCpuApicIdOrderTable[Index].Flags == 1) {
+ //
+ //move enabled entry up
+ //
+ mCpuApicIdOrderTable[CurrProcessor].Flags = 1;
+ mCpuApicIdOrderTable[CurrProcessor].ApicId = mCpuApicIdOrderTable[Index].ApicId;
+ mCpuApicIdOrderTable[CurrProcessor].AcpiProcessorId = mCpuApicIdOrderTable[Index].AcpiProcessorId;
+ mCpuApicIdOrderTable[CurrProcessor].SwProcApicId = mCpuApicIdOrderTable[Index].SwProcApicId;
+ mCpuApicIdOrderTable[CurrProcessor].SocketNum = mCpuApicIdOrderTable[Index].SocketNum;
+ //
+ //disable moved entry
+ //
+ mCpuApicIdOrderTable[Index].Flags = 0;
+ mCpuApicIdOrderTable[Index].ApicId = (UINT32)-1;
+ mCpuApicIdOrderTable[Index].AcpiProcessorId = (UINT32)-1;
+ mCpuApicIdOrderTable[Index].SwProcApicId = (UINT32)-1;
+ break;
+ }
+ }
+ }
+ }
+ //
+ //keep for debug purpose
+ //
+ DEBUG ((EFI_D_ERROR, "APIC ID Order Table ReOrdered\n"));
+ DebugDisplayReOrderTable();
+
+ mCpuOrderSorted = TRUE;
+ }
+
+ return Status;
+}
+
+
+/** Structure of a sub-structure of the ACPI header.
+
+ This structure contains the type and length fields, which are common to every
+ sub-structure of the ACPI tables. A pointer to any structure can be cast as this.
+**/
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+} STRUCTURE_HEADER;
+
+STRUCTURE_HEADER mMadtStructureTable[] = {
+ {EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC, sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE)},
+ {EFI_ACPI_4_0_IO_APIC, sizeof (EFI_ACPI_4_0_IO_APIC_STRUCTURE)},
+ {EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE, sizeof (EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE)},
+ {EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE, sizeof (EFI_ACPI_4_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE)},
+ {EFI_ACPI_4_0_LOCAL_APIC_NMI, sizeof (EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE)},
+ {EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE, sizeof (EFI_ACPI_4_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE)},
+ {EFI_ACPI_4_0_IO_SAPIC, sizeof (EFI_ACPI_4_0_IO_SAPIC_STRUCTURE)},
+ {EFI_ACPI_4_0_LOCAL_SAPIC, sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE)},
+ {EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES, sizeof (EFI_ACPI_4_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE)},
+ {EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC, sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE)},
+ {EFI_ACPI_4_0_LOCAL_X2APIC_NMI, sizeof (EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE)}
+};
+
+/**
+ Get the size of the ACPI table.
+
+ This function calculates the size needed for the ACPI Table based on the number and
+ size of the sub-structures that will compose it.
+
+ @param[in] TableSpecificHdrLength Size of the table specific header, not the ACPI standard header size.
+ @param[in] Structures Pointer to an array of sub-structure pointers.
+ @param[in] StructureCount Number of structure pointers in the array.
+
+ @return Total size needed for the ACPI table.
+**/
+UINT32
+GetTableSize (
+ IN UINTN TableSpecificHdrLength,
+ IN STRUCTURE_HEADER **Structures,
+ IN UINTN StructureCount
+ )
+{
+ UINT32 TableLength;
+ UINT32 Index;
+
+ //
+ // Compute size of the ACPI table; header plus all structures needed.
+ //
+ TableLength = (UINT32) TableSpecificHdrLength;
+
+ for (Index = 0; Index < StructureCount; Index++) {
+ ASSERT (Structures[Index] != NULL);
+ if (Structures[Index] == NULL) {
+ return 0;
+ }
+
+ TableLength += Structures[Index]->Length;
+ }
+
+ return TableLength;
+}
+
+/**
+ Allocate the ACPI Table.
+
+ This function allocates space for the ACPI table based on the number and size of
+ the sub-structures that will compose it.
+
+ @param[in] TableSpecificHdrLength Size of the table specific header, not the ACPI standard header size.
+ @param[in] Structures Pointer to an array of sub-structure pointers.
+ @param[in] StructureCount Number of structure pointers in the array.
+ @param[out] Table Newly allocated ACPI Table pointer.
+
+ @retval EFI_SUCCESS Successfully allocated the Table.
+ @retval EFI_OUT_OF_RESOURCES Space for the Table could not be allocated.
+**/
+EFI_STATUS
+AllocateTable (
+ IN UINTN TableSpecificHdrLength,
+ IN STRUCTURE_HEADER **Structures,
+ IN UINTN StructureCount,
+ OUT EFI_ACPI_DESCRIPTION_HEADER **Table
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Size;
+ EFI_ACPI_DESCRIPTION_HEADER *InternalTable;
+
+ //
+ // Get the size of the ACPI table and allocate memory.
+ //
+ Size = GetTableSize (TableSpecificHdrLength, Structures, StructureCount);
+ InternalTable = (EFI_ACPI_DESCRIPTION_HEADER *) AllocatePool (Size);
+
+ if (InternalTable == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ DEBUG ((
+ DEBUG_ERROR,
+ "Failed to allocate %d bytes for ACPI Table\n",
+ Size
+ ));
+ } else {
+ Status = EFI_SUCCESS;
+ DEBUG ((
+ DEBUG_INFO,
+ "Successfully allocated %d bytes for ACPI Table at 0x%p\n",
+ Size,
+ InternalTable
+ ));
+ *Table = InternalTable;
+ }
+
+ return Status;
+}
+
+/**
+ Initialize the header.
+
+ This function fills in the standard table header with correct values,
+ except for the length and checksum fields, which are filled in later.
+
+ @param[in,out] Header Pointer to the header structure.
+
+ @retval EFI_SUCCESS Successfully initialized the header.
+ @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+**/
+EFI_STATUS
+InitializeHeader (
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER *Header,
+ IN UINT32 Signature,
+ IN UINT8 Revision,
+ IN UINT32 OemRevision
+ )
+{
+ UINT64 AcpiTableOemId;
+
+ if (Header == NULL) {
+ DEBUG ((DEBUG_ERROR, "Header pointer is NULL\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Header->Signature = Signature;
+ Header->Length = 0; // filled in by Build function
+ Header->Revision = Revision;
+ Header->Checksum = 0; // filled in by InstallAcpiTable
+
+ CopyMem (
+ (VOID *) &Header->OemId,
+ PcdGetPtr (PcdAcpiDefaultOemId),
+ sizeof (Header->OemId)
+ );
+
+ AcpiTableOemId = PcdGet64 (PcdAcpiDefaultOemTableId);
+ CopyMem (
+ (VOID *) &Header->OemTableId,
+ (VOID *) &AcpiTableOemId,
+ sizeof (Header->OemTableId)
+ );
+
+ Header->OemRevision = OemRevision;
+ Header->CreatorId = 0;
+ Header->CreatorRevision = 0;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initialize the MADT header.
+
+ This function fills in the MADT's standard table header with correct values,
+ except for the length and checksum fields, which are filled in later.
+
+ @param[in,out] MadtHeader Pointer to the MADT header structure.
+
+ @retval EFI_SUCCESS Successfully initialized the MADT header.
+ @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+**/
+EFI_STATUS
+InitializeMadtHeader (
+ IN OUT EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *MadtHeader
+ )
+{
+ EFI_STATUS Status;
+
+ if (MadtHeader == NULL) {
+ DEBUG ((DEBUG_ERROR, "MADT header pointer is NULL\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = InitializeHeader (
+ &MadtHeader->Header,
+ EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
+ EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ MadtHeader->LocalApicAddress = PcdGet32(PcdLocalApicAddress);
+ MadtHeader->Flags = EFI_ACPI_4_0_PCAT_COMPAT;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Copy an ACPI sub-structure; MADT and SRAT supported
+
+ This function validates the structure type and size of a sub-structure
+ and returns a newly allocated copy of it.
+
+ @param[in] Header Pointer to the header of the table.
+ @param[in] Structure Pointer to the structure to copy.
+ @param[in] NewStructure Newly allocated copy of the structure.
+
+ @retval EFI_SUCCESS Successfully copied the structure.
+ @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+ @retval EFI_INVALID_PARAMETER Structure type was unknown.
+ @retval EFI_INVALID_PARAMETER Structure length was wrong for its type.
+ @retval EFI_UNSUPPORTED Header passed in is not supported.
+**/
+EFI_STATUS
+CopyStructure (
+ IN EFI_ACPI_DESCRIPTION_HEADER *Header,
+ IN STRUCTURE_HEADER *Structure,
+ OUT STRUCTURE_HEADER **NewStructure
+ )
+{
+ STRUCTURE_HEADER *NewStructureInternal;
+ STRUCTURE_HEADER *StructureTable;
+ UINTN TableNumEntries;
+ BOOLEAN EntryFound;
+ UINT8 Index;
+
+ //
+ // Initialize the number of table entries and the table based on the table header passed in.
+ //
+ if (Header->Signature == EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
+ TableNumEntries = sizeof (mMadtStructureTable) / sizeof (STRUCTURE_HEADER);
+ StructureTable = mMadtStructureTable;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Check the incoming structure against the table of supported structures.
+ //
+ EntryFound = FALSE;
+ for (Index = 0; Index < TableNumEntries; Index++) {
+ if (Structure->Type == StructureTable[Index].Type) {
+ if (Structure->Length == StructureTable[Index].Length) {
+ EntryFound = TRUE;
+ } else {
+ DEBUG ((
+ DEBUG_ERROR,
+ "Invalid length for structure type %d: expected %d, actually %d\n",
+ Structure->Type,
+ StructureTable[Index].Length,
+ Structure->Length
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ }
+
+ //
+ // If no entry in the table matches the structure type and length passed in
+ // then return invalid parameter.
+ //
+ if (!EntryFound) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "Unknown structure type: %d\n",
+ Structure->Type
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ NewStructureInternal = (STRUCTURE_HEADER *) AllocatePool (Structure->Length);
+ if (NewStructureInternal == NULL) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "Failed to allocate %d bytes for type %d structure\n",
+ Structure->Length,
+ Structure->Type
+ ));
+ return EFI_OUT_OF_RESOURCES;
+ } else {
+ DEBUG ((
+ DEBUG_INFO,
+ "Successfully allocated %d bytes for type %d structure at 0x%p\n",
+ Structure->Length,
+ Structure->Type,
+ NewStructureInternal
+ ));
+ }
+
+ CopyMem (
+ (VOID *) NewStructureInternal,
+ (VOID *) Structure,
+ Structure->Length
+ );
+
+ *NewStructure = NewStructureInternal;
+ return EFI_SUCCESS;
+}
+
+/**
+ Build ACPI Table. MADT tables supported.
+
+ This function builds the ACPI table from the header plus the list of sub-structures
+ passed in. The table returned by this function is ready to be installed using
+ the ACPI table protocol's InstallAcpiTable function, which copies it into
+ ACPI memory. After that, the caller should free the memory returned by this
+ function.
+
+ @param[in] AcpiHeader Pointer to the header structure.
+ @param[in] TableSpecificHdrLength Size of the table specific header, not the ACPI standard header size.
+ @param[in] Structures Pointer to an array of sub-structure pointers.
+ @param[in] StructureCount Number of structure pointers in the array.
+ @param[out] NewTable Newly allocated and initialized pointer to the ACPI Table.
+
+ @retval EFI_SUCCESS Successfully built the ACPI table.
+ @retval EFI_INVALID_PARAMETER Pointer parameter was null.
+ @retval EFI_INVALID_PARAMETER Header parameter had the wrong signature.
+ @retval EFI_OUT_OF_RESOURCES Space for the ACPI Table could not be allocated.
+**/
+EFI_STATUS
+BuildAcpiTable (
+ IN EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader,
+ IN UINTN TableSpecificHdrLength,
+ IN STRUCTURE_HEADER **Structures,
+ IN UINTN StructureCount,
+ OUT UINT8 **NewTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_DESCRIPTION_HEADER *InternalTable;
+ UINTN Index;
+ UINT8 *CurrPtr;
+ UINT8 *EndOfTablePtr;
+
+ if (AcpiHeader == NULL) {
+ DEBUG ((DEBUG_ERROR, "AcpiHeader pointer is NULL\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (AcpiHeader->Signature != EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "MADT header signature is expected, actually 0x%08x\n",
+ AcpiHeader->Signature
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Structures == NULL) {
+ DEBUG ((DEBUG_ERROR, "Structure array pointer is NULL\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (Index = 0; Index < StructureCount; Index++) {
+ if (Structures[Index] == NULL) {
+ DEBUG ((DEBUG_ERROR, "Structure pointer %d is NULL\n", Index));
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
+ // Allocate the memory needed for the table.
+ //
+ Status = AllocateTable (
+ TableSpecificHdrLength,
+ Structures,
+ StructureCount,
+ &InternalTable
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Copy Header and patch in structure length, checksum is programmed later
+ // after all structures are populated.
+ //
+ CopyMem (
+ (VOID *) InternalTable,
+ (VOID *) AcpiHeader,
+ TableSpecificHdrLength
+ );
+
+ InternalTable->Length = GetTableSize (TableSpecificHdrLength, Structures, StructureCount);
+
+ //
+ // Copy all the sub structures to the table.
+ //
+ CurrPtr = ((UINT8 *) InternalTable) + TableSpecificHdrLength;
+ EndOfTablePtr = ((UINT8 *) InternalTable) + InternalTable->Length;
+
+ for (Index = 0; Index < StructureCount; Index++) {
+ ASSERT (Structures[Index] != NULL);
+ if (Structures[Index] == NULL) {
+ break;
+ }
+
+ CopyMem (
+ (VOID *) CurrPtr,
+ (VOID *) Structures[Index],
+ Structures[Index]->Length
+ );
+
+ CurrPtr += Structures[Index]->Length;
+ ASSERT (CurrPtr <= EndOfTablePtr);
+ if (CurrPtr > EndOfTablePtr) {
+ break;
+ }
+ }
+
+ //
+ // Update the return pointer.
+ //
+ *NewTable = (UINT8 *) InternalTable;
+ return EFI_SUCCESS;
+}
+
+/**
+ Build from scratch and install the MADT.
+
+ @retval EFI_SUCCESS The MADT was installed successfully.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate required structures.
+**/
+EFI_STATUS
+InstallMadtFromScratch (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *NewMadtTable;
+ UINTN TableHandle;
+ EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER MadtTableHeader;
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE ProcLocalApicStruct;
+ EFI_ACPI_4_0_IO_APIC_STRUCTURE IoApicStruct;
+ EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE IntSrcOverrideStruct;
+ EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE LocalApciNmiStruct;
+ EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE ProcLocalX2ApicStruct;
+ EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE LocalX2ApicNmiStruct;
+ STRUCTURE_HEADER **MadtStructs;
+ UINTN MaxMadtStructCount;
+ UINTN MadtStructsIndex;
+ UINT32 CurrentIoApicAddress = (UINT32)(PcdGet32(PcdPcIoApicAddressBase));
+ UINT32 PcIoApicEnable;
+ UINT32 PcIoApicMask;
+ UINTN PcIoApicIndex;
+
+ DetectApicIdMap();
+
+ // Call for Local APIC ID Reorder
+ SortCpuLocalApicInTable ();
+
+ NewMadtTable = NULL;
+
+ MaxMadtStructCount = (UINT32) (
+ MAX_CPU_NUM + // processor local APIC structures
+ MAX_CPU_NUM + // processor local x2APIC structures
+ 1 + PcdGet8(PcdPcIoApicCount) + // I/O APIC structures
+ 2 + // interrupt source override structures
+ 1 + // local APIC NMI structures
+ 1 // local x2APIC NMI structures
+ ); // other structures are not used
+
+ MadtStructs = (STRUCTURE_HEADER **) AllocateZeroPool (MaxMadtStructCount * sizeof (STRUCTURE_HEADER *));
+ if (MadtStructs == NULL) {
+ DEBUG ((DEBUG_ERROR, "Could not allocate MADT structure pointer array\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initialize the next index into the structure pointer array. It is
+ // incremented every time a structure of any type is copied to the array.
+ //
+ MadtStructsIndex = 0;
+
+ //
+ // Initialize MADT Header Structure
+ //
+ Status = InitializeMadtHeader (&MadtTableHeader);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "InitializeMadtHeader failed: %r\n", Status));
+ goto Done;
+ }
+
+ DEBUG ((EFI_D_INFO, "Number of CPUs detected = %d \n", mNumberOfCPUs));
+
+ //
+ // Build Processor Local APIC Structures and Processor Local X2APIC Structures
+ //
+ ProcLocalApicStruct.Type = EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC;
+ ProcLocalApicStruct.Length = sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC_STRUCTURE);
+
+ ProcLocalX2ApicStruct.Type = EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC;
+ ProcLocalX2ApicStruct.Length = sizeof (EFI_ACPI_4_0_PROCESSOR_LOCAL_X2APIC_STRUCTURE);
+ ProcLocalX2ApicStruct.Reserved[0] = 0;
+ ProcLocalX2ApicStruct.Reserved[1] = 0;
+
+ for (Index = 0; Index < MAX_CPU_NUM; Index++) {
+ //
+ // If x2APIC mode is not enabled, and if it is possible to express the
+ // APIC ID as a UINT8, use a processor local APIC structure. Otherwise,
+ // use a processor local x2APIC structure.
+ //
+ if (!mX2ApicEnabled && mCpuApicIdOrderTable[Index].ApicId < MAX_UINT8) {
+ ProcLocalApicStruct.Flags = (UINT8) mCpuApicIdOrderTable[Index].Flags;
+ ProcLocalApicStruct.ApicId = (UINT8) mCpuApicIdOrderTable[Index].ApicId;
+ ProcLocalApicStruct.AcpiProcessorId = (UINT8) mCpuApicIdOrderTable[Index].AcpiProcessorId;
+
+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
+ Status = CopyStructure (
+ &MadtTableHeader.Header,
+ (STRUCTURE_HEADER *) &ProcLocalApicStruct,
+ &MadtStructs[MadtStructsIndex++]
+ );
+ } else if (mCpuApicIdOrderTable[Index].ApicId != 0xFFFFFFFF) {
+ ProcLocalX2ApicStruct.Flags = (UINT8) mCpuApicIdOrderTable[Index].Flags;
+ ProcLocalX2ApicStruct.X2ApicId = mCpuApicIdOrderTable[Index].ApicId;
+ ProcLocalX2ApicStruct.AcpiProcessorUid = mCpuApicIdOrderTable[Index].AcpiProcessorId;
+
+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
+ Status = CopyStructure (
+ &MadtTableHeader.Header,
+ (STRUCTURE_HEADER *) &ProcLocalX2ApicStruct,
+ &MadtStructs[MadtStructsIndex++]
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (local APIC/x2APIC) failed: %r\n", Status));
+ goto Done;
+ }
+ }
+
+ //
+ // Build I/O APIC Structures
+ //
+ IoApicStruct.Type = EFI_ACPI_4_0_IO_APIC;
+ IoApicStruct.Length = sizeof (EFI_ACPI_4_0_IO_APIC_STRUCTURE);
+ IoApicStruct.Reserved = 0;
+
+ PcIoApicEnable = PcdGet32(PcdPcIoApicEnable);
+
+ if (FixedPcdGet32(PcdMaxCpuSocketCount) <= 4) {
+ IoApicStruct.IoApicId = PcdGet8(PcdIoApicId);
+ IoApicStruct.IoApicAddress = PcdGet32(PcdIoApicAddress);
+ IoApicStruct.GlobalSystemInterruptBase = 0;
+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
+ Status = CopyStructure (
+ &MadtTableHeader.Header,
+ (STRUCTURE_HEADER *) &IoApicStruct,
+ &MadtStructs[MadtStructsIndex++]
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (I/O APIC) failed: %r\n", Status));
+ goto Done;
+ }
+ }
+
+ for (PcIoApicIndex = 0; PcIoApicIndex < PcdGet8(PcdPcIoApicCount); PcIoApicIndex++) {
+ PcIoApicMask = (1 << PcIoApicIndex);
+ if ((PcIoApicEnable & PcIoApicMask) == 0) {
+ continue;
+ }
+
+ IoApicStruct.IoApicId = (UINT8)(PcdGet8(PcdPcIoApicIdBase) + PcIoApicIndex);
+ IoApicStruct.IoApicAddress = CurrentIoApicAddress;
+ CurrentIoApicAddress = (CurrentIoApicAddress & 0xFFFF8000) + 0x8000;
+ IoApicStruct.GlobalSystemInterruptBase = (UINT32)(24 + (PcIoApicIndex * 8));
+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
+ Status = CopyStructure (
+ &MadtTableHeader.Header,
+ (STRUCTURE_HEADER *) &IoApicStruct,
+ &MadtStructs[MadtStructsIndex++]
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (I/O APIC) failed: %r\n", Status));
+ goto Done;
+ }
+ }
+
+ //
+ // Build Interrupt Source Override Structures
+ //
+ IntSrcOverrideStruct.Type = EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE;
+ IntSrcOverrideStruct.Length = sizeof (EFI_ACPI_4_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE);
+
+ //
+ // IRQ0=>IRQ2 Interrupt Source Override Structure
+ //
+ IntSrcOverrideStruct.Bus = 0x0; // Bus - ISA
+ IntSrcOverrideStruct.Source = 0x0; // Source - IRQ0
+ IntSrcOverrideStruct.GlobalSystemInterrupt = 0x2; // Global System Interrupt - IRQ2
+ IntSrcOverrideStruct.Flags = 0x0; // Flags - Conforms to specifications of the bus
+
+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
+ Status = CopyStructure (
+ &MadtTableHeader.Header,
+ (STRUCTURE_HEADER *) &IntSrcOverrideStruct,
+ &MadtStructs[MadtStructsIndex++]
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (IRQ2 source override) failed: %r\n", Status));
+ goto Done;
+ }
+
+ //
+ // IRQ9 (SCI Active High) Interrupt Source Override Structure
+ //
+ IntSrcOverrideStruct.Bus = 0x0; // Bus - ISA
+ IntSrcOverrideStruct.Source = 0x9; // Source - IRQ9
+ IntSrcOverrideStruct.GlobalSystemInterrupt = 0x9; // Global System Interrupt - IRQ9
+ IntSrcOverrideStruct.Flags = 0xD; // Flags - Level-tiggered, Active High
+
+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
+ Status = CopyStructure (
+ &MadtTableHeader.Header,
+ (STRUCTURE_HEADER *) &IntSrcOverrideStruct,
+ &MadtStructs[MadtStructsIndex++]
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (IRQ9 source override) failed: %r\n", Status));
+ goto Done;
+ }
+
+ //
+ // Build Local APIC NMI Structures
+ //
+ LocalApciNmiStruct.Type = EFI_ACPI_4_0_LOCAL_APIC_NMI;
+ LocalApciNmiStruct.Length = sizeof (EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE);
+ LocalApciNmiStruct.AcpiProcessorId = 0xFF; // Applies to all processors
+ LocalApciNmiStruct.Flags = 0x000D; // Flags - Level-tiggered, Active High
+ LocalApciNmiStruct.LocalApicLint = 0x1;
+
+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
+ Status = CopyStructure (
+ &MadtTableHeader.Header,
+ (STRUCTURE_HEADER *) &LocalApciNmiStruct,
+ &MadtStructs[MadtStructsIndex++]
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (APIC NMI) failed: %r\n", Status));
+ goto Done;
+ }
+
+ //
+ // Build Local x2APIC NMI Structure
+ //
+ LocalX2ApicNmiStruct.Type = EFI_ACPI_4_0_LOCAL_X2APIC_NMI;
+ LocalX2ApicNmiStruct.Length = sizeof (EFI_ACPI_4_0_LOCAL_X2APIC_NMI_STRUCTURE);
+ LocalX2ApicNmiStruct.Flags = 0x000D; // Flags - Level-tiggered, Active High
+ LocalX2ApicNmiStruct.AcpiProcessorUid = 0xFFFFFFFF; // Applies to all processors
+ LocalX2ApicNmiStruct.LocalX2ApicLint = 0x01;
+ LocalX2ApicNmiStruct.Reserved[0] = 0x00;
+ LocalX2ApicNmiStruct.Reserved[1] = 0x00;
+ LocalX2ApicNmiStruct.Reserved[2] = 0x00;
+
+ ASSERT (MadtStructsIndex < MaxMadtStructCount);
+ Status = CopyStructure (
+ &MadtTableHeader.Header,
+ (STRUCTURE_HEADER *) &LocalX2ApicNmiStruct,
+ &MadtStructs[MadtStructsIndex++]
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "CopyMadtStructure (x2APIC NMI) failed: %r\n", Status));
+ goto Done;
+ }
+
+ //
+ // Build Madt Structure from the Madt Header and collection of pointers in MadtStructs[]
+ //
+ Status = BuildAcpiTable (
+ (EFI_ACPI_DESCRIPTION_HEADER *) &MadtTableHeader,
+ sizeof (EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER),
+ MadtStructs,
+ MadtStructsIndex,
+ (UINT8 **)&NewMadtTable
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "BuildAcpiTable failed: %r\n", Status));
+ goto Done;
+ }
+
+ //
+ // Publish Madt Structure to ACPI
+ //
+ Status = mAcpiTable->InstallAcpiTable (
+ mAcpiTable,
+ NewMadtTable,
+ NewMadtTable->Header.Length,
+ &TableHandle
+ );
+
+Done:
+ //
+ // Free memory
+ //
+ for (MadtStructsIndex = 0; MadtStructsIndex < MaxMadtStructCount; MadtStructsIndex++) {
+ if (MadtStructs[MadtStructsIndex] != NULL) {
+ FreePool (MadtStructs[MadtStructsIndex]);
+ }
+ }
+
+ FreePool (MadtStructs);
+
+ if (NewMadtTable != NULL) {
+ FreePool (NewMadtTable);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+InstallMcfgFromScratch (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER *McfgTable;
+ EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *Segment;
+ UINTN Index;
+ UINTN SegmentCount;
+ PCI_SEGMENT_INFO *PciSegmentInfo;
+ UINTN TableHandle;
+
+ PciSegmentInfo = GetPciSegmentInfo (&SegmentCount);
+
+ McfgTable = AllocateZeroPool (
+ sizeof(EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER) +
+ sizeof(EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE) * SegmentCount
+ );
+ if (McfgTable == NULL) {
+ DEBUG ((DEBUG_ERROR, "Could not allocate MCFG structure\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = InitializeHeader (
+ &McfgTable->Header,
+ EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
+ EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Set MCFG table "Length" field based on the number of PCIe segments enumerated so far
+ //
+ McfgTable->Header.Length = (UINT32)(sizeof (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER) +
+ sizeof (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE) * SegmentCount);
+
+ Segment = (VOID *)(McfgTable + 1);
+
+ for (Index = 0; Index < SegmentCount; Index++) {
+ Segment[Index].PciSegmentGroupNumber = PciSegmentInfo[Index].SegmentNumber;
+ Segment[Index].BaseAddress = PciSegmentInfo[Index].BaseAddress;
+ Segment[Index].StartBusNumber = PciSegmentInfo[Index].StartBusNumber;
+ Segment[Index].EndBusNumber = PciSegmentInfo[Index].EndBusNumber;
+ }
+
+ //
+ // Publish Madt Structure to ACPI
+ //
+ Status = mAcpiTable->InstallAcpiTable (
+ mAcpiTable,
+ McfgTable,
+ McfgTable->Header.Length,
+ &TableHandle
+ );
+
+ return Status;
+}
+
+/**
+ This function will update any runtime platform specific information.
+ This currently includes:
+ Setting OEM table values, ID, table ID, creator ID and creator revision.
+ Enabling the proper processor entries in the APIC tables
+ It also indicates with which ACPI table version the table belongs.
+
+ @param[in] Table The table to update
+ @param[in] Version Where to install this table
+
+ @retval EFI_SUCCESS Updated tables commplete.
+**/
+EFI_STATUS
+PlatformUpdateTables (
+ IN OUT EFI_ACPI_COMMON_HEADER *Table,
+ IN OUT EFI_ACPI_TABLE_VERSION *Version
+ )
+{
+ EFI_ACPI_DESCRIPTION_HEADER *TableHeader;
+ UINT8 *TempOemId;
+ UINT64 TempOemTableId;
+ EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader;
+ EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *HpetTable;
+ UINT32 HpetBaseAddress;
+ EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_BLOCK_ID HpetBlockId;
+ UINT32 HpetCapabilitiesData;
+ HPET_GENERAL_CAPABILITIES_ID_REGISTER HpetCapabilities;
+
+ TableHeader = NULL;
+
+ //
+ // By default, a table belongs in all ACPI table versions published.
+ // Some tables will override this because they have different versions of the table.
+ //
+ TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
+
+ //
+ // Update the OEM and creator information for every table except FACS.
+ //
+ if (Table->Signature != EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {
+ TempOemId = (UINT8 *)PcdGetPtr(PcdAcpiDefaultOemId);
+ CopyMem (&TableHeader->OemId, TempOemId, 6);
+
+ //
+ // Skip OEM table ID and creator information for DSDT, SSDT and PSDT tables, since these are
+ // created by an ASL compiler and the creator information is useful.
+ //
+ if (Table->Signature != EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE &&
+ Table->Signature != EFI_ACPI_1_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE &&
+ Table->Signature != EFI_ACPI_1_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
+ ) {
+ TempOemTableId = PcdGet64(PcdAcpiDefaultOemTableId);
+ CopyMem (&TableHeader->OemTableId, &TempOemTableId, 8);
+
+ //
+ // Update the creator ID
+ //
+ TableHeader->CreatorId = PcdGet32(PcdAcpiDefaultCreatorId);
+
+ //
+ // Update the creator revision
+ //
+ TableHeader->CreatorRevision = PcdGet32(PcdAcpiDefaultCreatorRevision);
+ }
+ }
+
+
+ //
+ // By default, a table belongs in all ACPI table versions published.
+ // Some tables will override this because they have different versions of the table.
+ //
+ *Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0;
+
+ //
+ // Update the various table types with the necessary updates
+ //
+ switch (Table->Signature) {
+
+ case EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
+ ASSERT(FALSE);
+ break;
+
+ case EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
+ FadtHeader = (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE *) Table;
+
+ FadtHeader->PreferredPmProfile = PcdGet8 (PcdFadtPreferredPmProfile);
+ FadtHeader->IaPcBootArch = PcdGet16 (PcdFadtIaPcBootArch);
+ FadtHeader->Flags = PcdGet32 (PcdFadtFlags);
+
+ FadtHeader->AcpiEnable = PcdGet8 (PcdAcpiEnableSwSmi);
+ FadtHeader->AcpiDisable = PcdGet8 (PcdAcpiDisableSwSmi);
+
+ FadtHeader->Pm1aEvtBlk = PcdGet16 (PcdAcpiPm1AEventBlockAddress);
+ FadtHeader->Pm1bEvtBlk = PcdGet16 (PcdAcpiPm1BEventBlockAddress);
+ FadtHeader->Pm1aCntBlk = PcdGet16 (PcdAcpiPm1AControlBlockAddress);
+ FadtHeader->Pm1bCntBlk = PcdGet16 (PcdAcpiPm1BControlBlockAddress);
+ FadtHeader->Pm2CntBlk = PcdGet16 (PcdAcpiPm2ControlBlockAddress);
+ FadtHeader->PmTmrBlk = PcdGet16 (PcdAcpiPmTimerBlockAddress);
+ FadtHeader->Gpe0Blk = PcdGet16 (PcdAcpiGpe0BlockAddress);
+ FadtHeader->Gpe1Blk = PcdGet16 (PcdAcpiGpe1BlockAddress);
+
+ FadtHeader->XPm1aEvtBlk.Address = PcdGet16 (PcdAcpiPm1AEventBlockAddress);
+ FadtHeader->XPm1bEvtBlk.Address = PcdGet16 (PcdAcpiPm1BEventBlockAddress);
+ if (FadtHeader->XPm1bEvtBlk.Address == 0) {
+ FadtHeader->XPm1bEvtBlk.AccessSize = 0;
+ }
+ FadtHeader->XPm1aCntBlk.Address = PcdGet16 (PcdAcpiPm1AControlBlockAddress);
+ FadtHeader->XPm1bCntBlk.Address = PcdGet16 (PcdAcpiPm1BControlBlockAddress);
+ if (FadtHeader->XPm1bCntBlk.Address == 0) {
+ FadtHeader->XPm1bCntBlk.AccessSize = 0;
+ }
+ FadtHeader->XPm2CntBlk.Address = PcdGet16 (PcdAcpiPm2ControlBlockAddress);
+ //if (FadtHeader->XPm2CntBlk.Address == 0) {
+ FadtHeader->XPm2CntBlk.AccessSize = 0;
+ //}
+ FadtHeader->XPmTmrBlk.Address = PcdGet16 (PcdAcpiPmTimerBlockAddress);
+ FadtHeader->XGpe0Blk.Address = PcdGet16 (PcdAcpiGpe0BlockAddress);
+ FadtHeader->XGpe1Blk.Address = PcdGet16 (PcdAcpiGpe1BlockAddress);
+ if (FadtHeader->XGpe1Blk.Address == 0) {
+ FadtHeader->XGpe1Blk.AccessSize = 0;
+ }
+
+ DEBUG(( EFI_D_ERROR, "ACPI FADT table @ address 0x%x\n", Table ));
+ DEBUG(( EFI_D_ERROR, " IaPcBootArch 0x%x\n", FadtHeader->IaPcBootArch ));
+ DEBUG(( EFI_D_ERROR, " Flags 0x%x\n", FadtHeader->Flags ));
+ break;
+
+ case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE:
+ HpetTable = (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *)Table;
+ HpetBaseAddress = PcdGet32 (PcdHpetBaseAddress);
+ HpetTable->BaseAddressLower32Bit.Address = HpetBaseAddress;
+ HpetTable->BaseAddressLower32Bit.RegisterBitWidth = 0;
+ HpetCapabilitiesData = MmioRead32 (HpetBaseAddress + HPET_GENERAL_CAPABILITIES_ID_OFFSET);
+ HpetCapabilities.Uint64 = HpetCapabilitiesData;
+ HpetCapabilitiesData = MmioRead32 (HpetBaseAddress + HPET_GENERAL_CAPABILITIES_ID_OFFSET + 4);
+ HpetCapabilities.Uint64 |= LShiftU64 (HpetCapabilitiesData, 32);
+ HpetBlockId.Bits.Revision = HpetCapabilities.Bits.Revision;
+ HpetBlockId.Bits.NumberOfTimers = HpetCapabilities.Bits.NumberOfTimers;
+ HpetBlockId.Bits.CounterSize = HpetCapabilities.Bits.CounterSize;
+ HpetBlockId.Bits.Reserved = 0;
+ HpetBlockId.Bits.LegacyRoute = HpetCapabilities.Bits.LegacyRoute;
+ HpetBlockId.Bits.VendorId = HpetCapabilities.Bits.VendorId;
+ HpetTable->EventTimerBlockId = HpetBlockId.Uint32;
+ HpetTable->MainCounterMinimumClockTickInPeriodicMode = (UINT16)HpetCapabilities.Bits.CounterClockPeriod;
+ DEBUG(( EFI_D_ERROR, "ACPI HPET table @ address 0x%x\n", Table ));
+ DEBUG(( EFI_D_ERROR, " HPET base 0x%x\n", PcdGet32 (PcdHpetBaseAddress) ));
+ break;
+
+ case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:
+ ASSERT(FALSE);
+ break;
+
+ default:
+ break;
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ This function calculates RCR based on PCI Device ID and Vendor ID from the devices
+ available on the platform.
+ It also includes other instances of BIOS change to calculate CRC and provides as
+ HWSignature filed in FADT table.
+**/
+VOID
+IsHardwareChange (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT32 CRC;
+ UINT32 *HWChange;
+ UINTN HWChangeSize;
+ UINT32 PciId;
+ UINTN Handle;
+ EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *FacsPtr;
+ EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *pFADT;
+
+ HandleCount = 0;
+ HandleBuffer = NULL;
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiPciIoProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return; // PciIO protocol not installed yet!
+ }
+
+ //
+ // Allocate memory for HWChange and add additional entrie for
+ // pFADT->XDsdt
+ //
+ HWChangeSize = HandleCount + 1;
+ HWChange = AllocateZeroPool( sizeof(UINT32) * HWChangeSize );
+ ASSERT( HWChange != NULL );
+
+ if (HWChange == NULL) return;
+
+ //
+ // add HWChange inputs: PCI devices
+ //
+ for (Index = 0; HandleCount > 0; HandleCount--) {
+ PciId = 0;
+ Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID **) &PciIo);
+ if (!EFI_ERROR (Status)) {
+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0, 1, &PciId);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+ HWChange[Index++] = PciId;
+ }
+ }
+
+ //
+ // Locate FACP Table
+ //
+ Handle = 0;
+ Status = LocateAcpiTableBySignature (
+ EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
+ (EFI_ACPI_DESCRIPTION_HEADER **) &pFADT,
+ &Handle
+ );
+ if (EFI_ERROR (Status) || (pFADT == NULL)) {
+ return; //Table not found or out of memory resource for pFADT table
+ }
+
+ //
+ // add HWChange inputs: others
+ //
+ HWChange[Index++] = (UINT32)pFADT->XDsdt;
+
+ //
+ // Calculate CRC value with HWChange data.
+ //
+ Status = gBS->CalculateCrc32(HWChange, HWChangeSize, &CRC);
+ DEBUG((DEBUG_INFO, "CRC = %x and Status = %r\n", CRC, Status));
+
+ //
+ // Set HardwareSignature value based on CRC value.
+ //
+ FacsPtr = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)pFADT->FirmwareCtrl;
+ FacsPtr->HardwareSignature = CRC;
+ FreePool( HWChange );
+}
+
+VOID
+UpdateLocalTable (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_COMMON_HEADER *CurrentTable;
+ EFI_ACPI_TABLE_VERSION Version;
+ UINTN TableHandle;
+ UINTN Index;
+
+ for (Index = 0; Index < sizeof(mLocalTable)/sizeof(mLocalTable[0]); Index++) {
+ CurrentTable = mLocalTable[Index];
+
+ PlatformUpdateTables (CurrentTable, &Version);
+
+ TableHandle = 0;
+
+ if (Version != EFI_ACPI_TABLE_VERSION_NONE) {
+ Status = mAcpiTable->InstallAcpiTable (
+ mAcpiTable,
+ CurrentTable,
+ CurrentTable->Length,
+ &TableHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+}
+
+
+VOID
+EFIAPI
+AcpiEndOfDxeEvent (
+ EFI_EVENT Event,
+ VOID *ParentImageHandle
+ )
+{
+
+ if (Event != NULL) {
+ gBS->CloseEvent(Event);
+ }
+
+
+ //
+ // Calculate Hardware Signature value based on current platform configurations
+ //
+ IsHardwareChange();
+}
+
+/**
+ ACPI Platform driver installation function.
+
+ @param[in] ImageHandle Handle for this drivers loaded image protocol.
+ @param[in] SystemTable EFI system table.
+
+ @retval EFI_SUCCESS The driver installed without error.
+ @retval EFI_ABORTED The driver encountered an error and could not complete installation of
+ the ACPI tables.
+
+**/
+EFI_STATUS
+EFIAPI
+InstallAcpiPlatform (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT EndOfDxeEvent;
+
+
+ Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&mMpService);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&mAcpiTable);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Create an End of DXE event.
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ AcpiEndOfDxeEvent,
+ NULL,
+ &gEfiEndOfDxeEventGroupGuid,
+ &EndOfDxeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Determine the number of processors
+ //
+ mMpService->GetNumberOfProcessors (
+ mMpService,
+ &mNumberOfCPUs,
+ &mNumberOfEnabledCPUs
+ );
+ ASSERT (mNumberOfCPUs <= MAX_CPU_NUM && mNumberOfEnabledCPUs >= 1);
+ DEBUG ((DEBUG_INFO, "mNumberOfCPUs - %d\n", mNumberOfCPUs));
+ DEBUG ((DEBUG_INFO, "mNumberOfEnabledCPUs - %d\n", mNumberOfEnabledCPUs));
+
+ DEBUG ((DEBUG_INFO, "mX2ApicEnabled - 0x%x\n", mX2ApicEnabled));
+ DEBUG ((DEBUG_INFO, "mForceX2ApicId - 0x%x\n", mForceX2ApicId));
+
+ // support up to 64 threads/socket
+ AsmCpuidEx(CPUID_EXTENDED_TOPOLOGY, 1, &mNumOfBitShift, NULL, NULL, NULL);
+ mNumOfBitShift &= 0x1F;
+ DEBUG ((DEBUG_INFO, "mNumOfBitShift - 0x%x\n", mNumOfBitShift));
+
+ UpdateLocalTable ();
+
+ InstallMadtFromScratch ();
+ InstallMcfgFromScratch ();
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Facs/Facs.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Facs/Facs.c
new file mode 100644
index 0000000000..e649b5b89c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Facs/Facs.c
@@ -0,0 +1,84 @@
+/** @file
+ This file contains a structure definition for the ACPI 5.0 Firmware ACPI
+ Control Structure (FACS). The contents of this file should only be modified
+ for bug fixes, no porting is required.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+
+//
+// FACS Definitions
+//
+#define EFI_ACPI_FIRMWARE_WAKING_VECTOR 0x00000000
+#define EFI_ACPI_GLOBAL_LOCK 0x00000000
+
+//
+// Firmware Control Structure Feature Flags are defined in AcpiX.0.h
+//
+#define EFI_ACPI_FIRMWARE_CONTROL_STRUCTURE_FLAGS 0x00000000
+
+#define EFI_ACPI_X_FIRMWARE_WAKING_VECTOR 0x0000000000000000
+
+#define EFI_ACPI_OSPM_FLAGS 0x00000000
+
+
+//
+// Firmware ACPI Control Structure
+// Please modify all values in Facs.h only.
+//
+
+EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE Facs = {
+ EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE,
+ sizeof (EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE),
+
+ //
+ // Hardware Signature will be updated at runtime
+ //
+ 0x00000000,
+
+ EFI_ACPI_FIRMWARE_WAKING_VECTOR,
+ EFI_ACPI_GLOBAL_LOCK,
+ EFI_ACPI_FIRMWARE_CONTROL_STRUCTURE_FLAGS,
+ EFI_ACPI_X_FIRMWARE_WAKING_VECTOR,
+ EFI_ACPI_5_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION,
+ {
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE
+ },
+ EFI_ACPI_OSPM_FLAGS,
+ {
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE
+ }
+};
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.c
new file mode 100644
index 0000000000..d1fe98e24b
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Fadt/Fadt.c
@@ -0,0 +1,359 @@
+/** @file
+ This file contains a structure definition for the ACPI 5.0 Fixed ACPI
+ Description Table (FADT). The contents of this file should only be modified
+ for bug fixes, no porting is required.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include <IndustryStandard/Acpi.h>
+
+//
+// FADT Definitions
+//
+#define EFI_ACPI_OEM_FADT_REVISION 0x00000000
+
+#define EFI_ACPI_PREFERRED_PM_PROFILE 0x00 // To be fixed
+
+#define EFI_ACPI_SCI_INT 0x0009
+#define EFI_ACPI_SMI_CMD 0x000000B2
+
+#define EFI_ACPI_ACPI_ENABLE 0 // To be fixed
+#define EFI_ACPI_ACPI_DISABLE 0 // To be fixed
+#define EFI_ACPI_S4_BIOS_REQ 0x00
+#define EFI_ACPI_CST_CNT 0x00
+
+#define EFI_ACPI_PSTATE_CNT 0x00
+#define EFI_ACPI_GPE1_BASE (EFI_ACPI_GPE1_BLK_BIT_WIDTH / 2)
+#define EFI_ACPI_P_LVL2_LAT 0x0065 // 101
+#define EFI_ACPI_P_LVL3_LAT 0x03E9 // 1001
+#define EFI_ACPI_FLUSH_SIZE 0x0000
+#define EFI_ACPI_FLUSH_STRIDE 0x0000
+#define EFI_ACPI_DUTY_OFFSET 0x01
+#define EFI_ACPI_DUTY_WIDTH 0x00
+
+#define EFI_ACPI_DAY_ALRM 0x0D
+#define EFI_ACPI_MON_ALRM 0x00
+#define EFI_ACPI_CENTURY 0x32
+
+//
+// IA-PC Boot Architecture Flags
+//
+
+#define EFI_ACPI_IAPC_BOOT_ARCH 0 // To be fixed
+
+//
+// Fixed Feature Flags
+//
+#define EFI_ACPI_FIXED_FEATURE_FLAGS 0 // To be fixed
+
+//
+// PM1A Event Register Block Generic Address Information
+//
+#define EFI_ACPI_PM1A_EVT_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO
+#define EFI_ACPI_PM1A_EVT_BLK_BIT_WIDTH 0x20
+#define EFI_ACPI_PM1A_EVT_BLK_BIT_OFFSET 0x00
+#define EFI_ACPI_PM1A_EVT_BLK_ADDRESS 0 // To be fixed
+
+//
+// PM1B Event Register Block Generic Address Information
+//
+#define EFI_ACPI_PM1B_EVT_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO
+#define EFI_ACPI_PM1B_EVT_BLK_BIT_WIDTH 0x00
+#define EFI_ACPI_PM1B_EVT_BLK_BIT_OFFSET 0x00
+#define EFI_ACPI_PM1B_EVT_BLK_ADDRESS 0 // To be fixed
+
+//
+// PM1A Control Register Block Generic Address Information
+//
+#define EFI_ACPI_PM1A_CNT_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO
+#define EFI_ACPI_PM1A_CNT_BLK_BIT_WIDTH 0x10
+#define EFI_ACPI_PM1A_CNT_BLK_BIT_OFFSET 0x00
+#define EFI_ACPI_PM1A_CNT_BLK_ADDRESS 0 // To be fixed
+
+//
+// PM1B Control Register Block Generic Address Information
+//
+#define EFI_ACPI_PM1B_CNT_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO
+#define EFI_ACPI_PM1B_CNT_BLK_BIT_WIDTH 0x00
+#define EFI_ACPI_PM1B_CNT_BLK_BIT_OFFSET 0x00
+#define EFI_ACPI_PM1B_CNT_BLK_ADDRESS 0 // To be fixed
+
+//
+// PM2 Control Register Block Generic Address Information
+//
+#define EFI_ACPI_PM2_CNT_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO
+#define EFI_ACPI_PM2_CNT_BLK_BIT_WIDTH 0x08
+#define EFI_ACPI_PM2_CNT_BLK_BIT_OFFSET 0x00
+#define EFI_ACPI_PM2_CNT_BLK_ADDRESS 0 // To be fixed
+
+//
+// Power Management Timer Control Register Block Generic Address
+// Information
+//
+#define EFI_ACPI_PM_TMR_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO
+#define EFI_ACPI_PM_TMR_BLK_BIT_WIDTH 0x20
+#define EFI_ACPI_PM_TMR_BLK_BIT_OFFSET 0x00
+#define EFI_ACPI_PM_TMR_BLK_ADDRESS 0 // To be fixed
+
+//
+// General Purpose Event 0 Register Block Generic Address
+// Information
+//
+#define EFI_ACPI_GPE0_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO
+#define EFI_ACPI_GPE0_BLK_BIT_WIDTH 0 // size of R_PCH_ACPI_GPE0_STS_127_96 + R_PCH_ACPI_GPE0_EN_127_96
+#define EFI_ACPI_GPE0_BLK_BIT_OFFSET 0x00
+#define EFI_ACPI_GPE0_BLK_ADDRESS 0 // To be fixed
+
+//
+// General Purpose Event 1 Register Block Generic Address
+// Information
+//
+#define EFI_ACPI_GPE1_BLK_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO
+#define EFI_ACPI_GPE1_BLK_BIT_WIDTH 0x0
+#define EFI_ACPI_GPE1_BLK_BIT_OFFSET 0x0
+#define EFI_ACPI_GPE1_BLK_ADDRESS 0 // To be fixed
+//
+// Reset Register Generic Address Information
+//
+#define EFI_ACPI_RESET_REG_ADDRESS_SPACE_ID EFI_ACPI_2_0_SYSTEM_IO
+#define EFI_ACPI_RESET_REG_BIT_WIDTH 0x08
+#define EFI_ACPI_RESET_REG_BIT_OFFSET 0x00
+#define EFI_ACPI_RESET_REG_ADDRESS 0x00000CF9
+#define EFI_ACPI_RESET_VALUE 0x06
+
+//
+// Number of bytes decoded by PM1 event blocks (a and b)
+//
+#define EFI_ACPI_PM1_EVT_LEN ((EFI_ACPI_PM1A_EVT_BLK_BIT_WIDTH + EFI_ACPI_PM1B_EVT_BLK_BIT_WIDTH) / 8)
+
+//
+// Number of bytes decoded by PM1 control blocks (a and b)
+//
+#define EFI_ACPI_PM1_CNT_LEN ((EFI_ACPI_PM1A_CNT_BLK_BIT_WIDTH + EFI_ACPI_PM1B_CNT_BLK_BIT_WIDTH) / 8)
+
+//
+// Number of bytes decoded by PM2 control block
+//
+#define EFI_ACPI_PM2_CNT_LEN (EFI_ACPI_PM2_CNT_BLK_BIT_WIDTH / 8)
+
+//
+// Number of bytes decoded by PM timer block
+//
+#define EFI_ACPI_PM_TMR_LEN (EFI_ACPI_PM_TMR_BLK_BIT_WIDTH / 8)
+
+//
+// Number of bytes decoded by GPE0 block
+//
+#define EFI_ACPI_GPE0_BLK_LEN (EFI_ACPI_GPE0_BLK_BIT_WIDTH / 8)
+
+//
+// Number of bytes decoded by GPE1 block
+//
+#define EFI_ACPI_GPE1_BLK_LEN (EFI_ACPI_GPE1_BLK_BIT_WIDTH / 8)
+
+//
+// Fixed ACPI Description Table
+// Please modify all values in Fadt.h only.
+//
+
+EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE Fadt = {
+ {
+ EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
+ sizeof (EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE),
+ EFI_ACPI_5_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,
+
+ //
+ // Checksum will be updated at runtime
+ //
+ 0x00,
+
+ //
+ // It is expected that these values will be updated at runtime
+ //
+ { ' ', ' ', ' ', ' ', ' ', ' ' },
+
+ 0,
+ EFI_ACPI_OEM_FADT_REVISION,
+ 0,
+ 0
+ },
+
+ //
+ // These addresses will be updated at runtime
+ //
+ 0x00000000,
+ 0x00000000,
+
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_PREFERRED_PM_PROFILE,
+ EFI_ACPI_SCI_INT,
+ EFI_ACPI_SMI_CMD,
+ EFI_ACPI_ACPI_ENABLE,
+ EFI_ACPI_ACPI_DISABLE,
+ EFI_ACPI_S4_BIOS_REQ,
+ EFI_ACPI_PSTATE_CNT,
+
+ EFI_ACPI_PM1A_EVT_BLK_ADDRESS,
+ EFI_ACPI_PM1B_EVT_BLK_ADDRESS,
+ EFI_ACPI_PM1A_CNT_BLK_ADDRESS,
+ EFI_ACPI_PM1B_CNT_BLK_ADDRESS,
+ EFI_ACPI_PM2_CNT_BLK_ADDRESS,
+ EFI_ACPI_PM_TMR_BLK_ADDRESS,
+ EFI_ACPI_GPE0_BLK_ADDRESS,
+ EFI_ACPI_GPE1_BLK_ADDRESS,
+ EFI_ACPI_PM1_EVT_LEN,
+ EFI_ACPI_PM1_CNT_LEN,
+ EFI_ACPI_PM2_CNT_LEN,
+ EFI_ACPI_PM_TMR_LEN,
+ EFI_ACPI_GPE0_BLK_LEN,
+ EFI_ACPI_GPE1_BLK_LEN,
+ EFI_ACPI_GPE1_BASE,
+
+ //
+ // Latest OS have C-State capability and CST_CNT SMI doesn't need to be defined.
+ // CST_CNT SMI is not handled in BIOS and it can be removed safely.
+ //
+ EFI_ACPI_CST_CNT,
+ EFI_ACPI_P_LVL2_LAT,
+ EFI_ACPI_P_LVL3_LAT,
+ EFI_ACPI_FLUSH_SIZE,
+ EFI_ACPI_FLUSH_STRIDE,
+ EFI_ACPI_DUTY_OFFSET,
+ EFI_ACPI_DUTY_WIDTH,
+ EFI_ACPI_DAY_ALRM,
+ EFI_ACPI_MON_ALRM,
+ EFI_ACPI_CENTURY,
+ EFI_ACPI_IAPC_BOOT_ARCH,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_FIXED_FEATURE_FLAGS,
+
+ //
+ // Reset Register Block
+ //
+ {
+ EFI_ACPI_RESET_REG_ADDRESS_SPACE_ID,
+ EFI_ACPI_RESET_REG_BIT_WIDTH,
+ EFI_ACPI_RESET_REG_BIT_OFFSET,
+ EFI_ACPI_5_0_BYTE,
+ EFI_ACPI_RESET_REG_ADDRESS
+ },
+ EFI_ACPI_RESET_VALUE,
+ {
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE
+ },
+
+ //
+ // These addresses will be updated at runtime
+ //
+ 0x0000000000000000, // X_FIRMWARE_CTRL
+ 0x0000000000000000, // X_DSDT
+
+ {
+ //
+ // X_PM1a Event Register Block
+ //
+ EFI_ACPI_PM1A_EVT_BLK_ADDRESS_SPACE_ID,
+ EFI_ACPI_PM1A_EVT_BLK_BIT_WIDTH,
+ EFI_ACPI_PM1A_EVT_BLK_BIT_OFFSET,
+ EFI_ACPI_5_0_WORD,
+ EFI_ACPI_PM1A_EVT_BLK_ADDRESS
+ },
+ {
+ //
+ // X_PM1b Event Register Block
+ //
+ EFI_ACPI_PM1B_EVT_BLK_ADDRESS_SPACE_ID,
+ EFI_ACPI_PM1B_EVT_BLK_BIT_WIDTH,
+ EFI_ACPI_PM1B_EVT_BLK_BIT_OFFSET,
+ EFI_ACPI_5_0_WORD,
+ EFI_ACPI_PM1B_EVT_BLK_ADDRESS
+ },
+ {
+ //
+ // X_PM1a Control Register Block
+ //
+ EFI_ACPI_PM1A_CNT_BLK_ADDRESS_SPACE_ID,
+ EFI_ACPI_PM1A_CNT_BLK_BIT_WIDTH,
+ EFI_ACPI_PM1A_CNT_BLK_BIT_OFFSET,
+ EFI_ACPI_5_0_WORD,
+ EFI_ACPI_PM1A_CNT_BLK_ADDRESS
+ },
+ {
+ //
+ // X_PM1b Control Register Block
+ //
+ EFI_ACPI_PM1B_CNT_BLK_ADDRESS_SPACE_ID,
+ EFI_ACPI_PM1B_CNT_BLK_BIT_WIDTH,
+ EFI_ACPI_PM1B_CNT_BLK_BIT_OFFSET,
+ EFI_ACPI_5_0_WORD,
+ EFI_ACPI_PM1B_CNT_BLK_ADDRESS
+ },
+ {
+ //
+ // X_PM2 Control Register Block
+ //
+ EFI_ACPI_PM2_CNT_BLK_ADDRESS_SPACE_ID,
+ EFI_ACPI_PM2_CNT_BLK_BIT_WIDTH,
+ EFI_ACPI_PM2_CNT_BLK_BIT_OFFSET,
+ EFI_ACPI_5_0_BYTE,
+ EFI_ACPI_PM2_CNT_BLK_ADDRESS
+ },
+ {
+ //
+ // X_PM Timer Control Register Block
+ //
+ EFI_ACPI_PM_TMR_BLK_ADDRESS_SPACE_ID,
+ EFI_ACPI_PM_TMR_BLK_BIT_WIDTH,
+ EFI_ACPI_PM_TMR_BLK_BIT_OFFSET,
+ EFI_ACPI_5_0_DWORD,
+ EFI_ACPI_PM_TMR_BLK_ADDRESS
+ },
+ {
+ //
+ // X_General Purpose Event 0 Register Block
+ //
+ EFI_ACPI_GPE0_BLK_ADDRESS_SPACE_ID,
+ EFI_ACPI_GPE0_BLK_BIT_WIDTH,
+ EFI_ACPI_GPE0_BLK_BIT_OFFSET,
+ EFI_ACPI_5_0_BYTE,
+ EFI_ACPI_GPE0_BLK_ADDRESS
+ },
+ {
+ //
+ // X_General Purpose Event 1 Register Block
+ //
+ EFI_ACPI_GPE1_BLK_ADDRESS_SPACE_ID,
+ EFI_ACPI_GPE1_BLK_BIT_WIDTH,
+ EFI_ACPI_GPE1_BLK_BIT_OFFSET,
+ EFI_ACPI_5_0_BYTE,
+ EFI_ACPI_GPE1_BLK_ADDRESS
+ },
+ {
+ //
+ // Sleep Control Reg - update in DXE driver
+ //
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ },
+ {
+ //
+ // Sleep Status Reg - update in DXE driver
+ //
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }
+};
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.c
new file mode 100644
index 0000000000..e9528b0ec3
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Hpet/Hpet.c
@@ -0,0 +1,78 @@
+/** @file
+ This file contains a structure definition for the ACPI 1.0 High Precision Event Timer
+ Description Table (HPET). The contents of this file should only be modified
+ for bug fixes, no porting is required.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+
+//
+// HPET Definitions
+//
+#define EFI_ACPI_OEM_HPET_REVISION 0x00000001
+
+#define EFI_ACPI_EVENT_TIMER_BLOCK_ID 0x0 // To be filled
+
+//
+// Event Timer Block Base Address Information
+//
+#define EFI_ACPI_EVENT_TIMER_BLOCK_ADDRESS_SPACE_ID EFI_ACPI_3_0_SYSTEM_MEMORY
+#define EFI_ACPI_EVENT_TIMER_BLOCK_BIT_WIDTH 0x40
+#define EFI_ACPI_EVENT_TIMER_BLOCK_BIT_OFFSET 0x00
+#define EFI_ACPI_EVENT_TIMER_ACCESS_SIZE 0x00
+#define EFI_ACPI_EVENT_TIMER_BLOCK_ADDRESS 0x0 // To be filled
+
+#define EFI_ACPI_HPET_NUMBER 0x00
+
+#define EFI_ACPI_MIN_CLOCK_TICK 0x0080
+
+#define EFI_ACPI_HPET_ATTRIBUTES 0x00
+
+//
+// High Precision Event Timer Table
+// Please modify all values in Hpet.h only.
+//
+
+EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER Hpet = {
+ {
+ EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE,
+ sizeof (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER),
+ EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_REVISION,
+
+ //
+ // Checksum will be updated at runtime
+ //
+ 0x00,
+
+ //
+ // It is expected that these values will be updated at runtime
+ //
+ { ' ', ' ', ' ', ' ', ' ', ' ' },
+
+ 0,
+ EFI_ACPI_OEM_HPET_REVISION,
+ 0,
+ 0
+ },
+
+ EFI_ACPI_EVENT_TIMER_BLOCK_ID,
+ {
+ EFI_ACPI_EVENT_TIMER_BLOCK_ADDRESS_SPACE_ID,
+ EFI_ACPI_EVENT_TIMER_BLOCK_BIT_WIDTH,
+ EFI_ACPI_EVENT_TIMER_BLOCK_BIT_OFFSET,
+ EFI_ACPI_EVENT_TIMER_ACCESS_SIZE,
+ EFI_ACPI_EVENT_TIMER_BLOCK_ADDRESS
+ },
+ EFI_ACPI_HPET_NUMBER,
+ EFI_ACPI_MIN_CLOCK_TICK,
+ EFI_ACPI_HPET_ATTRIBUTES
+};
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c
new file mode 100644
index 0000000000..625b7560bb
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c
@@ -0,0 +1,46 @@
+/** @file
+ ACPI WSMT table
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
+#include <Library/PcdLib.h>
+
+//
+// WSMT Definitions
+//
+
+#define EFI_ACPI_OEM_WSMT_REVISION 0x00000001
+
+EFI_ACPI_WSMT_TABLE Wsmt = {
+ {
+ EFI_ACPI_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE,
+ sizeof (EFI_ACPI_WSMT_TABLE),
+ EFI_WSMT_TABLE_REVISION,
+
+ //
+ // Checksum will be updated at runtime
+ //
+ 0x00,
+
+ //
+ // It is expected that these values will be updated at runtime
+ //
+ { ' ', ' ', ' ', ' ', ' ', ' ' },
+
+ 0,
+ EFI_ACPI_OEM_WSMT_REVISION,
+ 0,
+ 0
+ },
+
+ FixedPcdGet32(PcdWsmtProtectionFlags)
+};
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/ComponentName.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/ComponentName.c
new file mode 100644
index 0000000000..d6d1d451df
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/ComponentName.c
@@ -0,0 +1,205 @@
+/** @file
+ Component name for the QEMU video controller.
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Qemu.h"
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gQemuVideoComponentName = {
+ QemuVideoComponentNameGetDriverName,
+ QemuVideoComponentNameGetControllerName,
+ "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gQemuVideoComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) QemuVideoComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) QemuVideoComponentNameGetControllerName,
+ "en"
+};
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mQemuVideoDriverNameTable[] = {
+ { "eng;en", L"QEMU Video Driver" },
+ { NULL , NULL }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mQemuVideoControllerNameTable[] = {
+ { "eng;en", L"QEMU Video PCI Adapter" },
+ { NULL , NULL }
+};
+
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mQemuVideoDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &gQemuVideoComponentName)
+ );
+}
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // This is a device driver, so ChildHandle must be NULL.
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver is currently managing ControllHandle
+ //
+ Status = EfiTestManagedDevice (
+ ControllerHandle,
+ gQemuVideoDriverBinding.DriverBindingHandle,
+ &gEfiPciIoProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get the QEMU Video's Device structure
+ //
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mQemuVideoControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gQemuVideoComponentName)
+ );
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driver.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driver.c
new file mode 100644
index 0000000000..e49e7a465c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driver.c
@@ -0,0 +1,1011 @@
+/** @file
+ This driver is a sample implementation of the Graphics Output Protocol for
+ the QEMU (Cirrus Logic 5446) video controller.
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Qemu.h"
+#include <IndustryStandard/Acpi.h>
+
+EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding = {
+ QemuVideoControllerDriverSupported,
+ QemuVideoControllerDriverStart,
+ QemuVideoControllerDriverStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+QEMU_VIDEO_CARD gQemuVideoCardList[] = {
+ {
+ PCI_CLASS_DISPLAY_VGA,
+ CIRRUS_LOGIC_VENDOR_ID,
+ CIRRUS_LOGIC_5430_DEVICE_ID,
+ QEMU_VIDEO_CIRRUS_5430,
+ L"Cirrus 5430"
+ },{
+ PCI_CLASS_DISPLAY_VGA,
+ CIRRUS_LOGIC_VENDOR_ID,
+ CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID,
+ QEMU_VIDEO_CIRRUS_5430,
+ L"Cirrus 5430"
+ },{
+ PCI_CLASS_DISPLAY_VGA,
+ CIRRUS_LOGIC_VENDOR_ID,
+ CIRRUS_LOGIC_5446_DEVICE_ID,
+ QEMU_VIDEO_CIRRUS_5446,
+ L"Cirrus 5446"
+ },{
+ PCI_CLASS_DISPLAY_VGA,
+ 0x4321,
+ 0x1111,
+ QEMU_VIDEO_BOCHS_MMIO,
+ L"QEMU Standard VGA"
+ },{
+ PCI_CLASS_DISPLAY_OTHER,
+ 0x1234,
+ 0x1111,
+ QEMU_VIDEO_BOCHS_MMIO,
+ L"QEMU Standard VGA (secondary)"
+ },{
+ PCI_CLASS_DISPLAY_VGA,
+ 0x1b36,
+ 0x0100,
+ QEMU_VIDEO_BOCHS,
+ L"QEMU QXL VGA"
+ },{
+ PCI_CLASS_DISPLAY_VGA,
+ 0x1af4,
+ 0x1050,
+ QEMU_VIDEO_BOCHS_MMIO,
+ L"QEMU VirtIO VGA"
+ },{
+ 0 /* end of list */
+ }
+};
+
+static QEMU_VIDEO_CARD*
+QemuVideoDetect(
+ IN UINT8 SubClass,
+ IN UINT16 VendorId,
+ IN UINT16 DeviceId
+ )
+{
+ UINTN Index = 0;
+
+ while (gQemuVideoCardList[Index].VendorId != 0) {
+ if (gQemuVideoCardList[Index].SubClass == SubClass &&
+ gQemuVideoCardList[Index].VendorId == VendorId &&
+ gQemuVideoCardList[Index].DeviceId == DeviceId) {
+ return gQemuVideoCardList + Index;
+ }
+ Index++;
+ }
+ return NULL;
+}
+
+/**
+ Check if this device is supported.
+
+ @param This The driver binding protocol.
+ @param Controller The controller handle to check.
+ @param RemainingDevicePath The remaining device path.
+
+ @retval EFI_SUCCESS The bus supports this controller.
+ @retval EFI_UNSUPPORTED This device isn't supported.
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoControllerDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ PCI_TYPE00 Pci;
+ QEMU_VIDEO_CARD *Card;
+
+ //
+ // Open the PCI I/O Protocol
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Read the PCI Configuration Header from the PCI Device
+ //
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ sizeof (Pci) / sizeof (UINT32),
+ &Pci
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ Status = EFI_UNSUPPORTED;
+ if (!IS_PCI_DISPLAY (&Pci)) {
+ goto Done;
+ }
+ Card = QemuVideoDetect(Pci.Hdr.ClassCode[1], Pci.Hdr.VendorId, Pci.Hdr.DeviceId);
+ if (Card != NULL) {
+ DEBUG ((EFI_D_INFO, "QemuVideo: %s detected\n", Card->Name));
+ Status = EFI_SUCCESS;
+ }
+
+Done:
+ //
+ // Close the PCI I/O Protocol
+ //
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ return Status;
+}
+
+/**
+ Start to process the controller.
+
+ @param This The USB bus driver binding instance.
+ @param Controller The controller to check.
+ @param RemainingDevicePath The remaining device patch.
+
+ @retval EFI_SUCCESS The controller is controlled by the usb bus.
+ @retval EFI_ALREADY_STARTED The controller is already controlled by the usb
+ bus.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoControllerDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_TPL OldTpl;
+ EFI_STATUS Status;
+ QEMU_VIDEO_PRIVATE_DATA *Private;
+ BOOLEAN IsQxl;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ ACPI_ADR_DEVICE_PATH AcpiDeviceNode;
+ PCI_TYPE00 Pci;
+ QEMU_VIDEO_CARD *Card;
+ EFI_PCI_IO_PROTOCOL *ChildPciIo;
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ //
+ // Allocate Private context data for GOP inteface.
+ //
+ Private = AllocateZeroPool (sizeof (QEMU_VIDEO_PRIVATE_DATA));
+ if (Private == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RestoreTpl;
+ }
+
+ //
+ // Set up context record
+ //
+ Private->Signature = QEMU_VIDEO_PRIVATE_DATA_SIGNATURE;
+
+ //
+ // Open PCI I/O Protocol
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &Private->PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreePrivate;
+ }
+
+ //
+ // Read the PCI Configuration Header from the PCI Device
+ //
+ Status = Private->PciIo->Pci.Read (
+ Private->PciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ sizeof (Pci) / sizeof (UINT32),
+ &Pci
+ );
+ if (EFI_ERROR (Status)) {
+ goto ClosePciIo;
+ }
+
+ //
+ // Determine card variant.
+ //
+ Card = QemuVideoDetect(Pci.Hdr.ClassCode[1], Pci.Hdr.VendorId, Pci.Hdr.DeviceId);
+ if (Card == NULL) {
+ Status = EFI_DEVICE_ERROR;
+ goto ClosePciIo;
+ }
+ Private->Variant = Card->Variant;
+
+ //
+ // IsQxl is based on the detected Card->Variant, which at a later point might
+ // not match Private->Variant.
+ //
+ IsQxl = (BOOLEAN)(Card->Variant == QEMU_VIDEO_BOCHS);
+
+ //
+ // Save original PCI attributes
+ //
+ Status = Private->PciIo->Attributes (
+ Private->PciIo,
+ EfiPciIoAttributeOperationGet,
+ 0,
+ &Private->OriginalPciAttributes
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto ClosePciIo;
+ }
+
+ //
+ // Set new PCI attributes
+ //
+ Status = Private->PciIo->Attributes (
+ Private->PciIo,
+ EfiPciIoAttributeOperationEnable,
+ EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto ClosePciIo;
+ }
+
+ //
+ // Check whenever the qemu stdvga mmio bar is present (qemu 1.3+).
+ //
+ if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *MmioDesc;
+
+ Status = Private->PciIo->GetBarAttributes (
+ Private->PciIo,
+ PCI_BAR_IDX2,
+ NULL,
+ (VOID**) &MmioDesc
+ );
+ if (EFI_ERROR (Status) ||
+ MmioDesc->ResType != ACPI_ADDRESS_SPACE_TYPE_MEM) {
+ DEBUG ((EFI_D_INFO, "QemuVideo: No mmio bar, fallback to port io\n"));
+ Private->Variant = QEMU_VIDEO_BOCHS;
+ } else {
+ DEBUG ((EFI_D_INFO, "QemuVideo: Using mmio bar @ 0x%lx\n",
+ MmioDesc->AddrRangeMin));
+ }
+
+ if (!EFI_ERROR (Status)) {
+ FreePool (MmioDesc);
+ }
+ }
+
+ //
+ // Check if accessing the bochs interface works.
+ //
+ if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO ||
+ Private->Variant == QEMU_VIDEO_BOCHS) {
+ UINT16 BochsId;
+ BochsId = BochsRead(Private, VBE_DISPI_INDEX_ID);
+ if ((BochsId & 0xFFF0) != VBE_DISPI_ID0) {
+ DEBUG ((EFI_D_INFO, "QemuVideo: BochsID mismatch (got 0x%x)\n", BochsId));
+ Status = EFI_DEVICE_ERROR;
+ goto RestoreAttributes;
+ }
+ }
+
+ //
+ // Get ParentDevicePath
+ //
+ Status = gBS->HandleProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &ParentDevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ goto RestoreAttributes;
+ }
+
+ //
+ // Set Gop Device Path
+ //
+ ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));
+ AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;
+ AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;
+ AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);
+ SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH));
+
+ Private->GopDevicePath = AppendDevicePathNode (
+ ParentDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode
+ );
+ if (Private->GopDevicePath == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RestoreAttributes;
+ }
+
+ //
+ // Create new child handle and install the device path protocol on it.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Private->Handle,
+ &gEfiDevicePathProtocolGuid,
+ Private->GopDevicePath,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreeGopDevicePath;
+ }
+
+ //
+ // Construct video mode buffer
+ //
+ switch (Private->Variant) {
+ case QEMU_VIDEO_CIRRUS_5430:
+ case QEMU_VIDEO_CIRRUS_5446:
+ Status = QemuVideoCirrusModeSetup (Private);
+ break;
+ case QEMU_VIDEO_BOCHS_MMIO:
+ case QEMU_VIDEO_BOCHS:
+ Status = QemuVideoBochsModeSetup (Private, IsQxl);
+ break;
+ default:
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ break;
+ }
+ if (EFI_ERROR (Status)) {
+ goto UninstallGopDevicePath;
+ }
+
+ //
+ // Start the GOP software stack.
+ //
+ Status = QemuVideoGraphicsOutputConstructor (Private);
+ if (EFI_ERROR (Status)) {
+ goto FreeModeData;
+ }
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Private->Handle,
+ &gEfiGraphicsOutputProtocolGuid,
+ &Private->GraphicsOutput,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto DestructQemuVideoGraphics;
+ }
+
+ //
+ // Reference parent handle from child handle.
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &ChildPciIo,
+ This->DriverBindingHandle,
+ Private->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ goto UninstallGop;
+ }
+
+#if defined MDE_CPU_IA32 || defined MDE_CPU_X64
+ if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO ||
+ Private->Variant == QEMU_VIDEO_BOCHS) {
+ InstallVbeShim (Card->Name, Private->GraphicsOutput.Mode->FrameBufferBase);
+ }
+#endif
+
+ gBS->RestoreTPL (OldTpl);
+ return EFI_SUCCESS;
+
+UninstallGop:
+ gBS->UninstallProtocolInterface (Private->Handle,
+ &gEfiGraphicsOutputProtocolGuid, &Private->GraphicsOutput);
+
+DestructQemuVideoGraphics:
+ QemuVideoGraphicsOutputDestructor (Private);
+
+FreeModeData:
+ FreePool (Private->ModeData);
+
+UninstallGopDevicePath:
+ gBS->UninstallProtocolInterface (Private->Handle,
+ &gEfiDevicePathProtocolGuid, Private->GopDevicePath);
+
+FreeGopDevicePath:
+ FreePool (Private->GopDevicePath);
+
+RestoreAttributes:
+ Private->PciIo->Attributes (Private->PciIo, EfiPciIoAttributeOperationSet,
+ Private->OriginalPciAttributes, NULL);
+
+ClosePciIo:
+ gBS->CloseProtocol (Controller, &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle, Controller);
+
+FreePrivate:
+ FreePool (Private);
+
+RestoreTpl:
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+/**
+ Stop this device
+
+ @param This The USB bus driver binding protocol.
+ @param Controller The controller to release.
+ @param NumberOfChildren The number of children of this device that
+ opened the controller BY_CHILD.
+ @param ChildHandleBuffer The array of child handle.
+
+ @retval EFI_SUCCESS The controller or children are stopped.
+ @retval EFI_DEVICE_ERROR Failed to stop the driver.
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoControllerDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+
+ EFI_STATUS Status;
+ QEMU_VIDEO_PRIVATE_DATA *Private;
+
+ if (NumberOfChildren == 0) {
+ //
+ // Close the PCI I/O Protocol
+ //
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ return EFI_SUCCESS;
+ }
+
+ //
+ // free all resources for whose access we need the child handle, because the
+ // child handle is going away
+ //
+ ASSERT (NumberOfChildren == 1);
+ Status = gBS->OpenProtocol (
+ ChildHandleBuffer[0],
+ &gEfiGraphicsOutputProtocolGuid,
+ (VOID **) &GraphicsOutput,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get our private context information
+ //
+ Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput);
+ ASSERT (Private->Handle == ChildHandleBuffer[0]);
+
+ QemuVideoGraphicsOutputDestructor (Private);
+ //
+ // Remove the GOP protocol interface from the system
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ Private->Handle,
+ &gEfiGraphicsOutputProtocolGuid,
+ &Private->GraphicsOutput,
+ NULL
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Restore original PCI attributes
+ //
+ Private->PciIo->Attributes (
+ Private->PciIo,
+ EfiPciIoAttributeOperationSet,
+ Private->OriginalPciAttributes,
+ NULL
+ );
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Private->Handle
+ );
+
+ FreePool (Private->ModeData);
+ gBS->UninstallProtocolInterface (Private->Handle,
+ &gEfiDevicePathProtocolGuid, Private->GopDevicePath);
+ FreePool (Private->GopDevicePath);
+
+ //
+ // Free our instance data
+ //
+ gBS->FreePool (Private);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+ @param Address TODO: add argument description
+ @param Data TODO: add argument description
+
+ TODO: add return values
+
+**/
+VOID
+outb (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Address,
+ UINT8 Data
+ )
+{
+ EFI_STATUS Status;
+ VOID *Interface;
+ Private->PciIo->Io.Write (
+ Private->PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Address,
+ 1,
+ &Data
+ );
+ Status = gBS->LocateProtocol(&gEfiDxeSmmReadyToLockProtocolGuid, NULL, &Interface);
+ if (!EFI_ERROR(Status)) {
+ return;
+ }
+
+ Status = S3BootScriptSaveIoWrite(
+ S3BootScriptWidthUint8,
+ Address,
+ (UINTN)1,
+ &Data
+ );
+}
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+ @param Address TODO: add argument description
+ @param Data TODO: add argument description
+
+ TODO: add return values
+
+**/
+VOID
+outw (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Address,
+ UINT16 Data
+ )
+{
+ EFI_STATUS Status;
+ VOID *Interface;
+
+ Private->PciIo->Io.Write (
+ Private->PciIo,
+ EfiPciIoWidthUint16,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Address,
+ 1,
+ &Data
+ );
+
+ Status = gBS->LocateProtocol(&gEfiDxeSmmReadyToLockProtocolGuid, NULL, &Interface);
+ if (!EFI_ERROR(Status)) {
+ return;
+ }
+ Status = S3BootScriptSaveIoWrite(
+ S3BootScriptWidthUint16,
+ Address,
+ 1,
+ &Data
+ );
+}
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+ @param Address TODO: add argument description
+
+ TODO: add return values
+
+**/
+UINT8
+inb (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Address
+ )
+{
+ UINT8 Data;
+
+ Private->PciIo->Io.Read (
+ Private->PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Address,
+ 1,
+ &Data
+ );
+ return Data;
+}
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+ @param Address TODO: add argument description
+
+ TODO: add return values
+
+**/
+UINT16
+inw (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Address
+ )
+{
+ UINT16 Data;
+
+ Private->PciIo->Io.Read (
+ Private->PciIo,
+ EfiPciIoWidthUint16,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Address,
+ 1,
+ &Data
+ );
+ return Data;
+}
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+ @param Index TODO: add argument description
+ @param Red TODO: add argument description
+ @param Green TODO: add argument description
+ @param Blue TODO: add argument description
+
+ TODO: add return values
+
+**/
+VOID
+SetPaletteColor (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Index,
+ UINT8 Red,
+ UINT8 Green,
+ UINT8 Blue
+ )
+{
+ VgaOutb (Private, PALETTE_INDEX_REGISTER, (UINT8) Index);
+ VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8) (Red >> 2));
+ VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8) (Green >> 2));
+ VgaOutb (Private, PALETTE_DATA_REGISTER, (UINT8) (Blue >> 2));
+}
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+
+ TODO: add return values
+
+**/
+VOID
+SetDefaultPalette (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ )
+{
+ UINTN Index;
+ UINTN RedIndex;
+ UINTN GreenIndex;
+ UINTN BlueIndex;
+
+ Index = 0;
+ for (RedIndex = 0; RedIndex < 8; RedIndex++) {
+ for (GreenIndex = 0; GreenIndex < 8; GreenIndex++) {
+ for (BlueIndex = 0; BlueIndex < 4; BlueIndex++) {
+ SetPaletteColor (Private, Index, (UINT8) (RedIndex << 5), (UINT8) (GreenIndex << 5), (UINT8) (BlueIndex << 6));
+ Index++;
+ }
+ }
+ }
+}
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+
+ TODO: add return values
+
+**/
+VOID
+ClearScreen (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ )
+{
+ UINT32 Color;
+
+ Color = 0;
+ Private->PciIo->Mem.Write (
+ Private->PciIo,
+ EfiPciIoWidthFillUint32,
+ 0,
+ 0,
+ 0x400000 >> 2,
+ &Color
+ );
+}
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+
+ TODO: add return values
+
+**/
+VOID
+DrawLogo (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN ScreenWidth,
+ UINTN ScreenHeight
+ )
+{
+}
+
+/**
+ TODO: Add function description
+
+ @param Private TODO: add argument description
+ @param ModeData TODO: add argument description
+
+ TODO: add return values
+
+**/
+VOID
+InitializeCirrusGraphicsMode (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ QEMU_VIDEO_CIRRUS_MODES *ModeData
+ )
+{
+ UINT8 Byte;
+ UINTN Index;
+
+ outw (Private, SEQ_ADDRESS_REGISTER, 0x1206);
+ outw (Private, SEQ_ADDRESS_REGISTER, 0x0012);
+
+ for (Index = 0; Index < 15; Index++) {
+ outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]);
+ }
+
+ if (Private->Variant == QEMU_VIDEO_CIRRUS_5430) {
+ outb (Private, SEQ_ADDRESS_REGISTER, 0x0f);
+ Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30);
+ outb (Private, SEQ_DATA_REGISTER, Byte);
+ }
+
+ outb (Private, MISC_OUTPUT_REGISTER, ModeData->MiscSetting);
+ outw (Private, GRAPH_ADDRESS_REGISTER, 0x0506);
+ outw (Private, SEQ_ADDRESS_REGISTER, 0x0300);
+ outw (Private, CRTC_ADDRESS_REGISTER, 0x2011);
+
+ for (Index = 0; Index < 28; Index++) {
+ outw (Private, CRTC_ADDRESS_REGISTER, (UINT16) ((ModeData->CrtcSettings[Index] << 8) | Index));
+ }
+
+ for (Index = 0; Index < 9; Index++) {
+ outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((GraphicsController[Index] << 8) | Index));
+ }
+
+ inb (Private, INPUT_STATUS_1_REGISTER);
+
+ for (Index = 0; Index < 21; Index++) {
+ outb (Private, ATT_ADDRESS_REGISTER, (UINT8) Index);
+ outb (Private, ATT_ADDRESS_REGISTER, AttributeController[Index]);
+ }
+
+ outb (Private, ATT_ADDRESS_REGISTER, 0x20);
+
+ outw (Private, GRAPH_ADDRESS_REGISTER, 0x0009);
+ outw (Private, GRAPH_ADDRESS_REGISTER, 0x000a);
+ outw (Private, GRAPH_ADDRESS_REGISTER, 0x000b);
+ outb (Private, DAC_PIXEL_MASK_REGISTER, 0xff);
+
+ SetDefaultPalette (Private);
+ ClearScreen (Private);
+}
+
+VOID
+BochsWrite (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINT16 Reg,
+ UINT16 Data
+ )
+{
+ EFI_STATUS Status;
+
+ if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
+ Status = Private->PciIo->Mem.Write (
+ Private->PciIo,
+ EfiPciIoWidthUint16,
+ PCI_BAR_IDX2,
+ 0x500 + (Reg << 1),
+ 1,
+ &Data
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ outw (Private, VBE_DISPI_IOPORT_INDEX, Reg);
+ outw (Private, VBE_DISPI_IOPORT_DATA, Data);
+ }
+}
+
+UINT16
+BochsRead (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINT16 Reg
+ )
+{
+ EFI_STATUS Status;
+ UINT16 Data;
+
+ if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
+ Status = Private->PciIo->Mem.Read (
+ Private->PciIo,
+ EfiPciIoWidthUint16,
+ PCI_BAR_IDX2,
+ 0x500 + (Reg << 1),
+ 1,
+ &Data
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ outw (Private, VBE_DISPI_IOPORT_INDEX, Reg);
+ Data = inw (Private, VBE_DISPI_IOPORT_DATA);
+ }
+ return Data;
+}
+
+VOID
+VgaOutb (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Reg,
+ UINT8 Data
+ )
+{
+ EFI_STATUS Status;
+
+ if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {
+ Status = Private->PciIo->Mem.Write (
+ Private->PciIo,
+ EfiPciIoWidthUint8,
+ PCI_BAR_IDX2,
+ 0x400 - 0x3c0 + Reg,
+ 1,
+ &Data
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ outb (Private, Reg, Data);
+ }
+}
+
+VOID
+InitializeBochsGraphicsMode (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ QEMU_VIDEO_BOCHS_MODES *ModeData
+ )
+{
+ DEBUG ((EFI_D_INFO, "InitializeBochsGraphicsMode: %dx%d @ %d\n",
+ ModeData->Width, ModeData->Height, ModeData->ColorDepth));
+
+ /* unblank */
+ VgaOutb (Private, ATT_ADDRESS_REGISTER, 0x20);
+
+ BochsWrite (Private, VBE_DISPI_INDEX_ENABLE, 0);
+ BochsWrite (Private, VBE_DISPI_INDEX_BANK, 0);
+ BochsWrite (Private, VBE_DISPI_INDEX_X_OFFSET, 0);
+ BochsWrite (Private, VBE_DISPI_INDEX_Y_OFFSET, 0);
+
+ BochsWrite (Private, VBE_DISPI_INDEX_BPP, (UINT16) ModeData->ColorDepth);
+ BochsWrite (Private, VBE_DISPI_INDEX_XRES, (UINT16) ModeData->Width);
+ BochsWrite (Private, VBE_DISPI_INDEX_VIRT_WIDTH, (UINT16) ModeData->Width);
+ BochsWrite (Private, VBE_DISPI_INDEX_YRES, (UINT16) ModeData->Height);
+ BochsWrite (Private, VBE_DISPI_INDEX_VIRT_HEIGHT, (UINT16) ModeData->Height);
+
+ BochsWrite (Private, VBE_DISPI_INDEX_ENABLE,
+ VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
+
+ SetDefaultPalette (Private);
+ ClearScreen (Private);
+}
+
+EFI_STATUS
+EFIAPI
+InitializeQemuVideo (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EfiLibInstallDriverBindingComponentName2 (
+ ImageHandle,
+ SystemTable,
+ &gQemuVideoDriverBinding,
+ ImageHandle,
+ &gQemuVideoComponentName,
+ &gQemuVideoComponentName2
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Install EFI Driver Supported EFI Version Protocol required for
+ // EFI drivers that are on PCI and other plug in cards.
+ //
+ gQemuVideoDriverSupportedEfiVersion.FirmwareVersion = PcdGet32 (PcdDriverSupportedEfiVersion);
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &gEfiDriverSupportedEfiVersionProtocolGuid,
+ &gQemuVideoDriverSupportedEfiVersion,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/DriverSupportedEfiVersion.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/DriverSupportedEfiVersion.c
new file mode 100644
index 0000000000..af658f9f60
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/DriverSupportedEfiVersion.c
@@ -0,0 +1,15 @@
+/** @file
+ Driver supported version protocol for the QEMU video driver.
+
+ Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Qemu.h"
+
+EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gQemuVideoDriverSupportedEfiVersion = {
+ sizeof (EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL), // Size of Protocol structure.
+ 0 // Version number to be filled at start up.
+};
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.c
new file mode 100644
index 0000000000..5158e4851e
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.c
@@ -0,0 +1,416 @@
+/** @file
+ Graphics Output Protocol functions for the QEMU video controller.
+
+ Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Qemu.h"
+
+STATIC
+VOID
+QemuVideoCompleteModeInfo (
+ IN QEMU_VIDEO_MODE_DATA *ModeData,
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info
+ )
+{
+ Info->Version = 0;
+ if (ModeData->ColorDepth == 8) {
+ Info->PixelFormat = PixelBitMask;
+ Info->PixelInformation.RedMask = PIXEL_RED_MASK;
+ Info->PixelInformation.GreenMask = PIXEL_GREEN_MASK;
+ Info->PixelInformation.BlueMask = PIXEL_BLUE_MASK;
+ Info->PixelInformation.ReservedMask = 0;
+ } else if (ModeData->ColorDepth == 24) {
+ Info->PixelFormat = PixelBitMask;
+ Info->PixelInformation.RedMask = PIXEL24_RED_MASK;
+ Info->PixelInformation.GreenMask = PIXEL24_GREEN_MASK;
+ Info->PixelInformation.BlueMask = PIXEL24_BLUE_MASK;
+ Info->PixelInformation.ReservedMask = 0;
+ } else if (ModeData->ColorDepth == 32) {
+ DEBUG ((EFI_D_INFO, "PixelBlueGreenRedReserved8BitPerColor\n"));
+ Info->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
+ }
+ Info->PixelsPerScanLine = Info->HorizontalResolution;
+}
+
+
+STATIC
+EFI_STATUS
+QemuVideoCompleteModeData (
+ IN QEMU_VIDEO_PRIVATE_DATA *Private,
+ OUT EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode
+ )
+{
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *FrameBufDesc;
+ QEMU_VIDEO_MODE_DATA *ModeData;
+
+ ModeData = &Private->ModeData[Mode->Mode];
+ Info = Mode->Info;
+ QemuVideoCompleteModeInfo (ModeData, Info);
+
+ Private->PciIo->GetBarAttributes (
+ Private->PciIo,
+ 0,
+ NULL,
+ (VOID**) &FrameBufDesc
+ );
+
+ Mode->FrameBufferBase = FrameBufDesc->AddrRangeMin;
+ Mode->FrameBufferSize = Info->HorizontalResolution * Info->VerticalResolution;
+ Mode->FrameBufferSize = Mode->FrameBufferSize * ((ModeData->ColorDepth + 7) / 8);
+ Mode->FrameBufferSize = EFI_PAGES_TO_SIZE (
+ EFI_SIZE_TO_PAGES (Mode->FrameBufferSize)
+ );
+ DEBUG ((EFI_D_INFO, "FrameBufferBase: 0x%Lx, FrameBufferSize: 0x%Lx\n",
+ Mode->FrameBufferBase, (UINT64)Mode->FrameBufferSize));
+
+ FreePool (FrameBufDesc);
+ return EFI_SUCCESS;
+}
+
+//
+// Graphics Output Protocol Member Functions
+//
+EFI_STATUS
+EFIAPI
+QemuVideoGraphicsOutputQueryMode (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN UINT32 ModeNumber,
+ OUT UINTN *SizeOfInfo,
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
+ )
+/*++
+
+Routine Description:
+
+ Graphics Output protocol interface to query video mode
+
+ Arguments:
+ This - Protocol instance pointer.
+ ModeNumber - The mode number to return information on.
+ Info - Caller allocated buffer that returns information about ModeNumber.
+ SizeOfInfo - A pointer to the size, in bytes, of the Info buffer.
+
+ Returns:
+ EFI_SUCCESS - Mode information returned.
+ EFI_BUFFER_TOO_SMALL - The Info buffer was too small.
+ EFI_DEVICE_ERROR - A hardware error occurred trying to retrieve the video mode.
+ EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()
+ EFI_INVALID_PARAMETER - One of the input args was NULL.
+
+--*/
+{
+ QEMU_VIDEO_PRIVATE_DATA *Private;
+ QEMU_VIDEO_MODE_DATA *ModeData;
+
+ Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
+
+ if (Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
+ if (*Info == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
+
+ ModeData = &Private->ModeData[ModeNumber];
+ (*Info)->HorizontalResolution = ModeData->HorizontalResolution;
+ (*Info)->VerticalResolution = ModeData->VerticalResolution;
+ QemuVideoCompleteModeInfo (ModeData, *Info);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+QemuVideoGraphicsOutputSetMode (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN UINT32 ModeNumber
+ )
+/*++
+
+Routine Description:
+
+ Graphics Output protocol interface to set video mode
+
+ Arguments:
+ This - Protocol instance pointer.
+ ModeNumber - The mode number to be set.
+
+ Returns:
+ EFI_SUCCESS - Graphics mode was changed.
+ EFI_DEVICE_ERROR - The device had an error and could not complete the request.
+ EFI_UNSUPPORTED - ModeNumber is not supported by this device.
+
+--*/
+{
+ QEMU_VIDEO_PRIVATE_DATA *Private;
+ QEMU_VIDEO_MODE_DATA *ModeData;
+ RETURN_STATUS Status;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black;
+
+ Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
+
+ if (ModeNumber >= This->Mode->MaxMode) {
+ return EFI_UNSUPPORTED;
+ }
+
+ ModeData = &Private->ModeData[ModeNumber];
+
+ switch (Private->Variant) {
+ case QEMU_VIDEO_CIRRUS_5430:
+ case QEMU_VIDEO_CIRRUS_5446:
+ InitializeCirrusGraphicsMode (Private, &QemuVideoCirrusModes[ModeData->InternalModeIndex]);
+ break;
+ case QEMU_VIDEO_BOCHS_MMIO:
+ case QEMU_VIDEO_BOCHS:
+ InitializeBochsGraphicsMode (Private, &QemuVideoBochsModes[ModeData->InternalModeIndex]);
+ break;
+ default:
+ ASSERT (FALSE);
+ return EFI_DEVICE_ERROR;
+ }
+
+ This->Mode->Mode = ModeNumber;
+ This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;
+ This->Mode->Info->VerticalResolution = ModeData->VerticalResolution;
+ This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
+
+ QemuVideoCompleteModeData (Private, This->Mode);
+
+ //
+ // Re-initialize the frame buffer configure when mode changes.
+ //
+ Status = FrameBufferBltConfigure (
+ (VOID*) (UINTN) This->Mode->FrameBufferBase,
+ This->Mode->Info,
+ Private->FrameBufferBltConfigure,
+ &Private->FrameBufferBltConfigureSize
+ );
+ if (Status == RETURN_BUFFER_TOO_SMALL) {
+ //
+ // Frame buffer configure may be larger in new mode.
+ //
+ if (Private->FrameBufferBltConfigure != NULL) {
+ FreePool (Private->FrameBufferBltConfigure);
+ }
+ Private->FrameBufferBltConfigure =
+ AllocatePool (Private->FrameBufferBltConfigureSize);
+ ASSERT (Private->FrameBufferBltConfigure != NULL);
+
+ //
+ // Create the configuration for FrameBufferBltLib
+ //
+ Status = FrameBufferBltConfigure (
+ (VOID*) (UINTN) This->Mode->FrameBufferBase,
+ This->Mode->Info,
+ Private->FrameBufferBltConfigure,
+ &Private->FrameBufferBltConfigureSize
+ );
+ }
+ ASSERT (Status == RETURN_SUCCESS);
+
+ //
+ // Per UEFI Spec, need to clear the visible portions of the output display to black.
+ //
+ ZeroMem (&Black, sizeof (Black));
+ Status = FrameBufferBlt (
+ Private->FrameBufferBltConfigure,
+ &Black,
+ EfiBltVideoFill,
+ 0, 0,
+ 0, 0,
+ This->Mode->Info->HorizontalResolution, This->Mode->Info->VerticalResolution,
+ 0
+ );
+ ASSERT_RETURN_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+QemuVideoGraphicsOutputBlt (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta
+ )
+/*++
+
+Routine Description:
+
+ Graphics Output protocol instance to block transfer for CirrusLogic device
+
+Arguments:
+
+ This - Pointer to Graphics Output protocol instance
+ BltBuffer - The data to transfer to screen
+ BltOperation - The operation to perform
+ SourceX - The X coordinate of the source for BltOperation
+ SourceY - The Y coordinate of the source for BltOperation
+ DestinationX - The X coordinate of the destination for BltOperation
+ DestinationY - The Y coordinate of the destination for BltOperation
+ Width - The width of a rectangle in the blt rectangle in pixels
+ Height - The height of a rectangle in the blt rectangle in pixels
+ Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
+ If a Delta of 0 is used, the entire BltBuffer will be operated on.
+ If a subrectangle of the BltBuffer is used, then Delta represents
+ the number of bytes in a row of the BltBuffer.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter passed in
+ EFI_SUCCESS - Blt operation success
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_TPL OriginalTPL;
+ QEMU_VIDEO_PRIVATE_DATA *Private;
+
+ Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
+ //
+ // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
+ // We would not want a timer based event (Cursor, ...) to come in while we are
+ // doing this operation.
+ //
+ OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);
+
+ switch (BltOperation) {
+ case EfiBltVideoToBltBuffer:
+ case EfiBltBufferToVideo:
+ case EfiBltVideoFill:
+ case EfiBltVideoToVideo:
+ Status = FrameBufferBlt (
+ Private->FrameBufferBltConfigure,
+ BltBuffer,
+ BltOperation,
+ SourceX,
+ SourceY,
+ DestinationX,
+ DestinationY,
+ Width,
+ Height,
+ Delta
+ );
+ break;
+
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ gBS->RestoreTPL (OriginalTPL);
+
+ return Status;
+}
+
+EFI_STATUS
+QemuVideoGraphicsOutputConstructor (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+
+
+ GraphicsOutput = &Private->GraphicsOutput;
+ GraphicsOutput->QueryMode = QemuVideoGraphicsOutputQueryMode;
+ GraphicsOutput->SetMode = QemuVideoGraphicsOutputSetMode;
+ GraphicsOutput->Blt = QemuVideoGraphicsOutputBlt;
+
+ //
+ // Initialize the private data
+ //
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE),
+ (VOID **) &Private->GraphicsOutput.Mode
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
+ (VOID **) &Private->GraphicsOutput.Mode->Info
+ );
+ if (EFI_ERROR (Status)) {
+ goto FreeMode;
+ }
+ Private->GraphicsOutput.Mode->MaxMode = (UINT32) Private->MaxMode;
+ Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;
+ Private->FrameBufferBltConfigure = NULL;
+ Private->FrameBufferBltConfigureSize = 0;
+
+ //
+ // Initialize the hardware
+ //
+ Status = GraphicsOutput->SetMode (GraphicsOutput, 0);
+ if (EFI_ERROR (Status)) {
+ goto FreeInfo;
+ }
+
+ DrawLogo (
+ Private,
+ Private->ModeData[Private->GraphicsOutput.Mode->Mode].HorizontalResolution,
+ Private->ModeData[Private->GraphicsOutput.Mode->Mode].VerticalResolution
+ );
+
+ return EFI_SUCCESS;
+
+FreeInfo:
+ FreePool (Private->GraphicsOutput.Mode->Info);
+
+FreeMode:
+ FreePool (Private->GraphicsOutput.Mode);
+ Private->GraphicsOutput.Mode = NULL;
+
+ return Status;
+}
+
+EFI_STATUS
+QemuVideoGraphicsOutputDestructor (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+{
+ if (Private->FrameBufferBltConfigure != NULL) {
+ FreePool (Private->FrameBufferBltConfigure);
+ }
+
+ if (Private->GraphicsOutput.Mode != NULL) {
+ if (Private->GraphicsOutput.Mode->Info != NULL) {
+ gBS->FreePool (Private->GraphicsOutput.Mode->Info);
+ }
+ gBS->FreePool (Private->GraphicsOutput.Mode);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Initialize.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Initialize.c
new file mode 100644
index 0000000000..543d360861
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Initialize.c
@@ -0,0 +1,341 @@
+/** @file
+ Graphics Output Protocol functions for the QEMU video controller.
+
+ Copyright (c) 2007 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Qemu.h"
+
+
+///
+/// Generic Attribute Controller Register Settings
+///
+UINT8 AttributeController[21] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x41, 0x00, 0x0F, 0x00, 0x00
+};
+
+///
+/// Generic Graphics Controller Register Settings
+///
+UINT8 GraphicsController[9] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF
+};
+
+//
+// 640 x 480 x 256 color @ 60 Hertz
+//
+UINT8 Crtc_640_480_256_60[28] = {
+ 0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xe1, 0x83, 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3,
+ 0xff, 0x00, 0x00, 0x22
+};
+
+UINT8 Crtc_640_480_32bpp_60[28] = {
+ 0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xe1, 0x83, 0xdf, 0x40, 0x00, 0xe7, 0x04, 0xe3,
+ 0xff, 0x00, 0x00, 0x32
+};
+
+UINT16 Seq_640_480_256_60[15] = {
+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
+ 0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e
+};
+
+UINT16 Seq_640_480_32bpp_60[15] = {
+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,
+ 0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e
+};
+
+//
+// 800 x 600 x 256 color @ 60 Hertz
+//
+UINT8 Crtc_800_600_256_60[28] = {
+ 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x58, 0x8C, 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3,
+ 0xFF, 0x00, 0x00, 0x22
+};
+
+UINT8 Crtc_800_600_32bpp_60[28] = {
+ 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x58, 0x8C, 0x57, 0x90, 0x00, 0x5F, 0x91, 0xE3,
+ 0xFF, 0x00, 0x00, 0x32
+};
+
+UINT16 Seq_800_600_256_60[15] = {
+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
+ 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e
+};
+
+UINT16 Seq_800_600_32bpp_60[15] = {
+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,
+ 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e
+};
+
+UINT8 Crtc_960_720_32bpp_60[28] = {
+ 0xA3, 0x77, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x88, 0xCF, 0xe0, 0x00, 0x00, 0x64, 0xE3,
+ 0xFF, 0x4A, 0x00, 0x32
+};
+
+UINT16 Seq_960_720_32bpp_60[15] = {
+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,
+ 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
+};
+
+//
+// 1024 x 768 x 256 color @ 60 Hertz
+//
+UINT8 Crtc_1024_768_256_60[28] = {
+ 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,
+ 0xFF, 0x4A, 0x00, 0x22
+};
+
+UINT16 Seq_1024_768_256_60[15] = {
+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
+ 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
+};
+
+//
+// 1024 x 768 x 24-bit color @ 60 Hertz
+//
+UINT8 Crtc_1024_768_24bpp_60[28] = {
+ 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,
+ 0xFF, 0x4A, 0x00, 0x32
+};
+
+UINT16 Seq_1024_768_24bpp_60[15] = {
+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1507, 0x0008, 0x4a0b,
+ 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
+};
+
+UINT8 Crtc_1024_768_32bpp_60[28] = {
+ 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x88, 0xFF, 0xe0, 0x00, 0x00, 0x64, 0xE3,
+ 0xFF, 0x4A, 0x00, 0x32
+};
+
+UINT16 Seq_1024_768_32bpp_60[15] = {
+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1907, 0x0008, 0x4a0b,
+ 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
+};
+
+///
+/// Table of supported video modes
+///
+QEMU_VIDEO_CIRRUS_MODES QemuVideoCirrusModes[] = {
+// { 640, 480, 8, Crtc_640_480_256_60, Seq_640_480_256_60, 0xe3 },
+// { 800, 600, 8, Crtc_800_600_256_60, Seq_800_600_256_60, 0xef },
+ { 640, 480, 32, Crtc_640_480_32bpp_60, Seq_640_480_32bpp_60, 0xef },
+ { 800, 600, 32, Crtc_800_600_32bpp_60, Seq_800_600_32bpp_60, 0xef },
+// { 1024, 768, 8, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef }
+ { 1024, 768, 24, Crtc_1024_768_24bpp_60, Seq_1024_768_24bpp_60, 0xef }
+// { 1024, 768, 32, Crtc_1024_768_32bpp_60, Seq_1024_768_32bpp_60, 0xef }
+// { 960, 720, 32, Crtc_960_720_32bpp_60, Seq_1024_768_32bpp_60, 0xef }
+};
+
+#define QEMU_VIDEO_CIRRUS_MODE_COUNT \
+ (ARRAY_SIZE (QemuVideoCirrusModes))
+
+/**
+ Construct the valid video modes for QemuVideo.
+
+**/
+EFI_STATUS
+QemuVideoCirrusModeSetup (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ )
+{
+ UINT32 Index;
+ QEMU_VIDEO_MODE_DATA *ModeData;
+ QEMU_VIDEO_CIRRUS_MODES *VideoMode;
+
+ //
+ // Setup Video Modes
+ //
+ Private->ModeData = AllocatePool (
+ sizeof (Private->ModeData[0]) * QEMU_VIDEO_CIRRUS_MODE_COUNT
+ );
+ if (Private->ModeData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ ModeData = Private->ModeData;
+ VideoMode = &QemuVideoCirrusModes[0];
+ for (Index = 0; Index < QEMU_VIDEO_CIRRUS_MODE_COUNT; Index ++) {
+ ModeData->InternalModeIndex = Index;
+ ModeData->HorizontalResolution = VideoMode->Width;
+ ModeData->VerticalResolution = VideoMode->Height;
+ ModeData->ColorDepth = VideoMode->ColorDepth;
+ DEBUG ((EFI_D_INFO,
+ "Adding Mode %d as Cirrus Internal Mode %d: %dx%d, %d-bit\n",
+ (INT32) (ModeData - Private->ModeData),
+ ModeData->InternalModeIndex,
+ ModeData->HorizontalResolution,
+ ModeData->VerticalResolution,
+ ModeData->ColorDepth
+ ));
+
+ ModeData ++ ;
+ VideoMode ++;
+ }
+ Private->MaxMode = ModeData - Private->ModeData;
+
+ return EFI_SUCCESS;
+}
+
+///
+/// Table of supported video modes
+///
+QEMU_VIDEO_BOCHS_MODES QemuVideoBochsModes[] = {
+ { 640, 480, 32 },
+ { 800, 480, 32 },
+ { 800, 600, 32 },
+ { 832, 624, 32 },
+ { 960, 640, 32 },
+ { 1024, 600, 32 },
+ { 1024, 768, 32 },
+ { 1152, 864, 32 },
+ { 1152, 870, 32 },
+ { 1280, 720, 32 },
+ { 1280, 760, 32 },
+ { 1280, 768, 32 },
+ { 1280, 800, 32 },
+ { 1280, 960, 32 },
+ { 1280, 1024, 32 },
+ { 1360, 768, 32 },
+ { 1366, 768, 32 },
+ { 1400, 1050, 32 },
+ { 1440, 900, 32 },
+ { 1600, 900, 32 },
+ { 1600, 1200, 32 },
+ { 1680, 1050, 32 },
+ { 1920, 1080, 32 },
+ { 1920, 1200, 32 },
+ { 1920, 1440, 32 },
+ { 2000, 2000, 32 },
+ { 2048, 1536, 32 },
+ { 2048, 2048, 32 },
+ { 2560, 1440, 32 },
+ { 2560, 1600, 32 },
+ { 2560, 2048, 32 },
+ { 2800, 2100, 32 },
+ { 3200, 2400, 32 },
+ { 3840, 2160, 32 },
+ { 4096, 2160, 32 },
+ { 7680, 4320, 32 },
+ { 8192, 4320, 32 }
+};
+
+#define QEMU_VIDEO_BOCHS_MODE_COUNT \
+ (ARRAY_SIZE (QemuVideoBochsModes))
+
+EFI_STATUS
+QemuVideoBochsModeSetup (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ BOOLEAN IsQxl
+ )
+{
+ UINT32 AvailableFbSize;
+ UINT32 Index;
+ QEMU_VIDEO_MODE_DATA *ModeData;
+ QEMU_VIDEO_BOCHS_MODES *VideoMode;
+
+ //
+ // Fetch the available framebuffer size.
+ //
+ // VBE_DISPI_INDEX_VIDEO_MEMORY_64K is expected to return the size of the
+ // drawable framebuffer. Up to and including qemu-2.1 however it used to
+ // return the size of PCI BAR 0 (ie. the full video RAM size).
+ //
+ // On stdvga the two concepts coincide with each other; the full memory size
+ // is usable for drawing.
+ //
+ // On QXL however, only a leading segment, "surface 0", can be used for
+ // drawing; the rest of the video memory is used for the QXL guest-host
+ // protocol. VBE_DISPI_INDEX_VIDEO_MEMORY_64K should report the size of
+ // "surface 0", but since it doesn't (up to and including qemu-2.1), we
+ // retrieve the size of the drawable portion from a field in the QXL ROM BAR,
+ // where it is also available.
+ //
+ if (IsQxl) {
+ UINT32 Signature;
+ UINT32 DrawStart;
+
+ Signature = 0;
+ DrawStart = 0xFFFFFFFF;
+ AvailableFbSize = 0;
+ if (EFI_ERROR (
+ Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32,
+ PCI_BAR_IDX2, 0, 1, &Signature)) ||
+ Signature != SIGNATURE_32 ('Q', 'X', 'R', 'O') ||
+ EFI_ERROR (
+ Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32,
+ PCI_BAR_IDX2, 36, 1, &DrawStart)) ||
+ DrawStart != 0 ||
+ EFI_ERROR (
+ Private->PciIo->Mem.Read (Private->PciIo, EfiPciIoWidthUint32,
+ PCI_BAR_IDX2, 40, 1, &AvailableFbSize))) {
+ DEBUG ((EFI_D_ERROR, "%a: can't read size of drawable buffer from QXL "
+ "ROM\n", __FUNCTION__));
+ return EFI_NOT_FOUND;
+ }
+ } else {
+ AvailableFbSize = BochsRead (Private, VBE_DISPI_INDEX_VIDEO_MEMORY_64K);
+ AvailableFbSize *= SIZE_64KB;
+ }
+ DEBUG ((EFI_D_INFO, "%a: AvailableFbSize=0x%x\n", __FUNCTION__,
+ AvailableFbSize));
+
+ //
+ // Setup Video Modes
+ //
+ Private->ModeData = AllocatePool (
+ sizeof (Private->ModeData[0]) * QEMU_VIDEO_BOCHS_MODE_COUNT
+ );
+ if (Private->ModeData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ ModeData = Private->ModeData;
+ VideoMode = &QemuVideoBochsModes[0];
+ for (Index = 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index ++) {
+ UINTN RequiredFbSize;
+
+ ASSERT (VideoMode->ColorDepth % 8 == 0);
+ RequiredFbSize = (UINTN) VideoMode->Width * VideoMode->Height *
+ (VideoMode->ColorDepth / 8);
+ if (RequiredFbSize <= AvailableFbSize) {
+ ModeData->InternalModeIndex = Index;
+ ModeData->HorizontalResolution = VideoMode->Width;
+ ModeData->VerticalResolution = VideoMode->Height;
+ ModeData->ColorDepth = VideoMode->ColorDepth;
+ DEBUG ((EFI_D_INFO,
+ "Adding Mode %d as Bochs Internal Mode %d: %dx%d, %d-bit\n",
+ (INT32) (ModeData - Private->ModeData),
+ ModeData->InternalModeIndex,
+ ModeData->HorizontalResolution,
+ ModeData->VerticalResolution,
+ ModeData->ColorDepth
+ ));
+
+ ModeData ++ ;
+ }
+ VideoMode ++;
+ }
+ Private->MaxMode = ModeData - Private->ModeData;
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c
new file mode 100644
index 0000000000..aa4648f813
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c
@@ -0,0 +1,302 @@
+/** @file
+ Install a fake VGABIOS service handler (real mode Int10h) for the buggy
+ Windows 2008 R2 SP1 UEFI guest.
+
+ The handler is never meant to be directly executed by a VCPU; it's there for
+ the internal real mode emulator of Windows 2008 R2 SP1.
+
+ The code is based on Ralf Brown's Interrupt List:
+ <http://www.cs.cmu.edu/~ralf/files.html>
+ <http://www.ctyme.com/rbrown.htm>
+
+ Copyright (C) 2014, Red Hat, Inc.
+ Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <IndustryStandard/LegacyVgaBios.h>
+#include <Library/DebugLib.h>
+#include <Library/PciLib.h>
+#include <Library/PrintLib.h>
+#include <SimicsPlatforms.h>
+
+#include "Qemu.h"
+#include "VbeShim.h"
+
+#pragma pack (1)
+typedef struct {
+ UINT16 Offset;
+ UINT16 Segment;
+} IVT_ENTRY;
+#pragma pack ()
+
+//
+// This string is displayed by Windows 2008 R2 SP1 in the Screen Resolution,
+// Advanced Settings dialog. It should be short.
+//
+STATIC CONST CHAR8 mProductRevision[] = "OVMF Int10h (fake)";
+
+/**
+ Install the VBE Info and VBE Mode Info structures, and the VBE service
+ handler routine in the C segment. Point the real-mode Int10h interrupt vector
+ to the handler. The only advertised mode is 1024x768x32.
+
+ @param[in] CardName Name of the video card to be exposed in the
+ Product Name field of the VBE Info structure. The
+ parameter must originate from a
+ QEMU_VIDEO_CARD.Name field.
+ @param[in] FrameBufferBase Guest-physical base address of the video card's
+ frame buffer.
+**/
+VOID
+InstallVbeShim (
+ IN CONST CHAR16 *CardName,
+ IN EFI_PHYSICAL_ADDRESS FrameBufferBase
+ )
+{
+ EFI_PHYSICAL_ADDRESS Segment0, SegmentC, SegmentF;
+ UINTN Segment0Pages;
+ IVT_ENTRY *Int0x10;
+ EFI_STATUS Segment0AllocationStatus;
+ UINT16 HostBridgeDevId;
+ UINTN SegmentCPages;
+ VBE_INFO *VbeInfoFull;
+ VBE_INFO_BASE *VbeInfo;
+ UINT8 *Ptr;
+ UINTN Printed;
+ VBE_MODE_INFO *VbeModeInfo;
+
+ if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT0|BIT7)) == BIT0) {
+ DEBUG ((
+ DEBUG_WARN,
+ "%a: page 0 protected, not installing VBE shim\n",
+ __FUNCTION__
+ ));
+ DEBUG ((
+ DEBUG_WARN,
+ "%a: page 0 protection prevents Windows 7 from booting anyway\n",
+ __FUNCTION__
+ ));
+ return;
+ }
+
+ Segment0 = 0x00000;
+ SegmentC = 0xC0000;
+ SegmentF = 0xF0000;
+
+ //
+ // Attempt to cover the real mode IVT with an allocation. This is a UEFI
+ // driver, hence the arch protocols have been installed previously. Among
+ // those, the CPU arch protocol has configured the IDT, so we can overwrite
+ // the IVT used in real mode.
+ //
+ // The allocation request may fail, eg. if LegacyBiosDxe has already run.
+ //
+ Segment0Pages = 1;
+ Int0x10 = (IVT_ENTRY *)(UINTN)Segment0 + 0x10;
+ Segment0AllocationStatus = gBS->AllocatePages (
+ AllocateAddress,
+ EfiBootServicesCode,
+ Segment0Pages,
+ &Segment0
+ );
+
+ if (EFI_ERROR (Segment0AllocationStatus)) {
+ EFI_PHYSICAL_ADDRESS Handler;
+
+ //
+ // Check if a video BIOS handler has been installed previously -- we
+ // shouldn't override a real video BIOS with our shim, nor our own shim if
+ // it's already present.
+ //
+ Handler = (Int0x10->Segment << 4) + Int0x10->Offset;
+ if (Handler >= SegmentC && Handler < SegmentF) {
+ DEBUG ((EFI_D_INFO, "%a: Video BIOS handler found at %04x:%04x\n",
+ __FUNCTION__, Int0x10->Segment, Int0x10->Offset));
+ return;
+ }
+
+ //
+ // Otherwise we'll overwrite the Int10h vector, even though we may not own
+ // the page at zero.
+ //
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: failed to allocate page at zero: %r\n",
+ __FUNCTION__,
+ Segment0AllocationStatus
+ ));
+ } else {
+ //
+ // We managed to allocate the page at zero. SVN r14218 guarantees that it
+ // is NUL-filled.
+ //
+ ASSERT (Int0x10->Segment == 0x0000);
+ ASSERT (Int0x10->Offset == 0x0000);
+ }
+
+ HostBridgeDevId = PcdGet16(PcdSimicsX58HostBridgePciDevId);
+ switch (HostBridgeDevId) {
+ case INTEL_ICH10_DEVICE_ID:
+ break;
+ default:
+ DEBUG((
+ DEBUG_ERROR,
+ "%a: unknown host bridge device ID: 0x%04x\n",
+ __FUNCTION__,
+ HostBridgeDevId
+ ));
+ ASSERT (FALSE);
+
+ if (!EFI_ERROR(Segment0AllocationStatus)) {
+ gBS->FreePages(Segment0, Segment0Pages);
+ }
+ return;
+ }
+ //
+ // low nibble covers 0xC0000 to 0xC3FFF
+ // high nibble covers 0xC4000 to 0xC7FFF
+ // bit1 in each nibble is Write Enable
+ // bit0 in each nibble is Read Enable
+ //
+
+ //
+ // We never added memory space during PEI or DXE for the C segment, so we
+ // don't need to (and can't) allocate from there. Also, guest operating
+ // systems will see a hole in the UEFI memory map there.
+ //
+ SegmentCPages = 4;
+
+ ASSERT (sizeof mVbeShim <= EFI_PAGES_TO_SIZE (SegmentCPages));
+ CopyMem ((VOID *)(UINTN)SegmentC, mVbeShim, sizeof mVbeShim);
+
+ //
+ // Fill in the VBE INFO structure.
+ //
+ VbeInfoFull = (VBE_INFO *)(UINTN)SegmentC;
+ VbeInfo = &VbeInfoFull->Base;
+ Ptr = VbeInfoFull->Buffer;
+
+ CopyMem (VbeInfo->Signature, "VESA", 4);
+ VbeInfo->VesaVersion = 0x0300;
+
+ VbeInfo->OemNameAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr;
+ CopyMem (Ptr, "QEMU", 5);
+ Ptr += 5;
+
+ VbeInfo->Capabilities = BIT0; // DAC can be switched into 8-bit mode
+
+ VbeInfo->ModeListAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr;
+ *(UINT16*)Ptr = 0x00f1; // mode number
+ Ptr += 2;
+ *(UINT16*)Ptr = 0xFFFF; // mode list terminator
+ Ptr += 2;
+
+ VbeInfo->VideoMem64K = (UINT16)((1024 * 768 * 4 + 65535) / 65536);
+ VbeInfo->OemSoftwareVersion = 0x0000;
+
+ VbeInfo->VendorNameAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr;
+ CopyMem (Ptr, "OVMF", 5);
+ Ptr += 5;
+
+ VbeInfo->ProductNameAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr;
+ Printed = AsciiSPrint ((CHAR8 *)Ptr,
+ sizeof VbeInfoFull->Buffer - (Ptr - VbeInfoFull->Buffer), "%s",
+ CardName);
+ Ptr += Printed + 1;
+
+ VbeInfo->ProductRevAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr;
+ CopyMem (Ptr, mProductRevision, sizeof mProductRevision);
+ Ptr += sizeof mProductRevision;
+
+ ASSERT (sizeof VbeInfoFull->Buffer >= Ptr - VbeInfoFull->Buffer);
+ ZeroMem (Ptr, sizeof VbeInfoFull->Buffer - (Ptr - VbeInfoFull->Buffer));
+
+ //
+ // Fil in the VBE MODE INFO structure.
+ //
+ VbeModeInfo = (VBE_MODE_INFO *)(VbeInfoFull + 1);
+
+ //
+ // bit0: mode supported by present hardware configuration
+ // bit1: optional information available (must be =1 for VBE v1.2+)
+ // bit3: set if color, clear if monochrome
+ // bit4: set if graphics mode, clear if text mode
+ // bit5: mode is not VGA-compatible
+ // bit7: linear framebuffer mode supported
+ //
+ VbeModeInfo->ModeAttr = BIT7 | BIT5 | BIT4 | BIT3 | BIT1 | BIT0;
+
+ //
+ // bit0: exists
+ // bit1: bit1: readable
+ // bit2: writeable
+ //
+ VbeModeInfo->WindowAAttr = BIT2 | BIT1 | BIT0;
+
+ VbeModeInfo->WindowBAttr = 0x00;
+ VbeModeInfo->WindowGranularityKB = 0x0040;
+ VbeModeInfo->WindowSizeKB = 0x0040;
+ VbeModeInfo->WindowAStartSegment = 0xA000;
+ VbeModeInfo->WindowBStartSegment = 0x0000;
+ VbeModeInfo->WindowPositioningAddress = 0x0000;
+ VbeModeInfo->BytesPerScanLine = 1024 * 4;
+
+ VbeModeInfo->Width = 1024;
+ VbeModeInfo->Height = 768;
+ VbeModeInfo->CharCellWidth = 8;
+ VbeModeInfo->CharCellHeight = 16;
+ VbeModeInfo->NumPlanes = 1;
+ VbeModeInfo->BitsPerPixel = 32;
+ VbeModeInfo->NumBanks = 1;
+ VbeModeInfo->MemoryModel = 6; // direct color
+ VbeModeInfo->BankSizeKB = 0;
+ VbeModeInfo->NumImagePagesLessOne = 0;
+ VbeModeInfo->Vbe3 = 0x01;
+
+ VbeModeInfo->RedMaskSize = 8;
+ VbeModeInfo->RedMaskPos = 16;
+ VbeModeInfo->GreenMaskSize = 8;
+ VbeModeInfo->GreenMaskPos = 8;
+ VbeModeInfo->BlueMaskSize = 8;
+ VbeModeInfo->BlueMaskPos = 0;
+ VbeModeInfo->ReservedMaskSize = 8;
+ VbeModeInfo->ReservedMaskPos = 24;
+
+ //
+ // bit1: Bytes in reserved field may be used by application
+ //
+ VbeModeInfo->DirectColorModeInfo = BIT1;
+
+ VbeModeInfo->LfbAddress = (UINT32)FrameBufferBase;
+ VbeModeInfo->OffScreenAddress = 0;
+ VbeModeInfo->OffScreenSizeKB = 0;
+
+ VbeModeInfo->BytesPerScanLineLinear = 1024 * 4;
+ VbeModeInfo->NumImagesLessOneBanked = 0;
+ VbeModeInfo->NumImagesLessOneLinear = 0;
+ VbeModeInfo->RedMaskSizeLinear = 8;
+ VbeModeInfo->RedMaskPosLinear = 16;
+ VbeModeInfo->GreenMaskSizeLinear = 8;
+ VbeModeInfo->GreenMaskPosLinear = 8;
+ VbeModeInfo->BlueMaskSizeLinear = 8;
+ VbeModeInfo->BlueMaskPosLinear = 0;
+ VbeModeInfo->ReservedMaskSizeLinear = 8;
+ VbeModeInfo->ReservedMaskPosLinear = 24;
+ VbeModeInfo->MaxPixelClockHz = 0;
+
+ ZeroMem (VbeModeInfo->Reserved, sizeof VbeModeInfo->Reserved);
+
+ //
+ // Clear Write Enable (bit1), keep Read Enable (bit0) set
+ //
+
+ //
+ // Second, point the Int10h vector at the shim.
+ //
+ Int0x10->Segment = (UINT16) ((UINT32)SegmentC >> 4);
+ Int0x10->Offset = (UINT16) ((UINTN) (VbeModeInfo + 1) - SegmentC);
+
+ DEBUG ((EFI_D_INFO, "%a: VBE shim installed\n", __FUNCTION__));
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp b/Platform/Intel/SimicsOpenBoardPkg/Logo/Logo.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..86d7030833a096f545393735d931d9f4f2fbf8c0
GIT binary patch
literal 141078
zcmeHwJ9Hz-kzh@gFoN)Qu|weq&F~F*XbyPdaEHTfE*dKcjU5ohf-&!%BU8pXGG)q?
zD^tc9GS`(UQ>MIoGG)r#cb?2OW$Gd_vnu0Pg~E?y>sT{Q)F&%4G9u%Xk&#)e|2h0&
zn&2`0PLf>1@BjWNN&Xl7`zYzU`~UYcP5w_masS+n@=v#$bm8A8pL~*ZKm9cM6#l(=
z^C_Iaf!{aDCtrS<d<p+Pc?<u(e4D(*e{bKy^(^^xHcMvkZ-xI>tK`$wx5>BPew+N{
zCqGF({r0EHo1gqN`6>SUDV+cGXUUiF?`J>zS@QFr|2+Bf=f6mP@rz$1Z-4R2<d?tv
zW%A`Oeg)^hN`Cb#`2FRtlefS6b@J<9|2p~dSHDSq^PAr!Z-4zC$qfGe$A7@@Z+@Hn
z_P4)H-u~uyaQ?gGcfW(*-~K-N{qKLDtbX^0<PU%NLo)l_AL0Cu$shj+zrX)e@~1!j
zDf#vfe@_1V=RYT_KmKR(E&Th>|AgN^{U!O!U;dK(*MI$2^6j7hn*8;ze@*`Ox4)It
zdHsE*z$*n_Dey{xR|>pR;FSWe6nLe;D+OLD@JfMK3cOO_l>)C6c%=ZLK$`j}9J%#+
z`g{~f-@JKc$n%k3)||b2c=-M+LnK+A>$>;;@$vEfKfY?L=VAb__wxr}$K&JI&mkaS
zw~kS*1G~9@9j0;vimRVfxy_Y(?c(tf7y|!~-77nSYEzvqlcpIQf^ZIl@W;O*3M7fT
z!9kZ0_+7Z-@1+@3FK$(@q_Qx*CNCLHfLrh%DN_M$JaLeE@0@S|JKldEOG8tTLJSzc
zYJ|Dn!`@e*DIXr+U-e-^H5^DwWD+9bE5=`ek8z`XKS_FDqrkua>L0^f)%(?nEBo=A
z_fYpY?}i^&&`AMu>PnMqa+)M3U!$^re1FlY5cqf;0Cy_D)w70^J`w{D#QyQ|9Rf@{
z8kVb`(W3$AHjlEeUB&Ltb>`mu&NuNEoIQM&cK+Snc~b#~A`kH2n~2dD(13?{J;ulG
z|Id&fV>kskN%9G{)3wsUdQ;W(-n%jm@Z%%a^j$>b;a#Vy<Dc-|$FJd0z%bzRz4!P4
z{sCjp0*YfS>J9)L?rr`_zY37>O@Q{_-78}U2meqcS?f20ZdoD)$&5I7LUsP#5!2mA
zEIv!W^NqXXbtyvT1i?FFELrj6Q@p|h8in*2V;#tu|Ax1|Dk=1pD}m+Uwxe4Bj5U1+
zJNV<fsLOyKaN}*L9!@<z9mh8h<ni$wkx9P7lK%h4Z%*B<7Jsrp4EO5e<5xcS!ohMF
zJ_0O6y=;Bij258V7V**nn0p+qQDwP~>Dq?`cmO&E`M9W{0!H{GGAQ{1E-QX`E<5s}
zixRkn@-arZCEI?0@4(@!dEW!@f%90CZ#9t*CtDBKkZs|re|+@#d>x=TP>&8u37Fif
zP;WRXRfWgu@yZqbfd>-qeS<tg%t&h+Aa47}cR8#P>jS!=`3l7Lc);J!$~z?;OIihj
zxJtjk;$;D^S?~^kMG7IeoW6RCcaSk~q(8<IzH0o9OmK=1x&^#M_~DWL3Z%@l%Bx4@
zQb6AQ0u=1$cz8ZPP&8e|HGe+wWG;a{KAZ!dmCOWS0ZA+r)prfR?Qf3}ZHIRt%l`lv
zzO}JApCzUJ@O1P=5WkZCa0l!MTn7vs`QQIzf_!;+1fA~c0XAemf*X$MP!igY&BDW#
zd-rkbYJv*{4EhQVuCL$*Dm%m{luAOUt{}bp7>!hUi69=~R-0q&3OmUD4Bta0ky`-E
zBMCQ&c4z~>MVXJ@dBmalpL?R*f<qBnTQ#X(J_tX?h<1tLTfD%Bj#$v8##j&Vqk}Yl
z@AY!xHNnH@N%pU<a<nu~HUmE#yNG;vNkH|7S}oL&{>V4s^ECYzID`MbpMsHs!vn@!
z&V+3w2Pj#D`tZXJ_M-sGAqlrXPlBcONaEABVz;s4SiqS=@9#jn@OTgGC#?-dgT$2G
z--!^SMEK$C2MRMB*}oyW&Rm32W4K0r<wWA0cjG*hKmZaaM^HJ~Vp3Cse}#_#BI4uv
z?}PKYf)sz2zQKnMuroQOk$1S&{|Qw)?8fju9MHeU6|8@9k`j?5-ef({?Vfmz{NTul
z6~lkvK)7~A<pUsHuchXjkS)~s1>zt017ZiRi1VxPE@+rB{(^ty{I0;Y<X_;P2a4d3
zzTPsx848;6ue=%x{w`7+O9gX_Fu@+d-G_0CQt1Jgj02h4c>L1?!h9HEL8Lugef_t;
zp{PGRq8g8|BDz@ifQQ!rNT?+7E-FwFyj#SjQa(^$Ab&|ne*?-yfnolYlQqW=01AB<
z`2nRtKFVKgL(mTh)C&}X`>xkSc+-}ThiiC5@cGo?>P&AiC2xWXLl_@<ZAS2fn>B~y
zEP9hpAtG3)%foU#Ho^kTkU&H`)PUUf_74!O_alHGC?AjDQv~}Fsb9)RL?Ea%Qe=$y
zhXSsny77dg7WC*bJj9k_&vlFfOrd>PIjS`$P>+v5YSQ(Be8ll!kPo0&7$ISGu3jg5
zXsxgbZ_sH7fPv9?AP+Yl!AUOpf$xFw@~#>p8DWL)(2C0&tEB~kMLm!50Ugba{s5Us
z{jxvCJA`Zj-WP~}DDcsbfH{urt^(i(j^2?UIN(APg@+Rg<Px4DH&KuPFrJR#rf;?B
zU-?Il{bQ^byA-_PT`lAX@&y408LS4N0a^3MwID!3+5?Pt9q;bCP7`5;K~m|xn9z2*
z>AQp%c031C0MSbO0qqHgqY^dWo@^!kv6Qptfgi3X1$_k|p?4zHpiv*AdsRkDKJvp4
zCm;S4$mS{S0Q*XVe}%Ys?dtt2B$q2SM)p<m;qHcx>;OAaaYNG3l=>gnf&eMdp2>%o
z=g?`O9Y^r5u=@fRaNGm>3J*Lli5*cdsZ`zZu8ix(;hvL#HxLPh>lAxe&{qJ{*>j-T
zxp#cZ&g$A6<iop~AV{7GB|qS0Cm%j|=!XJm&x4gg_WNFq-6+ThAcfEZU}xf;_f_Fu
zcj6*&ffzxTI(}$a&VJDDSqF04`;~k^V}kt%@&V){;uxqD?;wMq2+^Qppxxuh6E6KR
zJo^TR`e2}fJ;%pzH=2)NKVbCl)CxWd_5;oku&)D1;=FPgmV0jy`9Z251JJTdy~Wyq
zmtH6;zz^;0#~4uv^5JwTigFn02i=EN5hSti9rSSO-H;DQIAW}^{cyxP!JbD3d3}ZN
zfu3>%iSkkUSMU%B1_L+W2G?fj#&8u}NoPMCO%bpc0?=+K7Y}~e4JT-u0UxXixi*Gh
zIGlXAVJO)1f5UnLVAmAXaT^aO;V4#6*vZF3u;&2GBU!=<_5-pV%C>9--mZXie*!<6
z><6ePY@xE}kwK;20D^trTk6uDd-;H-I6}j3nY4jg4Jiqz_FYR+BAt^PLs>wQ%xgJd
zuaCaq3@Yg#m6nMlC-M;iZzf34d`@{+@&UT97RiyDq}mL)eTmB7g~n9&qa1%k>X+@0
zcN~L|v{hZf8oJ;_91jwI*R>1&c*9b?=T1I#{CK$doA3Fa^Iix*K76-7`y2AZhl_)F
zV)bLZ7vzHj#VZ61{a}RWn-1Rs@HzmhX9EppR<NKCVs~(WK^wdqVOaV=2iI4w0|Ppt
zIwy`^BB_8n5%nFE+Vim|sk0j(?EnkM=Z?wf@8XTm(ykMU(x6w32r*QA!#fI&(Y}s%
z8JG`j{I%nUleUr|jvrWW&@vUk@+4?~he~;`_IK<^?429bS8y4eJNHTn%Lg#9*7CTH
zvy!#I+dZi4ITWwt!;Q9}E-#LbA)Yjk7k)|_=v=X^s>ew?VhMH}q}|yOjAp>C;O~NF
z#yA9O<?1bWQch96hj1!!U7!wN;=4}JIqyD>^5IJP;pZ5tf&&e%Iy_*QiUz=&53jF0
zKcc=W-=nYsIgn-8;)nM=tM>BEEq+lx0HzyEMf>5ZgNm>&-%{+g{t9lO2Z{q^IHbM`
z*G@jd_yb-H_8bRQuKSk*!hmQg9d48mnp*l-*hR;_(GTAb;}3X^lo~rkeG_=gQvmFd
zRszWjhAU^!12IrO0P{*dI4txuT(wvTk9HN9wX&Oa@)6pBRUs9z{jO#B2apT|0W}|?
zx!x77g?xYoeuJO@k^{u}k%mMkCs-KkcTFw*D-<T2)WzyQ13`fw?_VJ%&Lj7|+IvM2
z8$1hu(W3DOHCG4;tHHjGEr9ci9~@Rts;<04<eNba%q?$69fkVJH8<D~#0F79&0O_I
zk1z(LgTN4fcZ_8NKb(9-`vJYjJq1WXJ|dcFIfWix4m}?oH-Gx>AH4AdLyq#{`yxJq
z3oJFpli(sous~4&?4EeHm_DjGuOLB#-H@`94++clDgch~-QR~%4a_ZXoBkCN&DZ3r
zLx0rWDes|tkT7hh()H88A0i*fC8w_dRwW<NBk4eD2*QPbo|mDisQBFJ<GTTtz+&%C
zTsa&|c>Ceh<rrRt|D9JvT91IkL4=qT(5IEYf=6Co1^EcD5MYHQ!UiP2hn@=@IBR%-
zqp}|WtFj-y6GJ`zKja7YM?Bmeln-~qyQKjQ=Picuh?5VeC7b|K`+<O>zAE9u%|Nwq
zC-4Jme0K&9zj*_#et6@sD97h`1Bft&$8hRQV5CTJh>=)ChU0VV%=M_?sZo7pB8il!
zkfcqrAh*6}+mGPgx`sl}189H}BH)j}54=Q-!r@vIu8DjAsi=Ioj$OGsp%+4tO2xaH
zJa;@A@7_U0@B0`S{^0}GNyq2N54<P+-O@J=MybTH`PcQRAZcOR1MP=bT~Gx>5=r5@
zkjrj)I8fd-%17C`VCV#OVn=gIzUr~qh_csK4RSY_d;ndlYaC7aVc!^Gdi&u#13!OW
z>MQpSV(@jC!L0-jJGHO$Jr0n+c2gVgoL7OqjDO^YKdv80eFcF15dl}I*Pe{sD?k7!
z5mH}}AO1Exi?Bk6b&}`ncg|!j<kk<Ue0bheN}kTnmhurr9|(d?*7D&5#s@4=uv}xH
z6kzQ<12?5q%15B;<2Rp2goEuu#RszFDuKTj<+Lo4#qq;+9<1JRT*wE$iSJUtWfh-5
zYAM*GfBm$)QT>Abz&1HcgflqsAMgWu5ZvXkLWgzQ+0_rCbC5_DlMk%bIV!X|kFBR1
zizm7UGkyU6V~nr?kub~3X?K_*a#G{4K2QCisvHlxU<y$KSeL7*Qq4#o_y?`^u`9gt
z@pgFNCD>bGZqHp3qyX$2@~O)q!gn7Ovs_On_5%t5KYXrA)Kw*tfR=0h7;!`leFgjd
z4HR)*!k?qKx;|PdpMU`Nmq`9nK4SH*HHaGG<}M)F)eo&fP{!^FfI#fO3U8GJ@RyE}
zUJ`v%LnnY2z<Wud!}_DLA6|mT?yegpIXKuI+&!Qy1?<kDTYNMA2RQxi7(~crlK3+C
zx3V8_j+PB71bzT4#G1kKt@qI)Yy=cIkbFR$0PF&pTggh$&V>5<j-wS*X-?W5y?t*+
z^5G@uhAy<#pTa%35!!~+t5C{iV1mYWhxhGD`EcN%2$~F^=K(K7`{Cr(QSkxhx?BhK
zP<#d{2aFVlA<0*jrTY9EAUEDEk1=8w^c8p{NE+aW8;x2>9z#AVn*ohM`2ZaJpbbx>
zG*rE|M7_Kb{9C;3I=gES_)5-k0$}byaR^Uc4Q02CNerd@0I7Y~b9FnOBLvs^$Bub$
z75GtN2>0>8QLFd09>41N&W(cPMa8}2T1dwt;EN-y>hPM+OPY`GqI~=aiQ=5P2+JWE
z2sFmp52df1Jr61~%15vt1a~D4;RazD_EY~K`mVuIz_vJ7wtNbx|ELV^1)YHTxPg*j
zsy!2&D!@~uh4<7#HX8a`rGMqPR#6e5xEH<--mY6}Hg>%NeE`ho0)ZI2=pyjqGw39h
zn~hBQ!dK@w>v4lgFvl2l*)@{h-^Kc&-G{LsOg@mB&YlAy@H~1`Wv`9m;EDu^#kN!u
zfb_#~5i}0L0Xv*_!b?0J-bKF#@)@v%Zz?`RQio6-_JvRfYVq>Qm5&$L9mc*MFCPxz
zS1yiN(y#>V6f)of{DAElzd<7gfqW_;6=$IWudgt4>gB_Cni5t((h&&ihvPu@Japq=
z&mCm1ukbWdpK5hL77pyY(0C$3{(k)XJ($dffm~Qa5%0${udguri&VnWpkW+fU^Ltd
zr!GDWmwr~N8V^EoS89we2CYAKr(bpaoSvg~1sDOKrW`-K?*e3}G{0t%czhdxxdkLn
z;X?2E*tzb=TLVe&?_&Md92>l_^-;+Oyb0$38r3JDi}FE~k-J01A>1G$v~}HRWUwuj
zd^mL;>PEofG}s1^I4{6hK6rpw%2Uy6eV>2zwHuBKz$sSeE!q2C$%h}XeqDA>Y)NPz
z*bgDZ6iG)QtRKjBD1C(#@x~DCxj!%M2lfen0D8!+$f0n9h)`Ly{jblz^77$5BIt#o
zZUpS=fNDdy%g;t3nX5-w%2Uxd!9y9la7_@a3NS)OsT*S>AAjW3rn4dy!oEY|>IkRG
zuo&<jWi7}@1&b2M^#PcXs=(}X0tf|}K<@(&CLhofJx@Y+!5LhiVFef=_acLKz`~D#
z(T6EBrvRL*$#XuOmcxYdGVr66U`Iv&LZID+2^b-Jeth$<Ujy!V4n9KZd*c<hC@kJ_
zaRg*3z{J}%NJ9Vdfr>KZumc(BD?Z-tJC{q9a<Wpg->t1h7Wl3TjjrxM;}CgF>)ict
z76H4z?}d)NW!+_^q!MpHoIH_IL2Q6>kf(*DgVtDpOMZL-_5&9^;iw3BN%#?h_>S~r
z2MJvo3szZumimR!dJ1|+q5wj0c;&0)!=nV_xt`b8uA^XaXfa7>-mz+U?F)qU`1r$*
zLq-o0CrAMbUMUbI$$|k9<Bzh`=V|ss*BEf`#s=Whet3TuEQsR=b$Ek+@%YupKCa-S
z&K9gtXGtKab}vI3DHw#^Ig9Zes-p+UqPT+#Ze0l!`rVJ9Aga2ML<Dd+#k=mPB!QI*
zNz{(BjzCb}O(c41Ip7{d@UM^)Fcd)z^VV^tYCz~8;YIktG7U%~*Re4CZ8sxa)l_#<
z8bf>@&p{lqqVhk)-%a3`Hy~Rt6xoj-*darET&u!J5351Izz;k{r^p@OaY+?UUxi1m
z`p}O`P&kOO0GHZn3=RTjZ^OF)1*@zMH{>i4!e4}M!3x!55npYEV+Cus6Q{32Kq;O>
zb@YH<;se;#O}C&BuN*;ks~X>ORXUd7AE!G)-3U0GMpfWOG;Dm1K>SdFLoom&yayO{
zj9n|<V~Bsu$L9$w*z(+PML;~9WE!v{fw03oKK{52IUqj!94He2&}ry+4%Ol9@;@gZ
z)fL`7kbF3|3flu9;c(0ibq9VxWkeNteS&?Fl=2!SLh)VIhbk#xcnc^?I}luoevKY@
zfCN9KZPBm@fe`T+quhrV_^#*u<B*@DVju_F4}ND@-k{Cf1(%Qh8R|g}!~Y&usLAoe
zRf;-19NvI9et3LB_1{DN6QBeNYrqKOpC2D0?I4AxjBJ(_B=I#EqLelv-V{h8jUL{O
zOZ!$q`H)Y(`vns7@yGkM>XWyQK@^G!7$nTke{{y6lNCFFkl*`fr>tq54T5S1LGnXp
z)3I>>)M+HAlfq^($ExWSZaWHiQL^UG+r9r<>Xibo6nLe;D+OLD@JfMK3cOO_l>)C6
zc%{HA1zsueN`Y4jyi(wm0<RR<mI7I)+w1jD`u*-+87A9S`&wR7Ano=C!?V%l_3iEb
z{r%+rW;FOa;0S&Q;lpc2);k$qT;EL>t9)G@`ShHvqL2)H`PbdS`Diq{I6oVn4o>>r
zxL^EBMm_EHPe-@YWl=GrI>|@X8kd*cf*Rb?!Obi$)<sd|tHpeBcRe~Aym+Q``opV<
z#S6!j;_Snd^^!a3`J(Dr;iOnhZ!S(>u4T-+gUcz=P!j+3dj7#q>8Hb*hUL?nGZ2%K
zZ7=6H>z?1&;2aq<{7?m?tE3|~s#xBh^<J1YN&A-#7+1I-Zbz=C?TFb$)dc%wc{6xP
z9O>UIZ9K)@`wvuMbtj@B#^sEBl<H}Fi>$3JH`eP9l^?w}!e1;d53|}v(s#S--u1$8
zZjBBEw{AYrAxLj!w@2J97FYf4h<EVPozZNg6^~fEJy;Ho!|?&Ok`HWVKEHZa85vGi
zt%YN~UOX$Vd$6sI{Rq8oH61;hk?dW~x8TNl?e^Q)gDlVX>PG)6s(|%+dH+0aeR?+8
zLRGET#fNG=pd0k(l;RuCi~034n33M)HaNoI{OZ}{cz?M{&)Qk^z^VNH?1_i$>EN~v
zh8TQX%xAON{q^vPG2EXC6hb=MPBkyC4z>3&#iI7Sb2i;%Ir8Ofa(8n%g7`E9sQVu@
zH-HZ5@NTxs^Ss#9?jRz?-RaXcxqH#9tBNHE#7mBS)^@ap2i@W5>iXv9_I@&*v8kOJ
zb259X37@oo)ugNP<@EMq@PUr}8u;NK!FB>L^?81IGnp-6KBVbbUiP0Newv=#*85e(
zYJPX|Bxr1;+>r}(PR?&&3bctK#qG)Qbyhm453Uuf+11HY^ob+Wx-Iz5>D81@N-O3}
zj&4NK;Y`&UZWQ_S#l$$<QgrWf+3<GJptt77o)bN*4Rz+TW7oYm@s0za*W?Q?jvJIX
ztDWeWyA9Kh)8dy7H9N2OH&>TO#QwaF9m~tVSBI({H5)jxx;~mktz$=i_XLhaJHk9y
zskD1p*H@3mkUC{Gzlb06eJ*-Df4$kDZXB?>IfjI!L%RdycZ1`5+0Rez78rETXZ8s3
z7!r~WY|jd2jgP_o7R`ToMY6$-JwRMt9hyezi9PPvkd~Xdyz29d3zzr$;u9=Q7DGPr
z>F_+X0g^<UNDIENIXqj9n%*+2ZM>QG@2z@@`}zTB+QTr<-DEnSFP6(C#@!*${qp>@
z_u;5FNPxY#gb3nnzVL0BO?~QaEmN|ydsAmE&kx$_-i=jDep?qE>71NhL58~?xk4EJ
z{_1@20XP6@_w?fWex}ori+nM?y*#UNDIxLN)LDx|PEmC(tq|hs+D=f&`e#>@hAg0B
zIlVqVdD#P&&fwy9Y7*A#iDGeoHMD1SdRM07GlMUv9_Yv}tQwYArU-TiqkF43*LSPQ
z<!P<Z9|-N8!KA(6b&EWv#ofh;CFq@z>H6H)DU)sSOox_{T3%ZG?hdYMoIcJExLRDl
zOpc_zv)j!b$~7mSURtU*y)YSab0AOj#E7sL%aOs>&fwa_MDfDkSlygj{mTISbhm&T
zn-le8dy4s`Wk}4hYjK#MQuiiSU!7U(NNY4_^^!hW-B_)8I_j&MI;VG*snnRqJ9BFU
zc53y@<slL@(@VpwEiY9|((IzahDY?p*^3%arYE*@Bybj&#mw-X1{N`9Zi`k$x~*=U
z8OCFEr9h;8L#qkI?aS%&<nyT(z~^pky>FvU?-qC3G?)@{zjvlwZ%Qln=eZ6cXQOS!
zJc3<azl>D5{x*gqqVLXDS`}FgDQ--k)aV;Ex6&I;XCw2oZ;wg^(sh@`^gtg5uW3ZP
z+h>-BsY6-aFK$(*vW)t2uW!>Ni6y~zau}GMZI`{L8na%E+R^NIrLt?oOlm~y?-Wxx
z;4|Ic>FGXg=o{K<B0Doo#aPjlden_4%Y6lTpH{-Vy*+eQXil+^=^WWek7J6vJpvP{
zF~u^I=C`+tPoh|o-%F|6lfv7)o(?wVzbb@{8%vop-Z6x3p9ytiMo<MRo6_S9oNI3t
zlV{uFB(;3VT0|QjtZsz=)VtN1V<z=W>z>oqy{5Pl;x=d&bVyj7+~3|p-s|0DzCo=i
z1>73Z{R%cDBRJY)O#03>;eI-AUJ$mrJ>j?**@MO1u0Gb4_N}BXZ)C@EayvSQ<n~^-
z+l6hHPR~X+O>y7#^Nd8YrtI*10h!^$)05DK!Rh&BW84>}AQ(fe*xzbLAFHpe(Ol@1
zLA{@gLG^(M;ifn*QoqB=diD&fL^}1!QxH_Y9QH+s4fX}OxTz1tL#_>DNH)@b+iWLO
zncXSfw-U2lClgg9XxGL4s3tO%^)K#f-Q%a1ka}g6&u-52u-g&4Gq|jsQ^@bQ4e4Gh
z8Wnmx&3I^Dq^AmwTtHqo3M>|P=W29BD(Rfv){VU;(upUp9pe;+PPTo9Re<$#(SS+s
zqE629Ti*SRF~f?>P^*S@_0VI^E9%<Hs#r}fnz(_r!!)y2hK?`?o3&}x$aJV%>Cjl*
z3eBv+bw@Q?E5BtvkCiAjVI?$deJ4Fv{U+xlkB;HX!8=8}HSsWsrsWS`7violJLDb1
z{lRAE(^k3R{TsUtIiESru5?Q|DO)tDukw3}J2oMhT_Wb{$nQ6HtWbOZPFp$vS3Kb^
zKs{T+7i|NaAYR%9#WwKhVn++%wtImYOW>DG2^sQ(yjjU1Y7^^6=72=>t|kC`KFf??
zDGIpzc5^$}HNlC3cglelkc;gGA$>K!m2<CoV0P}sc5-;Cgb;aZ%{{iG&X%RDnYMMY
z-5f<`Cz&sqsZF)U+HUiZY=nei$CNd;XHs&?T|M@Od0{Jz`Cc(lvm)!JnE{(`t1i=l
zNeXVUQ`NoKqisz3iSh!MEb3y;sju&tMzctu?sZL-G251}3T}%Vh64$*dAXe)!FueO
zQ65;*8!#@m@OeARR_C|Wm}euc5Z7xxBh!W|*5c{iLp&{N3`J5aabdZoTKBN}cTAJ`
zi=4$8Qtdfxk!_-rr{}E4+EbC+2w<dJ$6`o+9Sa=k%&JxeuUppLvludG0&t=<R(k=-
zE@k)U3G>#tytvt3S^3s>tz^`F=QTGH(wItE@5&CG&XN=ZKkbIv^z>SJ#;pb9MET3i
zP+Qr&`A*8pQ>|yjk=F}muQrl*+X9v?U&;BsEr41KSuy3;Q+b<hCqi_t2v4^%LOywu
zlbCgTCvep78*FCJPita%TM((fXwOJa$}e}7aIEJ<&lRmX!IgJiwDcYHT8{~pyq=Ex
z7E`7x2_3p8XP4J^um{Uza({Pyc_t(9zNoGdY$A^W5t#d*n(pDw3fJRfjHL=T&hM#U
zc+0dJmCeouXqn>k8s;rb8g&NeFabsMCaj!*FHeXG1$fo;;oEi}v+Bm1S^)t2XZvou
zqPKVlgG9YjmEF+p69e5_>Af*!WDI|n<|YJgcMk~)V|CX<F--*wv2vAGMj9ri^RD0G
z$V^+lU1Wjc5zaGX-3OzbwlVCn0n*)4=3zA=MU9w`Iizh$bzj^JrK(OZh!~YjoHtB{
zz=ti)&QHzt7X(}DG&MBKIyYBOSg+UL>*^6r&P;?-JS(#!^BOX>H0_=m2gNNjLcVE3
z_r<kbTa>D5fh)C>Apn26DvH(gs%93Fw~1Yy7=wj^4R=}bEiR1d(isi?^wc8E7G9}x
zc5}Kmw4)tu!+3OthW}FbdjC5+6T`<$nL8+0vm%ac`efynH<GY>%@M(?Vk(engi!xb
zn-HF`t1L*1P_i=DEFV#c+}c>m+pFC>f{=ncAJE30F}YLNAJw7pgDtl-%B;~RA4=EL
zd()FlkEG_*)lq)r=9%=4k}0YJjhPiT3Uvru3V|@9I-LrS=G2(N<sM3)2lqI*m%oW*
zx(ma~xh*C<n&B&ggEprDO0^20cA!w!Gn8=_7W`HMx1OtU^gxa7D-MX01)sG^jMSJl
zQ@|d{bjX7f+k7^`vgO8VmXaD<|7t&xF<Z?KZ_FN5@oze&$yBJnU@-wizkUNb!40@v
z3MbP@7Y3UyiPE{^khU<!R%o1uu4QFgUS|R~uub=543etI;C-{@Qp;~vRR3M5NkN&f
zn4Bq=apLi-CC?k^7&cumtWZi}V<#(#YNlYY;6qt*=U=TIn1Gzhi6v%VbggRkk*0fO
zDkQcN9egY4K-MfcLzHs|MR;r(P}ZG%(Qb3P)QYjU3|eSX*>}=&Igl#uNlE41ZJ1e5
zLmH}&^e*O9nPIJ`MpTVUguLR*7tBm^No^$`5bRJ&jnJSvwH6mGSV*HPy8DTq3t7-H
zh>8tN<<OW`-BaR3&9x%-QfxWUS0yC*)io?Lpa@t?Sfou?eGHWJq^VV*f>R?+b!j`)
z6s0ZC)1g%A#VrA$I@7XAw$<>03V=>2;d8`EM@g3=zrIo2vZ=?ev4o|Vup;R>_pcCU
zaYL*oX+Ama8^$T8?IUIPIn}}A1wlW%5Xk40Te4mmN~bA_sfshwdH_<YM?;?cun1%}
zt6lve!e4!f1Hcd&nA(6q5gJ91&BANbmQ(9!y|l}{^i&E+ensF6qzanVi*{F)B@-V#
zS<RZKMJD!!e#H_tSb|R+3}FW*V+0P=UhvGWQzO>GZMqo^mcBC~0iLGTxcoRPfI4bJ
zi#Zt+D)DJhSju1%g_Nq4tQBDvwAfC`THc+Pp+nrL#pH-kM>=E)BNaA;HiI5BVazx~
zRMW5{YzXLc2(7PDrPvFCeR|ejVaf3rO?&L9fdya1kf~mQie`GjnAS1Bs>-K>la3zd
z!1r~S2c^3pRAy|FP|`5f=^fxmZ<Uf(f@<-bsR;5t5fGIbJ+B)QW=dT})t0Ip)D^K(
zpbw1YBI}jT+CQ;AtRtd0U7d@uUh`p_8n*&Jiu&AP%i<g_aa+?WC%v*G1I%p5P1$`S
zhcd)Ks2*9|(N`0TK;}jmR`Nn2G8^?w8jzcR56nss$;I-m3PGi_0o?kC3#>C0!XwjN
zs^``Y2~}`~#QS<O_?nAx12&N#xt(BiqNh;S`85$}AfwJ#1<-V8nk1${kl_N)k<4(A
z*9#F{u9$a#6J;aTGoq8U*Hq)H%hB8-0!hy}tzim>;jQ!G*ZEaVH7bS!pmRQRnVw2f
z#WH;Q*7B~Wqz6U(tk2a6V6pH)&N8)<f;bzQR9HFF{1pNnNdvNn1)p+o1gzeJ6B%-a
z0`*Z>^XqY9NnI+3O#o5Y^u${EuHu`3oa#%69p^u7%R$c7B2J?E(^G5=ISTIZmk11n
zBeo{euhu>j*@5>@q&8cxx%`xMxL=*F4ajkTNouWz<0@Z!d_ZTR_^>{+voM4Xf6<eD
zn=Xjz3Tm;4V}(m9d74M>Dmy3a#8W=XH(K1d-o&)86K+CM6-<U|d3eLJ>BjW2l5J47
zysnA{hdWWh8KOxu8R=MB=%~r2N!0(UNlQ8{l4!!L$Oy=2r0IVWk;Yf7uPTcSGHdcx
zrwC~7^K5+szx{8iusa=ED`U(CSE2H*5V3+pgp|L-I+)f!o95ii-T9@vYQ<mpd`V_a
zXz+kBG)|$nA+)kTGXO$Y&U;VE5Tqw9196AT+S8#>NkwFu^50h1<!kt>Qx-Qaa8eMl
z@+Ehm%$+p(eqPq{D%i}BBBzI{hDzfv9OO#Iy6N~psUkXl54EfH%L}5eq=&|)SoCVC
z7A;oQAw$GCy`v`c!C>?KLDX~tK*@<;=o-iK&_q1>AjCI-sF_wW)1uaQuHwj|1l18?
zRciFrj>v4aqM}LBCgY=H#MKM2)r2)p&siS2nf$pVniiXv(o7<`zew5sL;tF&Ju0>;
zxI~600TJnh<(CmdsmZyzQd5xa7B^XwiMa?t>FfZx<kH-ub-}z1*q$RA{#@s)#C9I^
zOe!q8KCL6?E_mz#@K7-@qVLq|XV%`1^pj;Ys;-r%M(};f*C?ftkf_i6!9T6nQ3;ix
z)P&*#hTJ;}<n!xj73=Ui(0w`ATF}%D846L0UDSRHWPH|>{xX}bR(-ggctEQq#z=0S
z-;iWh>M2hNF$0uJWA;Zk_xE>KL#?O}M1BQE`J}|-O=JXH#oT2SxR}HWB*k+!S*@}P
z`6xPqQD>RN3K=rt9k^%NbY8=WN^v#E>9A~0uLM#!9qxu&;!Ib2$o1$dgw+-1oCbkq
zD3u9-3dFBQt=nX*n1Hw!cUP^&yg7@#r)o+X*ebSkX^qkW3(CO}U81VO<s>%cP>`eH
zRZK%sNsdfkNa0zl@mNC>tyPdKD%bF?m2%6o7qW9{9)TfC5};_n;E0c8Dl|19DjGzy
z))6N;{kM!UU==K3Tlz{PU`6!m8$GmgqIm2zRsI`Ldqs21z{<!0FBI80CauTnFi+GX
zUfR)QxRlWp+$$L{BnCz%WwZ1ZHEqt)RW~<GXUs!fox7`gyb09i@yd>xv4$el;opqN
z;Y+9xHAP6SJP=twGR8wkgHrBT{-){#)M~Y8qiNH{2AoDhB8=r(Otd4X{(&EBdw#M7
zQU@v`J#o5Hg$_{>SDuZKNS&15M4aSOOJ+V)a*h!ii=d1%Su-NXa`fRH#dIvhqau9~
z4Rv4+ottZ*-*iiUcZ&warM+JB*quyAAba+z=|z@&Ao~EVvkBMuOsYeqB=zpFq%j@5
zUi0h)nbw40SePx=_*7?dR)I#$l|kntblG6i5}B~g*1V-M3bjKxLUtphB<T-GJ##*N
z#k!Q4t-6h`cX%!-t48-ali?I<?7_Vf;!b94WH6DDO3KxmgKgEu8h4ewt3o!&G``Bf
z*uNPDGto_C@Sf&Erd&{iE=MO!>!>MzvH)0iU*`SDhdB+>v~6_9bXWPXup?tOzz;Fg
z(UU<TD3b5cKiZ<bxttseP|GXh@oWnv+5M<{C4sVlhICi;^3KgzgS|G0y%rvMSItNx
zwc`{&)MF(Q$=G`vbPiTVuBD`LSUJZ{!@nv8gV<B0msvbRMwfO=;7_e}YH~lBfiZOC
zDY&WZI;hl`I3JAC?Ep!GPJ$kZoF5_ablpM83Q0BKqiF}J4CU>p9#U%uK)HLrlyFCF
zmZEO${U;V+wIk$#N=aY7AcFywQ%W_xoZ=&E61sxq`G_Ffl}Ycrdi;7BBzA4)K*4$+
zBTU6TsGiKw2PiqUq6GIRI8`ZB%)t^d9x|Vs&<!YDw~OH+DRXQkhK#JPSW@pcEzabu
z7NQ~clj$1N7W=&q3@fvuRM-Zm{maUz2z8?5WCK+#(zp;$QifOAeho6zw?_=m*r^7_
z;M~cwQn3ZKr3pp0+WT|uPwmYRq>81!kQ_<Vw#p@MBw0xA06{?}a`ui-6m7<rmgpM^
zi84igXq4egWX*52vpz)YJodTt_-F)6@`}>#ObiD}?xyrvm^PL&$MZS2Y^{u2x~?q@
zlC^}K@9@)+gD?amqNiITwtI0I3!=%Ba_C0p{L>3WIv(`X64HpWbQ>8hp*CszR!C_>
zgyej>M8}n3gK+B`bA^#`wmp8^zae8y#7|OdT*%N(4hLy;SBe00cf};{n)+<pW1q;;
z3=&%e#JX}K2Z|JYQx@X`LF<B|y#r=Dz9Jo7I+rcizmgsD<?IKUagwXfX^b+F8UJ+s
z=PoTUZMsN>v9cFv|ABf3BA*}Gx@Oy{?}FSe@5tDAaTTG+y~Oh9)5-}SG8~lqljSsV
zT_z2SNtIZ4+cW8RBO&EFD`_KL8MdOuOb%8V9Bpyhr<_bZpt12xtlJ~g>oOysY`81)
zPS|2l6{Y9y=?*PX(_27omd*mPcbV>j4B-PGDeqWfEhZgzKyHUu<Xj#Vc4>TL+JH1W
zWJXp7)XBsMC<c*Kzkicc8K88O<n!qr>uVPa7Fq0C^XV-%^W1^r&9BJJ7djx6)-pOn
zGF(F3G8yS3UI6R`ClocyTWm(O?y2Rj7AzJG(Kc)A0dCV}v<}%?Ji~mt9KF#&hIGs$
zdUDE%#6;!V4&o)lnq$Eam8Drn^@jU>Bla#o8ZPm5)aEM(Et@U_lnq!M>X95%(XBz`
z06k6~NFgA@NI7a@!*eN(2hj*}428tz3H6ZtZKRX%&pRY)!5DxM0m?%Wy#bDlHqq`Z
zRdXCn%N#=zzLNZ4={$0y5thc;fMw$&bB{PWkb<{U8Bjo`@sGQii9}*B(}>4G9!kp6
z8A2KPh`m{MH^N1k@Xx{}GL`x;fmAyL#UsaNM&g96YUxV<1z5(vS#uDIHv>_cCk`?a
zN!mEkr}z;A5cMwsBFEuJ(v_ADdp`+rA_=VJRqNOyEYc=97|R{=kfT>(nG<R2<J_v8
zog-F93Ka`qDT{QV)fLkJMt;c8x0%@sm(1&xx)z}<c%IWSd4aH%=Sp06iC#1XiXU-Y
zS8sHnHYp!;N@cH>TI2LWY*%G&PsylVGnk3%RQJNM)ywizcw{7@(l4SED1O9l*2oVz
zQfAa>g>OwE>l@YUl?Xve(Z%l1!@(UH48<a`*)^3P^0t(8nr$w9ujsnU<X$qalOn)O
zwuqPP8%`vINaai?QgY6hbfm^sq+<1n@vSS^>Ld0xQscg-S+@`0EbFi=Zy36YKmp}P
z{m`y~AI&C$Cq0rRx_w)h*xzU2dscO<9ey~q&B4qOV()3^0=|^Bn%@c;mYHQF5~a3L
zh+b_&+(XV0aTCEDvx29C?8%bU$TnOvZvw2P+J_Cp!K{l)qlt1R1~Ypi>Rvx7Cz5kI
z4XzWZ+VNu>`QXA%=1*yI(IJ{B7sMka<@Z@kYL95`sT{L9hVV6`wES-8{g{cwx60m4
zKAQL;LR4HnAcR#$F4}yXYP-hDBnwB$xUA6uvurx`@y*?@z!DwEF%J!5tAW^7R9o?*
z8uB*qL)mjKA4%G~m@HSz*(F!)+flxzw5%H$BEHXJd?5&ij&V2(kj(%k{pLVT?d@-i
z^aHkzb~k%2<}t|Ls*V1xLpkg8dOhh^v~Ns9N#omkFjvlXjqHHPGclhoV@Oy;PC7PV
zvH6kM`h_GvCr#sz2LGy5I*2M9gdb8N2#dNI*?mfM#gr!ECO;%S5c#ZFhEfC<^N8-|
zitL$sL7OEOlhdsfn#Skt`9TC;W^M5h5yk2l=T_HVaR(~3GZHB_nH77NAFrY>Y<VvC
zEuO^)KvVpxemuzBR_HyHAEIwPEkDfI`<x{&Bz8EM#8GQ(I#B{!(q9%o;hE6|<%h_K
zqUKK~X2igOlpHeuQTb0O<Z#5Gm&EEQ*O?suAP%%qP^&e?3)u^?lj>nILXnDZcl-rE
z)`TBY!0G&lbk-wjRg}K+yb}3RWa94lZ}X=4eU^y117+ECSYAaLVg)F35un@#Eml_U
zZ842COPv(Q;AE(Py#tQeDmfob@{gMUGNg`m(c=3oFw@~%ME{EARWbyDMHhU<^sX&P
z2ee)gylI5g)Sc_6mKwYO*|EsfdaU)RXQu|S`FE3(RHh9efyC#!?ZHg!$-B2f?l(>S
zD>>&x^Gl@b8Y6Ei3K>ViGDO7kuXb<47H`&k4TnK6qar+eA(iP)$TKmRVK7@?$i>NY
zF|3@Cp!rvFXcvbPGVPaS1j_ux?e|}3-LATVnbo!Bx2vq>RdGTAL0b!S)klr%aA>+O
zH}9rj;%LfGl%exDm9cC7ZWERVeAcyyExy}ley*FxS_fqe79}GbE4lB~4rphi5}N-d
z+1)aKcTIQJlUV{WA5QMSPV(F3UgO99Fn~!9zJYFNy+|(V8oOhPDc&=q$N|0w*+f0D
zaWNrmqE=VLe9`PuaQHfsMfS}Dbf^ft?U|T}^w^5oVHp&~LgI7XQbS-7F_>wK5h*9N
zJz3--H#5vf<UP5PCFWC$03~ch5&aG+RWXZ>fIjxA+Km<|DL<)VnHl1_1CH4ZA4ww=
z8m!x`8Op>)Z%8^y#4slf>kZU`39`IPdI3)xFexb{dyJzb|K^%j0FK%$9Be7R;+9P)
zmNmBjmATu?7^{&3J34)?*5i;=AUX9zjHMj4aHpj`)_ayz+e9F-<A~Nlx0Y9l&vncA
z1wz^Pd-P;-5W&Hhsj9Zh(KJ<#awP{@uclUbk#*!vAgg+x;Kckkx=^0hIGu-s%>X5x
z)ZV@&ayUpQALVe6c4oO>GTl%{j>3uBm2G7EGi;Cj?r-#s{bWQ4%BD682WQrNI$PAT
zEryv`oV+IAv5}S0>}MI?rJ*gkDF)GVQsw5+T5XH@p5^6g6Q>*a`t(d%J1j$$1PlwM
z!w4k`qMx@$Qts?c=Fio4C8&=sXO^h)l@U_1fKU!V<X42Z#((D*GRs}%-)BiWMvh!T
zwFJzkiz#hn**-R1c35JL<R)qb{RE(#Nr>Sq>@<i~JjjHn=CR0V*qOdtzu38nX*DIT
z;`=O+y`WuM{<-edvgtY53295b<fm~-c9)FPvaJqfE^AyK1&+BG^0N?(AOi1gTOz+-
zaeFU!-ao92M4r811}Il@1NF9;rt&j^#286mh?s#Sk;_x!@EoT6&&&Q6e#r(V(nsLx
zxGma;DR*ilEiPl+2P-jcI(I_M0OgD)2e-yo#x~Z(7Rj*!Rj!$s$>n=n$nTTR<B9_*
z-gJ!F8tX$9lr6;W!@s%K?sMH*sloS!V^CrXbmb77s+LQ!O%F5KVk<YYJp<G(l_1IK
zQWfs5YPV=+O;OXPlj(kZt;O;x8RBqSK@4VUFp#%pE(kH_$`zvSm0Y{O<bediEn<{p
zOiV6Rk_aC6+Wf*DSs#J5%O2#Y9cO#6i0pq@B<J5s!eX0`RDL^}*a*4JIotb1dhdKM
z1-YRCU0^JiVmzZk2l|{yJBXCzd$}jp2c6fP+QXGrS-X5EQhKH|S4x_5_R&(gaTFaY
z>I@~S1tllxnybwn=-?$}a+2%X{0n!fjK{e$d^v>F?O24`+m?7s>$<*+(MdTtWuB1q
z%j4`I)-2~7*Ru##R+(S6#PvwUWdHEQW|f)YU>YET(tIru0)bD4#84oESAQW>AIa88
zYDp0_=c&xnkh3{Le3#L|l7sj4z5(j`*0p+~0!B#56(5D9<`yT6+A`jaP}aPcZbnD$
zj6}Cz7HQTTxZJ8rd~YI=A2=ubDrHxKS5KW2C&{98Hd2y*pCvJuS8)$Y23QfwYD?!)
z1_i-uuCSHQ*eAy1{wi|ou&$6FI@2p<a=-X=h41bsG7f>16yImr^>f|CJ!*lU%2z1J
zOt&;2WS&Yd73c017<3`vG>J(136xhYkUl~Yt80sIqpQuJkY{{8-5ktpWz%K)I*d)L
z)~ZjVFtsALcBYA02tq04c{J$CpXYl`RTv!QBpaNM&Ie+BSvnL!HAie7f=aFVbWUya
z1Jcy$ZfcRLf~YIGU*(!<OPPBl(?nzv>UtH&i)#Bj5;EI_@t)5+XLs|(ayh>jskSlz
ziu{1@v#^MVNp1PLZebb$3jf$-BmV09(=>1?-N1r2K`mAl>!e{&D|%c`rq$%`M#QOW
z#CPw9z3Vb%YQcIJ>Q_xk`Gvclu|8d_N4AoK+uL+$A*gqy(yQqFcp~G4dbdsK{?QSk
zoX&l!?S<*=QXyQ?p0RU&E|?}qPAEi6rWvwxu~ZL>5F^moqvT8!+w-O)H4<C@BVE=x
zch{j>xmE0X9)(|f*-@D_V!Yo&z8_4^KJ@{cX&UqCOTMHdHL1;}c+JmsivVR^E7W`?
zUGuFLIIw8}*_p)0fS^X1rM=FhC!Jmh<?u8LORORgQA4$#7k2GAXIdsFMX?NDGSQXu
zbWoxoX1R_TxW5)cqX&)b$#nXHdK(?Fs(;PnJ+98apgGOdm7|w}<WSTjyyp}7!2`Kn
zjro0+DW6vAT2s87+SXvE%}03kYHYfDgxtD&O=grpwgs)%9BW6oOlne+G^#vaGC#5>
z)oWkZi=C;1g0FRq5R~}l8f*wAn=U=5R1UAO#}^`;WMC=%CoXu(A*XX6Y8WY^J+3yn
zQ~P=qM<B|*Bnb}&s)x8`d@zR_2dJbk)i6*p7k1yW>HKruH5*<>^JzAxC++o`?eD8*
z1*p1G-;T1>jY{IBLNpNGFpdA3=<a({&GP`Mb)P*|L_r6NQL@$Ny2ZRIN(h+-x7w0v
z*`%W~HNGJ6S(w3;_0c?_sy1CJ3W)rw7i`v6y?2b0RIaf{645ReDkb|1VF`B#cQupq
zX;_GnC+Wz^2rMGCBWtF$UmA6w<hrOeQ&&TTPY!7rLsim&oW&@G3a8Nc7Q^%~7b+YL
z*z-@G`+C&Z5wVrzW3O1MML3vk&=UwHrb~FcWRee}N22+uw8gA1soZd48E7>!ld>Q+
zsP9>?qB~4s9Ohh!BhrWs<jQ(v925%{BKEGwZBU3$@yh4~f+4$9l(mK5^i(?uRGaGM
zD$Cfl!4DC8UeE=(v?e)-Uy~Fq^{rwWS*Ab^aV}SYA$8V7T4^0B#0o{p3O-k~#quhn
z!>{RZf>vopGwJ@osY*$uo6D<EVKJi6<9W6eY$qcyHC$XXmPa55I5YQuS=DW@Wx1<7
zd8X!b-OL=N#(a9gqrqj%%oKUHS)o!UYZ}kUu3Z0$e{}FFR3&}&oCHj@MmNTkCCYpK
z+WR9h>QVTX16AD662@!-5`%|>4Tou6%y?3Y18VKy0qTz^Bo%t%-l+PhDTz#RwB>RI
zs<3n=2j29qLPf_Rz$BQ)!@tte4iw#D#}%^7j0gu?8(y!Mw_@a+of$!6?rWrS?i)sz
z#06Kzg)C60Xy8wJ!qBXV!b)U3WrIg3K)1iNGSmzDogW3t_&&=ry6V2TwHts42g?N+
zPNC$}t3ia-J-aO@0HV5qGxk+2mC?Ii(&(+4O{yO{q)K6toF$b2e4MW=c4eX%G`C<=
zor)i7mvk6kL>h+TC(@e-xGOf|x56)2Xm)dP+J`*}PtGpy=5izl1pq&4u66Ds*Pe3S
z;9AGps}`yVGTly8&Pufj@>G!9o@65_qtITme9nZE%2bZ^T$i)DKMx068#p*}FK3hc
zyZh-}1}X3%90mI>km~>ZV`J%1u#`?TNvu_(C0W>+WU7bJrxMg|*Xfx^B*yk`{vNOl
zLGd2xQ8B~8lejh+rW~x%J|eK;-~oJ@C=Jq0tcM<*Hmw)X3X4wOXuHYeeK!v9x8#Ct
zq{NB}DKB1KiE%nhttkt2WKIXb=HcMXnl9PEjCH~DXLU4yrR}QEr1C&~iEH_*5+>;K
z|E`Jxh#l@rC_Ddlb(9YFzi$%>$Y?+{zok90!lpkFssc#OZMyBtHgjY#sw#jJ{bdFo
zEl_dN!p1eg>`QgApm9UFcLt<DQqO_nwbMDBFE5EuOycH&O+b5**g2nYif@_WU=oCY
ztPVM?SE5n-%je^bwGL!$EMTHmlQyX<V6TdF(x|1}83J_40k^RQ{Vk_4feJI)AtGt@
zS?_M)x_`d7C2==i&N2{udDXTI5$woRV0X>G`k<!OX`F>4>#o#-FuEgVqE{0iWQVnY
zhqZ6<W?No0B86NnNY%RKQ|Q%WJTWs8dG^9q3@MgOx?mz!&8c(oP?0$qYGdfag<R9a
z$Cg?^ng-4i_J(V1p1|Hx@!aq}JkEMuHSl0>nV;*PkXQ#UcN0;(T2%$Za_a6tMMfBa
z4yl1(${xf7Q-)}Dq0%i_{-hqPiP@hD&ekWXG5IRKn6@=c{eqRfAo{2oFEp8=;*Bcc
zwC3WGs!#9ozM%0<RJfEaVpoI91MLY3h{)L&q(EK7+rYc+E!94#CLgi4&Ch=t3{iGU
zYpXR+bykxDWc4RQAzr9Op*-xSQY0Z*z{EX5+UhKoiyE-~$H-!lLq|vF6&)4=-exwc
z;K<@!w%hmurO+Nqe)v$*q?qzS$XZ*_t}?_0!{?C+XRDj3N|=Dw%Z$XWAl4Snl+HlT
zi!n}S?L0sklHc^Dr7{8l1r5U+3x5kfOKIY)XE*6iC+e$`fMjcz)U40lRO23O`*yax
z9=LeY6PvX-GD|(4b}x**AY4)Sli!_6;Yh4}Nw$I$N=Sdc&B`X7I>FvDzSAo<&=JjV
zb19cwyLPu4m$!i~%P1`l)#;v^^)But{TyD!{ASqI0RST!DV7N7R`Ny863=k0c4R5o
z;vMxEyUTvVbn^=Z)4B=T8noNrHtlt;v%9k1@akU7cjWWC(ZJw_nVTn;>nibBwVGnp
z-%e&0glC<*9;1>1+tUV1c2v|1pt9u>+risd+O+9QYaH3>4==9oCbRisv6#>9Z?Dcz
zd(v*W>a55cANeQR+_!Wel}pG2{9R)y4Bw@2BSBb!j`ARY9V;=?VsGqyp}QPZIah0x
zTs>*0H#i**&xXUnNiWlS$`vx#Vu`r4YG&K9bVrR)dC<#nv%$$SyG;wqnM-2w>zanQ
z0NAF8`MK_?&5#!GOoht^(w1l1!rAq8tLZkL&6=GX6J<-Se_J#JLLAnb8E&y!!P&Bq
znZ2+pLpnyX&|2<>qDF3oke~V%7;`Et<JZ~~a=kKgW9q9YpV;i6du^5_5BzI=u6w;3
zL%J3_a^bDZ1^%07p-F>vq?PBy%Kb>4RTrDD5^(jWoeMR`g_?X*kgXnI`zKa#e?7B|
z`UaRiJuL)nkS?c={Lu{)H&meogim9o*5>u=;%eJ1);i_{=^+OE8ybj@_2dC|g~qgY
z18UkAJ1Mxn$+D~QEuFHuRWL{{P=hfB3-M%fMWM&ycDpfyJw2M!k7O7WIMglkbKS6f
zM31~1YD}%cB~VMGQ>J?EeygcfHE#kvhj~0YUD0u5dYZCg4J}F16Dz_F0b>zMYJ#!X
zGc!no^YyKpkYw_EfWBX<Z(R@6%)Ll4-qaA4^9WNz3{9OL=TPA(W{tI|;i_*-%Ry2j
z=#~%FK+9vWDcvhVw*?%sR$>u%rq_e4TRT@ClumkF)8!ygNUmb=ZGmi~miY%XAtbzu
zKOzJt8g}4IH9PGQX}e{{&{!@95Q-`5xsa8hL&|c0rHu{K`Rrn5-Y`+FHO2C}HlLuX
z6%4sOD>^@9f<#qa-H8?Z!A2B|7Ne<?Te}U#Oh)tc`U9G&UWXjNueL}AEX5dHd&Q0+
z>wJFMYy!F$Go?@ct8zk`<8=5dGr<8-Sxq)LTK#L4uIZZq>lg%{nf?T|oNp0tSeJ4`
z6GW1vSHmmj#@i05)$Cg2>Bkz<{^iuz+|#|c>mWZu-}cPfFT<fytR@$=hCMyKu`{dT
z)fp!eL?E=bTJI8_Q_I)XlDf1;{{mL4`R&Dt4r!(Rv)fr6Hy}}WD_?V4+MDIAe0s-_
zb+MdYpBXI4PDb~&+<?hBX*~4UL27;zF?Cbt#=%@USB+-0!?y;Tb9;Gq(hVWeH0$<<
zqnoKuS_@_P&vUQ?^LvbFTtF<JPjIn8Cv>bd>kZDX?q;^#z;}w7ib?AERxy@Sgs;1y
zv#nH+Dm%Ab4Bwt&HJ`$q!R6&>ba{1iKbhAz1YT%kL+eo8=YChMvhdi4HZ13pyBlo7
z<>mG5{d7?)-B7-mO6jn^2F_z0TcB>t6Uj+}?5ts$IkYHWt@6CafXAk99jVx&A<acQ
z)|!)u7@p;>4Yo@dOBVOic0l-A&-wCLU^8y)srA9K30dQbh0~$Ape`cW@@)2`jxK8^
zY#wPvHCrMci{)~$AyCH{a^@pm`xaM5P`XfQ1}C@m3OFL$e3r9?F<W4Gn4+)@Xj9*B
z#vh+9Z}hn9M6E=J0rMVCi=kTiiV37g?@G($X7p)^l}hzH44vCU8SE|Pi%ah7VBOY4
z(Y$TKzJ<J=gNJ^gBA_sfu}}9Z=354HEKK*k*S!&$B(%S5KF_V06KimjU+smdwE?Gg
zgdpm?(O%cKDWC4sWA<tteL1ZS8q{JQAFM=bj{|J2N93s?wEmXoYT6f&Frpd|c-T!u
ziY5O_c}uj8QS9VyM?+Yct5nP{S?!(6X?_!#tzrwL>F*>WhR1#kQn!PdHjbvEG>Eg6
za&cUBIx7Ui7Nd5UG?cPdOsvfXtY_O>k;TDR=r**Z#iOn{fh_3HFQG@7fUP~|*Nyv3
zm|*nHp<L60_?QgY)~+u%#DO&~N57Ny&1rSc0&-Q%YU02qI}S3}mKsA$V2IT#(%waT
zM}Bc>r(PbN=FJskC)cgr_hNEx<?=!Wa<f{;!UIk2=zK+l&cEGIwlV9Sx3Y>kM6-4H
zw}kS%zn%W5Rj*p!4(paHTDzry@i<V6jSX~=AvXB5dkPaAu0PcM$!Ax?7t0Oo3y|4f
zJKYo-wVK#@?yf6Ydzq`?_#U0kPHI`!4dXif)4Hv2U@CNSb=I$u@;y*I@T+O}<m`G<
z6OYD42dBN-u!rgB?((s)+BT)uun@ero7#M<PVe;m@)jcOc{wa8^5uMb2MPQAj+n8j
zt@e2zq%dIviwz*cUbdkqR<P9%%<2r9q`PKPNbF?3U)$2583E1jPa9NXr+0EXJcp@|
z>+9>Q%hCDS=}GSc;YCTUw9_A)o?VQt$~Fv7s~NVkjQH)^(R(>jA>P{d(sr`!9R@k<
zG|f7lEUQ~N!3)38t2A?MXp!p&{<7(vEo<E3og190wYuK0Ev{;H*3NZ(xG!d>#tub5
zsDrsyku<3hdq<Y!cf(rC7T^B=<E&c~aLKP4)cUTZN$aLLU|{!QSm<3_-txV)Uqd1J
zz2lbfHWf>4)d(UoIn#47o1p#OJ@1^^`QebEeFW)1^3_TR?9hGkK^yG-J4aSy$f36$
ziygp_`taxKx_0sD{*8U{5Ympd4AOZ#Ir#$j;oD(5*REpVNDGJX@F=|ih%jC*hrNyz
z<j)bM!!`WO*dMp7KEES-IlllhJrN2u(F;eFV=vrJlA+p?u4D(~=jGGO|KElqo%34R
zfS7B;zVip_E$Kj~&qt1|^X25yNTfbc<u46PI=GsZ(JexR@^o?NQMuKA2njSMlN77P
z^ycE^1B+ByE!}Vr6Wtrq!(r*c4y&g()M-Ah37M6>0)F%5Vs>{kIv);TC;D!gA8rEs
zFmI-P*!ySRoKvH-d5_iBY&apruQ@I9)nYN5&8E}I-AJw(Iu>R}hnse~C&P;?48zyC
zRGuEIYmw=EOw`hW@gdS0zQAo<Z1jPLR62tTSaEQ5eS0^Vl3AVFHZMj`JLd*#0Bdov
z9*EC09<#F?1NQ07bcxF*ie{lGTV71mx}0NRMPa6=w`QcjL`nXx)KV1+?PZ^DoBzJN
zc|u)Pk*+(6d)Q0r8`o+Xa0Te4pXiSk7|n~fis>_~gLE_;)GsrQ=v8MQtbp{kQO(8T
zw%v{h$LNLdxv`oYjEW2K<RBX-AEOl;U}opB4I9rkE?nPG*}jiE=aUVNU)2P@clN#&
zKi&K0*ITPru@lHFYu*as39#;5wB!i;?9~$>cBm@UX8;)s$VIWZc@g8R>}=8y#HkSG
zn`a-2TE~aeYv)H6>f@2eN3E`gba1;_YduA9tq#F`?ziK|>REi;`gV0Lrj237_3GI*
zYd!LfPr5CFLoYC=BhC7a1CmyoV>c4!nI2}NO6A%o`Q6#ejAmz@{`pPKUP^~p8uUyI
zX;fH{=>C#3k~7#|`{H`C5GxMaeAMxosJ*$`^sFXoRV?l<26bydHp6|Y62Oy_!TIP4
zwqJ2O(J!Xg#`iLw3Y!DelNp=!uI6`Far>eJRB~hxu)$Kd-#<ASz|sHE)8(?^UDz%F
zXLVrB!PUiwm#lwehCeO%9!x@A!K#T1ST+HZo_~i^o=;29{cD3o2Os#diT!Et3gMLk
TuM~Ktz$*n_Dey{xHWc`O(cS1K
literal 0
HcmV?d00001
diff --git a/Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec b/Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec
new file mode 100644
index 0000000000..ea070a10cd
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/OpenBoardPkg.dec
@@ -0,0 +1,152 @@
+## @file
+# EFI/Framework Simics platform
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = SimicsOpenBoardPkg
+ PACKAGE_GUID = E6A03E0D-5944-4dc6-9292-090D609EDD3A
+ PACKAGE_VERSION = 0.1
+
+[Includes]
+ Include
+
+[Guids]
+ gBoardModuleTokenSpaceGuid = {0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a, 0xea, 0x71, 0x5f, 0xd3, 0x59, 0xa5}}
+ gSimicsBoardConfigGuid = {0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a, 0xea, 0x71, 0x5f, 0xd3, 0x59, 0xa5}}
+
+[PcdsFixedAtBuild]
+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase|0x0|UINT32|0
+ gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize|0x0|UINT32|1
+ gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase|0x0|UINT32|0x15
+ gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize|0x0|UINT32|0x16
+
+ #TODO: Remove these two when we integrate new PlatformPei
+ gBoardModuleTokenSpaceGuid.PcdSimicsMemFvBase|0x00800000|UINT32|2
+ gBoardModuleTokenSpaceGuid.PcdSimicsMemFvSize|0x00500000|UINT32|3
+
+ gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase|0x0|UINT32|0x8
+ gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize|0x0|UINT32|0x9
+ gBoardModuleTokenSpaceGuid.PcdSimicsFirmwareFdSize|0x0|UINT32|0xa
+ gBoardModuleTokenSpaceGuid.PcdSimicsFirmwareBlockSize|0|UINT32|0xb
+ gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase|0x0|UINT32|0xc
+ gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase|0x0|UINT32|0xd
+ gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase|0x0|UINT32|0xe
+ gBoardModuleTokenSpaceGuid.PcdSimicsFdBaseAddress|0x0|UINT32|0xf
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesBase|0x0|UINT32|0x11
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesSize|0x0|UINT32|0x12
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|0x0|UINT32|0x13
+ gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamSize|0x0|UINT32|0x14
+ gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageBase|0x0|UINT32|0x18
+ gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageSize|0x0|UINT32|0x19
+ gBoardModuleTokenSpaceGuid.PcdGuidedExtractHandlerTableSize|0x0|UINT32|0x1a
+ gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd|0x0|UINT32|0x1f
+
+[PcdsDynamic, PcdsDynamicEx]
+
+ # TODO: investigate whether next two Pcds are needed
+ gBoardModuleTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|0x28
+ gBoardModuleTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
+ gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0|UINT16|0x1b
+
+ ## The IO port aperture shared by all PCI root bridges.
+ #
+ gBoardModuleTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x22
+ gBoardModuleTokenSpaceGuid.PcdPciIoSize|0x0|UINT64|0x23
+
+ ## The 32-bit MMIO aperture shared by all PCI root bridges.
+ #
+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Base|0x0|UINT64|0x24
+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Size|0x0|UINT64|0x25
+
+ ## The 64-bit MMIO aperture shared by all PCI root bridges.
+ #
+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Base|0x0|UINT64|0x26
+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Size|0x0|UINT64|0x27
+
+[PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx, PcdsPatchableInModule]
+ ## Pcd8259LegacyModeMask defines the default mask value for platform. This value is determined<BR><BR>
+ # 1) If platform only support pure UEFI, value should be set to 0xFFFF or 0xFFFE;
+ # Because only clock interrupt is allowed in legacy mode in pure UEFI platform.<BR>
+ # 2) If platform install CSM and use thunk module:<BR>
+ # a) If thunk call provided by CSM binary requires some legacy interrupt support, the corresponding bit
+ # should be opened as 0.<BR>
+ # For example, if keyboard interfaces provided CSM binary use legacy keyboard interrupt in 8259 bit 1, then
+ # the value should be set to 0xFFFC.<BR>
+ # b) If all thunk call provied by CSM binary do not require legacy interrupt support, value should be set
+ # to 0xFFFF or 0xFFFE.<BR>
+ #
+ # The default value of legacy mode mask could be changed by EFI_LEGACY_8259_PROTOCOL->SetMask(). But it is rarely
+ # need change it except some special cases such as when initializing the CSM binary, it should be set to 0xFFFF to
+ # mask all legacy interrupt. Please restore the original legacy mask value if changing is made for these special case.<BR>
+ # @Prompt 8259 Legacy Mode mask.
+ gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeMask|0xFFFF|UINT16|0x00000001
+
+ ## Pcd8259LegacyModeEdgeLevel defines the default edge level for legacy mode's interrrupt controller.
+ # For the corresponding bits, 0 = Edge triggered and 1 = Level triggered.
+ # @Prompt 8259 Legacy Mode edge level.
+ gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel|0x0000|UINT16|0x00000002
+
+ ## Indicates if we need enable IsaAcpiCom1 device.<BR><BR>
+ # TRUE - Enables IsaAcpiCom1 device.<BR>
+ # FALSE - Doesn't enable IsaAcpiCom1 device.<BR>
+ # @Prompt Enable IsaAcpiCom1 device.
+ gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiCom1Enable|TRUE|BOOLEAN|0x00000003
+
+ ## Indicates if we need enable IsaAcpiCom2 device.<BR><BR>
+ # TRUE - Enables IsaAcpiCom2 device.<BR>
+ # FALSE - Doesn't enable IsaAcpiCom2 device.<BR>
+ # @Prompt Enable IsaAcpiCom12 device.
+ gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiCom2Enable|TRUE|BOOLEAN|0x00000004
+
+ ## Indicates if we need enable IsaAcpiPs2Keyboard device.<BR><BR>
+ # TRUE - Enables IsaAcpiPs2Keyboard device.<BR>
+ # FALSE - Doesn't enable IsaAcpiPs2Keyboard device.<BR>
+ # @Prompt Enable IsaAcpiPs2Keyboard device.
+ gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiPs2KeyboardEnable|TRUE|BOOLEAN|0x00000005
+
+ ## Indicates if we need enable IsaAcpiPs2Mouse device.<BR><BR>
+ # TRUE - Enables IsaAcpiPs2Mouse device.<BR>
+ # FALSE - Doesn't enable IsaAcpiPs2Mouse device.<BR>
+ # @Prompt Enable IsaAcpiPs2Mouse device.
+ gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiPs2MouseEnable|TRUE|BOOLEAN|0x00000006
+
+ ## Indicates if we need enable IsaAcpiFloppyA device.<BR><BR>
+ # TRUE - Enables IsaAcpiFloppyA device.<BR>
+ # FALSE - Doesn't enable IsaAcpiFloppyA device.<BR>
+ # @Prompt Enable IsaAcpiFloppyA device.
+ gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiFloppyAEnable|TRUE|BOOLEAN|0x00000007
+
+ ## Indicates if we need enable IsaAcpiFloppyB device.<BR><BR>
+ # TRUE - Enables IsaAcpiFloppyB device.<BR>
+ # FALSE - Doesn't enable IsaAcpiFloppyB device.<BR>
+ # @Prompt Enable IsaAcpiFloppyB device.
+ gPcAtChipsetPkgTokenSpaceGuid.PcdIsaAcpiFloppyBEnable|TRUE|BOOLEAN|0x00000008
+
+[PcdsFixedAtBuild, PcdsPatchableInModule]
+ ## FFS filename to find the shell application.
+ # @Prompt FFS Name of Shell Application
+ gBoardModuleTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }|VOID*|0x40000004
+
+ ## ISA Bus features to support DMA, SlaveDMA and ISA Memory. <BR><BR>
+ # BIT0 indicates if DMA is supported<BR>
+ # BIT1 indicates if only slave DMA is supported<BR>
+ # BIT2 indicates if ISA memory is supported<BR>
+ # Other BITs are reseved and must be zero.
+ # If more than one features are supported, the different BIT will be enabled at the same time.
+ # @Prompt ISA Bus Features
+ # @Expression 0x80000002 | (gBoardModuleTokenSpaceGuid.PcdIsaBusSupportedFeatures & 0xF8) == 0
+ gBoardModuleTokenSpaceGuid.PcdIsaBusSupportedFeatures|0x05|UINT8|0x00010040
+
+ gBoardModuleTokenSpaceGuid.PcdLogoFile |{ 0x99, 0x8b, 0xB2, 0x7B, 0xBB, 0x61, 0xD5, 0x11, 0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }|VOID*|0x00010037
+
+[Protocols]
+ ##
+ ## IntelFrameworkModulePkg
+ ##
+ gEfiOEMBadgingProtocolGuid = { 0x170E13C0, 0xBF1B, 0x4218, { 0x87, 0x1D, 0x2A, 0xBD, 0xC6, 0xF8, 0x87, 0xBC }}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h
new file mode 100644
index 0000000000..e98aac4676
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h
@@ -0,0 +1,45 @@
+/** @file
+ This is an implementation of the ACPI platform driver.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ACPI_PLATFORM_H_
+#define _ACPI_PLATFORM_H_
+
+//
+// Statements that include other header files
+//
+
+#include <Base.h>
+#include <Uefi.h>
+#include <IndustryStandard/Pci30.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
+#include <Register/Hpet.h>
+#include <Guid/EventGroup.h>
+#include <Guid/GlobalVariable.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BoardAcpiTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/AslUpdateLib.h>
+#include <Library/PciSegmentInfoLib.h>
+
+#include <Protocol/AcpiTable.h>
+#include <Protocol/MpService.h>
+#include <Protocol/PciIo.h>
+
+#include <Register/Cpuid.h>
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.inf
new file mode 100644
index 0000000000..7dfd0832a3
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.inf
@@ -0,0 +1,105 @@
+## @file
+# Component information file for AcpiPlatform module
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = AcpiPlatform
+ FILE_GUID = FC90EB7A-3E0A-483C-A26C-484D36593FF4
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InstallAcpiPlatform
+
+[Sources.common]
+ AcpiPlatform.h
+ AcpiPlatform.c
+ Fadt/Fadt.c
+ Facs/Facs.c
+ Hpet/Hpet.c
+ Wsmt/Wsmt.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ PcAtChipsetPkg/PcAtChipsetPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ BaseLib
+ DebugLib
+ IoLib
+ PcdLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ BaseMemoryLib
+ HobLib
+ PciSegmentInfoLib
+ AslUpdateLib
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
+
+ gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicEnable
+ gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicCount
+ gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicIdBase
+ gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicAddressBase
+ gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicInterruptBase
+ gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuThreadCount
+ gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuCoreCount
+ gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuSocketCount
+
+ gMinPlatformPkgTokenSpaceGuid.PcdFadtPreferredPmProfile
+ gMinPlatformPkgTokenSpaceGuid.PcdFadtIaPcBootArch
+ gMinPlatformPkgTokenSpaceGuid.PcdFadtFlags
+
+ gPcAtChipsetPkgTokenSpaceGuid.PcdHpetBaseAddress
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiEnableSwSmi
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiDisableSwSmi
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1AEventBlockAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1BEventBlockAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1AControlBlockAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1BControlBlockAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm2ControlBlockAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPmTimerBlockAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiGpe0BlockAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiGpe1BlockAddress
+
+ gMinPlatformPkgTokenSpaceGuid.PcdLocalApicAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdIoApicAddress
+ gMinPlatformPkgTokenSpaceGuid.PcdIoApicId
+
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
+ gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuSocketCount
+
+ gMinPlatformPkgTokenSpaceGuid.PcdWsmtProtectionFlags
+
+[Protocols]
+ gEfiAcpiTableProtocolGuid ## CONSUMES
+ gEfiMpServiceProtocolGuid ## CONSUMES
+ gEfiPciIoProtocolGuid ## CONSUMES
+
+[Guids]
+ gEfiGlobalVariableGuid ## CONSUMES
+ gEfiHobListGuid ## CONSUMES
+ gEfiEndOfDxeEventGroupGuid ## CONSUMES
+
+[Depex]
+ gEfiAcpiTableProtocolGuid AND
+ gEfiMpServiceProtocolGuid AND
+ gEfiPciRootBridgeIoProtocolGuid AND
+ gEfiVariableArchProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid
+
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qemu.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qemu.h
new file mode 100644
index 0000000000..f6ef44a14f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qemu.h
@@ -0,0 +1,507 @@
+/** @file
+ QEMU Video Controller Driver
+
+ Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// QEMU Video Controller Driver
+//
+
+#ifndef _QEMU_H_
+#define _QEMU_H_
+
+
+#include <Uefi.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/DriverSupportedEfiVersion.h>
+#include <Protocol/DevicePath.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/TimerLib.h>
+#include <Library/FrameBufferBltLib.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Acpi.h>
+
+#include <Library/S3BootScriptLib.h>
+
+//
+// QEMU Video PCI Configuration Header values
+//
+#define CIRRUS_LOGIC_VENDOR_ID 0x1013
+#define CIRRUS_LOGIC_5430_DEVICE_ID 0x00a8
+#define CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID 0x00a0
+#define CIRRUS_LOGIC_5446_DEVICE_ID 0x00b8
+
+//
+// QEMU Vide Graphical Mode Data
+//
+typedef struct {
+ UINT32 InternalModeIndex; // points into card-specific mode table
+ UINT32 HorizontalResolution;
+ UINT32 VerticalResolution;
+ UINT32 ColorDepth;
+} QEMU_VIDEO_MODE_DATA;
+
+#define PIXEL_RED_SHIFT 0
+#define PIXEL_GREEN_SHIFT 3
+#define PIXEL_BLUE_SHIFT 6
+
+#define PIXEL_RED_MASK (BIT7 | BIT6 | BIT5)
+#define PIXEL_GREEN_MASK (BIT4 | BIT3 | BIT2)
+#define PIXEL_BLUE_MASK (BIT1 | BIT0)
+
+#define PIXEL_TO_COLOR_BYTE(pixel, mask, shift) ((UINT8) ((pixel & mask) << shift))
+#define PIXEL_TO_RED_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel, PIXEL_RED_MASK, PIXEL_RED_SHIFT)
+#define PIXEL_TO_GREEN_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel, PIXEL_GREEN_MASK, PIXEL_GREEN_SHIFT)
+#define PIXEL_TO_BLUE_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel, PIXEL_BLUE_MASK, PIXEL_BLUE_SHIFT)
+
+#define RGB_BYTES_TO_PIXEL(Red, Green, Blue) \
+ (UINT8) ( (((Red) >> PIXEL_RED_SHIFT) & PIXEL_RED_MASK) | \
+ (((Green) >> PIXEL_GREEN_SHIFT) & PIXEL_GREEN_MASK) | \
+ (((Blue) >> PIXEL_BLUE_SHIFT) & PIXEL_BLUE_MASK) )
+
+#define PIXEL24_RED_MASK 0x00ff0000
+#define PIXEL24_GREEN_MASK 0x0000ff00
+#define PIXEL24_BLUE_MASK 0x000000ff
+
+#define GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER 0xffff
+
+//
+// QEMU Video Private Data Structure
+//
+#define QEMU_VIDEO_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('Q', 'V', 'I', 'D')
+
+typedef enum {
+ QEMU_VIDEO_CIRRUS_5430 = 1,
+ QEMU_VIDEO_CIRRUS_5446,
+ QEMU_VIDEO_BOCHS,
+ QEMU_VIDEO_BOCHS_MMIO,
+} QEMU_VIDEO_VARIANT;
+
+typedef struct {
+ UINT8 SubClass;
+ UINT16 VendorId;
+ UINT16 DeviceId;
+ QEMU_VIDEO_VARIANT Variant;
+ CHAR16 *Name;
+} QEMU_VIDEO_CARD;
+
+typedef struct {
+ UINT64 Signature;
+ EFI_HANDLE Handle;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT64 OriginalPciAttributes;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL GraphicsOutput;
+ EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;
+
+ //
+ // The next two fields match the client-visible
+ // EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.MaxMode field.
+ //
+ UINTN MaxMode;
+ QEMU_VIDEO_MODE_DATA *ModeData;
+
+ QEMU_VIDEO_VARIANT Variant;
+ FRAME_BUFFER_CONFIGURE *FrameBufferBltConfigure;
+ UINTN FrameBufferBltConfigureSize;
+} QEMU_VIDEO_PRIVATE_DATA;
+
+///
+/// Card-specific Video Mode structures
+///
+typedef struct {
+ UINT32 Width;
+ UINT32 Height;
+ UINT32 ColorDepth;
+ UINT8 *CrtcSettings;
+ UINT16 *SeqSettings;
+ UINT8 MiscSetting;
+} QEMU_VIDEO_CIRRUS_MODES;
+
+typedef struct {
+ UINT32 Width;
+ UINT32 Height;
+ UINT32 ColorDepth;
+} QEMU_VIDEO_BOCHS_MODES;
+
+#define QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS(a) \
+ CR(a, QEMU_VIDEO_PRIVATE_DATA, GraphicsOutput, QEMU_VIDEO_PRIVATE_DATA_SIGNATURE)
+
+
+//
+// Global Variables
+//
+extern UINT8 AttributeController[];
+extern UINT8 GraphicsController[];
+extern UINT8 Crtc_640_480_256_60[];
+extern UINT16 Seq_640_480_256_60[];
+extern UINT8 Crtc_800_600_256_60[];
+extern UINT16 Seq_800_600_256_60[];
+extern UINT8 Crtc_1024_768_256_60[];
+extern UINT16 Seq_1024_768_256_60[];
+extern QEMU_VIDEO_CIRRUS_MODES QemuVideoCirrusModes[];
+extern QEMU_VIDEO_BOCHS_MODES QemuVideoBochsModes[];
+extern EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gQemuVideoComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gQemuVideoComponentName2;
+extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gQemuVideoDriverSupportedEfiVersion;
+
+//
+// Io Registers defined by VGA
+//
+#define CRTC_ADDRESS_REGISTER 0x3d4
+#define CRTC_DATA_REGISTER 0x3d5
+#define SEQ_ADDRESS_REGISTER 0x3c4
+#define SEQ_DATA_REGISTER 0x3c5
+#define GRAPH_ADDRESS_REGISTER 0x3ce
+#define GRAPH_DATA_REGISTER 0x3cf
+#define ATT_ADDRESS_REGISTER 0x3c0
+#define MISC_OUTPUT_REGISTER 0x3c2
+#define INPUT_STATUS_1_REGISTER 0x3da
+#define DAC_PIXEL_MASK_REGISTER 0x3c6
+#define PALETTE_INDEX_REGISTER 0x3c8
+#define PALETTE_DATA_REGISTER 0x3c9
+
+#define VBE_DISPI_IOPORT_INDEX 0x01CE
+#define VBE_DISPI_IOPORT_DATA 0x01D0
+
+#define VBE_DISPI_INDEX_ID 0x0
+#define VBE_DISPI_INDEX_XRES 0x1
+#define VBE_DISPI_INDEX_YRES 0x2
+#define VBE_DISPI_INDEX_BPP 0x3
+#define VBE_DISPI_INDEX_ENABLE 0x4
+#define VBE_DISPI_INDEX_BANK 0x5
+#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
+#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
+#define VBE_DISPI_INDEX_X_OFFSET 0x8
+#define VBE_DISPI_INDEX_Y_OFFSET 0x9
+#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa
+
+#define VBE_DISPI_ID0 0xB0C0
+#define VBE_DISPI_ID1 0xB0C1
+#define VBE_DISPI_ID2 0xB0C2
+#define VBE_DISPI_ID3 0xB0C3
+#define VBE_DISPI_ID4 0xB0C4
+#define VBE_DISPI_ID5 0xB0C5
+
+#define VBE_DISPI_DISABLED 0x00
+#define VBE_DISPI_ENABLED 0x01
+#define VBE_DISPI_GETCAPS 0x02
+#define VBE_DISPI_8BIT_DAC 0x20
+#define VBE_DISPI_LFB_ENABLED 0x40
+#define VBE_DISPI_NOCLEARMEM 0x80
+
+//
+// Graphics Output Hardware abstraction internal worker functions
+//
+EFI_STATUS
+QemuVideoGraphicsOutputConstructor (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ );
+
+EFI_STATUS
+QemuVideoGraphicsOutputDestructor (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ );
+
+
+//
+// EFI_DRIVER_BINDING_PROTOCOL Protocol Interface
+//
+/**
+ TODO: Add function description
+
+ @param This TODO: add argument description
+ @param Controller TODO: add argument description
+ @param RemainingDevicePath TODO: add argument description
+
+ TODO: add return values
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoControllerDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ TODO: Add function description
+
+ @param This TODO: add argument description
+ @param Controller TODO: add argument description
+ @param RemainingDevicePath TODO: add argument description
+
+ TODO: add return values
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoControllerDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ TODO: Add function description
+
+ @param This TODO: add argument description
+ @param Controller TODO: add argument description
+ @param NumberOfChildren TODO: add argument description
+ @param ChildHandleBuffer TODO: add argument description
+
+ TODO: add return values
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoControllerDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+//
+// EFI Component Name Functions
+//
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+QemuVideoComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+
+//
+// Local Function Prototypes
+//
+VOID
+InitializeCirrusGraphicsMode (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ QEMU_VIDEO_CIRRUS_MODES *ModeData
+ );
+
+VOID
+InitializeBochsGraphicsMode (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ QEMU_VIDEO_BOCHS_MODES *ModeData
+ );
+
+VOID
+SetPaletteColor (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Index,
+ UINT8 Red,
+ UINT8 Green,
+ UINT8 Blue
+ );
+
+VOID
+SetDefaultPalette (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ );
+
+VOID
+DrawLogo (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN ScreenWidth,
+ UINTN ScreenHeight
+ );
+
+VOID
+outb (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Address,
+ UINT8 Data
+ );
+
+VOID
+outw (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Address,
+ UINT16 Data
+ );
+
+UINT8
+inb (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Address
+ );
+
+UINT16
+inw (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Address
+ );
+
+VOID
+BochsWrite (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINT16 Reg,
+ UINT16 Data
+ );
+
+UINT16
+BochsRead (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINT16 Reg
+ );
+
+VOID
+VgaOutb (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ UINTN Reg,
+ UINT8 Data
+ );
+
+EFI_STATUS
+QemuVideoCirrusModeSetup (
+ QEMU_VIDEO_PRIVATE_DATA *Private
+ );
+
+EFI_STATUS
+QemuVideoBochsModeSetup (
+ QEMU_VIDEO_PRIVATE_DATA *Private,
+ BOOLEAN IsQxl
+ );
+
+VOID
+InstallVbeShim (
+ IN CONST CHAR16 *CardName,
+ IN EFI_PHYSICAL_ADDRESS FrameBufferBase
+ );
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
new file mode 100644
index 0000000000..4143487366
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
@@ -0,0 +1,74 @@
+## @file
+# This driver is a sample implementation of the Graphics Output Protocol for
+# the QEMU (Cirrus Logic 5446) video controller.
+#
+# Copyright (c) 2006 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = QemuVideoDxe
+ FILE_GUID = e3752948-b9a1-4770-90c4-df41c38986be
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializeQemuVideo
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+# DRIVER_BINDING = gQemuVideoDriverBinding
+# COMPONENT_NAME = gQemuVideoComponentName
+#
+
+[Sources.common]
+ ComponentName.c
+ Driver.c
+ DriverSupportedEfiVersion.c
+ Gop.c
+ Initialize.c
+ Qemu.h
+
+[Sources.Ia32, Sources.X64]
+ VbeShim.c
+ VbeShim.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ OptionRomPkg/OptionRomPkg.dec
+ OvmfPkg/OvmfPkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ FrameBufferBltLib
+ DebugLib
+ DevicePathLib
+ MemoryAllocationLib
+ PcdLib
+ PciLib
+ PrintLib
+ TimerLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+ S3BootScriptLib
+
+[Protocols]
+ gEfiDriverSupportedEfiVersionProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+ gEfiGraphicsOutputProtocolGuid # PROTOCOL BY_START
+ gEfiDevicePathProtocolGuid # PROTOCOL BY_START
+ gEfiPciIoProtocolGuid # PROTOCOL TO_START
+ gEfiDxeSmmReadyToLockProtocolGuid
+
+[Pcd]
+ gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion
+ gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
+ gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm
new file mode 100644
index 0000000000..a82077e2d9
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm
@@ -0,0 +1,279 @@
+; @file
+; A minimal Int10h stub that allows the Windows 2008 R2 SP1 UEFI guest's buggy,
+; default VGA driver to switch to 1024x768x32, on the stdvga and QXL video
+; cards of QEMU.
+;
+; Copyright (C) 2014, Red Hat, Inc.
+; Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+
+; enable this macro for debug messages
+;%define DEBUG
+
+%macro DebugLog 1
+%ifdef DEBUG
+ push si
+ mov si, %1
+ call PrintStringSi
+ pop si
+%endif
+%endmacro
+
+
+BITS 16
+ORG 0
+
+VbeInfo:
+TIMES 256 nop
+
+VbeModeInfo:
+TIMES 256 nop
+
+
+Handler:
+ cmp ax, 0x4f00
+ je GetInfo
+ cmp ax, 0x4f01
+ je GetModeInfo
+ cmp ax, 0x4f02
+ je SetMode
+ cmp ax, 0x4f03
+ je GetMode
+ cmp ax, 0x4f10
+ je GetPmCapabilities
+ cmp ax, 0x4f15
+ je ReadEdid
+ cmp ah, 0x00
+ je SetModeLegacy
+ DebugLog StrUnkownFunction
+Hang:
+ jmp Hang
+
+
+GetInfo:
+ push es
+ push di
+ push ds
+ push si
+ push cx
+
+ DebugLog StrEnterGetInfo
+
+ ; target (es:di) set on input
+ push cs
+ pop ds
+ mov si, VbeInfo
+ ; source (ds:si) set now
+
+ mov cx, 256
+ cld
+ rep movsb
+
+ pop cx
+ pop si
+ pop ds
+ pop di
+ pop es
+ jmp Success
+
+
+GetModeInfo:
+ push es
+ push di
+ push ds
+ push si
+ push cx
+
+ DebugLog StrEnterGetModeInfo
+
+ and cx, ~0x4000 ; clear potentially set LFB bit in mode number
+ cmp cx, 0x00f1
+ je KnownMode1
+ DebugLog StrUnkownMode
+ jmp Hang
+KnownMode1:
+ ; target (es:di) set on input
+ push cs
+ pop ds
+ mov si, VbeModeInfo
+ ; source (ds:si) set now
+
+ mov cx, 256
+ cld
+ rep movsb
+
+ pop cx
+ pop si
+ pop ds
+ pop di
+ pop es
+ jmp Success
+
+
+%define ATT_ADDRESS_REGISTER 0x03c0
+%define VBE_DISPI_IOPORT_INDEX 0x01ce
+%define VBE_DISPI_IOPORT_DATA 0x01d0
+
+%define VBE_DISPI_INDEX_XRES 0x1
+%define VBE_DISPI_INDEX_YRES 0x2
+%define VBE_DISPI_INDEX_BPP 0x3
+%define VBE_DISPI_INDEX_ENABLE 0x4
+%define VBE_DISPI_INDEX_BANK 0x5
+%define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
+%define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
+%define VBE_DISPI_INDEX_X_OFFSET 0x8
+%define VBE_DISPI_INDEX_Y_OFFSET 0x9
+
+%define VBE_DISPI_ENABLED 0x01
+%define VBE_DISPI_LFB_ENABLED 0x40
+
+%macro BochsWrite 2
+ push dx
+ push ax
+
+ mov dx, VBE_DISPI_IOPORT_INDEX
+ mov ax, %1
+ out dx, ax
+
+ mov dx, VBE_DISPI_IOPORT_DATA
+ mov ax, %2
+ out dx, ax
+
+ pop ax
+ pop dx
+%endmacro
+
+SetMode:
+ push dx
+ push ax
+
+ DebugLog StrEnterSetMode
+
+ cmp bx, 0x40f1
+ je KnownMode2
+ DebugLog StrUnkownMode
+ jmp Hang
+KnownMode2:
+
+ ; unblank
+ mov dx, ATT_ADDRESS_REGISTER
+ mov al, 0x20
+ out dx, al
+
+ BochsWrite VBE_DISPI_INDEX_ENABLE, 0
+ BochsWrite VBE_DISPI_INDEX_BANK, 0
+ BochsWrite VBE_DISPI_INDEX_X_OFFSET, 0
+ BochsWrite VBE_DISPI_INDEX_Y_OFFSET, 0
+ BochsWrite VBE_DISPI_INDEX_BPP, 32
+ BochsWrite VBE_DISPI_INDEX_XRES, 1024
+ BochsWrite VBE_DISPI_INDEX_VIRT_WIDTH, 1024
+ BochsWrite VBE_DISPI_INDEX_YRES, 768
+ BochsWrite VBE_DISPI_INDEX_VIRT_HEIGHT, 768
+ BochsWrite VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED
+
+ pop ax
+ pop dx
+ jmp Success
+
+
+GetMode:
+ DebugLog StrEnterGetMode
+ mov bx, 0x40f1
+ jmp Success
+
+
+GetPmCapabilities:
+ DebugLog StrGetPmCapabilities
+ jmp Unsupported
+
+
+ReadEdid:
+ DebugLog StrReadEdid
+ jmp Unsupported
+
+
+SetModeLegacy:
+ DebugLog StrEnterSetModeLegacy
+
+ cmp al, 0x03
+ je KnownMode3
+ cmp al, 0x12
+ je KnownMode4
+ DebugLog StrUnkownMode
+ jmp Hang
+KnownMode3:
+ mov al, 0x30
+ jmp SetModeLegacyDone
+KnownMode4:
+ mov al, 0x20
+SetModeLegacyDone:
+ DebugLog StrExitSuccess
+ iret
+
+
+Success:
+ DebugLog StrExitSuccess
+ mov ax, 0x004f
+ iret
+
+
+Unsupported:
+ DebugLog StrExitUnsupported
+ mov ax, 0x014f
+ iret
+
+
+%ifdef DEBUG
+PrintStringSi:
+ pusha
+ push ds ; save original
+ push cs
+ pop ds
+ mov dx, 0x0402
+PrintStringSiLoop:
+ lodsb
+ cmp al, 0
+ je PrintStringSiDone
+ out dx, al
+ jmp PrintStringSiLoop
+PrintStringSiDone:
+ pop ds ; restore original
+ popa
+ ret
+
+
+StrExitSuccess:
+ db 'Exit', 0x0a, 0
+
+StrExitUnsupported:
+ db 'Unsupported', 0x0a, 0
+
+StrUnkownFunction:
+ db 'Unknown Function', 0x0a, 0
+
+StrEnterGetInfo:
+ db 'GetInfo', 0x0a, 0
+
+StrEnterGetModeInfo:
+ db 'GetModeInfo', 0x0a, 0
+
+StrEnterGetMode:
+ db 'GetMode', 0x0a, 0
+
+StrEnterSetMode:
+ db 'SetMode', 0x0a, 0
+
+StrEnterSetModeLegacy:
+ db 'SetModeLegacy', 0x0a, 0
+
+StrUnkownMode:
+ db 'Unkown Mode', 0x0a, 0
+
+StrGetPmCapabilities:
+ db 'GetPmCapabilities', 0x0a, 0
+
+StrReadEdid:
+ db 'ReadEdid', 0x0a, 0
+%endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h
new file mode 100644
index 0000000000..cc9b6e14cd
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h
@@ -0,0 +1,701 @@
+//
+// THIS FILE WAS GENERATED BY "VbeShim.sh". DO NOT EDIT.
+//
+#ifndef _VBE_SHIM_H_
+#define _VBE_SHIM_H_
+STATIC CONST UINT8 mVbeShim[] = {
+ /* 00000000 nop */ 0x90,
+ /* 00000001 nop */ 0x90,
+ /* 00000002 nop */ 0x90,
+ /* 00000003 nop */ 0x90,
+ /* 00000004 nop */ 0x90,
+ /* 00000005 nop */ 0x90,
+ /* 00000006 nop */ 0x90,
+ /* 00000007 nop */ 0x90,
+ /* 00000008 nop */ 0x90,
+ /* 00000009 nop */ 0x90,
+ /* 0000000A nop */ 0x90,
+ /* 0000000B nop */ 0x90,
+ /* 0000000C nop */ 0x90,
+ /* 0000000D nop */ 0x90,
+ /* 0000000E nop */ 0x90,
+ /* 0000000F nop */ 0x90,
+ /* 00000010 nop */ 0x90,
+ /* 00000011 nop */ 0x90,
+ /* 00000012 nop */ 0x90,
+ /* 00000013 nop */ 0x90,
+ /* 00000014 nop */ 0x90,
+ /* 00000015 nop */ 0x90,
+ /* 00000016 nop */ 0x90,
+ /* 00000017 nop */ 0x90,
+ /* 00000018 nop */ 0x90,
+ /* 00000019 nop */ 0x90,
+ /* 0000001A nop */ 0x90,
+ /* 0000001B nop */ 0x90,
+ /* 0000001C nop */ 0x90,
+ /* 0000001D nop */ 0x90,
+ /* 0000001E nop */ 0x90,
+ /* 0000001F nop */ 0x90,
+ /* 00000020 nop */ 0x90,
+ /* 00000021 nop */ 0x90,
+ /* 00000022 nop */ 0x90,
+ /* 00000023 nop */ 0x90,
+ /* 00000024 nop */ 0x90,
+ /* 00000025 nop */ 0x90,
+ /* 00000026 nop */ 0x90,
+ /* 00000027 nop */ 0x90,
+ /* 00000028 nop */ 0x90,
+ /* 00000029 nop */ 0x90,
+ /* 0000002A nop */ 0x90,
+ /* 0000002B nop */ 0x90,
+ /* 0000002C nop */ 0x90,
+ /* 0000002D nop */ 0x90,
+ /* 0000002E nop */ 0x90,
+ /* 0000002F nop */ 0x90,
+ /* 00000030 nop */ 0x90,
+ /* 00000031 nop */ 0x90,
+ /* 00000032 nop */ 0x90,
+ /* 00000033 nop */ 0x90,
+ /* 00000034 nop */ 0x90,
+ /* 00000035 nop */ 0x90,
+ /* 00000036 nop */ 0x90,
+ /* 00000037 nop */ 0x90,
+ /* 00000038 nop */ 0x90,
+ /* 00000039 nop */ 0x90,
+ /* 0000003A nop */ 0x90,
+ /* 0000003B nop */ 0x90,
+ /* 0000003C nop */ 0x90,
+ /* 0000003D nop */ 0x90,
+ /* 0000003E nop */ 0x90,
+ /* 0000003F nop */ 0x90,
+ /* 00000040 nop */ 0x90,
+ /* 00000041 nop */ 0x90,
+ /* 00000042 nop */ 0x90,
+ /* 00000043 nop */ 0x90,
+ /* 00000044 nop */ 0x90,
+ /* 00000045 nop */ 0x90,
+ /* 00000046 nop */ 0x90,
+ /* 00000047 nop */ 0x90,
+ /* 00000048 nop */ 0x90,
+ /* 00000049 nop */ 0x90,
+ /* 0000004A nop */ 0x90,
+ /* 0000004B nop */ 0x90,
+ /* 0000004C nop */ 0x90,
+ /* 0000004D nop */ 0x90,
+ /* 0000004E nop */ 0x90,
+ /* 0000004F nop */ 0x90,
+ /* 00000050 nop */ 0x90,
+ /* 00000051 nop */ 0x90,
+ /* 00000052 nop */ 0x90,
+ /* 00000053 nop */ 0x90,
+ /* 00000054 nop */ 0x90,
+ /* 00000055 nop */ 0x90,
+ /* 00000056 nop */ 0x90,
+ /* 00000057 nop */ 0x90,
+ /* 00000058 nop */ 0x90,
+ /* 00000059 nop */ 0x90,
+ /* 0000005A nop */ 0x90,
+ /* 0000005B nop */ 0x90,
+ /* 0000005C nop */ 0x90,
+ /* 0000005D nop */ 0x90,
+ /* 0000005E nop */ 0x90,
+ /* 0000005F nop */ 0x90,
+ /* 00000060 nop */ 0x90,
+ /* 00000061 nop */ 0x90,
+ /* 00000062 nop */ 0x90,
+ /* 00000063 nop */ 0x90,
+ /* 00000064 nop */ 0x90,
+ /* 00000065 nop */ 0x90,
+ /* 00000066 nop */ 0x90,
+ /* 00000067 nop */ 0x90,
+ /* 00000068 nop */ 0x90,
+ /* 00000069 nop */ 0x90,
+ /* 0000006A nop */ 0x90,
+ /* 0000006B nop */ 0x90,
+ /* 0000006C nop */ 0x90,
+ /* 0000006D nop */ 0x90,
+ /* 0000006E nop */ 0x90,
+ /* 0000006F nop */ 0x90,
+ /* 00000070 nop */ 0x90,
+ /* 00000071 nop */ 0x90,
+ /* 00000072 nop */ 0x90,
+ /* 00000073 nop */ 0x90,
+ /* 00000074 nop */ 0x90,
+ /* 00000075 nop */ 0x90,
+ /* 00000076 nop */ 0x90,
+ /* 00000077 nop */ 0x90,
+ /* 00000078 nop */ 0x90,
+ /* 00000079 nop */ 0x90,
+ /* 0000007A nop */ 0x90,
+ /* 0000007B nop */ 0x90,
+ /* 0000007C nop */ 0x90,
+ /* 0000007D nop */ 0x90,
+ /* 0000007E nop */ 0x90,
+ /* 0000007F nop */ 0x90,
+ /* 00000080 nop */ 0x90,
+ /* 00000081 nop */ 0x90,
+ /* 00000082 nop */ 0x90,
+ /* 00000083 nop */ 0x90,
+ /* 00000084 nop */ 0x90,
+ /* 00000085 nop */ 0x90,
+ /* 00000086 nop */ 0x90,
+ /* 00000087 nop */ 0x90,
+ /* 00000088 nop */ 0x90,
+ /* 00000089 nop */ 0x90,
+ /* 0000008A nop */ 0x90,
+ /* 0000008B nop */ 0x90,
+ /* 0000008C nop */ 0x90,
+ /* 0000008D nop */ 0x90,
+ /* 0000008E nop */ 0x90,
+ /* 0000008F nop */ 0x90,
+ /* 00000090 nop */ 0x90,
+ /* 00000091 nop */ 0x90,
+ /* 00000092 nop */ 0x90,
+ /* 00000093 nop */ 0x90,
+ /* 00000094 nop */ 0x90,
+ /* 00000095 nop */ 0x90,
+ /* 00000096 nop */ 0x90,
+ /* 00000097 nop */ 0x90,
+ /* 00000098 nop */ 0x90,
+ /* 00000099 nop */ 0x90,
+ /* 0000009A nop */ 0x90,
+ /* 0000009B nop */ 0x90,
+ /* 0000009C nop */ 0x90,
+ /* 0000009D nop */ 0x90,
+ /* 0000009E nop */ 0x90,
+ /* 0000009F nop */ 0x90,
+ /* 000000A0 nop */ 0x90,
+ /* 000000A1 nop */ 0x90,
+ /* 000000A2 nop */ 0x90,
+ /* 000000A3 nop */ 0x90,
+ /* 000000A4 nop */ 0x90,
+ /* 000000A5 nop */ 0x90,
+ /* 000000A6 nop */ 0x90,
+ /* 000000A7 nop */ 0x90,
+ /* 000000A8 nop */ 0x90,
+ /* 000000A9 nop */ 0x90,
+ /* 000000AA nop */ 0x90,
+ /* 000000AB nop */ 0x90,
+ /* 000000AC nop */ 0x90,
+ /* 000000AD nop */ 0x90,
+ /* 000000AE nop */ 0x90,
+ /* 000000AF nop */ 0x90,
+ /* 000000B0 nop */ 0x90,
+ /* 000000B1 nop */ 0x90,
+ /* 000000B2 nop */ 0x90,
+ /* 000000B3 nop */ 0x90,
+ /* 000000B4 nop */ 0x90,
+ /* 000000B5 nop */ 0x90,
+ /* 000000B6 nop */ 0x90,
+ /* 000000B7 nop */ 0x90,
+ /* 000000B8 nop */ 0x90,
+ /* 000000B9 nop */ 0x90,
+ /* 000000BA nop */ 0x90,
+ /* 000000BB nop */ 0x90,
+ /* 000000BC nop */ 0x90,
+ /* 000000BD nop */ 0x90,
+ /* 000000BE nop */ 0x90,
+ /* 000000BF nop */ 0x90,
+ /* 000000C0 nop */ 0x90,
+ /* 000000C1 nop */ 0x90,
+ /* 000000C2 nop */ 0x90,
+ /* 000000C3 nop */ 0x90,
+ /* 000000C4 nop */ 0x90,
+ /* 000000C5 nop */ 0x90,
+ /* 000000C6 nop */ 0x90,
+ /* 000000C7 nop */ 0x90,
+ /* 000000C8 nop */ 0x90,
+ /* 000000C9 nop */ 0x90,
+ /* 000000CA nop */ 0x90,
+ /* 000000CB nop */ 0x90,
+ /* 000000CC nop */ 0x90,
+ /* 000000CD nop */ 0x90,
+ /* 000000CE nop */ 0x90,
+ /* 000000CF nop */ 0x90,
+ /* 000000D0 nop */ 0x90,
+ /* 000000D1 nop */ 0x90,
+ /* 000000D2 nop */ 0x90,
+ /* 000000D3 nop */ 0x90,
+ /* 000000D4 nop */ 0x90,
+ /* 000000D5 nop */ 0x90,
+ /* 000000D6 nop */ 0x90,
+ /* 000000D7 nop */ 0x90,
+ /* 000000D8 nop */ 0x90,
+ /* 000000D9 nop */ 0x90,
+ /* 000000DA nop */ 0x90,
+ /* 000000DB nop */ 0x90,
+ /* 000000DC nop */ 0x90,
+ /* 000000DD nop */ 0x90,
+ /* 000000DE nop */ 0x90,
+ /* 000000DF nop */ 0x90,
+ /* 000000E0 nop */ 0x90,
+ /* 000000E1 nop */ 0x90,
+ /* 000000E2 nop */ 0x90,
+ /* 000000E3 nop */ 0x90,
+ /* 000000E4 nop */ 0x90,
+ /* 000000E5 nop */ 0x90,
+ /* 000000E6 nop */ 0x90,
+ /* 000000E7 nop */ 0x90,
+ /* 000000E8 nop */ 0x90,
+ /* 000000E9 nop */ 0x90,
+ /* 000000EA nop */ 0x90,
+ /* 000000EB nop */ 0x90,
+ /* 000000EC nop */ 0x90,
+ /* 000000ED nop */ 0x90,
+ /* 000000EE nop */ 0x90,
+ /* 000000EF nop */ 0x90,
+ /* 000000F0 nop */ 0x90,
+ /* 000000F1 nop */ 0x90,
+ /* 000000F2 nop */ 0x90,
+ /* 000000F3 nop */ 0x90,
+ /* 000000F4 nop */ 0x90,
+ /* 000000F5 nop */ 0x90,
+ /* 000000F6 nop */ 0x90,
+ /* 000000F7 nop */ 0x90,
+ /* 000000F8 nop */ 0x90,
+ /* 000000F9 nop */ 0x90,
+ /* 000000FA nop */ 0x90,
+ /* 000000FB nop */ 0x90,
+ /* 000000FC nop */ 0x90,
+ /* 000000FD nop */ 0x90,
+ /* 000000FE nop */ 0x90,
+ /* 000000FF nop */ 0x90,
+ /* 00000100 nop */ 0x90,
+ /* 00000101 nop */ 0x90,
+ /* 00000102 nop */ 0x90,
+ /* 00000103 nop */ 0x90,
+ /* 00000104 nop */ 0x90,
+ /* 00000105 nop */ 0x90,
+ /* 00000106 nop */ 0x90,
+ /* 00000107 nop */ 0x90,
+ /* 00000108 nop */ 0x90,
+ /* 00000109 nop */ 0x90,
+ /* 0000010A nop */ 0x90,
+ /* 0000010B nop */ 0x90,
+ /* 0000010C nop */ 0x90,
+ /* 0000010D nop */ 0x90,
+ /* 0000010E nop */ 0x90,
+ /* 0000010F nop */ 0x90,
+ /* 00000110 nop */ 0x90,
+ /* 00000111 nop */ 0x90,
+ /* 00000112 nop */ 0x90,
+ /* 00000113 nop */ 0x90,
+ /* 00000114 nop */ 0x90,
+ /* 00000115 nop */ 0x90,
+ /* 00000116 nop */ 0x90,
+ /* 00000117 nop */ 0x90,
+ /* 00000118 nop */ 0x90,
+ /* 00000119 nop */ 0x90,
+ /* 0000011A nop */ 0x90,
+ /* 0000011B nop */ 0x90,
+ /* 0000011C nop */ 0x90,
+ /* 0000011D nop */ 0x90,
+ /* 0000011E nop */ 0x90,
+ /* 0000011F nop */ 0x90,
+ /* 00000120 nop */ 0x90,
+ /* 00000121 nop */ 0x90,
+ /* 00000122 nop */ 0x90,
+ /* 00000123 nop */ 0x90,
+ /* 00000124 nop */ 0x90,
+ /* 00000125 nop */ 0x90,
+ /* 00000126 nop */ 0x90,
+ /* 00000127 nop */ 0x90,
+ /* 00000128 nop */ 0x90,
+ /* 00000129 nop */ 0x90,
+ /* 0000012A nop */ 0x90,
+ /* 0000012B nop */ 0x90,
+ /* 0000012C nop */ 0x90,
+ /* 0000012D nop */ 0x90,
+ /* 0000012E nop */ 0x90,
+ /* 0000012F nop */ 0x90,
+ /* 00000130 nop */ 0x90,
+ /* 00000131 nop */ 0x90,
+ /* 00000132 nop */ 0x90,
+ /* 00000133 nop */ 0x90,
+ /* 00000134 nop */ 0x90,
+ /* 00000135 nop */ 0x90,
+ /* 00000136 nop */ 0x90,
+ /* 00000137 nop */ 0x90,
+ /* 00000138 nop */ 0x90,
+ /* 00000139 nop */ 0x90,
+ /* 0000013A nop */ 0x90,
+ /* 0000013B nop */ 0x90,
+ /* 0000013C nop */ 0x90,
+ /* 0000013D nop */ 0x90,
+ /* 0000013E nop */ 0x90,
+ /* 0000013F nop */ 0x90,
+ /* 00000140 nop */ 0x90,
+ /* 00000141 nop */ 0x90,
+ /* 00000142 nop */ 0x90,
+ /* 00000143 nop */ 0x90,
+ /* 00000144 nop */ 0x90,
+ /* 00000145 nop */ 0x90,
+ /* 00000146 nop */ 0x90,
+ /* 00000147 nop */ 0x90,
+ /* 00000148 nop */ 0x90,
+ /* 00000149 nop */ 0x90,
+ /* 0000014A nop */ 0x90,
+ /* 0000014B nop */ 0x90,
+ /* 0000014C nop */ 0x90,
+ /* 0000014D nop */ 0x90,
+ /* 0000014E nop */ 0x90,
+ /* 0000014F nop */ 0x90,
+ /* 00000150 nop */ 0x90,
+ /* 00000151 nop */ 0x90,
+ /* 00000152 nop */ 0x90,
+ /* 00000153 nop */ 0x90,
+ /* 00000154 nop */ 0x90,
+ /* 00000155 nop */ 0x90,
+ /* 00000156 nop */ 0x90,
+ /* 00000157 nop */ 0x90,
+ /* 00000158 nop */ 0x90,
+ /* 00000159 nop */ 0x90,
+ /* 0000015A nop */ 0x90,
+ /* 0000015B nop */ 0x90,
+ /* 0000015C nop */ 0x90,
+ /* 0000015D nop */ 0x90,
+ /* 0000015E nop */ 0x90,
+ /* 0000015F nop */ 0x90,
+ /* 00000160 nop */ 0x90,
+ /* 00000161 nop */ 0x90,
+ /* 00000162 nop */ 0x90,
+ /* 00000163 nop */ 0x90,
+ /* 00000164 nop */ 0x90,
+ /* 00000165 nop */ 0x90,
+ /* 00000166 nop */ 0x90,
+ /* 00000167 nop */ 0x90,
+ /* 00000168 nop */ 0x90,
+ /* 00000169 nop */ 0x90,
+ /* 0000016A nop */ 0x90,
+ /* 0000016B nop */ 0x90,
+ /* 0000016C nop */ 0x90,
+ /* 0000016D nop */ 0x90,
+ /* 0000016E nop */ 0x90,
+ /* 0000016F nop */ 0x90,
+ /* 00000170 nop */ 0x90,
+ /* 00000171 nop */ 0x90,
+ /* 00000172 nop */ 0x90,
+ /* 00000173 nop */ 0x90,
+ /* 00000174 nop */ 0x90,
+ /* 00000175 nop */ 0x90,
+ /* 00000176 nop */ 0x90,
+ /* 00000177 nop */ 0x90,
+ /* 00000178 nop */ 0x90,
+ /* 00000179 nop */ 0x90,
+ /* 0000017A nop */ 0x90,
+ /* 0000017B nop */ 0x90,
+ /* 0000017C nop */ 0x90,
+ /* 0000017D nop */ 0x90,
+ /* 0000017E nop */ 0x90,
+ /* 0000017F nop */ 0x90,
+ /* 00000180 nop */ 0x90,
+ /* 00000181 nop */ 0x90,
+ /* 00000182 nop */ 0x90,
+ /* 00000183 nop */ 0x90,
+ /* 00000184 nop */ 0x90,
+ /* 00000185 nop */ 0x90,
+ /* 00000186 nop */ 0x90,
+ /* 00000187 nop */ 0x90,
+ /* 00000188 nop */ 0x90,
+ /* 00000189 nop */ 0x90,
+ /* 0000018A nop */ 0x90,
+ /* 0000018B nop */ 0x90,
+ /* 0000018C nop */ 0x90,
+ /* 0000018D nop */ 0x90,
+ /* 0000018E nop */ 0x90,
+ /* 0000018F nop */ 0x90,
+ /* 00000190 nop */ 0x90,
+ /* 00000191 nop */ 0x90,
+ /* 00000192 nop */ 0x90,
+ /* 00000193 nop */ 0x90,
+ /* 00000194 nop */ 0x90,
+ /* 00000195 nop */ 0x90,
+ /* 00000196 nop */ 0x90,
+ /* 00000197 nop */ 0x90,
+ /* 00000198 nop */ 0x90,
+ /* 00000199 nop */ 0x90,
+ /* 0000019A nop */ 0x90,
+ /* 0000019B nop */ 0x90,
+ /* 0000019C nop */ 0x90,
+ /* 0000019D nop */ 0x90,
+ /* 0000019E nop */ 0x90,
+ /* 0000019F nop */ 0x90,
+ /* 000001A0 nop */ 0x90,
+ /* 000001A1 nop */ 0x90,
+ /* 000001A2 nop */ 0x90,
+ /* 000001A3 nop */ 0x90,
+ /* 000001A4 nop */ 0x90,
+ /* 000001A5 nop */ 0x90,
+ /* 000001A6 nop */ 0x90,
+ /* 000001A7 nop */ 0x90,
+ /* 000001A8 nop */ 0x90,
+ /* 000001A9 nop */ 0x90,
+ /* 000001AA nop */ 0x90,
+ /* 000001AB nop */ 0x90,
+ /* 000001AC nop */ 0x90,
+ /* 000001AD nop */ 0x90,
+ /* 000001AE nop */ 0x90,
+ /* 000001AF nop */ 0x90,
+ /* 000001B0 nop */ 0x90,
+ /* 000001B1 nop */ 0x90,
+ /* 000001B2 nop */ 0x90,
+ /* 000001B3 nop */ 0x90,
+ /* 000001B4 nop */ 0x90,
+ /* 000001B5 nop */ 0x90,
+ /* 000001B6 nop */ 0x90,
+ /* 000001B7 nop */ 0x90,
+ /* 000001B8 nop */ 0x90,
+ /* 000001B9 nop */ 0x90,
+ /* 000001BA nop */ 0x90,
+ /* 000001BB nop */ 0x90,
+ /* 000001BC nop */ 0x90,
+ /* 000001BD nop */ 0x90,
+ /* 000001BE nop */ 0x90,
+ /* 000001BF nop */ 0x90,
+ /* 000001C0 nop */ 0x90,
+ /* 000001C1 nop */ 0x90,
+ /* 000001C2 nop */ 0x90,
+ /* 000001C3 nop */ 0x90,
+ /* 000001C4 nop */ 0x90,
+ /* 000001C5 nop */ 0x90,
+ /* 000001C6 nop */ 0x90,
+ /* 000001C7 nop */ 0x90,
+ /* 000001C8 nop */ 0x90,
+ /* 000001C9 nop */ 0x90,
+ /* 000001CA nop */ 0x90,
+ /* 000001CB nop */ 0x90,
+ /* 000001CC nop */ 0x90,
+ /* 000001CD nop */ 0x90,
+ /* 000001CE nop */ 0x90,
+ /* 000001CF nop */ 0x90,
+ /* 000001D0 nop */ 0x90,
+ /* 000001D1 nop */ 0x90,
+ /* 000001D2 nop */ 0x90,
+ /* 000001D3 nop */ 0x90,
+ /* 000001D4 nop */ 0x90,
+ /* 000001D5 nop */ 0x90,
+ /* 000001D6 nop */ 0x90,
+ /* 000001D7 nop */ 0x90,
+ /* 000001D8 nop */ 0x90,
+ /* 000001D9 nop */ 0x90,
+ /* 000001DA nop */ 0x90,
+ /* 000001DB nop */ 0x90,
+ /* 000001DC nop */ 0x90,
+ /* 000001DD nop */ 0x90,
+ /* 000001DE nop */ 0x90,
+ /* 000001DF nop */ 0x90,
+ /* 000001E0 nop */ 0x90,
+ /* 000001E1 nop */ 0x90,
+ /* 000001E2 nop */ 0x90,
+ /* 000001E3 nop */ 0x90,
+ /* 000001E4 nop */ 0x90,
+ /* 000001E5 nop */ 0x90,
+ /* 000001E6 nop */ 0x90,
+ /* 000001E7 nop */ 0x90,
+ /* 000001E8 nop */ 0x90,
+ /* 000001E9 nop */ 0x90,
+ /* 000001EA nop */ 0x90,
+ /* 000001EB nop */ 0x90,
+ /* 000001EC nop */ 0x90,
+ /* 000001ED nop */ 0x90,
+ /* 000001EE nop */ 0x90,
+ /* 000001EF nop */ 0x90,
+ /* 000001F0 nop */ 0x90,
+ /* 000001F1 nop */ 0x90,
+ /* 000001F2 nop */ 0x90,
+ /* 000001F3 nop */ 0x90,
+ /* 000001F4 nop */ 0x90,
+ /* 000001F5 nop */ 0x90,
+ /* 000001F6 nop */ 0x90,
+ /* 000001F7 nop */ 0x90,
+ /* 000001F8 nop */ 0x90,
+ /* 000001F9 nop */ 0x90,
+ /* 000001FA nop */ 0x90,
+ /* 000001FB nop */ 0x90,
+ /* 000001FC nop */ 0x90,
+ /* 000001FD nop */ 0x90,
+ /* 000001FE nop */ 0x90,
+ /* 000001FF nop */ 0x90,
+ /* 00000200 cmp ax,0x4f00 */ 0x3D, 0x00, 0x4F,
+ /* 00000203 jz 0x22d */ 0x74, 0x28,
+ /* 00000205 cmp ax,0x4f01 */ 0x3D, 0x01, 0x4F,
+ /* 00000208 jz 0x245 */ 0x74, 0x3B,
+ /* 0000020A cmp ax,0x4f02 */ 0x3D, 0x02, 0x4F,
+ /* 0000020D jz 0x269 */ 0x74, 0x5A,
+ /* 0000020F cmp ax,0x4f03 */ 0x3D, 0x03, 0x4F,
+ /* 00000212 jz word 0x331 */ 0x0F, 0x84, 0x1B, 0x01,
+ /* 00000216 cmp ax,0x4f10 */ 0x3D, 0x10, 0x4F,
+ /* 00000219 jz word 0x336 */ 0x0F, 0x84, 0x19, 0x01,
+ /* 0000021D cmp ax,0x4f15 */ 0x3D, 0x15, 0x4F,
+ /* 00000220 jz word 0x338 */ 0x0F, 0x84, 0x14, 0x01,
+ /* 00000224 cmp ah,0x0 */ 0x80, 0xFC, 0x00,
+ /* 00000227 jz word 0x33a */ 0x0F, 0x84, 0x0F, 0x01,
+ /* 0000022B jmp short 0x22b */ 0xEB, 0xFE,
+ /* 0000022D push es */ 0x06,
+ /* 0000022E push di */ 0x57,
+ /* 0000022F push ds */ 0x1E,
+ /* 00000230 push si */ 0x56,
+ /* 00000231 push cx */ 0x51,
+ /* 00000232 push cs */ 0x0E,
+ /* 00000233 pop ds */ 0x1F,
+ /* 00000234 mov si,0x0 */ 0xBE, 0x00, 0x00,
+ /* 00000237 mov cx,0x100 */ 0xB9, 0x00, 0x01,
+ /* 0000023A cld */ 0xFC,
+ /* 0000023B rep movsb */ 0xF3, 0xA4,
+ /* 0000023D pop cx */ 0x59,
+ /* 0000023E pop si */ 0x5E,
+ /* 0000023F pop ds */ 0x1F,
+ /* 00000240 pop di */ 0x5F,
+ /* 00000241 pop es */ 0x07,
+ /* 00000242 jmp word 0x34c */ 0xE9, 0x07, 0x01,
+ /* 00000245 push es */ 0x06,
+ /* 00000246 push di */ 0x57,
+ /* 00000247 push ds */ 0x1E,
+ /* 00000248 push si */ 0x56,
+ /* 00000249 push cx */ 0x51,
+ /* 0000024A and cx,0xbfff */ 0x81, 0xE1, 0xFF, 0xBF,
+ /* 0000024E cmp cx,0xf1 */ 0x81, 0xF9, 0xF1, 0x00,
+ /* 00000252 jz 0x256 */ 0x74, 0x02,
+ /* 00000254 jmp short 0x22b */ 0xEB, 0xD5,
+ /* 00000256 push cs */ 0x0E,
+ /* 00000257 pop ds */ 0x1F,
+ /* 00000258 mov si,0x100 */ 0xBE, 0x00, 0x01,
+ /* 0000025B mov cx,0x100 */ 0xB9, 0x00, 0x01,
+ /* 0000025E cld */ 0xFC,
+ /* 0000025F rep movsb */ 0xF3, 0xA4,
+ /* 00000261 pop cx */ 0x59,
+ /* 00000262 pop si */ 0x5E,
+ /* 00000263 pop ds */ 0x1F,
+ /* 00000264 pop di */ 0x5F,
+ /* 00000265 pop es */ 0x07,
+ /* 00000266 jmp word 0x34c */ 0xE9, 0xE3, 0x00,
+ /* 00000269 push dx */ 0x52,
+ /* 0000026A push ax */ 0x50,
+ /* 0000026B cmp bx,0x40f1 */ 0x81, 0xFB, 0xF1, 0x40,
+ /* 0000026F jz 0x273 */ 0x74, 0x02,
+ /* 00000271 jmp short 0x22b */ 0xEB, 0xB8,
+ /* 00000273 mov dx,0x3c0 */ 0xBA, 0xC0, 0x03,
+ /* 00000276 mov al,0x20 */ 0xB0, 0x20,
+ /* 00000278 out dx,al */ 0xEE,
+ /* 00000279 push dx */ 0x52,
+ /* 0000027A push ax */ 0x50,
+ /* 0000027B mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 0000027E mov ax,0x4 */ 0xB8, 0x04, 0x00,
+ /* 00000281 out dx,ax */ 0xEF,
+ /* 00000282 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 00000285 mov ax,0x0 */ 0xB8, 0x00, 0x00,
+ /* 00000288 out dx,ax */ 0xEF,
+ /* 00000289 pop ax */ 0x58,
+ /* 0000028A pop dx */ 0x5A,
+ /* 0000028B push dx */ 0x52,
+ /* 0000028C push ax */ 0x50,
+ /* 0000028D mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 00000290 mov ax,0x5 */ 0xB8, 0x05, 0x00,
+ /* 00000293 out dx,ax */ 0xEF,
+ /* 00000294 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 00000297 mov ax,0x0 */ 0xB8, 0x00, 0x00,
+ /* 0000029A out dx,ax */ 0xEF,
+ /* 0000029B pop ax */ 0x58,
+ /* 0000029C pop dx */ 0x5A,
+ /* 0000029D push dx */ 0x52,
+ /* 0000029E push ax */ 0x50,
+ /* 0000029F mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 000002A2 mov ax,0x8 */ 0xB8, 0x08, 0x00,
+ /* 000002A5 out dx,ax */ 0xEF,
+ /* 000002A6 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 000002A9 mov ax,0x0 */ 0xB8, 0x00, 0x00,
+ /* 000002AC out dx,ax */ 0xEF,
+ /* 000002AD pop ax */ 0x58,
+ /* 000002AE pop dx */ 0x5A,
+ /* 000002AF push dx */ 0x52,
+ /* 000002B0 push ax */ 0x50,
+ /* 000002B1 mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 000002B4 mov ax,0x9 */ 0xB8, 0x09, 0x00,
+ /* 000002B7 out dx,ax */ 0xEF,
+ /* 000002B8 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 000002BB mov ax,0x0 */ 0xB8, 0x00, 0x00,
+ /* 000002BE out dx,ax */ 0xEF,
+ /* 000002BF pop ax */ 0x58,
+ /* 000002C0 pop dx */ 0x5A,
+ /* 000002C1 push dx */ 0x52,
+ /* 000002C2 push ax */ 0x50,
+ /* 000002C3 mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 000002C6 mov ax,0x3 */ 0xB8, 0x03, 0x00,
+ /* 000002C9 out dx,ax */ 0xEF,
+ /* 000002CA mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 000002CD mov ax,0x20 */ 0xB8, 0x20, 0x00,
+ /* 000002D0 out dx,ax */ 0xEF,
+ /* 000002D1 pop ax */ 0x58,
+ /* 000002D2 pop dx */ 0x5A,
+ /* 000002D3 push dx */ 0x52,
+ /* 000002D4 push ax */ 0x50,
+ /* 000002D5 mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 000002D8 mov ax,0x1 */ 0xB8, 0x01, 0x00,
+ /* 000002DB out dx,ax */ 0xEF,
+ /* 000002DC mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 000002DF mov ax,0x400 */ 0xB8, 0x00, 0x04,
+ /* 000002E2 out dx,ax */ 0xEF,
+ /* 000002E3 pop ax */ 0x58,
+ /* 000002E4 pop dx */ 0x5A,
+ /* 000002E5 push dx */ 0x52,
+ /* 000002E6 push ax */ 0x50,
+ /* 000002E7 mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 000002EA mov ax,0x6 */ 0xB8, 0x06, 0x00,
+ /* 000002ED out dx,ax */ 0xEF,
+ /* 000002EE mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 000002F1 mov ax,0x400 */ 0xB8, 0x00, 0x04,
+ /* 000002F4 out dx,ax */ 0xEF,
+ /* 000002F5 pop ax */ 0x58,
+ /* 000002F6 pop dx */ 0x5A,
+ /* 000002F7 push dx */ 0x52,
+ /* 000002F8 push ax */ 0x50,
+ /* 000002F9 mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 000002FC mov ax,0x2 */ 0xB8, 0x02, 0x00,
+ /* 000002FF out dx,ax */ 0xEF,
+ /* 00000300 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 00000303 mov ax,0x300 */ 0xB8, 0x00, 0x03,
+ /* 00000306 out dx,ax */ 0xEF,
+ /* 00000307 pop ax */ 0x58,
+ /* 00000308 pop dx */ 0x5A,
+ /* 00000309 push dx */ 0x52,
+ /* 0000030A push ax */ 0x50,
+ /* 0000030B mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 0000030E mov ax,0x7 */ 0xB8, 0x07, 0x00,
+ /* 00000311 out dx,ax */ 0xEF,
+ /* 00000312 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 00000315 mov ax,0x300 */ 0xB8, 0x00, 0x03,
+ /* 00000318 out dx,ax */ 0xEF,
+ /* 00000319 pop ax */ 0x58,
+ /* 0000031A pop dx */ 0x5A,
+ /* 0000031B push dx */ 0x52,
+ /* 0000031C push ax */ 0x50,
+ /* 0000031D mov dx,0x1ce */ 0xBA, 0xCE, 0x01,
+ /* 00000320 mov ax,0x4 */ 0xB8, 0x04, 0x00,
+ /* 00000323 out dx,ax */ 0xEF,
+ /* 00000324 mov dx,0x1d0 */ 0xBA, 0xD0, 0x01,
+ /* 00000327 mov ax,0x41 */ 0xB8, 0x41, 0x00,
+ /* 0000032A out dx,ax */ 0xEF,
+ /* 0000032B pop ax */ 0x58,
+ /* 0000032C pop dx */ 0x5A,
+ /* 0000032D pop ax */ 0x58,
+ /* 0000032E pop dx */ 0x5A,
+ /* 0000032F jmp short 0x34c */ 0xEB, 0x1B,
+ /* 00000331 mov bx,0x40f1 */ 0xBB, 0xF1, 0x40,
+ /* 00000334 jmp short 0x34c */ 0xEB, 0x16,
+ /* 00000336 jmp short 0x350 */ 0xEB, 0x18,
+ /* 00000338 jmp short 0x350 */ 0xEB, 0x16,
+ /* 0000033A cmp al,0x3 */ 0x3C, 0x03,
+ /* 0000033C jz 0x345 */ 0x74, 0x07,
+ /* 0000033E cmp al,0x12 */ 0x3C, 0x12,
+ /* 00000340 jz 0x349 */ 0x74, 0x07,
+ /* 00000342 jmp word 0x22b */ 0xE9, 0xE6, 0xFE,
+ /* 00000345 mov al,0x30 */ 0xB0, 0x30,
+ /* 00000347 jmp short 0x34b */ 0xEB, 0x02,
+ /* 00000349 mov al,0x20 */ 0xB0, 0x20,
+ /* 0000034B iretw */ 0xCF,
+ /* 0000034C mov ax,0x4f */ 0xB8, 0x4F, 0x00,
+ /* 0000034F iretw */ 0xCF,
+ /* 00000350 mov ax,0x14f */ 0xB8, 0x4F, 0x01,
+ /* 00000353 iretw */ 0xCF,
+};
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh
new file mode 100644
index 0000000000..7669f8a219
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+###
+# @file
+# Shell script to assemble and dump the fake Int10h handler from NASM source to
+# a C array.
+#
+# Copyright (C) 2014, Red Hat, Inc.
+# Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+###
+
+set -e -u
+
+STEM=$(dirname -- "$0")/$(basename -- "$0" .sh)
+
+#
+# Install exit handler -- remove temporary files.
+#
+exit_handler()
+{
+ rm -f -- "$STEM".bin "$STEM".disasm "$STEM".offsets "$STEM".insns \
+ "$STEM".bytes
+}
+trap exit_handler EXIT
+
+#
+# Assemble the source file.
+#
+nasm -o "$STEM".bin -- "$STEM".asm
+
+#
+# Disassemble it, in order to get a binary dump associated with the source.
+# (ndisasm doesn't recognize the "--" end-of-options delimiter.)
+#
+ndisasm "$STEM".bin >"$STEM".disasm
+
+#
+# Create three files, each with one column of the disassembly.
+#
+# The first column contains the offsets, and it starts the comment.
+#
+cut -c 1-8 -- "$STEM".disasm \
+| sed -e 's,^, /* ,' >"$STEM".offsets
+
+#
+# The second column contains the assembly-language instructions, and it closes
+# the comment. We first pad it to 30 characters.
+#
+cut -c 29- -- "$STEM".disasm \
+| sed -e 's,$, ,' \
+ -e 's,^\(.\{30\}\).*$,\1 */,' >"$STEM".insns
+
+#
+# The third column contains the bytes corresponding to the instruction,
+# represented as C integer constants. First strip trailing whitespace from the
+# middle column of the input disassembly, then process pairs of nibbles.
+#
+cut -c 11-28 -- "$STEM".disasm \
+| sed -e 's, \+$,,' -e 's/\(..\)/ 0x\1,/g' >"$STEM".bytes
+
+#
+# Write the output file, recombining the columns. The output should have CRLF
+# line endings.
+#
+{
+ printf '//\n'
+ printf '// THIS FILE WAS GENERATED BY "%s". DO NOT EDIT.\n' \
+ "$(basename -- "$0")"
+ printf '//\n'
+ printf '#ifndef _VBE_SHIM_H_\n'
+ printf '#define _VBE_SHIM_H_\n'
+ printf 'STATIC CONST UINT8 mVbeShim[] = {\n'
+ paste -d ' ' -- "$STEM".offsets "$STEM".insns "$STEM".bytes
+ printf '};\n'
+ printf '#endif\n'
+} \
+| unix2dos >"$STEM".h
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [edk2-platforms PATCH v2 6/7] SimicsOpenBoardPkg/BoardX58Ich10: Add board module for QSP Build tip
2019-08-28 0:40 ` [edk2-platforms PATCH v2 6/7] SimicsOpenBoardPkg/BoardX58Ich10: Add board module for QSP Build tip David Wei
@ 2019-08-28 23:13 ` Nate DeSimone
0 siblings, 0 replies; 16+ messages in thread
From: Nate DeSimone @ 2019-08-28 23:13 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Kubacki, Michael A, Kinney, Michael D
Update copyright year on DecomprScratchEnd.fdf.inc, OpenBoardPkg.fdf.inc, VarStore.fdf.inc
-----Original Message-----
From: Wei, David Y
Sent: Tuesday, August 27, 2019 5:40 PM
To: devel@edk2.groups.io
Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Kubacki, Michael A <michael.a.kubacki@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: [edk2-platforms PATCH v2 6/7] SimicsOpenBoardPkg/BoardX58Ich10: Add board module for QSP Build tip
Add BoardX58ICH10 module for QSP Build tip
Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../Library/BoardInitLib/PeiBoardInitPostMemLib.c | 44 +++
.../Library/BoardInitLib/PeiBoardInitPreMemLib.c | 110 ++++++++
.../Library/BoardInitLib/PeiX58Ich10Detect.c | 26 ++
.../BoardInitLib/PeiX58Ich10InitPostMemLib.c | 34 +++
.../BoardInitLib/PeiX58Ich10InitPreMemLib.c | 111 ++++++++
.../BoardX58Ich10/DecomprScratchEnd.fdf.inc | 66 +++++
.../BoardInitLib/PeiBoardInitPostMemLib.inf | 36 +++
.../Library/BoardInitLib/PeiBoardInitPreMemLib.inf | 39 +++
.../Library/BoardInitLib/PeiX58Ich10InitLib.h | 16 ++
.../BoardX58Ich10/OpenBoardPkg.dsc | 233 ++++++++++++++++
.../BoardX58Ich10/OpenBoardPkg.fdf | 304 +++++++++++++++++++++
.../BoardX58Ich10/OpenBoardPkg.fdf.inc | 54 ++++
.../BoardX58Ich10/OpenBoardPkgBuildOption.dsc | 78 ++++++
.../BoardX58Ich10/OpenBoardPkgConfig.dsc | 56 ++++
.../BoardX58Ich10/OpenBoardPkgPcd.dsc | 281 +++++++++++++++++++
.../BoardX58Ich10/VarStore.fdf.inc | 53 ++++
.../BoardX58Ich10/build_config.cfg | 31 +++
17 files changed, 1572 insertions(+)
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10Detect.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitPostMemLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitPreMemLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/DecomprScratchEnd.fdf.inc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf.inc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgBuildOption.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgConfig.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgPcd.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/VarStore.fdf.inc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/build_config.cfg
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.c b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.c
new file mode 100644
index 0000000000..5ece8c6e34
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.c
@@ -0,0 +1,44 @@
+/** @file
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardInitLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardInitBeforeSiliconInit (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardInitAfterSiliconInit (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+BoardInitBeforeSiliconInit (
+ VOID
+ )
+{
+ X58Ich10BoardInitBeforeSiliconInit ();
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitAfterSiliconInit (
+ VOID
+ )
+{
+ X58Ich10BoardInitAfterSiliconInit ();
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.c b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.c
new file mode 100644
index 0000000000..d16e649d34
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.c
@@ -0,0 +1,110 @@
+/** @file
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/BoardInitLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardDetect(
+ VOID
+ );
+
+EFI_BOOT_MODE
+EFIAPI
+X58Ich10BoardBootModeDetect (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardDebugInit (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardInitBeforeMemoryInit (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardInitAfterMemoryInit (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+BoardDetect (
+ VOID
+ )
+{
+ X58Ich10BoardDetect ();
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardDebugInit (
+ VOID
+ )
+{
+ X58Ich10BoardDebugInit ();
+ return EFI_SUCCESS;
+}
+
+EFI_BOOT_MODE
+EFIAPI
+BoardBootModeDetect (
+ VOID
+ )
+{
+ return X58Ich10BoardBootModeDetect ();
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitBeforeMemoryInit (
+ VOID
+ )
+{
+ X58Ich10BoardInitBeforeMemoryInit ();
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitAfterMemoryInit (
+ VOID
+ )
+{
+ X58Ich10BoardInitAfterMemoryInit ();
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitBeforeTempRamExit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+BoardInitAfterTempRamExit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10Detect.c b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10Detect.c
new file mode 100644
index 0000000000..03488ef1f4
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10Detect.c
@@ -0,0 +1,26 @@
+/** @file
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BoardInitLib.h>
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardDetect (
+ VOID
+ )
+{
+ DEBUG ((EFI_D_INFO, "X58Ich10BoardDetect\n"));
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitPostMemLib.c b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitPostMemLib.c
new file mode 100644
index 0000000000..bd6924e269
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitPostMemLib.c
@@ -0,0 +1,34 @@
+/** @file
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+
+#include "PeiX58Ich10InitLib.h"
+EFI_STATUS
+EFIAPI
+X58Ich10BoardInitBeforeSiliconInit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardInitAfterSiliconInit (
+ VOID
+ )
+{
+
+ DEBUG((EFI_D_ERROR, "X58Ich10BoardInitAfterSiliconInit\n"));
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitPreMemLib.c b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitPreMemLib.c
new file mode 100644
index 0000000000..c3a31ed426
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitPreMemLib.c
@@ -0,0 +1,111 @@
+/** @file
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <PiPei.h>
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/BoardInitLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+
+#include "PeiX58Ich10InitLib.h"
+#include <Register/X58Ich10.h>
+/**
+ Reads 8-bits of CMOS data.
+
+ Reads the 8-bits of CMOS data at the location specified by Index.
+ The 8-bit read value is returned.
+
+ @param Index The CMOS location to read.
+
+ @return The value read.
+
+**/
+UINT8
+EFIAPI
+CmosRead8(
+ IN UINTN Index
+ )
+{
+ IoWrite8 (0x70, (UINT8)Index);
+ return IoRead8(0x71);
+}
+
+
+/**
+ Writes 8-bits of CMOS data.
+
+ Writes 8-bits of CMOS data to the location specified by Index
+ with the value specified by Value and returns Value.
+
+ @param Index The CMOS location to write.
+ @param Value The value to write to CMOS.
+
+ @return The value written to CMOS.
+
+**/
+UINT8
+EFIAPI
+CmosWrite8(
+ IN UINTN Index,
+ IN UINT8 Value
+ )
+{
+ IoWrite8 (0x70, (UINT8)Index);
+ IoWrite8 (0x71, Value);
+ return Value;
+}
+
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardInitBeforeMemoryInit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardInitAfterMemoryInit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+X58Ich10BoardDebugInit (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_BOOT_MODE
+EFIAPI
+X58Ich10BoardBootModeDetect (
+ VOID
+ )
+{
+ EFI_BOOT_MODE BootMode = BOOT_WITH_FULL_CONFIGURATION;
+
+ DEBUG((EFI_D_INFO, "modeValue = %x\n", IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12)));
+ if (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) == 0x5) {
+ BootMode = BOOT_ON_S3_RESUME;
+ }
+
+ return BootMode;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/DecomprScratchEnd.fdf.inc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/DecomprScratchEnd.fdf.inc
new file mode 100644
index 0000000000..f1eed7819a
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/DecomprScratchEnd.fdf.inc
@@ -0,0 +1,66 @@
+## @file
+# This FDF include file computes the end of the scratch buffer used in
+# DecompressMemFvs() [SimicsX58Pkg/Sec/SecMain.c]. It is based on the decompressed
+# (ie. original) size of the LZMA-compressed section of the one FFS file in
+# the FVMAIN_COMPACT firmware volume.
+#
+# Copyright (C) 2015, Red Hat, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+# The GUID EE4E5898-3914-4259-9D6E-DC7BD79403CF means "LzmaCustomDecompress".
+# The decompressed output will have the following structure (see the file
+# "9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.guided.dummy" in the
+# Build/SimicsX58*/*/FV/Ffs/9E21FD93-9C72-4c15-8C4B-E77F1DB2D792/ directory):
+#
+# Size Contents
+# ------------------- --------------------------------------------------------
+# 4 EFI_COMMON_SECTION_HEADER, stating size 124 (0x7C) and
+# type 0x19 (EFI_SECTION_RAW). The purpose of this section
+# is to pad the start of PEIFV to 128 bytes.
+# 120 Zero bytes (padding).
+#
+# 4 EFI_COMMON_SECTION_HEADER, stating size
+# (PcdSimicsPeiMemFvSize + 4), and type 0x17
+# (EFI_SECTION_FIRMWARE_VOLUME_IMAGE).
+# PcdSimicsPeiMemFvSize PEIFV. Note that the above sizes pad the offset of this
+# object to 128 bytes. See also the "guided.dummy.txt"
+# file in the same directory.
+#
+# 4 EFI_COMMON_SECTION_HEADER, stating size 12 (0xC) and
+# type 0x19 (EFI_SECTION_RAW). The purpose of this section
+# is to pad the start of DXEFV to 16 bytes.
+# 8 Zero bytes (padding).
+#
+# 4 EFI_COMMON_SECTION_HEADER, stating size
+# (PcdSimicsDxeMemFvSize + 4), and type 0x17
+# (EFI_SECTION_FIRMWARE_VOLUME_IMAGE).
+# PcdSimicsDxeMemFvSize DXEFV. Note that the above sizes pad the offset of this
+# object to 16 bytes. See also the "guided.dummy.txt" file
+# in the same directory.
+#
+# The total size after decompression is (128 + PcdSimicsPeiMemFvSize + 16 +
+# PcdSimicsDxeMemFvSize).
+
+DEFINE OUTPUT_SIZE = (128 + gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize + 16 + gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize)
+
+# LzmaCustomDecompressLib uses a constant scratch buffer size of 64KB; see
+# SCRATCH_BUFFER_REQUEST_SIZE in
+# "MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompress.c".
+
+DEFINE DECOMP_SCRATCH_SIZE = 0x00010000
+
+# Note: when we use PcdSimicsDxeMemFvBase in this context, BaseTools have not yet
+# offset it with MEMFD's base address. For that reason we have to do it manually.
+#
+# The calculation below mirrors DecompressMemFvs() [SimicsX58Pkg/Sec/SecMain.c].
+
+DEFINE OUTPUT_BASE = ($(MEMFD_BASE_ADDRESS) + gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase + 0x00100000)
+DEFINE DECOMP_SCRATCH_BASE_UNALIGNED = ($(OUTPUT_BASE) + $(OUTPUT_SIZE))
+DEFINE DECOMP_SCRATCH_BASE_ALIGNMENT = 0x000FFFFF
+DEFINE DECOMP_SCRATCH_BASE_MASK = 0xFFF00000
+DEFINE DECOMP_SCRATCH_BASE = (($(DECOMP_SCRATCH_BASE_UNALIGNED) + $(DECOMP_SCRATCH_BASE_ALIGNMENT)) & $(DECOMP_SCRATCH_BASE_MASK))
+
+SET gBoardModuleTokenSpaceGuid.PcdSimicsDecompressionScratchEnd = $(DECOMP_SCRATCH_BASE) + $(DECOMP_SCRATCH_SIZE)
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.inf b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
new file mode 100644
index 0000000000..a035eb0e50
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
@@ -0,0 +1,36 @@
+## @file
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PeiBoardPostMemInitLib
+ FILE_GUID = 30F407D6-6B92-412A-B2DA-8E73E2B386E6
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = BoardInitLib
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ PcdLib
+
+[Packages]
+ MinPlatformPkg/MinPlatformPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[Sources]
+ PeiX58Ich10InitPostMemLib.c
+ PeiBoardInitPostMemLib.c
+
+[FixedPcd]
+
+[Pcd]
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.inf b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
new file mode 100644
index 0000000000..08a6eb159a
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
@@ -0,0 +1,39 @@
+## @file
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PeiBoardInitPreMemLib
+ FILE_GUID = 73AA24AE-FB20-43F9-A3BA-448953A03A78
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = BoardInitLib
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ PcdLib
+
+[Packages]
+ MinPlatformPkg/MinPlatformPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SimicsOpenBoardPkg/OpenBoardPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.dec
+
+[Sources]
+ PeiX58Ich10Detect.c
+ PeiX58Ich10InitPreMemLib.c
+ PeiBoardInitPreMemLib.c
+
+[Pcd]
+
+[FixedPcd]
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitLib.h b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitLib.h
new file mode 100644
index 0000000000..93544a838b
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/Library/BoardInitLib/PeiX58Ich10InitLib.h
@@ -0,0 +1,16 @@
+/** @file
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_X58Ich10_BOARD_INIT_LIB_H_
+#define _PEI_X58Ich10_BOARD_INIT_LIB_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc
new file mode 100644
index 0000000000..d75d33b494
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc
@@ -0,0 +1,233 @@
+## @file
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ DEFINE PLATFORM_PACKAGE = MinPlatformPkg
+ DEFINE BOARD_NAME = BoardX58Ich10
+ DEFINE BOARD_PKG = SimicsOpenBoardPkg
+ DEFINE SKT_PKG = SimicsX58SktPkg
+ DEFINE PCH_PKG = SimicsIch10Pkg
+ DEFINE DXE_ARCH = X64
+ DEFINE PEI_ARCH = IA32
+
+ PLATFORM_NAME = SimicsX58
+ PLATFORM_GUID = EE8EBB5A-CC95-412f-9987-2AF70F88B69A
+ PLATFORM_VERSION = 0.1
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/SimicsX58Ia32X64
+ SUPPORTED_ARCHITECTURES = IA32|X64
+ BUILD_TARGETS = DEBUG|RELEASE|NOOPT
+ SKUID_IDENTIFIER = DEFAULT
+ FLASH_DEFINITION = $(BOARD_PKG)/$(BOARD_NAME)/OpenBoardPkg.fdf
+
+ DEFINE SMM_REQUIRE = TRUE
+
+ #
+ #PLATFORMX64_ENABLE is set to TRUE when PEI is IA32 and DXE is X64 platform
+ #
+ DEFINE PLATFORMX64_ENABLE = TRUE
+ DEFINE NETWORK_TLS_ENABLE = FALSE
+ DEFINE NETWORK_ISCSI_ENABLE = FALSE
+ DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS = TRUE
+ !include NetworkPkg/NetworkDefines.dsc.inc
+################################################################################
+#
+# SKU Identification section - list of all SKU IDs supported by this Platform.
+#
+################################################################################
+[SkuIds]
+ 0|DEFAULT
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+
+[PcdsFeatureFlag]
+ #
+ # Platform On/Off features are defined here
+ #
+ !include $(BOARD_PKG)/$(BOARD_NAME)/OpenBoardPkgConfig.dsc
+ !include MinPlatformPkg/Include/Dsc/CoreCommonLib.dsc
+ !include $(PCH_PKG)/IchCommonLib.dsc
+
+[LibraryClasses]
+ ReportFvLib|$(BOARD_PKG)/Library/PeiReportFvLib/PeiReportFvLib.inf
+ BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+ SerialPortLib|PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf
+ NvVarsFileLib|$(BOARD_PKG)/Library/NvVarsFileLib/NvVarsFileLib.inf
+ SerializeVariablesLib|$(BOARD_PKG)/Library/SerializeVariablesLib/SerializeVariablesLib.inf
+ DxeLoadLinuxLib|$(BOARD_PKG)/Library/LoadLinuxLib/DxeLoadLinuxLib.inf
+ CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
+
+ TestPointCheckLib|MinPlatformPkg/Test/Library/TestPointCheckLibNull/TestPointCheckLibNull.inf
+ BoardInitLib|MinPlatformPkg/PlatformInit/Library/BoardInitLibNull/BoardInitLibNull.inf
+ SiliconPolicyInitLib|$(BOARD_PKG)/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf
+ SiliconPolicyUpdateLib|$(BOARD_PKG)/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf
+ PciSegmentInfoLib|MinPlatformPkg/Pci/Library/PciSegmentInfoLibSimple/PciSegmentInfoLibSimple.inf
+
+ !include MinPlatformPkg/Include/Dsc/CorePeiLib.dsc
+
+ S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
+ AslUpdateLib|MinPlatformPkg/Acpi/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf
+ LogoLib|$(BOARD_PKG)/Library/DxeLogoLib/DxeLogoLib.inf
+[LibraryClasses.common.SEC]
+ ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf
+
+[LibraryClasses.common.PEI_CORE]
+
+[LibraryClasses.common.PEIM]
+ PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
+ MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+
+[LibraryClasses.IA32]
+!if $(TARGET) == DEBUG
+ TestPointCheckLib|MinPlatformPkg/Test/Library/TestPointCheckLib/PeiTestPointCheckLib.inf
+!endif
+ TestPointLib|MinPlatformPkg/Test/Library/TestPointLib/PeiTestPointLib.inf
+
+ !include MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc
+
+[LibraryClasses.common.DXE_DRIVER]
+ PlatformBootManagerLib|$(BOARD_PKG)/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+
+[LibraryClasses.common.DXE_SMM_DRIVER]
+ SpiFlashCommonLib|$(PCH_PKG)/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
+
+ !include $(BOARD_PKG)/$(BOARD_NAME)/OpenBoardPkgPcd.dsc
+
+[Components.IA32]
+ $(BOARD_PKG)/SecCore/SecMain.inf {
+ <LibraryClasses>
+ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ }
+ !include $(SKT_PKG)/SktPkgPei.dsc
+ !include MinPlatformPkg/Include/Dsc/CorePeiInclude.dsc
+
+ $(BOARD_PKG)/SimicsPei/SimicsPei.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+ }
+# S3 SMM driver
+# UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
+ UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf {
+ <LibraryClasses>
+ LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
+ }
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+ $(SKT_PKG)/Smm/Access/SmmAccessPei.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+ }
+!endif
+ $(PLATFORM_PACKAGE)/PlatformInit/ReportFv/ReportFvPei.inf
+
+ MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPreMem.inf {
+ <LibraryClasses>
+ BoardInitLib|$(BOARD_PKG)/$(BOARD_NAME)/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
+ }
+ MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPostMem.inf {
+ <LibraryClasses>
+ BoardInitLib|$(BOARD_PKG)/$(BOARD_NAME)/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
+ }
+ MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMem.inf
+ MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPostMem.inf
+
+[Components.X64]
+ !include MinPlatformPkg/Include/Dsc/CoreDxeInclude.dsc
+ !include AdvancedFeaturePkg/Include/Dsc/CoreAdvancedDxeInclude.dsc
+
+ MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+
+ MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
+ #
+ # ISA Support
+ #
+ $(BOARD_PKG)/LegacySioDxe/LegacySioDxe.inf
+ MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf
+
+ $(BOARD_PKG)/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+ $(BOARD_PKG)/AcpiTables/AcpiTables.inf
+ #
+ # Video support
+ #
+ $(BOARD_PKG)/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
+
+ MinPlatformPkg/PlatformInit/PlatformInitDxe/PlatformInitDxe.inf
+ MinPlatformPkg/PlatformInit/PlatformInitSmm/PlatformInitSmm.inf
+ $(BOARD_PKG)/SimicsDxe/SimicsDxe.inf
+ MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+ MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
+
+ SimicsIch10SiliconBinPkg/UndiBinary/UndiDxe.inf
+
+ #
+ # Shell
+ #
+ ShellPkg/Application/Shell/Shell.inf {
+ <PcdsFixedAtBuild>
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+ <LibraryClasses>
+ NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
+ ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+ HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+ BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+ ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
+ ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+ }
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+ $(SKT_PKG)/Smm/Access/SmmAccess2Dxe.inf
+ $(PCH_PKG)/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
+ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+ $(PCH_PKG)/Spi/Smm/PchSpiSmm.inf
+ MinPlatformPkg/Flash/SpiFvbService/SpiFvbServiceSmm.inf
+ UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf
+ MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf {
+ <LibraryClasses>
+ LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf
+ }
+!endif
+ MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+ MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+ MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
+ <LibraryClasses>
+ PciHostBridgeLib|$(BOARD_PKG)/Library/PciHostBridgeLib/PciHostBridgeLib.inf
+ }
+ MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
+ UefiCpuPkg/CpuDxe/CpuDxe.inf
+ MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+ MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
+ MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+ MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+ #
+ # ACPI Support
+ #
+ MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
+ $(BOARD_PKG)/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.inf
+
+!if gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosEnable == TRUE
+ AdvancedFeaturePkg/Smbios/SmbiosBasicDxe/SmbiosBasicDxe.inf
+!endif
+
+ !include $(BOARD_PKG)/$(BOARD_NAME)/OpenBoardPkgBuildOption.dsc
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf
new file mode 100644
index 0000000000..bd97f7a3e2
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf
@@ -0,0 +1,304 @@
+## @file
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+!include OpenBoardPkg.fdf.inc
+
+#
+# Build the variable store and the firmware code as one unified flash device
+# image.
+#
+[FD.SIMICSX58IA32X64]
+BaseAddress = $(FW_BASE_ADDRESS)
+Size = $(FW_SIZE)
+ErasePolarity = 1
+BlockSize = $(BLOCK_SIZE)
+NumBlocks = $(FW_BLOCKS)
+
+!include VarStore.fdf.inc
+
+$(VARS_SIZE)|0x00002000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+#NV_FTW_WORKING
+DATA = {
+ # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid =
+ # { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
+ 0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
+ 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95,
+ # Crc:UINT32 #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
+ 0xE2, 0x33, 0xF2, 0x03, 0xFE, 0xFF, 0xFF, 0xFF,
+ # WriteQueueSize: UINT64
+ 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x00040000|0x00040000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+#NV_FTW_SPARE
+
+0x00080000|0x0016C000
+FV = FVMAIN_COMPACT
+
+$(SECFV_OFFSET)|$(SECFV_SIZE)
+FV = FvTempMemorySilicon
+
+#
+# Build the variable store and the firmware code as separate flash device
+# images.
+#
+[FD.SIMICS_VARS]
+BaseAddress = $(FW_BASE_ADDRESS)
+Size = 0x80000
+ErasePolarity = 1
+BlockSize = $(BLOCK_SIZE)
+NumBlocks = 0x80
+
+!include VarStore.fdf.inc
+
+[FD.SIMICS_CODE]
+BaseAddress = $(CODE_BASE_ADDRESS)
+Size = $(CODE_SIZE)
+ErasePolarity = 1
+BlockSize = $(BLOCK_SIZE)
+NumBlocks = $(CODE_BLOCKS)
+
+0x00000000|0x0016C000
+FV = FVMAIN_COMPACT
+
+0x0016C000|$(SECFV_SIZE)
+FV = FvTempMemorySilicon
+
+[FD.MEMFD]
+BaseAddress = $(MEMFD_BASE_ADDRESS)
+Size = 0xB00000
+ErasePolarity = 1
+BlockSize = 0x10000
+NumBlocks = 0xB0
+
+0x000000|0x006000
+gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesBase|gBoardModuleTokenSpaceGuid.PcdSimicsSecPageTablesSize
+
+0x006000|0x001000
+gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageBase|gBoardModuleTokenSpaceGuid.PcdSimicsLockBoxStorageSize
+
+0x007000|0x001000
+gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gBoardModuleTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+
+0x010000|0x008000
+gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|gBoardModuleTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
+
+0x020000|0x0E0000
+gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvBase|gBoardModuleTokenSpaceGuid.PcdSimicsPeiMemFvSize
+FV = FvPreMemory
+
+0x100000|0xA00000
+gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvBase|gBoardModuleTokenSpaceGuid.PcdSimicsDxeMemFvSize
+FV = DXEFV
+
+################################################################################
+
+[FV.FvTempMemorySilicon]
+FvAlignment = 16
+FvForceRebase = TRUE
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+FvNameGuid = 229EEDCE-8E76-4809-B233-EC36BFBF6989
+
+INF RuleOverride=RESET_SECMAIN USE = IA32 $(BOARD_PKG)/SecCore/SecMain.inf
+!include $(SKT_PKG)/SktSecInclude.fdf
+
+[FV.FvPreMemory]
+FvAlignment = 16
+FvForceRebase = TRUE
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+FvNameGuid = 6522280D-28F9-4131-ADC4-F40EBFA45864
+
+##
+# PEI Apriori file example, more PEIM module added later.
+##
+INF MdeModulePkg/Core/Pei/PeiMain.inf
+!include $(SKT_PKG)/SktPreMemoryInclude.fdf
+!include $(PCH_PKG)/IchPreMemoryInclude.fdf
+!include MinPlatformPkg/Include/Fdf/CorePreMemoryInclude.fdf
+INF MinPlatformPkg/PlatformInit/ReportFv/ReportFvPei.inf
+INF MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPreMem.inf
+INF MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMem.inf
+!include MinPlatformPkg/Include/Fdf/CoreSecurityPreMemoryInclude.fdf
+!include AdvancedFeaturePkg/Include/Fdf/CoreAdvancedPreMemoryInclude.fdf
+INF $(BOARD_PKG)/SimicsPei/SimicsPei.inf
+!include $(SKT_PKG)/SktPostMemoryInclude.fdf
+!include $(PCH_PKG)/IchPostMemoryInclude.fdf
+!include MinPlatformPkg/Include/Fdf/CorePostMemoryInclude.fdf
+INF MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPostMem.inf
+INF MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPostMem.inf
+!include MinPlatformPkg/Include/Fdf/CoreSecurityPostMemoryInclude.fdf
+!include AdvancedFeaturePkg/Include/Fdf/CoreAdvancedPostMemoryInclude.fdf
+
+INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
+INF $(SKT_PKG)/Smm/Access/SmmAccessPei.inf
+# S3 SMM PEI driver
+#INF UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
+
+[FV.DXEFV]
+FvNameGuid = EACAB9EA-C3C6-4438-8FD7-2270826DC0BB
+BlockSize = 0x10000
+FvAlignment = 16
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+
+!include MinPlatformPkg/Include/Fdf/CoreUefiBootInclude.fdf
+!include $(SKT_PKG)/SktUefiBootInclude.fdf
+!include $(PCH_PKG)/IchUefiBootInclude.fdf
+
+INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
+INF UefiCpuPkg/CpuDxe/CpuDxe.inf
+
+!include MinPlatformPkg/Include/Fdf/CoreOsBootInclude.fdf
+INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
+INF UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf
+INF MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
+INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+INF MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
+INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+
+INF MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+INF MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+INF MinPlatformPkg/Flash/SpiFvbService/SpiFvbServiceSmm.inf
+INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
+INF $(BOARD_PKG)/LegacySioDxe/LegacySioDxe.inf
+INF MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf
+
+INF $(BOARD_PKG)/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+
+INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
+INF $(BOARD_PKG)/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.inf
+INF RuleOverride=ACPITABLE $(BOARD_PKG)/AcpiTables/AcpiTables.inf
+
+INF $(BOARD_PKG)/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
+INF MinPlatformPkg/PlatformInit/PlatformInitDxe/PlatformInitDxe.inf
+INF MinPlatformPkg/PlatformInit/PlatformInitSmm/PlatformInitSmm.inf
+INF $(BOARD_PKG)/SimicsDxe/SimicsDxe.inf
+
+FILE FREEFORM = 7BB28B99-61BB-11D5-9A5D-0090273FC14D {
+ SECTION RAW = $(BOARD_PKG)/Logo/Logo.bmp
+}
+
+INF ShellPkg/Application/Shell/Shell.inf
+
+#
+# Network modules
+#
+INF SimicsIch10SiliconBinPkg/UndiBinary/UndiDxe.inf
+
+!include AdvancedFeaturePkg/Include/Fdf/CoreAdvancedLateInclude.fdf
+
+!if gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosEnable == TRUE
+ INF AdvancedFeaturePkg/Smbios/SmbiosBasicDxe/SmbiosBasicDxe.inf
+!endif
+
+!include MinPlatformPkg/Include/Fdf/CoreSecurityLateInclude.fdf
+
+[FV.FVMAIN_COMPACT]
+FvNameGuid = 6189987A-DDA6-4060-B313-49168DA9BD46
+FvAlignment = 16
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+
+FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+ SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+ #
+ # These firmware volumes will have files placed in them uncompressed,
+ # and then both firmware volumes will be compressed in a single
+ # compression operation in order to achieve better overall compression.
+ #
+ SECTION FV_IMAGE = FvPreMemory
+ SECTION FV_IMAGE = DXEFV
+ }
+}
+
+!include DecomprScratchEnd.fdf.inc
+
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+
+!include MinPlatformPkg/Include/Fdf/RuleInclude.fdf
+
+[Rule.Common.SEC.RESET_VECTOR]
+ FILE RAW = $(NAMED_GUID) {
+ RAW RAW |.raw
+ }
+
+[Rule.Common.SEC.RESET_SECMAIN]
+ FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ PE32 PE32 Align = 16 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ }
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf.inc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf.inc
new file mode 100644
index 0000000000..9a7368b46c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.fdf.inc
@@ -0,0 +1,54 @@
+## @file
+# FDF include file that defines the main macros and sets the dependent PCDs.
+#
+# Copyright (C) 2014, Red Hat, Inc.
+# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#
+# Default flash size is 2MB.
+#
+# Defining FD_SIZE_2MB on the build command line can override this.
+#
+
+DEFINE BLOCK_SIZE = 0x1000
+DEFINE VARS_SIZE = 0x3e000
+DEFINE VARS_BLOCKS = 0x3e
+
+DEFINE FW_BASE_ADDRESS = 0xFFE00000
+DEFINE FW_SIZE = 0x00200000
+DEFINE FW_BLOCKS = 0x200
+DEFINE CODE_BASE_ADDRESS = 0xFFE80000
+DEFINE CODE_SIZE = 0x00180000
+DEFINE CODE_BLOCKS = 0x180
+DEFINE FVMAIN_SIZE = 0x0016C000
+DEFINE SECFV_OFFSET = 0x001EC000
+DEFINE SECFV_SIZE = 0x14000
+
+
+SET gBoardModuleTokenSpaceGuid.PcdSimicsFdBaseAddress = $(FW_BASE_ADDRESS)
+SET gBoardModuleTokenSpaceGuid.PcdSimicsFirmwareFdSize = $(FW_SIZE)
+SET gBoardModuleTokenSpaceGuid.PcdSimicsFirmwareBlockSize = $(BLOCK_SIZE)
+
+SET gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase = $(FW_BASE_ADDRESS)
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize = 0xE000
+
+SET gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase = gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+SET gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize = $(BLOCK_SIZE)
+
+SET gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase = gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase + gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize = $(BLOCK_SIZE)
+
+SET gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase = gBoardModuleTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize = 0x10000
+
+SET gEfiPchTokenSpaceGuid.PcdFlashAreaBaseAddress = 0xFFE00000
+SET gEfiPchTokenSpaceGuid.PcdFlashAreaSize = 0x00200000
+
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress = gEfiPchTokenSpaceGuid.PcdFlashAreaBaseAddress
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize = gEfiPchTokenSpaceGuid.PcdFlashAreaSize
+
+DEFINE MEMFD_BASE_ADDRESS = 0x800000
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgBuildOption.dsc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgBuildOption.dsc
new file mode 100644
index 0000000000..25998b83e7
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgBuildOption.dsc
@@ -0,0 +1,78 @@
+## @file
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[BuildOptions.Common.EDKII]
+# Append build options for EDK and EDKII drivers (= is Append, == is Replace)
+
+ DEFINE EDKII_DSC_FEATURE_BUILD_OPTIONS =
+
+!if $(TARGET) == "DEBUG"
+ DEFINE DEBUG_BUILD_FLAG = -D SERIAL_DBG_MSG=1
+!else
+ DEFINE DEBUG_BUILD_FLAG = -D MDEPKG_NDEBUG -D SILENT_MODE
+!endif
+
+ DEFINE EDKII_DSC_FEATURE_BUILD_OPTIONS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS) $(DEBUG_BUILD_FLAG)
+#
+# PC_BUILD_END
+#
+
+
+ DEFINE EDKII_DSC_FEATURE_BUILD_OPTIONS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+
+
+ *_*_IA32_CC_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_IA32_VFRPP_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_IA32_APP_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_IA32_PP_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_IA32_ASLPP_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_IA32_ASLCC_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+
+ *_*_X64_CC_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_X64_VFRPP_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_X64_APP_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_X64_PP_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_X64_ASLPP_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+ *_*_X64_ASLCC_FLAGS = $(EDKII_DSC_FEATURE_BUILD_OPTIONS)
+
+
+
+#
+# Enable source level debugging for RELEASE build
+#
+!if $(TARGET) == "RELEASE"
+ DEFINE EDKII_RELEASE_SRCDBG_ASM_BUILD_OPTIONS = /Zi
+ DEFINE EDKII_RELEASE_SRCDBG_CC_BUILD_OPTIONS = /Zi /Gm
+ DEFINE EDKII_RELEASE_SRCDBG_DLINK_BUILD_OPTIONS = /DEBUG
+
+ MSFT:*_*_*_ASM_FLAGS = $(EDKII_RELEASE_SRCDBG_ASM_BUILD_OPTIONS)
+ MSFT:*_*_*_CC_FLAGS = $(EDKII_RELEASE_SRCDBG_CC_BUILD_OPTIONS)
+ MSFT:*_*_*_DLINK_FLAGS = $(EDKII_RELEASE_SRCDBG_DLINK_BUILD_OPTIONS)
+!endif
+
+
+#
+# Override the existing iasl path in tools_def.template
+#
+# MSFT:*_*_*_ASL_PATH == c:/Iasl/iasl.exe
+
+#
+# Override the VFR compile flags to speed the build time
+#
+
+*_*_*_VFR_FLAGS == -n
+
+# Force PE/COFF sections to be aligned at 4KB boundaries to support page level protection
+#[BuildOptions.common.EDKII.DXE_SMM_DRIVER, BuildOptions.common.EDKII.SMM_CORE]
+# MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+# GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+# Force PE/COFF sections to be aligned at 4KB boundaries to support MemoryAttribute table
+#[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+# MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096
+# GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgConfig.dsc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgConfig.dsc
new file mode 100644
index 0000000000..75de60e5bc
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgConfig.dsc
@@ -0,0 +1,56 @@
+## @file
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#
+# TRUE is ENABLE. FALSE is DISABLE.
+#
+
+[PcdsFixedAtBuild]
+ gMinPlatformPkgTokenSpaceGuid.PcdBootStage|4
+
+[PcdsFeatureFlag]
+ gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|FALSE
+ gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|FALSE
+ gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|FALSE
+ gMinPlatformPkgTokenSpaceGuid.PcdUefiSecureBootEnable|FALSE
+ gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable|FALSE
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 1
+ gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|TRUE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 2
+ gMinPlatformPkgTokenSpaceGuid.PcdStopAfterDebugInit|FALSE
+ gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|TRUE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 3
+ gMinPlatformPkgTokenSpaceGuid.PcdStopAfterMemInit|FALSE
+ gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|TRUE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 4
+ gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly|FALSE
+!endif
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootStage >= 5
+ gMinPlatformPkgTokenSpaceGuid.PcdUefiSecureBootEnable|TRUE
+ gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable|TRUE
+!endif
+
+ !if $(TARGET) == DEBUG
+ gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable|TRUE
+ !else
+ gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable|FALSE
+ !endif
+
+ gMinPlatformPkgTokenSpaceGuid.PcdPerformanceEnable|FALSE
+
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdNetworkEnable|TRUE
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosEnable|TRUE
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgPcd.dsc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgPcd.dsc
new file mode 100644
index 0000000000..3bf10ee524
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgPcd.dsc
@@ -0,0 +1,281 @@
+## @file
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+[PcdsFeatureFlag.common]
+!if $(TARGET) == RELEASE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
+!else
+ gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE
+!endif
+ # Server doesn't support capsle update on Reset.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|FALSE
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmEnableBspElection|FALSE
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugSupport|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport|FALSE
+
+
+#S3 add
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|TRUE
+#S3 add
+
+ ## This PCD specified whether ACPI SDT protocol is installed.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
+
+[PcdsFeatureFlag.X64]
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard|FALSE
+
+[PcdsFeatureFlag]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdBrowerGrayOutReadOnlyMenu|TRUE
+
+[PcdsDynamicExDefault]
+
+[PcdsFixedAtBuild.common]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|TRUE
+!if $(TARGET) == "RELEASE"
+ gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x03
+!else
+ gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+!endif
+ gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+ gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable|0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x0
+#S3 modified
+ gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnS3Boot|TRUE
+#S3 modified
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x0
+ gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x0
+ gEfiMdePkgTokenSpaceGuid.PcdFSBClock|133333333
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeiStackSize|0x100000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizeNonPopulateCapsule|0x1700000
+
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|10000
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|512
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x4000
+
+ ## Specifies delay value in microseconds after sending out an INIT IPI.
+ # @Prompt Configure delay value after send an INIT IPI
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds|10
+
+ ## Specifies max supported number of Logical Processors.
+ # @Prompt Configure max supported number of Logical Processorss
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|512
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize|0x1000
+!if gMinPlatformPkgTokenSpaceGuid.PcdPerformanceEnable == TRUE
+ gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x1
+!endif
+
+ ## Defines the ACPI register set base address.
+ # The invalid 0xFFFF is as its default value. It must be configured to the real value.
+ # @Prompt ACPI Timer IO Port Address
+ gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddress | 0x0400
+
+ ## Defines the PCI Bus Number of the PCI device that contains the BAR and Enable for ACPI hardware registers.
+ # @Prompt ACPI Hardware PCI Bus Number
+ gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBusNumber | 0x00
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision|0x00000002
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId|0x4C544E49
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision|0x20091013
+
+ ## Defines the PCI Device Number of the PCI device that contains the BAR and Enable for ACPI hardware registers.
+ # The invalid 0xFF is as its default value. It must be configured to the real value.
+ # @Prompt ACPI Hardware PCI Device Number
+ gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciDeviceNumber | 0x1F
+
+ ## Defines the PCI Function Number of the PCI device that contains the BAR and Enable for ACPI hardware registers.
+ # The invalid 0xFF is as its default value. It must be configured to the real value.
+ # @Prompt ACPI Hardware PCI Function Number
+ gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciFunctionNumber | 0x00
+
+ ## Defines the PCI Register Offset of the PCI device that contains the Enable for ACPI hardware registers.
+ # The invalid 0xFFFF is as its default value. It must be configured to the real value.
+ # @Prompt ACPI Hardware PCI Register Offset
+ gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciEnableRegisterOffset |0x0044
+
+ ## Defines the bit mask that must be set to enable the APIC hardware register BAR.
+ # @Prompt ACPI Hardware PCI Bar Enable BitMask
+ gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoBarEnableMask | 0x80
+
+ ## Defines the PCI Register Offset of the PCI device that contains the BAR for ACPI hardware registers.
+ # The invalid 0xFFFF is as its default value. It must be configured to the real value.
+ # @Prompt ACPI Hardware PCI Bar Register Offset
+ gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPciBarRegisterOffset |0x0040
+
+ ## Defines the offset to the 32-bit Timer Value register that resides within the ACPI BAR.
+ # @Prompt Offset to 32-bit Timer register in ACPI BAR
+ gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiPm1TmrOffset |0x0008
+
+ ## Defines the bit mask to retrieve ACPI IO Port Base Address
+ # @Prompt ACPI IO Port Base Address Mask
+ gPcAtChipsetPkgTokenSpaceGuid.PcdAcpiIoPortBaseAddressMask |0xFFFC
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+
+ gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuThreadCount|4
+ gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuCoreCount|128
+ gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuSocketCount|4
+ gMinPlatformPkgTokenSpaceGuid.PcdLocalApicAddress|0xFEE00000
+ gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicAddressBase|0xFEC01000
+ gMinPlatformPkgTokenSpaceGuid.PcdFadtPreferredPmProfile|0x0
+ gMinPlatformPkgTokenSpaceGuid.PcdFadtIaPcBootArch|0x0003
+ gMinPlatformPkgTokenSpaceGuid.PcdFadtFlags|0x000004A5
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1AEventBlockAddress|0x400
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1BEventBlockAddress|0
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1AControlBlockAddress|0x404
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm1BControlBlockAddress|0
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPm2ControlBlockAddress|0x450
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiPmTimerBlockAddress|0x408
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiGpe0BlockAddress|0x420
+ gMinPlatformPkgTokenSpaceGuid.PcdAcpiGpe1BlockAddress|0
+
+[PcdsFixedAtBuild.X64]
+ gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeMask|0x0eB8
+ gPcAtChipsetPkgTokenSpaceGuid.PcdMinimalValidYear|2015
+ gPcAtChipsetPkgTokenSpaceGuid.PcdMaximalValidYear|2099
+ # Change PcdBootManagerMenuFile to UiApp
+##
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable |TRUE
+
+ [PcdsPatchableInModule.common]
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable == TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmiHandlerProfilePropertyMask|0x1
+!endif
+
+ gPcAtChipsetPkgTokenSpaceGuid.PcdHpetBaseAddress|0xFED00000
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|1024
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable|TRUE
+
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashFvMicrocodeBase|0x0
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashFvMicrocodeSize|0x0
+
+[PcdsDynamicExDefault.common.DEFAULT]
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|30000
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuS3DataAddress|0
+
+[PcdsDynamicExHii.common.DEFAULT]
+ gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|50 # Variable: L"Timeout"
+ gEfiMdePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel|L"HwErrRecSupport"|gEfiGlobalVariableGuid|0x0|1 # Variable: L"HwErrRecSupport"
+
+
+[PcdsDynamicExDefault]
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMrIovSupport|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSystemPageSize|0x1F
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L""|VOID*|36
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId|{0x49, 0x4E, 0x54, 0x45, 0x4C, 0x20}
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId|0x2046573030363253
+
+[PcdsDynamicExDefault.X64]
+
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1
+ gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|0
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|31
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|100
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|800
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|600
+
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugDataAddress|0
+
+[PcdsFeatureFlag]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
+ #gOptionRomPkgTokenSpaceGuid.PcdSupportGop|TRUE
+ #gOptionRomPkgTokenSpaceGuid.PcdSupportUga|FALSE
+
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire|TRUE
+!endif
+
+[PcdsFixedAtBuild]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
+ gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x400
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x8000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xc000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0xc000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x2000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x10000
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
+
+ # DEBUG_INIT 0x00000001 // Initialization
+ # DEBUG_WARN 0x00000002 // Warnings
+ # DEBUG_LOAD 0x00000004 // Load events
+ # DEBUG_FS 0x00000008 // EFI File system
+ # DEBUG_POOL 0x00000010 // Alloc & Free (pool)
+ # DEBUG_PAGE 0x00000020 // Alloc & Free (page)
+ # DEBUG_INFO 0x00000040 // Informational debug messages
+ # DEBUG_DISPATCH 0x00000080 // PEI/DXE/SMM Dispatchers
+ # DEBUG_VARIABLE 0x00000100 // Variable
+ # DEBUG_BM 0x00000400 // Boot Manager
+ # DEBUG_BLKIO 0x00001000 // BlkIo Driver
+ # DEBUG_NET 0x00004000 // SNP Driver
+ # DEBUG_UNDI 0x00010000 // UNDI Driver
+ # DEBUG_LOADFILE 0x00020000 // LoadFile
+ # DEBUG_EVENT 0x00080000 // Event messages
+ # DEBUG_GCD 0x00100000 // Global Coherency Database changes
+ # DEBUG_CACHE 0x00200000 // Memory range cachability changes
+ # DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may
+ # // significantly impact boot performance
+ # DEBUG_ERROR 0x80000000 // Error
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
+
+ #
+ # PCI feature overrides.
+ #
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE
+
+################################################################################
+#
+# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsDynamicDefault]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0
+
+ gBoardModuleTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0
+ gBoardModuleTokenSpaceGuid.PcdPciIoBase|0x0
+ gBoardModuleTokenSpaceGuid.PcdPciIoSize|0x0
+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Base|0x0
+ gBoardModuleTokenSpaceGuid.PcdPciMmio32Size|0x0
+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Base|0x0
+ gBoardModuleTokenSpaceGuid.PcdPciMmio64Size|0x800000000
+
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType0StringBiosVersion|"Ver.1.0.0"
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType1StringProductName|"QSP UEFI BIOS"
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType2StringProductName|"QSP UEFI BIOS"
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType0StringBiosReleaseDate|"2019-08-09"
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable|FALSE
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/VarStore.fdf.inc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/VarStore.fdf.inc
new file mode 100644
index 0000000000..76c28e9efc
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/VarStore.fdf.inc
@@ -0,0 +1,53 @@
+## @file
+# FDF include file with Layout Regions that define an empty variable store.
+#
+# Copyright (C) 2014, Red Hat, Inc.
+# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+0x00000000|0x0003e000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+#NV_VARIABLE_STORE
+DATA = {
+ ## This is the EFI_FIRMWARE_VOLUME_HEADER
+ # ZeroVector []
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ # FileSystemGuid: gEfiSystemNvDataFvGuid =
+ # { 0xFFF12B8D, 0x7696, 0x4C8B,
+ # { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
+ 0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
+ 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
+ # FvLength: 0x80000
+ 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+ #Signature "_FVH" #Attributes
+ 0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
+ #HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision
+ 0x48, 0x00, 0x2A, 0x09, 0x00, 0x00, 0x00, 0x02,
+ #Blockmap[0]: 7 Blocks * 0x10000 Bytes / Block
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ #Blockmap[1]: End
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ ## This is the VARIABLE_STORE_HEADER
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ # Signature: gEfiAuthenticatedVariableGuid =
+ # { 0xaaf32c78, 0x947b, 0x439a,
+ # { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }}
+ 0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
+ 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
+!else
+ #Signature: gEfiVariableGuid =
+ # { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}
+ 0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
+ 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
+!endif
+ #Size: 0x3E000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x03DFB8
+ # This can speed up the Variable Dispatch a bit.
+ 0xB8, 0xDF, 0x03, 0x00,
+ # FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+ 0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/build_config.cfg b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/build_config.cfg
new file mode 100644
index 0000000000..72512837f5
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58Ich10/build_config.cfg
@@ -0,0 +1,31 @@
+# @ build_config.cfg
+# This is the BoardX58Ich10 board specific build settings
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+
+[CONFIG]
+WORKSPACE_PLATFORM_BIN = edk2-non-osi/Platform/Intel
+EDK_SETUP_OPTION =
+openssl_path =
+PLATFORM_BOARD_PACKAGE = SimicsOpenBoardPkg
+PROJECT = SimicsOpenBoardPkg/BoardX58Ich10
+BOARD = BoardX58Ich10
+FLASH_MAP_FDF = SimicsOpenBoardPkg/BoardX58Ich10/Include/Fdf/FlashMapInclude.fdf
+PROJECT_DSC = SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkg.dsc
+BOARD_PKG_PCD_DSC = SimicsOpenBoardPkg/BoardX58Ich10/OpenBoardPkgPcd.dsc
+PrepRELEASE = DEBUG
+SILENT_MODE = FALSE
+EXT_CONFIG_CLEAR =
+CapsuleBuild = FALSE
+EXT_BUILD_FLAGS =
+CAPSULE_BUILD = 0
+TARGET = DEBUG
+TARGET_SHORT = D
+PERFORMANCE_BUILD = FALSE
+FSP_WRAPPER_BUILD = FALSE
+FSP_BINARY_BUILD = FALSE
+FSP_TEST_RELEASE = FALSE
+SECURE_BOOT_ENABLE = FALSE
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [edk2-platforms PATCH v2 7/7] Platform/Intel: Add build option for SIMICS QSP Platform
2019-08-28 0:40 ` [edk2-platforms PATCH v2 7/7] Platform/Intel: Add build option for SIMICS QSP Platform David Wei
@ 2019-08-28 23:15 ` Nate DeSimone
0 siblings, 0 replies; 16+ messages in thread
From: Nate DeSimone @ 2019-08-28 23:15 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Kubacki, Michael A, Kinney, Michael D
Reviewed-by: Nate DeSimone <nathaniel.l.desimone@intel.com>
-----Original Message-----
From: Wei, David Y
Sent: Tuesday, August 27, 2019 5:40 PM
To: devel@edk2.groups.io
Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Kubacki, Michael A <michael.a.kubacki@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: [edk2-platforms PATCH v2 7/7] Platform/Intel: Add build option for SIMICS QSP Platform
Add build option in build script for SIMICS QSP Platform Add Maintainers of Simics QSP related packages
Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: David Wei <david.y.wei@intel.com>
---
Maintainers.txt | 12 ++++++++++++
Platform/Intel/build.cfg | 2 ++
Platform/Intel/build_bios.py | 3 +++
3 files changed, 17 insertions(+)
diff --git a/Maintainers.txt b/Maintainers.txt index b16432bf87..90eb3c3dd0 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -103,6 +103,10 @@ M: Chasel Chiu <chasel.chiu@intel.com>
M: Michael Kubacki <michael.a.kubacki@intel.com>
M: Nate DeSimone <nathaniel.l.desimone@intel.com>
+Platform/Intel/SimicsOpenBoardPkg
+M: Wei David Y <david.y.wei@intel.com>
+M: Agyeman Prince <prince.agyeman@intel.com>
+
Platform/Intel/Tools
M: Bob Feng <bob.c.feng@intel.com>
M: Liming Gao <liming.gao@intel.com>
@@ -155,6 +159,14 @@ M: Gillispie, Thad <thad.gillispie@intel.com>
M: Bu, Daocheng <daocheng.bu@intel.com>
M: Oram, Isaac W <isaac.w.oram@intel.com>
+Silicon/Intel/SimicsX58SktPkg
+M: Wei David Y <david.y.wei@intel.com>
+M: Agyeman Prince <prince.agyeman@intel.com>
+
+Silicon/Intel/SimicsIch10Pkg
+M: Wei David Y <david.y.wei@intel.com>
+M: Agyeman Prince <prince.agyeman@intel.com>
+
Silicon/Intel/Tools
M: Bob Feng <bob.c.feng@intel.com>
M: Liming Gao <liming.gao@intel.com>
diff --git a/Platform/Intel/build.cfg b/Platform/Intel/build.cfg index b6d32ada49..75cb446aa5 100644
--- a/Platform/Intel/build.cfg
+++ b/Platform/Intel/build.cfg
@@ -11,6 +11,7 @@ WORKSPACE =
WORKSPACE_FSP_BIN = FSP
EDK_TOOLS_BIN = edk2-BaseTools-win32
EDK_BASETOOLS = BaseTools
+WORKSPACE_DRIVERS = edk2-platforms/Drivers
WORKSPACE_PLATFORM = edk2-platforms/Platform/Intel WORKSPACE_SILICON = edk2-platforms/Silicon/Intel WORKSPACE_PLATFORM_BIN = @@ -52,6 +53,7 @@ NUMBER_OF_PROCESSORS = 0 [PLATFORMS] # board_name = path_to_board_build_config.cfg BoardMtOlympus = PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
+BoardX58Ich10 = SimicsOpenBoardPkg/BoardX58Ich10/build_config.cfg
KabylakeRvp3 = KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
N1xxWU = ClevoOpenBoardPkg/N1xxWU/build_config.cfg
WhiskeylakeURvp = WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
diff --git a/Platform/Intel/build_bios.py b/Platform/Intel/build_bios.py index 9152670dcb..46285df19a 100644
--- a/Platform/Intel/build_bios.py
+++ b/Platform/Intel/build_bios.py
@@ -104,6 +104,8 @@ def pre_build(build_config, build_type="DEBUG", silent=False, toolchain=None):
config["WORKSPACE_PLATFORM"])
config["WORKSPACE_SILICON"] = os.path.join(config["WORKSPACE"],
config["WORKSPACE_SILICON"])
+ config["WORKSPACE_DRIVERS"] = os.path.join(config["WORKSPACE"],
+
+ config["WORKSPACE_DRIVERS"])
config["WORKSPACE_PLATFORM_BIN"] = \
os.path.join(config["WORKSPACE"], config["WORKSPACE_PLATFORM_BIN"])
config["WORKSPACE_SILICON_BIN"] = \ @@ -115,6 +117,7 @@ def pre_build(build_config, build_type="DEBUG", silent=False, toolchain=None):
config["PACKAGES_PATH"] = config["WORKSPACE_PLATFORM"]
config["PACKAGES_PATH"] += os.pathsep + config["WORKSPACE_SILICON"]
config["PACKAGES_PATH"] += os.pathsep + config["WORKSPACE_SILICON_BIN"]
+ config["PACKAGES_PATH"] += os.pathsep + config["WORKSPACE_DRIVERS"]
config["PACKAGES_PATH"] += os.pathsep + \
os.path.join(config["WORKSPACE"], "FSP")
config["PACKAGES_PATH"] += os.pathsep + \
--
2.16.2.windows.1
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2019-08-28 23:16 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-08-28 0:40 [edk2-platforms PATCH v2 0/7] Add Initial QSP MinPlatform Pkg for SIMICS David Wei
2019-08-28 0:40 ` [edk2-platforms PATCH v2 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58 David Wei
2019-08-28 22:02 ` Nate DeSimone
2019-08-28 0:40 ` [edk2-platforms PATCH v2 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10 David Wei
2019-08-28 22:02 ` Nate DeSimone
2019-08-28 0:40 ` [edk2-platforms PATCH v2 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules David Wei
2019-08-28 22:02 ` Nate DeSimone
2019-08-28 0:40 ` [edk2-platforms PATCH v2 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio David Wei
2019-08-28 22:56 ` Nate DeSimone
2019-08-28 0:40 ` [edk2-platforms PATCH v2 5/7] SimicsOpenBoardPkg: Add Overrides modules and Logo image for SIMICS QSP Platform David Wei
2019-08-28 3:01 ` Liming Gao
2019-08-28 23:02 ` Nate DeSimone
2019-08-28 0:40 ` [edk2-platforms PATCH v2 6/7] SimicsOpenBoardPkg/BoardX58Ich10: Add board module for QSP Build tip David Wei
2019-08-28 23:13 ` Nate DeSimone
2019-08-28 0:40 ` [edk2-platforms PATCH v2 7/7] Platform/Intel: Add build option for SIMICS QSP Platform David Wei
2019-08-28 23:15 ` Nate DeSimone
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox